Skip to content

Commit b9450c6

Browse files
committed
fix: broken namespaced package parsing
1 parent d9b866b commit b9450c6

2 files changed

Lines changed: 21 additions & 15 deletions

File tree

src/core/prefix.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,17 @@ export function parseSkillInput(input: string): SkillSource {
6262
return { type: 'bare', package: rest }
6363
}
6464

65-
// @handle or @handle/collection
65+
// @handle (curator) or @scope/pkg (npm scoped package)
6666
if (trimmed.startsWith('@')) {
6767
const rest = trimmed.slice(1)
6868
const slashIdx = rest.indexOf('/')
6969
if (slashIdx === -1) {
7070
return { type: 'curator', handle: rest }
7171
}
72-
const handle = rest.slice(0, slashIdx)
73-
const name = rest.slice(slashIdx + 1)
74-
// Disambiguate: @scope/pkg (npm scoped) vs @handle/collection
75-
// Scoped npm packages need npm: prefix in the new world.
76-
// @handle with / is always a collection.
77-
return { type: 'collection', handle, name }
72+
// @scope/pkg → treat as npm scoped package (bare, deprecated form)
73+
// Collections must be installed via npm:@handle/coll or a future prefix.
74+
const { name, tag } = splitPackageTag(trimmed)
75+
return { type: 'bare', package: name, tag }
7876
}
7977

8078
// Try existing git detection (SSH, URLs, local paths, owner/repo shorthand)

test/unit/prefix.test.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,27 @@ describe('prefix parser', () => {
8282
})
8383
})
8484

85-
describe('@ prefix (curator and collection)', () => {
85+
describe('@ prefix (curator and scoped npm)', () => {
8686
it('parses @handle as curator', () => {
8787
expect(parseSkillInput('@antfu')).toEqual({
8888
type: 'curator',
8989
handle: 'antfu',
9090
})
9191
})
9292

93-
it('parses @handle/collection as collection', () => {
94-
expect(parseSkillInput('@antfu/vue-stack')).toEqual({
95-
type: 'collection',
96-
handle: 'antfu',
97-
name: 'vue-stack',
93+
it('parses @scope/pkg as bare scoped npm package', () => {
94+
expect(parseSkillInput('@nuxt/fonts')).toEqual({
95+
type: 'bare',
96+
package: '@nuxt/fonts',
97+
tag: undefined,
98+
})
99+
})
100+
101+
it('parses @scope/pkg@tag as bare scoped npm with tag', () => {
102+
expect(parseSkillInput('@nuxt/fonts@1.0.0')).toEqual({
103+
type: 'bare',
104+
package: '@nuxt/fonts',
105+
tag: '1.0.0',
98106
})
99107
})
100108
})
@@ -177,8 +185,8 @@ describe('prefix parser', () => {
177185
expect(resolveSkillName('@antfu')).toBeNull()
178186
})
179187

180-
it('returns null for collection', () => {
181-
expect(resolveSkillName('@antfu/utils')).toBeNull()
188+
it('returns scoped name for @scope/pkg', () => {
189+
expect(resolveSkillName('@nuxt/fonts')).toBe('@nuxt/fonts')
182190
})
183191

184192
it('returns crate:<name> for crate inputs', () => {

0 commit comments

Comments
 (0)