From 155680886356d001bdb749c1d16647d87166d930 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Fri, 6 Dec 2024 13:59:30 +0100 Subject: [PATCH 1/3] feat: add multiple modules at once Co-authored-by: rohrig <45824492+rohrig@users.noreply.github.com> --- src/commands/module/add.ts | 141 +++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 68 deletions(-) diff --git a/src/commands/module/add.ts b/src/commands/module/add.ts index 4cc1b7f2e..511d8d4d0 100644 --- a/src/commands/module/add.ts +++ b/src/commands/module/add.ts @@ -26,6 +26,15 @@ export type RegistryMeta = { authToken: string | null } +type ResolvedModule = { + nuxtModule?: NuxtModule + pkg: string + pkgName: string + pkgVersion: string +} +type UnresolvedModule = false +type ModuleResolution = ResolvedModule | UnresolvedModule + export default defineCommand({ meta: { name: 'add', @@ -48,6 +57,7 @@ export default defineCommand({ }, async setup(ctx) { const cwd = resolve(ctx.args.cwd || '.') + const modules = ctx.args._ const projectPkg = await getProjectPackage(cwd) if (!projectPkg.dependencies?.nuxt && !projectPkg.devDependencies?.nuxt) { @@ -64,63 +74,13 @@ export default defineCommand({ } } - const r = await resolveModule(ctx.args.moduleName, cwd) - if (r === false) { - return - } - - // Add npm dependency - if (!ctx.args.skipInstall) { - const isDev = Boolean(projectPkg.devDependencies?.nuxt) - consola.info( - `Installing \`${r.pkg}\`${isDev ? ' development' : ''} dependency`, - ) - const res = await addDependency(r.pkg, { cwd, dev: isDev, installPeerDependencies: true }).catch( - (error) => { - consola.error(error) - return consola.prompt( - `Install failed for ${colors.cyan( - r.pkg, - )}. Do you want to continue adding the module to ${colors.cyan( - 'nuxt.config', - )}?`, - { - type: 'confirm', - initial: false, - }, - ) - }, - ) - if (res === false) { + for (const moduleName of modules) { + const r = await resolveModule(moduleName, cwd) + if (r === false) { return } - } - - // Update nuxt.config.ts - if (!ctx.args.skipConfig) { - await updateConfig({ - cwd, - configFile: 'nuxt.config', - async onCreate() { - consola.info(`Creating \`nuxt.config.ts\``) - return getDefaultNuxtConfig() - }, - async onUpdate(config) { - if (!config.modules) { - config.modules = [] - } - if (config.modules.includes(r.pkgName)) { - consola.info(`\`${r.pkgName}\` is already in the \`modules\``) - return - } - consola.info(`Adding \`${r.pkgName}\` to the \`modules\``) - config.modules.push(r.pkgName) - }, - }).catch((error) => { - consola.error(`Failed to update \`nuxt.config\`: ${error.message}`) - consola.error(`Please manually add \`${r.pkgName}\` to the \`modules\` in \`nuxt.config.ts\``) - return null - }) + consola.info(`${moduleName} has been resolved. Adding module...`) + await addModule(r, ctx.args, projectPkg) } // update the types for new module @@ -130,6 +90,62 @@ export default defineCommand({ }) // -- Internal Utils -- +async function addModule(r: ResolvedModule, { skipInstall, skipConfig, cwd }: { skipInstall: boolean, skipConfig: boolean, cwd: string }, projectPkg: any) { + // Add npm dependency + if (!skipInstall) { + const isDev = Boolean(projectPkg.devDependencies?.nuxt) + consola.info( + `Installing \`${r.pkg}\`${isDev ? ' development' : ''} dependency`, + ) + const res = await addDependency(r.pkg, { cwd, dev: isDev, installPeerDependencies: true }).catch( + (error) => { + consola.error(error) + return consola.prompt( + `Install failed for ${colors.cyan( + r.pkg, + )}. Do you want to continue adding the module to ${colors.cyan( + 'nuxt.config', + )}?`, + { + type: 'confirm', + initial: false, + }, + ) + }, + ) + if (res === false) { + return + } + } + + // Update nuxt.config.ts + if (!skipConfig) { + await updateConfig({ + cwd, + configFile: 'nuxt.config', + async onCreate() { + consola.info(`Creating \`nuxt.config.ts\``) + return getDefaultNuxtConfig() + }, + async onUpdate(config) { + if (!config.modules) { + config.modules = [] + } + if (config.modules.includes(r.pkgName)) { + consola.info(`\`${r.pkgName}\` is already in the \`modules\``) + return + } + consola.info(`Adding \`${r.pkgName}\` to the \`modules\``) + config.modules.push(r.pkgName) + }, + }).catch((error) => { + consola.error(`Failed to update \`nuxt.config\`: ${error.message}`) + consola.error(`Please manually add \`${r.pkgName}\` to the \`modules\` in \`nuxt.config.ts\``) + return null + }) + } +} + function getDefaultNuxtConfig() { return ` // https://nuxt.com/docs/api/configuration/nuxt-config @@ -142,18 +158,7 @@ export default defineNuxtConfig({ const packageRegex = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?([a-z0-9-~][a-z0-9-._~]*)(@[^@]+)?$/ -async function resolveModule( - moduleName: string, - cwd: string, -): Promise< - | false - | { - nuxtModule?: NuxtModule - pkg: string - pkgName: string - pkgVersion: string - } - > { +async function resolveModule(moduleName: string, cwd: string): Promise { let pkgName = moduleName let pkgVersion: string | undefined @@ -361,7 +366,7 @@ async function getRegistryFromFile(paths: string[], scope: string | null) { } } catch { - // swallow errors as file does not exist + // swallow errors as file does not exist } finally { await fd?.close() From 20cff62ec9f37c1b410e5cf113f6e61dc8579d25 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Fri, 6 Dec 2024 14:37:47 +0100 Subject: [PATCH 2/3] fix: only install once --- src/commands/module/add.ts | 52 ++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/commands/module/add.ts b/src/commands/module/add.ts index 511d8d4d0..fb48ff7f6 100644 --- a/src/commands/module/add.ts +++ b/src/commands/module/add.ts @@ -74,14 +74,12 @@ export default defineCommand({ } } - for (const moduleName of modules) { - const r = await resolveModule(moduleName, cwd) - if (r === false) { - return - } - consola.info(`${moduleName} has been resolved. Adding module...`) - await addModule(r, ctx.args, projectPkg) - } + const maybeResolvedModules = await Promise.all(modules.map(moduleName => resolveModule(moduleName, cwd))) + const r = maybeResolvedModules.filter((x: ModuleResolution): x is ResolvedModule => x != null) + + consola.info(`Resolved ${r.map(x => x.pkgName).join(', ')}, adding module(s)...`) + + await addModule(r, ctx.args, projectPkg) // update the types for new module const args = Object.entries(ctx.args).filter(([k]) => k in sharedArgs).map(([k, v]) => `--${k}=${v}`) @@ -90,22 +88,20 @@ export default defineCommand({ }) // -- Internal Utils -- -async function addModule(r: ResolvedModule, { skipInstall, skipConfig, cwd }: { skipInstall: boolean, skipConfig: boolean, cwd: string }, projectPkg: any) { +async function addModule(r: ResolvedModule[], { skipInstall, skipConfig, cwd }: { skipInstall: boolean, skipConfig: boolean, cwd: string }, projectPkg: any) { // Add npm dependency if (!skipInstall) { const isDev = Boolean(projectPkg.devDependencies?.nuxt) - consola.info( - `Installing \`${r.pkg}\`${isDev ? ' development' : ''} dependency`, - ) - const res = await addDependency(r.pkg, { cwd, dev: isDev, installPeerDependencies: true }).catch( + consola.info(`Installing \`${r.map(x => x.pkg).join(', ')}\`${isDev ? ' development' : ''} dep(s)`) + const res = await addDependency(r.map(x => x.pkg), { cwd, dev: isDev, installPeerDependencies: true }).catch( (error) => { consola.error(error) return consola.prompt( - `Install failed for ${colors.cyan( - r.pkg, - )}. Do you want to continue adding the module to ${colors.cyan( - 'nuxt.config', - )}?`, + `Install failed for ${ + r.map(x => colors.cyan(x.pkg)).join(', ') + }. Do you want to continue adding the module(s) to ${ + colors.cyan('nuxt.config') + }?`, { type: 'confirm', initial: false, @@ -128,19 +124,21 @@ async function addModule(r: ResolvedModule, { skipInstall, skipConfig, cwd }: { return getDefaultNuxtConfig() }, async onUpdate(config) { - if (!config.modules) { - config.modules = [] - } - if (config.modules.includes(r.pkgName)) { - consola.info(`\`${r.pkgName}\` is already in the \`modules\``) - return + for (const resolved of r) { + if (!config.modules) { + config.modules = [] + } + if (config.modules.includes(resolved.pkgName)) { + consola.info(`\`${resolved.pkgName}\` is already in the \`modules\``) + return + } + consola.info(`Adding \`${resolved.pkgName}\` to the \`modules\``) + config.modules.push(resolved.pkgName) } - consola.info(`Adding \`${r.pkgName}\` to the \`modules\``) - config.modules.push(r.pkgName) }, }).catch((error) => { consola.error(`Failed to update \`nuxt.config\`: ${error.message}`) - consola.error(`Please manually add \`${r.pkgName}\` to the \`modules\` in \`nuxt.config.ts\``) + consola.error(`Please manually add \`${r.map(x => x.pkgName).join(', ')}\` to the \`modules\` in \`nuxt.config.ts\``) return null }) } From 86c2f7f6d6b720323103f5de56f4a83f394e6094 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Wed, 11 Dec 2024 17:21:10 +0100 Subject: [PATCH 3/3] fix: change `module add` argument description --- src/commands/module/add.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/module/add.ts b/src/commands/module/add.ts index e9adb5743..fd4b118cd 100644 --- a/src/commands/module/add.ts +++ b/src/commands/module/add.ts @@ -45,7 +45,7 @@ export default defineCommand({ ...logLevelArgs, moduleName: { type: 'positional', - description: 'Module name', + description: 'Specify one or more modules to install by name, separated by spaces', }, skipInstall: { type: 'boolean',