@@ -26,6 +26,15 @@ export type RegistryMeta = {
26
26
authToken : string | null
27
27
}
28
28
29
+ type ResolvedModule = {
30
+ nuxtModule ?: NuxtModule
31
+ pkg : string
32
+ pkgName : string
33
+ pkgVersion : string
34
+ }
35
+ type UnresolvedModule = false
36
+ type ModuleResolution = ResolvedModule | UnresolvedModule
37
+
29
38
export default defineCommand ( {
30
39
meta : {
31
40
name : 'add' ,
@@ -36,7 +45,7 @@ export default defineCommand({
36
45
...logLevelArgs ,
37
46
moduleName : {
38
47
type : 'positional' ,
39
- description : 'Module name' ,
48
+ description : 'Specify one or more modules to install by name, separated by spaces ' ,
40
49
} ,
41
50
skipInstall : {
42
51
type : 'boolean' ,
@@ -49,6 +58,7 @@ export default defineCommand({
49
58
} ,
50
59
async setup ( ctx ) {
51
60
const cwd = resolve ( ctx . args . cwd )
61
+ const modules = ctx . args . _
52
62
const projectPkg = await getProjectPackage ( cwd )
53
63
54
64
if ( ! projectPkg . dependencies ?. nuxt && ! projectPkg . devDependencies ?. nuxt ) {
@@ -65,64 +75,12 @@ export default defineCommand({
65
75
}
66
76
}
67
77
68
- const r = await resolveModule ( ctx . args . moduleName , cwd )
69
- if ( r === false ) {
70
- return
71
- }
78
+ const maybeResolvedModules = await Promise . all ( modules . map ( moduleName => resolveModule ( moduleName , cwd ) ) )
79
+ const r = maybeResolvedModules . filter ( ( x : ModuleResolution ) : x is ResolvedModule => x != null )
72
80
73
- // Add npm dependency
74
- if ( ! ctx . args . skipInstall ) {
75
- const isDev = Boolean ( projectPkg . devDependencies ?. nuxt )
76
- consola . info (
77
- `Installing \`${ r . pkg } \`${ isDev ? ' development' : '' } dependency` ,
78
- )
79
- const res = await addDependency ( r . pkg , { cwd, dev : isDev , installPeerDependencies : true } ) . catch (
80
- ( error ) => {
81
- consola . error ( error )
82
- return consola . prompt (
83
- `Install failed for ${ colors . cyan (
84
- r . pkg ,
85
- ) } . Do you want to continue adding the module to ${ colors . cyan (
86
- 'nuxt.config' ,
87
- ) } ?`,
88
- {
89
- type : 'confirm' ,
90
- initial : false ,
91
- } ,
92
- )
93
- } ,
94
- )
95
- if ( res === false ) {
96
- return
97
- }
98
- }
81
+ consola . info ( `Resolved ${ r . map ( x => x . pkgName ) . join ( ', ' ) } , adding module(s)...` )
99
82
100
- // Update nuxt.config.ts
101
- if ( ! ctx . args . skipConfig ) {
102
- await updateConfig ( {
103
- cwd,
104
- configFile : 'nuxt.config' ,
105
- async onCreate ( ) {
106
- consola . info ( `Creating \`nuxt.config.ts\`` )
107
- return getDefaultNuxtConfig ( )
108
- } ,
109
- async onUpdate ( config ) {
110
- if ( ! config . modules ) {
111
- config . modules = [ ]
112
- }
113
- if ( config . modules . includes ( r . pkgName ) ) {
114
- consola . info ( `\`${ r . pkgName } \` is already in the \`modules\`` )
115
- return
116
- }
117
- consola . info ( `Adding \`${ r . pkgName } \` to the \`modules\`` )
118
- config . modules . push ( r . pkgName )
119
- } ,
120
- } ) . catch ( ( error ) => {
121
- consola . error ( `Failed to update \`nuxt.config\`: ${ error . message } ` )
122
- consola . error ( `Please manually add \`${ r . pkgName } \` to the \`modules\` in \`nuxt.config.ts\`` )
123
- return null
124
- } )
125
- }
83
+ await addModule ( r , ctx . args , projectPkg )
126
84
127
85
// update the types for new module
128
86
const args = Object . entries ( ctx . args ) . filter ( ( [ k ] ) => k in cwdArgs || k in logLevelArgs ) . map ( ( [ k , v ] ) => `--${ k } =${ v } ` )
@@ -131,6 +89,62 @@ export default defineCommand({
131
89
} )
132
90
133
91
// -- Internal Utils --
92
+ async function addModule ( r : ResolvedModule [ ] , { skipInstall, skipConfig, cwd } : { skipInstall : boolean , skipConfig : boolean , cwd : string } , projectPkg : any ) {
93
+ // Add npm dependency
94
+ if ( ! skipInstall ) {
95
+ const isDev = Boolean ( projectPkg . devDependencies ?. nuxt )
96
+ consola . info ( `Installing \`${ r . map ( x => x . pkg ) . join ( ', ' ) } \`${ isDev ? ' development' : '' } dep(s)` )
97
+ const res = await addDependency ( r . map ( x => x . pkg ) , { cwd, dev : isDev , installPeerDependencies : true } ) . catch (
98
+ ( error ) => {
99
+ consola . error ( error )
100
+ return consola . prompt (
101
+ `Install failed for ${
102
+ r . map ( x => colors . cyan ( x . pkg ) ) . join ( ', ' )
103
+ } . Do you want to continue adding the module(s) to ${
104
+ colors . cyan ( 'nuxt.config' )
105
+ } ?`,
106
+ {
107
+ type : 'confirm' ,
108
+ initial : false ,
109
+ } ,
110
+ )
111
+ } ,
112
+ )
113
+ if ( res === false ) {
114
+ return
115
+ }
116
+ }
117
+
118
+ // Update nuxt.config.ts
119
+ if ( ! skipConfig ) {
120
+ await updateConfig ( {
121
+ cwd,
122
+ configFile : 'nuxt.config' ,
123
+ async onCreate ( ) {
124
+ consola . info ( `Creating \`nuxt.config.ts\`` )
125
+ return getDefaultNuxtConfig ( )
126
+ } ,
127
+ async onUpdate ( config ) {
128
+ for ( const resolved of r ) {
129
+ if ( ! config . modules ) {
130
+ config . modules = [ ]
131
+ }
132
+ if ( config . modules . includes ( resolved . pkgName ) ) {
133
+ consola . info ( `\`${ resolved . pkgName } \` is already in the \`modules\`` )
134
+ return
135
+ }
136
+ consola . info ( `Adding \`${ resolved . pkgName } \` to the \`modules\`` )
137
+ config . modules . push ( resolved . pkgName )
138
+ }
139
+ } ,
140
+ } ) . catch ( ( error ) => {
141
+ consola . error ( `Failed to update \`nuxt.config\`: ${ error . message } ` )
142
+ consola . error ( `Please manually add \`${ r . map ( x => x . pkgName ) . join ( ', ' ) } \` to the \`modules\` in \`nuxt.config.ts\`` )
143
+ return null
144
+ } )
145
+ }
146
+ }
147
+
134
148
function getDefaultNuxtConfig ( ) {
135
149
return `
136
150
// https://nuxt.com/docs/api/configuration/nuxt-config
@@ -143,18 +157,7 @@ export default defineNuxtConfig({
143
157
const packageRegex
144
158
= / ^ ( @ [ a - z 0 - 9 - ~ ] [ a - z 0 - 9 - ._ ~ ] * \/ ) ? ( [ a - z 0 - 9 - ~ ] [ a - z 0 - 9 - ._ ~ ] * ) ( @ [ ^ @ ] + ) ? $ /
145
159
146
- async function resolveModule (
147
- moduleName : string ,
148
- cwd : string ,
149
- ) : Promise <
150
- | false
151
- | {
152
- nuxtModule ?: NuxtModule
153
- pkg : string
154
- pkgName : string
155
- pkgVersion : string
156
- }
157
- > {
160
+ async function resolveModule ( moduleName : string , cwd : string ) : Promise < ModuleResolution > {
158
161
let pkgName = moduleName
159
162
let pkgVersion : string | undefined
160
163
@@ -362,7 +365,7 @@ async function getRegistryFromFile(paths: string[], scope: string | null) {
362
365
}
363
366
}
364
367
catch {
365
- // swallow errors as file does not exist
368
+ // swallow errors as file does not exist
366
369
}
367
370
finally {
368
371
await fd ?. close ( )
0 commit comments