Skip to content

Commit ce79ce9

Browse files
committed
Merge remote-tracking branch 'origin/main' into vt/feat-exec
2 parents e660183 + c07a41a commit ce79ce9

40 files changed

Lines changed: 1146 additions & 204 deletions

.lighthouserc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"assert": {
1818
"assertions": {
19-
"categories:accessibility": ["warn", { "minScore": 0.9 }]
19+
"categories:accessibility": ["warn", { "minScore": 1 }]
2020
}
2121
},
2222
"upload": {

README.md

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
1818
- **URL compatible** – Replace `npmjs.com` with `xnpmjs.com` or `npmx.dev` in any URL and it just works.
1919
- **Simplicity** – No noise, cluttered display, or confusing UI. If in doubt: choose simplicity.
2020

21+
## Shortcuts
22+
23+
> [!IMPORTANT]
24+
> We're keeping the website, repository, and our discord community low profile until the browser is polished enough. We'll do formal announcement at that point. Please avoid sharing the website or the invite link to discord in social media in a direct way. The repo is public, so people that care about the project can easily find it and join us. Anyone that wants to help is more than welcomed to [join us in Discord](https://chat.npm.dev). If you know others that would be interested, please invite them too!
25+
26+
- [chat.npmx.dev](https://chat.npmx.dev) - Discord Server
27+
- [social.npmx.dev](https://social.npmx.dev) - Bluesky Profile
28+
- [repo.npmx.dev](https://repo.npmx.dev) - GitHub Repository
29+
- [issues.npmx.dev](https://issues.npmx.dev) - GitHub Issues
30+
- [coc.npmx.dev](https://coc.npmx.dev) - Code of Conduct
31+
- [contributing.npmx.dev](https://contributing.npmx.dev) - Contributing Guide
32+
2133
## Features
2234

2335
### Package browsing
@@ -29,15 +41,18 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
2941
- **Provenance indicators** – verified build badges for packages with npm provenance
3042
- **Multi-provider repository support** – stars/forks from GitHub, GitLab, Bitbucket, Codeberg, Gitee, and Sourcehut
3143
- **JSR availability** – see if scoped packages are also available on JSR
32-
- **Package badges** – module format (ESM/CJS/dual), TypeScript types, and engine constraints
44+
- **Package badges** – module format (ESM/CJS/dual), TypeScript types (with `@types/*` links), and engine constraints
3345
- **Outdated dependency indicators** – visual cues showing which dependencies are behind
3446
- **Vulnerability warnings** – security advisories from the OSV database
3547
- **Download statistics** – weekly download counts with sparkline charts
36-
- **Install size** – total install size including dependencies
48+
- **Install size** – total install size (including transitive dependencies)
3749
- **Playground links** – quick access to StackBlitz, CodeSandbox, and other demo environments from READMEs
3850
- **Infinite search** – auto-load additional search pages as you scroll
39-
- **Keyboard navigation** – press `/` to focus search, arrow keys to navigate results, Enter to select
51+
- **Keyboard navigation** – press `/` to focus search, `.` to open code viewer, arrow keys to navigate results
52+
- **Deprecation notices** – clear warnings for deprecated packages and versions
53+
- **Version range resolution** – dependency ranges (e.g., `^1.0.0`) resolve to actual installed versions
4054
- **Claim new packages** – register new package names directly from search results (via local connector)
55+
- **Clickable version tags** – navigate directly to any version from the versions list
4156

4257
### User & org pages
4358

@@ -65,10 +80,12 @@ The aim of [npmx.dev](https://npmx.dev) is to provide a better browser for the n
6580
| Install size calculation |||
6681
| JSR cross-reference |||
6782
| Vulnerability warnings |||
83+
| Deprecation notices |||
6884
| Download charts |||
6985
| Playground links |||
7086
| Keyboard navigation |||
7187
| Multi-provider repo support |||
88+
| Version range resolution |||
7289
| Dependents list || 🚧 |
7390
| Package admin (access/owners) || 🚧 |
7491
| Org/team management || 🚧 |
@@ -105,12 +122,13 @@ npmx.dev supports npm permalinks – just replace `npmjs.com` with `npmx.dev
105122

106123
npmx.dev also supports shorter, cleaner URLs:
107124

108-
| Pattern | Example |
109-
| -------------- | -------------------------------------------------- |
110-
| `/<package>` | [`/nuxt`](https://npmx.dev/nuxt) |
111-
| `/@scope/name` | [`/@nuxt/kit`](https://npmx.dev/@nuxt/kit) |
112-
| `/@org` | [`/@nuxt`](https://npmx.dev/@nuxt) |
113-
| `/~username` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
125+
| Pattern | Example |
126+
| ------------------ | -------------------------------------------------- |
127+
| `/<package>` | [`/nuxt`](https://npmx.dev/nuxt) |
128+
| `/<pkg>@<version>` | [`/vue@3.4.0`](https://npmx.dev/vue@3.4.0) |
129+
| `/@scope/name` | [`/@nuxt/kit`](https://npmx.dev/@nuxt/kit) |
130+
| `/@org` | [`/@nuxt`](https://npmx.dev/@nuxt) |
131+
| `/~username` | [`/~sindresorhus`](https://npmx.dev/~sindresorhus) |
114132

115133
## Tech stack
116134

@@ -122,7 +140,7 @@ npmx.dev also supports shorter, cleaner URLs:
122140

123141
## Contributing
124142

125-
I'd welcome contributions &ndash; please do feel free to poke around and improve things. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to get up and running!
143+
We welcome contributions &ndash; please do feel free to poke around and improve things. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to get up and running!
126144

127145
## Related projects
128146

@@ -132,7 +150,7 @@ I'd welcome contributions &ndash; please do feel free to poke around and improve
132150
- [npm-alt](https://npm.willow.sh/) &ndash; An alternative npm package browser
133151
- [npkg.lorypelli.dev](https://npkg.lorypelli.dev/) &ndash; An alternative frontend to npm made with as little client-side JavaScript as possible
134152

135-
If you're building something cool, let me know! 🙏
153+
If you're building something cool, let us know! 🙏
136154

137155
## License
138156

app/components/AppFooter.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ onUnmounted(() => {
8383
: // JS-controlled: fixed position, hidden by default, transition only after mount
8484
isScrollable
8585
? [
86-
'fixed bottom-0 left-0 right-0 z-40 translate-y-full',
86+
'fixed bottom-0 left-0 right-0 z-40',
8787
isMounted && 'transition-transform duration-300 ease-out',
88-
isVisible && 'translate-y-0',
88+
isVisible ? 'translate-y-0' : 'translate-y-full',
8989
]
9090
: 'mt-auto',
9191
]"
@@ -97,19 +97,25 @@ onUnmounted(() => {
9797
<p class="text-xs text-fg-muted m-0 sm:hidden">not affiliated with npm, Inc.</p>
9898
<div class="flex items-center gap-4 sm:gap-6">
9999
<a
100-
href="https://github.com/npmx-dev/npmx.dev"
100+
href="https://repo.npmx.dev"
101101
rel="noopener noreferrer"
102-
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
102+
class="link-subtle font-mono text-xs min-h-11 min-w- flex items-center"
103103
>
104104
source
105105
</a>
106-
<span class="text-border">|</span>
107106
<a
108-
href="https://roe.dev"
107+
href="https://social.npmx.dev"
108+
rel="noopener noreferrer"
109+
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
110+
>
111+
social
112+
</a>
113+
<a
114+
href="https://chat.npmx.dev"
109115
rel="noopener noreferrer"
110116
class="link-subtle font-mono text-xs min-h-11 min-w-11 flex items-center"
111117
>
112-
@danielroe
118+
chat
113119
</a>
114120
</div>
115121
</div>

app/components/AppHeader.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ withDefaults(
3030
<NuxtLink
3131
to="/search"
3232
class="link-subtle font-mono text-sm inline-flex items-center gap-2"
33+
aria-keyshortcuts="/"
3334
>
3435
search
3536
<kbd
3637
class="hidden sm:inline-flex items-center justify-center w-5 h-5 text-xs bg-bg-muted border border-border rounded"
37-
>/</kbd
38+
aria-hidden="true"
3839
>
40+
/
41+
</kbd>
3942
</NuxtLink>
4043
</li>
4144
<li v-if="showConnector" class="flex">

app/components/OrgMembersPanel.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { NewOperation } from '~/composables/useConnector'
3+
import { buildScopeTeam } from '~/utils/npm'
34
45
const props = defineProps<{
56
orgName: string
@@ -144,10 +145,10 @@ async function loadTeamMemberships() {
144145
try {
145146
const teamsResult = await listOrgTeams(props.orgName)
146147
if (teamsResult) {
147-
// Teams come as "org:team" format
148+
// Teams come as "org:team" format from npm, need @scope:team for API calls
148149
const teamPromises = teamsResult.map(async (fullTeamName: string) => {
149150
const teamName = fullTeamName.replace(`${props.orgName}:`, '')
150-
const membersResult = await listTeamUsers(fullTeamName)
151+
const membersResult = await listTeamUsers(buildScopeTeam(props.orgName, teamName))
151152
if (membersResult) {
152153
teamMembers.value[teamName] = membersResult
153154
}
@@ -183,7 +184,7 @@ async function handleAddMember() {
183184
// Second operation: add user to team (if a team is selected)
184185
// This depends on the org operation completing first
185186
if (newTeam.value && addedOrgOp) {
186-
const scopeTeam = `${props.orgName}:${newTeam.value}`
187+
const scopeTeam = buildScopeTeam(props.orgName, newTeam.value)
187188
const teamOperation: NewOperation = {
188189
type: 'team:add-user',
189190
params: {

app/components/OrgTeamsPanel.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { NewOperation } from '~/composables/useConnector'
3+
import { buildScopeTeam } from '~/utils/npm'
34
45
const props = defineProps<{
56
orgName: string
@@ -103,7 +104,7 @@ async function loadTeamUsers(teamName: string) {
103104
isLoadingUsers.value[teamName] = true
104105
105106
try {
106-
const scopeTeam = `${props.orgName}:${teamName}`
107+
const scopeTeam = buildScopeTeam(props.orgName, teamName)
107108
const result = await listTeamUsers(scopeTeam)
108109
if (result) {
109110
teamUsers.value[teamName] = result
@@ -135,7 +136,7 @@ async function handleCreateTeam() {
135136
isCreatingTeam.value = true
136137
try {
137138
const teamName = newTeamName.value.trim()
138-
const scopeTeam = `${props.orgName}:${teamName}`
139+
const scopeTeam = buildScopeTeam(props.orgName, teamName)
139140
const operation: NewOperation = {
140141
type: 'team:create',
141142
params: { scopeTeam },
@@ -153,7 +154,7 @@ async function handleCreateTeam() {
153154
154155
// Destroy team
155156
async function handleDestroyTeam(teamName: string) {
156-
const scopeTeam = `${props.orgName}:${teamName}`
157+
const scopeTeam = buildScopeTeam(props.orgName, teamName)
157158
const operation: NewOperation = {
158159
type: 'team:destroy',
159160
params: { scopeTeam },
@@ -171,7 +172,7 @@ async function handleAddUser(teamName: string) {
171172
isAddingUser.value = true
172173
try {
173174
const username = newUserUsername.value.trim().replace(/^@/, '')
174-
const scopeTeam = `${props.orgName}:${teamName}`
175+
const scopeTeam = buildScopeTeam(props.orgName, teamName)
175176
176177
let dependsOnId: string | undefined
177178
@@ -213,7 +214,7 @@ async function handleAddUser(teamName: string) {
213214
214215
// Remove user from team
215216
async function handleRemoveUser(teamName: string, username: string) {
216-
const scopeTeam = `${props.orgName}:${teamName}`
217+
const scopeTeam = buildScopeTeam(props.orgName, teamName)
217218
const operation: NewOperation = {
218219
type: 'team:rm-user',
219220
params: { scopeTeam, user: username },

app/components/PackageAccessControls.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { NewOperation } from '~/composables/useConnector'
3+
import { buildScopeTeam } from '~/utils/npm'
34
45
const props = defineProps<{
56
packageName: string
@@ -96,7 +97,7 @@ async function handleGrantAccess() {
9697
9798
isGranting.value = true
9899
try {
99-
const scopeTeam = `${orgName.value}:${selectedTeam.value}`
100+
const scopeTeam = buildScopeTeam(orgName.value, selectedTeam.value)
100101
const operation: NewOperation = {
101102
type: 'access:grant',
102103
params: {

0 commit comments

Comments
 (0)