Skip to content
21 changes: 12 additions & 9 deletions packages/nuxi/src/commands/module/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ async function resolveModule(moduleName: string, cwd: string): Promise<ModuleRes
}

// Fetch package on npm
pkgVersion = pkgVersion || 'latest'
let version = pkgVersion || 'latest'
const pkgScope = pkgName.startsWith('@') ? pkgName.split('/')[0]! : null
const meta: RegistryMeta = await detectNpmRegistry(pkgScope)
const headers: HeadersInit = {}
Expand All @@ -298,14 +298,17 @@ async function resolveModule(moduleName: string, cwd: string): Promise<ModuleRes
headers.Authorization = `Bearer ${meta.authToken}`
}

const pkgDetails = await $fetch(joinURL(meta.registry, `${pkgName}`), {
headers,
})
const pkgDetails = await $fetch(joinURL(meta.registry, `${pkgName}`), { headers })

// check if a dist-tag exists
pkgVersion = (pkgDetails['dist-tags']?.[pkgVersion] || pkgVersion) as string
// fully resolve the version
if (pkgDetails['dist-tags']?.[version]) {
version = pkgDetails['dist-tags'][version]
}
else {
version = Object.keys(pkgDetails.versions)?.findLast(v => satisfies(v, version)) || version
}

const pkg = pkgDetails.versions[pkgVersion]
const pkg = pkgDetails.versions[version!]

const pkgDependencies = Object.assign(
pkg.dependencies || {},
Expand All @@ -332,9 +335,9 @@ async function resolveModule(moduleName: string, cwd: string): Promise<ModuleRes

return {
nuxtModule: matchedModule,
pkg: `${pkgName}@${pkgVersion}`,
pkg: `${pkgName}@${version}`,
pkgName,
pkgVersion,
pkgVersion: version,
}
}

Expand Down
74 changes: 70 additions & 4 deletions packages/nuxi/test/unit/commands/module/add.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as runCommands from '../../../../src/run'

const updateConfig = vi.fn(() => Promise.resolve())
const addDependency = vi.fn(() => Promise.resolve())
let v3 = '3.0.0'
interface CommandsType {
subCommands: {
// biome-ignore lint/correctness/noEmptyPattern: <explanation>
Expand Down Expand Up @@ -36,13 +37,46 @@ function applyMocks() {
},
}
})
vi.mock('ofetch', async () => {
return {
$fetch: vi.fn(() => Promise.resolve({
'name': '@nuxt/content',
'npm': '@nuxt/content',
'devDependencies': {
nuxt: v3,
},
'dist-tags': { latest: v3 },
'versions': {
[v3]: {
devDependencies: {
nuxt: v3,
},
},
'3.1.1': {
devDependencies: {
nuxt: v3,
},
},
'2.9.0': {
devDependencies: {
nuxt: v3,
},
},
'2.13.1': {
devDependencies: {
nuxt: v3,
},
},
},
})),
}
})
}
describe('module add', () => {
let v3: string
beforeAll(async () => {
v3 = await fetch('https://registry.npmjs.org/@nuxt/content')
.then(r => r.json())
.then(r => r['dist-tags'].latest)
const response = await fetch('https://registry.npmjs.org/@nuxt/content')
const json = await response.json()
v3 = json['dist-tags'].latest
})
applyMocks()
vi.spyOn(runCommands, 'runCommand').mockImplementation(vi.fn())
Expand Down Expand Up @@ -105,4 +139,36 @@ describe('module add', () => {
installPeerDependencies: true,
})
})

it('should convert major only version to full semver', async () => {
const addCommand = await (commands as CommandsType).subCommands.add()
await addCommand.setup({
args: {
cwd: '/fake-dir',
_: ['content@2'],
},
})

expect(addDependency).toHaveBeenCalledWith(['@nuxt/content@2.13.1'], {
cwd: '/fake-dir',
dev: true,
installPeerDependencies: true,
})
})

it('should convert not full version to full semver', async () => {
const addCommand = await (commands as CommandsType).subCommands.add()
await addCommand.setup({
args: {
cwd: '/fake-dir',
_: ['content@3.1'],
},
})

expect(addDependency).toHaveBeenCalledWith(['@nuxt/content@3.1.1'], {
cwd: '/fake-dir',
dev: true,
installPeerDependencies: true,
})
})
})
Loading