Skip to content

Commit c113f64

Browse files
authored
Merge branch 'main' into main
2 parents 3785a31 + d9376d0 commit c113f64

67 files changed

Lines changed: 1490 additions & 2850 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/autofix.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- uses: actions/setup-node@v6
2020
with:
2121
node-version: lts/*
22-
cache: "pnpm"
22+
cache: 'pnpm'
2323

2424
- name: 📦 Install dependencies
2525
run: pnpm install

.oxfmtrc.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "./node_modules/oxfmt/configuration_schema.json",
3+
"semi": false,
4+
"singleQuote": true,
5+
"arrowParens": "avoid",
6+
"quoteProps": "consistent",
7+
"experimentalSortPackageJson": false
8+
}

.oxlintrc.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"$schema": "./node_modules/oxlint/configuration_schema.json",
3+
"plugins": ["unicorn", "typescript", "oxc", "vue", "vitest"],
4+
"categories": {
5+
"correctness": "error",
6+
"suspicious": "warn",
7+
"perf": "warn"
8+
},
9+
"rules": {
10+
"no-console": "warn",
11+
"no-await-in-loop": "off",
12+
"unicorn/no-array-sort": "off"
13+
},
14+
"ignorePatterns": [
15+
".output/**",
16+
".data/**",
17+
".nuxt/**",
18+
".nitro/**",
19+
".cache/**",
20+
"dist/**",
21+
"node_modules/**",
22+
"coverage/**",
23+
"playwright-report/**",
24+
"test-results/**"
25+
]
26+
}

.vscode/extensions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"recommendations": ["oxc.oxc-vscode", "Vue.volar"]
3+
}

README.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,20 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
2727
- **Provenance indicators** - verified build indicators for packages with npm provenance
2828
- **Admin features** - org/team management, package access controls via local connector (coming soon)
2929

30-
### URL Compatibility
30+
### URL compatibility
3131

3232
npmx.dev supports npm permalink patterns:
3333

34-
| Pattern | Example |
35-
|---------|---------|
36-
| `/package/<name>` | [`/package/nuxt`](https://npmx.dev/package/nuxt) |
37-
| `/package/@scope/name` | [`/package/@nuxt/kit`](https://npmx.dev/package/@nuxt/kit) |
34+
| Pattern | Example |
35+
| ----------------------------- | -------------------------------------------------------------- |
36+
| `/package/<name>` | [`/package/nuxt`](https://npmx.dev/package/nuxt) |
37+
| `/package/@scope/name` | [`/package/@nuxt/kit`](https://npmx.dev/package/@nuxt/kit) |
3838
| `/package/<name>/v/<version>` | [`/package/vue/v/3.4.0`](https://npmx.dev/package/vue/v/3.4.0) |
39-
| `/search?q=<query>` | [`/search?q=vue`](https://npmx.dev/search?q=vue) |
40-
| `/~<username>` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
41-
| `/org/<name>` | [`/org/nuxt`](https://npmx.dev/org/nuxt) |
39+
| `/search?q=<query>` | [`/search?q=vue`](https://npmx.dev/search?q=vue) |
40+
| `/~<username>` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
41+
| `/org/<name>` | [`/org/nuxt`](https://npmx.dev/org/nuxt) |
4242

43-
## Tech Stack
43+
## Tech stack
4444

4545
- [Nuxt 4](https://nuxt.com/)
4646
- [Nitro](https://nuxt.com/docs/guide/concepts/server-engine)
@@ -50,6 +50,8 @@ npmx.dev supports npm permalink patterns:
5050

5151
## Try it out locally
5252

53+
I'd welcome contributions &ndash; please do feel free to poke around and improve things. Here's how you can get going locally.
54+
5355
### Setup
5456

5557
```bash
@@ -83,7 +85,7 @@ pnpm test:browser
8385
pnpm test:types
8486
```
8587

86-
### Local Connector (CLI)
88+
### Local connector (CLI)
8789

8890
The `cli/` workspace contains a local connector that enables authenticated npm operations from the web UI. It runs on your machine and uses your existing npm credentials.
8991

@@ -98,6 +100,14 @@ node cli/dist/cli.mjs
98100

99101
The connector will check your npm authentication, generate a connection token, and listen for requests from npmx.dev.
100102

103+
## Related projects
104+
105+
- [JSR](https://jsr.io/) - The open-source package registry for modern JavaScript and TypeScript
106+
- [npm-userscript](https://github.com/bluwy/npm-userscript) - Browser userscript with various improvements and fixes for npmjs.com
107+
- [npm-alt](https://npm.willow.sh/) - An alternative npm package browser
108+
109+
If you're building something cool, let me know! 🙏
110+
101111
## License
102112

103113
Made with ❤️

app/app.vue

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const router = useRouter()
55
const isHomepage = computed(() => route.path === '/')
66
77
useHead({
8-
titleTemplate: (titleChunk) => {
8+
titleTemplate: titleChunk => {
99
return titleChunk ? titleChunk : 'npmx - Better npm Package Browser'
1010
},
1111
})
@@ -14,11 +14,7 @@ useHead({
1414
function handleGlobalKeydown(e: KeyboardEvent) {
1515
// Ignore if user is typing in an input, textarea, or contenteditable
1616
const target = e.target as HTMLElement
17-
if (
18-
target.tagName === 'INPUT'
19-
|| target.tagName === 'TEXTAREA'
20-
|| target.isContentEditable
21-
) {
17+
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
2218
return
2319
}
2420
@@ -32,8 +28,7 @@ function handleGlobalKeydown(e: KeyboardEvent) {
3228
3329
if (searchInput) {
3430
searchInput.focus()
35-
}
36-
else {
31+
} else {
3732
// Navigate to search page
3833
router.push('/search')
3934
}
@@ -51,17 +46,11 @@ onUnmounted(() => {
5146

5247
<template>
5348
<div class="min-h-screen flex flex-col bg-bg text-fg">
54-
<a
55-
href="#main-content"
56-
class="skip-link font-mono"
57-
>Skip to main content</a>
49+
<a href="#main-content" class="skip-link font-mono">Skip to main content</a>
5850

5951
<AppHeader :show-logo="!isHomepage" />
6052

61-
<div
62-
id="main-content"
63-
class="flex-1"
64-
>
53+
<div id="main-content" class="flex-1">
6554
<NuxtPage />
6655
</div>
6756

@@ -71,7 +60,9 @@ onUnmounted(() => {
7160

7261
<style>
7362
/* Base reset and defaults */
74-
*, *::before, *::after {
63+
*,
64+
*::before,
65+
*::after {
7566
box-sizing: border-box;
7667
}
7768
@@ -94,7 +85,9 @@ a {
9485
text-decoration: underline;
9586
text-underline-offset: 3px;
9687
text-decoration-color: #404040;
97-
transition: color 0.2s ease, text-decoration-color 0.2s ease;
88+
transition:
89+
color 0.2s ease,
90+
text-decoration-color 0.2s ease;
9891
}
9992
10093
a:hover {
@@ -190,12 +183,26 @@ button {
190183
}
191184
192185
/* Visual styling based on original README heading level */
193-
.readme-content [data-level="1"] { font-size: 1.5rem; }
194-
.readme-content [data-level="2"] { font-size: 1.25rem; padding-bottom: 0.5rem; border-bottom: 1px solid #262626; }
195-
.readme-content [data-level="3"] { font-size: 1.125rem; }
196-
.readme-content [data-level="4"] { font-size: 1rem; }
197-
.readme-content [data-level="5"] { font-size: 0.925rem; }
198-
.readme-content [data-level="6"] { font-size: 0.875rem; }
186+
.readme-content [data-level='1'] {
187+
font-size: 1.5rem;
188+
}
189+
.readme-content [data-level='2'] {
190+
font-size: 1.25rem;
191+
padding-bottom: 0.5rem;
192+
border-bottom: 1px solid #262626;
193+
}
194+
.readme-content [data-level='3'] {
195+
font-size: 1.125rem;
196+
}
197+
.readme-content [data-level='4'] {
198+
font-size: 1rem;
199+
}
200+
.readme-content [data-level='5'] {
201+
font-size: 0.925rem;
202+
}
203+
.readme-content [data-level='6'] {
204+
font-size: 0.875rem;
205+
}
199206
200207
.readme-content p {
201208
margin-bottom: 1rem;
@@ -310,52 +317,52 @@ button {
310317
}
311318
312319
/* Note - blue */
313-
.readme-content blockquote[data-callout="note"] {
320+
.readme-content blockquote[data-callout='note'] {
314321
border-left-color: #3b82f6;
315322
background: rgba(59, 130, 246, 0.05);
316323
}
317-
.readme-content blockquote[data-callout="note"]::before {
318-
content: "Note";
324+
.readme-content blockquote[data-callout='note']::before {
325+
content: 'Note';
319326
color: #3b82f6;
320327
}
321328
322329
/* Tip - green */
323-
.readme-content blockquote[data-callout="tip"] {
330+
.readme-content blockquote[data-callout='tip'] {
324331
border-left-color: #22c55e;
325332
background: rgba(34, 197, 94, 0.05);
326333
}
327-
.readme-content blockquote[data-callout="tip"]::before {
328-
content: "Tip";
334+
.readme-content blockquote[data-callout='tip']::before {
335+
content: 'Tip';
329336
color: #22c55e;
330337
}
331338
332339
/* Important - purple */
333-
.readme-content blockquote[data-callout="important"] {
340+
.readme-content blockquote[data-callout='important'] {
334341
border-left-color: #a855f7;
335342
background: rgba(168, 85, 247, 0.05);
336343
}
337-
.readme-content blockquote[data-callout="important"]::before {
338-
content: "Important";
344+
.readme-content blockquote[data-callout='important']::before {
345+
content: 'Important';
339346
color: #a855f7;
340347
}
341348
342349
/* Warning - yellow/orange */
343-
.readme-content blockquote[data-callout="warning"] {
350+
.readme-content blockquote[data-callout='warning'] {
344351
border-left-color: #eab308;
345352
background: rgba(234, 179, 8, 0.05);
346353
}
347-
.readme-content blockquote[data-callout="warning"]::before {
348-
content: "Warning";
354+
.readme-content blockquote[data-callout='warning']::before {
355+
content: 'Warning';
349356
color: #eab308;
350357
}
351358
352359
/* Caution - red */
353-
.readme-content blockquote[data-callout="caution"] {
360+
.readme-content blockquote[data-callout='caution'] {
354361
border-left-color: #ef4444;
355362
background: rgba(239, 68, 68, 0.05);
356363
}
357-
.readme-content blockquote[data-callout="caution"]::before {
358-
content: "Caution";
364+
.readme-content blockquote[data-callout='caution']::before {
365+
content: 'Caution';
359366
color: #ef4444;
360367
}
361368
@@ -424,15 +431,15 @@ p > span > code,
424431
}
425432
426433
/* Safari search input fixes */
427-
input[type="search"] {
434+
input[type='search'] {
428435
-webkit-appearance: none;
429436
appearance: none;
430437
}
431438
432-
input[type="search"]::-webkit-search-decoration,
433-
input[type="search"]::-webkit-search-cancel-button,
434-
input[type="search"]::-webkit-search-results-button,
435-
input[type="search"]::-webkit-search-results-decoration {
439+
input[type='search']::-webkit-search-decoration,
440+
input[type='search']::-webkit-search-cancel-button,
441+
input[type='search']::-webkit-search-results-button,
442+
input[type='search']::-webkit-search-results-decoration {
436443
-webkit-appearance: none;
437444
appearance: none;
438445
}

app/components/AppFooter.vue

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
<footer class="border-t border-border mt-auto">
33
<div class="container py-8 flex flex-col gap-4 text-fg-subtle text-sm">
44
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
5-
<p class="font-mono m-0">
6-
a better browser for the npm registry
7-
</p>
5+
<p class="font-mono m-0">a better browser for the npm registry</p>
86
<div class="flex items-center gap-6">
97
<a
108
href="https://github.com/danielroe/npmx.dev"
@@ -14,11 +12,7 @@
1412
source
1513
</a>
1614
<span class="text-border">|</span>
17-
<a
18-
href="https://roe.dev"
19-
rel="noopener noreferrer"
20-
class="link-subtle font-mono text-xs"
21-
>
15+
<a href="https://roe.dev" rel="noopener noreferrer" class="link-subtle font-mono text-xs">
2216
@danielroe
2317
</a>
2418
</div>

0 commit comments

Comments
 (0)