nuxt-spec 0.2.4 → 0.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +13 -417
- package/app/app.vue +10 -10
- package/app/components/NuxtSpecApiTestComponent.vue +24 -24
- package/app/components/NuxtSpecTestComponent.vue +9 -9
- package/app/components/index.d.ts +7 -7
- package/app/components/index.ts +2 -2
- package/app/utils/vitest-utils.ts +5 -5
- package/bin/cli.js +54 -53
- package/bin/prepublish-check.js +16 -16
- package/bin/setup.js +251 -251
- package/config/index.d.ts +33 -17
- package/config/index.mjs +114 -95
- package/config/templates/pnpm-workspace.yaml.template +4 -4
- package/config/templates/vitest.config.ts.template +5 -5
- package/config/utils/merge.mjs +43 -43
- package/config/utils/warnings.mjs +33 -33
- package/nuxt.config.ts +19 -19
- package/package.json +28 -26
- package/utils/e2e.ts +131 -30
- package/utils/helpers/check-params.ts +41 -0
- package/utils/helpers/location-hint.ts +30 -0
- package/utils/index.ts +12 -12
- package/utils/screenshot/report-entry.html +8 -8
- package/utils/screenshot/report-head.html +24 -24
- package/utils/screenshot/report-tail.html +4 -4
- package/utils/screenshot/report-utils.ts +236 -227
- package/utils/screenshot.ts +172 -104
- package/utils/index.d.ts +0 -70
package/bin/cli.js
CHANGED
|
@@ -1,53 +1,54 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { getPackageManager } from 'elrh-cosca'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* CLI tool to scaffold necessary adjustments in project folder.
|
|
7
|
-
*
|
|
8
|
-
* Currently only allows `setup` to be passed as parameter.
|
|
9
|
-
*
|
|
10
|
-
* Second parameter for `setup` might be a boolean to indicate auto mode
|
|
11
|
-
* (no prompts, force = true) or manual mode (with prompts, force = false).
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// get parameters passed by user
|
|
15
|
-
const args = process.argv.slice(2);
|
|
16
|
-
|
|
17
|
-
// execute actions based on first param
|
|
18
|
-
// additional params might be passed into the called functions
|
|
19
|
-
(async () => {
|
|
20
|
-
let status = 0
|
|
21
|
-
try {
|
|
22
|
-
switch (args[0]) {
|
|
23
|
-
case 'setup':
|
|
24
|
-
await (await import('./setup.js')).specSetup(args[1] || false)
|
|
25
|
-
break
|
|
26
|
-
default:
|
|
27
|
-
console.log(`Usage: \`${getCmd()}
|
|
28
|
-
status = 1
|
|
29
|
-
}
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('Setup failed:', error.message)
|
|
32
|
-
status = 1
|
|
33
|
-
}
|
|
34
|
-
process.exit(status)
|
|
35
|
-
})()
|
|
36
|
-
|
|
37
|
-
// try detecting what package manager was used
|
|
38
|
-
// to give user appropriate usage hint
|
|
39
|
-
function getCmd() {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { getPackageManager } from 'elrh-cosca'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CLI tool to scaffold necessary adjustments in project folder.
|
|
7
|
+
*
|
|
8
|
+
* Currently only allows `setup` to be passed as parameter.
|
|
9
|
+
*
|
|
10
|
+
* Second parameter for `setup` might be a boolean to indicate auto mode
|
|
11
|
+
* (no prompts, force = true) or manual mode (with prompts, force = false).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// get parameters passed by user
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
|
|
17
|
+
// execute actions based on first param
|
|
18
|
+
// additional params might be passed into the called functions
|
|
19
|
+
(async () => {
|
|
20
|
+
let status = 0
|
|
21
|
+
try {
|
|
22
|
+
switch (args[0]) {
|
|
23
|
+
case 'setup':
|
|
24
|
+
await (await import('./setup.js')).specSetup(args[1] || false)
|
|
25
|
+
break
|
|
26
|
+
default:
|
|
27
|
+
console.log(`Usage: \`${getCmd()} setup [true|false]\``)
|
|
28
|
+
status = 1
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('Setup failed:', error.message)
|
|
32
|
+
status = 1
|
|
33
|
+
}
|
|
34
|
+
process.exit(status)
|
|
35
|
+
})()
|
|
36
|
+
|
|
37
|
+
// try detecting what package manager was used
|
|
38
|
+
// to give user appropriate usage hint
|
|
39
|
+
function getCmd() {
|
|
40
|
+
const command = 'nuxt-spec'
|
|
41
|
+
const packageManager = getPackageManager()
|
|
42
|
+
switch (packageManager) {
|
|
43
|
+
case 'pnpm':
|
|
44
|
+
return `pnpx ${command}`
|
|
45
|
+
case 'yarn':
|
|
46
|
+
return `yarn dlx ${command}`
|
|
47
|
+
case 'bun':
|
|
48
|
+
return `bunx ${command}`
|
|
49
|
+
case 'deno':
|
|
50
|
+
return `deno run -A npm:${command}`
|
|
51
|
+
default:
|
|
52
|
+
return `npx ${command}`
|
|
53
|
+
}
|
|
54
|
+
}
|
package/bin/prepublish-check.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { createInterface } from 'node:readline'
|
|
4
|
-
|
|
5
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
6
|
-
|
|
7
|
-
rl.question('Are you sure the current solution was properly tested and verified? (y/n) ', (answer) => {
|
|
8
|
-
rl.close()
|
|
9
|
-
if (answer.trim().toLowerCase().startsWith('y')) {
|
|
10
|
-
console.log('Proceeding with publish...')
|
|
11
|
-
process.exit(0)
|
|
12
|
-
} else {
|
|
13
|
-
console.error('Publish aborted. Please run the tests and try again.')
|
|
14
|
-
process.exit(1)
|
|
15
|
-
}
|
|
16
|
-
})
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createInterface } from 'node:readline'
|
|
4
|
+
|
|
5
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
6
|
+
|
|
7
|
+
rl.question('Are you sure the current solution was properly tested and verified? (y/n) ', (answer) => {
|
|
8
|
+
rl.close()
|
|
9
|
+
if (answer.trim().toLowerCase().startsWith('y')) {
|
|
10
|
+
console.log('Proceeding with publish...')
|
|
11
|
+
process.exit(0)
|
|
12
|
+
} else {
|
|
13
|
+
console.error('Publish aborted. Please run the tests and try again.')
|
|
14
|
+
process.exit(1)
|
|
15
|
+
}
|
|
16
|
+
})
|
package/bin/setup.js
CHANGED
|
@@ -1,251 +1,251 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { execSync } from 'node:child_process'
|
|
4
|
-
import {
|
|
5
|
-
createFileFromWebTemplate, deletePath, getPackageManager, hasJsonKey,
|
|
6
|
-
pathExists, promptUser, removeFromJsonFile, showMessage,
|
|
7
|
-
updateConfigFile, updateJsonFile, updateTextFile,
|
|
8
|
-
} from 'elrh-cosca'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* CLI tool to scaffold necessary adjustments in project folder.
|
|
12
|
-
*
|
|
13
|
-
* It first asks whether to run in "auto" mode (no prompts, force = true) or "manual" mode (with prompts, force = false).
|
|
14
|
-
*
|
|
15
|
-
* Then it:
|
|
16
|
-
* 1) adds `nuxt-spec` into `package.json` dependencies and removes `nuxt`, `vue` and `vue-router` if present
|
|
17
|
-
* 2) adds `extends: ['nuxt-spec']` to `nuxt.config.ts`
|
|
18
|
-
* 3) creates/updates `pnpm-workspace.yaml` file (only if pnpm is used)
|
|
19
|
-
* 4) creates default `vitest.config.ts` file
|
|
20
|
-
* 5) creates default `.nuxtrc` file
|
|
21
|
-
* 6) adds test-related scripts in `package.json`
|
|
22
|
-
* 7) creates sample test files
|
|
23
|
-
* 8) clear node_modules and lock file(s)
|
|
24
|
-
* 9) run install command
|
|
25
|
-
*
|
|
26
|
-
* @param {boolean} autoRun - Whether to run the setup automatically without any prompts (defaults to false).
|
|
27
|
-
*/
|
|
28
|
-
export async function specSetup(autoRun = false) {
|
|
29
|
-
showMessage('NUXT SPEC SETUP')
|
|
30
|
-
showMessage('This CLI tool will help you include Nuxt Spec in your project.')
|
|
31
|
-
showMessage('Refer to the documentation for more information.', 2)
|
|
32
|
-
|
|
33
|
-
const isAutoRun = autoRun || await promptUser('Do you want to set everything up automatically (no more prompts)?')
|
|
34
|
-
showMessage('')
|
|
35
|
-
|
|
36
|
-
const packageManager = getPackageManager()
|
|
37
|
-
|
|
38
|
-
// 1) manage dependencies in package.json
|
|
39
|
-
|
|
40
|
-
// add nuxt-spec
|
|
41
|
-
try {
|
|
42
|
-
await updateJsonFile('package.json', 'dependencies', {
|
|
43
|
-
'nuxt-spec': '0.
|
|
44
|
-
}, isAutoRun, 'This will add \'nuxt-spec\' dependency to your \'package.json\'. Continue?')
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('Error adding \'nuxt-spec\' dependency:\n', error.message)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// remove now obsolete nuxt, vue and vue-router
|
|
50
|
-
const removeDeps = isAutoRun || await promptUser('As \'nuxt-spec\' provides \'nuxt\', \'vue\' and \'vue-router\' dependencies out of the box, do you want to remove them from your \'package.json\' to avoid duplications and possible version clashes?')
|
|
51
|
-
if (removeDeps) {
|
|
52
|
-
if (hasJsonKey('package.json', 'dependencies.nuxt')) {
|
|
53
|
-
try {
|
|
54
|
-
await removeFromJsonFile('package.json', 'dependencies.nuxt', true)
|
|
55
|
-
} catch (error) {
|
|
56
|
-
console.error('Error removing \'nuxt\' dependency:\n', error.message)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (hasJsonKey('package.json', 'dependencies.vue')) {
|
|
60
|
-
try {
|
|
61
|
-
await removeFromJsonFile('package.json', 'dependencies.vue', true)
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.error('Error removing \'vue\' dependency:\n', error.message)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (hasJsonKey('package.json', 'dependencies.vue-router')) {
|
|
67
|
-
try {
|
|
68
|
-
await removeFromJsonFile('package.json', 'dependencies.vue-router', true)
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error('Error removing \'vue-router\' dependency:\n', error.message)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (hasJsonKey('package.json', 'devDependencies.nuxt')) {
|
|
74
|
-
try {
|
|
75
|
-
await removeFromJsonFile('package.json', 'devDependencies.nuxt', true)
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.error('Error removing \'nuxt\' devDependency:\n', error.message)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (hasJsonKey('package.json', 'devDependencies.vue')) {
|
|
81
|
-
try {
|
|
82
|
-
await removeFromJsonFile('package.json', 'devDependencies.vue', true)
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error('Error removing \'vue\' devDependency:\n', error.message)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (hasJsonKey('package.json', 'devDependencies.vue-router')) {
|
|
88
|
-
try {
|
|
89
|
-
await removeFromJsonFile('package.json', 'devDependencies.vue-router', true)
|
|
90
|
-
} catch (error) {
|
|
91
|
-
console.error('Error removing \'vue-router\' devDependency:\n', error.message)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// 2) modify nuxt.config.ts
|
|
97
|
-
try {
|
|
98
|
-
await updateConfigFile('nuxt.config.ts', {
|
|
99
|
-
extends: [
|
|
100
|
-
'nuxt-spec',
|
|
101
|
-
],
|
|
102
|
-
}, isAutoRun, 'This will add \'nuxt-spec\' module to your \'nuxt.config.ts\'. Continue?')
|
|
103
|
-
} catch (error) {
|
|
104
|
-
console.error('Error updating \'nuxt.config.ts\':\n', error.message)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// 3) `pnpm-workspace.yaml` file (only if pnpm is used)
|
|
108
|
-
if (packageManager === 'pnpm') {
|
|
109
|
-
try {
|
|
110
|
-
if (pathExists('pnpm-workspace.yaml')) {
|
|
111
|
-
await updateTextFile('pnpm-workspace.yaml', ['shamefully-hoist: true'], isAutoRun, 'This will adjust \'pnpm-workspace.yaml\' file in your project. Continue?')
|
|
112
|
-
} else {
|
|
113
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
114
|
-
'pnpm-workspace.yaml', isAutoRun, 'This will add \'pnpm-workspace.yaml\' file for your project. Continue?')
|
|
115
|
-
}
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error('Error setting up \'pnpm-workspace.yaml\':\n', error.message)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// 4) create vitest.config.ts
|
|
122
|
-
try {
|
|
123
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
124
|
-
'vitest.config.ts', isAutoRun, 'This will create a new \'vitest.config.ts\' file for your project. Continue?')
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error('Error setting up \'vitest.config.ts\':\n', error.message)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// 5) create .nuxtrc to prevent @nuxt/test-utils setup from running automatically on first start
|
|
130
|
-
if (!pathExists('.nuxtrc')) {
|
|
131
|
-
try {
|
|
132
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
133
|
-
} catch (error) {
|
|
134
|
-
console.error('Error creating \'.nuxtrc\':\n', error.message)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 6) modify package.json with test scripts
|
|
139
|
-
try {
|
|
140
|
-
await updateJsonFile('package.json', 'scripts', {
|
|
141
|
-
'test': 'vitest run',
|
|
142
|
-
'test-u': 'vitest run -u',
|
|
143
|
-
'test-i': 'vitest',
|
|
144
|
-
}, isAutoRun, 'This will adjust the test-related commands in your \'package.json\'. Continue?')
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.error('Error adjusting scripts in \'package.json\':\n', error.message)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 7) create sample test files
|
|
150
|
-
const createSampleTests = isAutoRun || await promptUser('Do you want to create sample tests in \'/test\' folder?')
|
|
151
|
-
if (createSampleTests) {
|
|
152
|
-
try {
|
|
153
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
154
|
-
'test/browser/vitest-browser.test.ts', true)
|
|
155
|
-
} catch (error) {
|
|
156
|
-
console.error('Error setting up \'vitest-browser.test.ts\':\n', error.message)
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
160
|
-
'test/e2e/nuxt-e2e.test.ts', true)
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error('Error setting up \'nuxt-e2e.test.ts\':\n', error.message)
|
|
163
|
-
}
|
|
164
|
-
try {
|
|
165
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
166
|
-
'test/e2e/nuxt-visual.test.ts', true)
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error('Error setting up \'nuxt-visual.test.ts\':\n', error.message)
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
172
|
-
'test/nuxt/nuxt-unit.test.ts', true)
|
|
173
|
-
} catch (error) {
|
|
174
|
-
console.error('Error setting up \'nuxt-unit.test.ts\':\n', error.message)
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.
|
|
178
|
-
'test/unit/vitest-unit.test.ts', true)
|
|
179
|
-
} catch (error) {
|
|
180
|
-
console.error('Error setting up \'vitest-unit.test.ts\':\n', error.message)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// 8) clear node_modules and lock file(s)
|
|
185
|
-
const prepareForReinstall = isAutoRun || await promptUser('Dependencies should be re-installed now. Do you want to remove node_modules and the lock file?')
|
|
186
|
-
if (prepareForReinstall) {
|
|
187
|
-
if (pathExists('node_modules')) {
|
|
188
|
-
try {
|
|
189
|
-
await deletePath('node_modules', true)
|
|
190
|
-
} catch (error) {
|
|
191
|
-
console.error('Error deleting \'node_modules\':\n', error.message)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (pathExists('package-lock.json')) {
|
|
195
|
-
try {
|
|
196
|
-
await deletePath('package-lock.json', true)
|
|
197
|
-
} catch (error) {
|
|
198
|
-
console.error('Error deleting \'package-lock.json\':\n', error.message)
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (pathExists('pnpm-lock.yaml')) {
|
|
202
|
-
try {
|
|
203
|
-
await deletePath('pnpm-lock.yaml', true)
|
|
204
|
-
} catch (error) {
|
|
205
|
-
console.error('Error deleting \'pnpm-lock.yaml\':\n', error.message)
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
if (pathExists('yarn.lock')) {
|
|
209
|
-
try {
|
|
210
|
-
await deletePath('yarn.lock', true)
|
|
211
|
-
} catch (error) {
|
|
212
|
-
console.error('Error deleting \'yarn.lock\':\n', error.message)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (pathExists('bun.lockb')) {
|
|
216
|
-
try {
|
|
217
|
-
await deletePath('bun.lockb', true)
|
|
218
|
-
} catch (error) {
|
|
219
|
-
console.error('Error deleting \'bun.lockb\':\n', error.message)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (pathExists('deno.lock')) {
|
|
223
|
-
try {
|
|
224
|
-
await deletePath('deno.lock', true)
|
|
225
|
-
} catch (error) {
|
|
226
|
-
console.error('Error deleting \'deno.lock\':\n', error.message)
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// 9) run install command
|
|
232
|
-
const runInstall = isAutoRun || await promptUser(`Fresh \`${packageManager} install\` is required. Do you want to run it now?`)
|
|
233
|
-
if (runInstall) {
|
|
234
|
-
try {
|
|
235
|
-
showMessage(`Running \`${packageManager} install\`...`)
|
|
236
|
-
execSync(`${packageManager} install`, { stdio: 'inherit' })
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.error(`Error running \`${packageManager} install\`:\n`, error.message)
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// 10) inform user
|
|
243
|
-
showMessage('')
|
|
244
|
-
showMessage('NUXT SPEC SETUP COMPLETE', 2)
|
|
245
|
-
if (!runInstall) {
|
|
246
|
-
showMessage(`Proceed with \`${packageManager} install\` to get started.`)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// force exit to prevent #20
|
|
250
|
-
process.exit(0)
|
|
251
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import {
|
|
5
|
+
createFileFromWebTemplate, deletePath, getPackageManager, hasJsonKey,
|
|
6
|
+
pathExists, promptUser, removeFromJsonFile, showMessage,
|
|
7
|
+
updateConfigFile, updateJsonFile, updateTextFile,
|
|
8
|
+
} from 'elrh-cosca'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* CLI tool to scaffold necessary adjustments in project folder.
|
|
12
|
+
*
|
|
13
|
+
* It first asks whether to run in "auto" mode (no prompts, force = true) or "manual" mode (with prompts, force = false).
|
|
14
|
+
*
|
|
15
|
+
* Then it:
|
|
16
|
+
* 1) adds `nuxt-spec` into `package.json` dependencies and removes `nuxt`, `vue` and `vue-router` if present
|
|
17
|
+
* 2) adds `extends: ['nuxt-spec']` to `nuxt.config.ts`
|
|
18
|
+
* 3) creates/updates `pnpm-workspace.yaml` file (only if pnpm is used)
|
|
19
|
+
* 4) creates default `vitest.config.ts` file
|
|
20
|
+
* 5) creates default `.nuxtrc` file
|
|
21
|
+
* 6) adds test-related scripts in `package.json`
|
|
22
|
+
* 7) creates sample test files
|
|
23
|
+
* 8) clear node_modules and lock file(s)
|
|
24
|
+
* 9) run install command
|
|
25
|
+
*
|
|
26
|
+
* @param {boolean} autoRun - Whether to run the setup automatically without any prompts (defaults to false).
|
|
27
|
+
*/
|
|
28
|
+
export async function specSetup(autoRun = false) {
|
|
29
|
+
showMessage('NUXT SPEC SETUP')
|
|
30
|
+
showMessage('This CLI tool will help you include Nuxt Spec in your project.')
|
|
31
|
+
showMessage('Refer to the documentation for more information.', 2)
|
|
32
|
+
|
|
33
|
+
const isAutoRun = autoRun || await promptUser('Do you want to set everything up automatically (no more prompts)?')
|
|
34
|
+
showMessage('')
|
|
35
|
+
|
|
36
|
+
const packageManager = getPackageManager()
|
|
37
|
+
|
|
38
|
+
// 1) manage dependencies in package.json
|
|
39
|
+
|
|
40
|
+
// add nuxt-spec
|
|
41
|
+
try {
|
|
42
|
+
await updateJsonFile('package.json', 'dependencies', {
|
|
43
|
+
'nuxt-spec': '0.3.0-alpha',
|
|
44
|
+
}, isAutoRun, 'This will add \'nuxt-spec\' dependency to your \'package.json\'. Continue?')
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('Error adding \'nuxt-spec\' dependency:\n', error.message)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// remove now obsolete nuxt, vue and vue-router
|
|
50
|
+
const removeDeps = isAutoRun || await promptUser('As \'nuxt-spec\' provides \'nuxt\', \'vue\' and \'vue-router\' dependencies out of the box, do you want to remove them from your \'package.json\' to avoid duplications and possible version clashes?')
|
|
51
|
+
if (removeDeps) {
|
|
52
|
+
if (hasJsonKey('package.json', 'dependencies.nuxt')) {
|
|
53
|
+
try {
|
|
54
|
+
await removeFromJsonFile('package.json', 'dependencies.nuxt', true)
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Error removing \'nuxt\' dependency:\n', error.message)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (hasJsonKey('package.json', 'dependencies.vue')) {
|
|
60
|
+
try {
|
|
61
|
+
await removeFromJsonFile('package.json', 'dependencies.vue', true)
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error('Error removing \'vue\' dependency:\n', error.message)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (hasJsonKey('package.json', 'dependencies.vue-router')) {
|
|
67
|
+
try {
|
|
68
|
+
await removeFromJsonFile('package.json', 'dependencies.vue-router', true)
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error('Error removing \'vue-router\' dependency:\n', error.message)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (hasJsonKey('package.json', 'devDependencies.nuxt')) {
|
|
74
|
+
try {
|
|
75
|
+
await removeFromJsonFile('package.json', 'devDependencies.nuxt', true)
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('Error removing \'nuxt\' devDependency:\n', error.message)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (hasJsonKey('package.json', 'devDependencies.vue')) {
|
|
81
|
+
try {
|
|
82
|
+
await removeFromJsonFile('package.json', 'devDependencies.vue', true)
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('Error removing \'vue\' devDependency:\n', error.message)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (hasJsonKey('package.json', 'devDependencies.vue-router')) {
|
|
88
|
+
try {
|
|
89
|
+
await removeFromJsonFile('package.json', 'devDependencies.vue-router', true)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error('Error removing \'vue-router\' devDependency:\n', error.message)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 2) modify nuxt.config.ts
|
|
97
|
+
try {
|
|
98
|
+
await updateConfigFile('nuxt.config.ts', {
|
|
99
|
+
extends: [
|
|
100
|
+
'nuxt-spec',
|
|
101
|
+
],
|
|
102
|
+
}, isAutoRun, 'This will add \'nuxt-spec\' module to your \'nuxt.config.ts\'. Continue?')
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Error updating \'nuxt.config.ts\':\n', error.message)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 3) `pnpm-workspace.yaml` file (only if pnpm is used)
|
|
108
|
+
if (packageManager === 'pnpm') {
|
|
109
|
+
try {
|
|
110
|
+
if (pathExists('pnpm-workspace.yaml')) {
|
|
111
|
+
await updateTextFile('pnpm-workspace.yaml', ['shamefully-hoist: true'], isAutoRun, 'This will adjust \'pnpm-workspace.yaml\' file in your project. Continue?')
|
|
112
|
+
} else {
|
|
113
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/config/templates/pnpm-workspace.yaml.template',
|
|
114
|
+
'pnpm-workspace.yaml', isAutoRun, 'This will add \'pnpm-workspace.yaml\' file for your project. Continue?')
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('Error setting up \'pnpm-workspace.yaml\':\n', error.message)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 4) create vitest.config.ts
|
|
122
|
+
try {
|
|
123
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/config/templates/vitest.config.ts.template',
|
|
124
|
+
'vitest.config.ts', isAutoRun, 'This will create a new \'vitest.config.ts\' file for your project. Continue?')
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error('Error setting up \'vitest.config.ts\':\n', error.message)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 5) create .nuxtrc to prevent @nuxt/test-utils setup from running automatically on first start
|
|
130
|
+
if (!pathExists('.nuxtrc')) {
|
|
131
|
+
try {
|
|
132
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/.nuxtrc', '.nuxtrc', isAutoRun, 'This will create a \'.nuxtrc\' file to prevent @nuxt/test-utils setup from running automatically when dev server starts. Continue?')
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error('Error creating \'.nuxtrc\':\n', error.message)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 6) modify package.json with test scripts
|
|
139
|
+
try {
|
|
140
|
+
await updateJsonFile('package.json', 'scripts', {
|
|
141
|
+
'test': 'vitest run',
|
|
142
|
+
'test-u': 'vitest run -u',
|
|
143
|
+
'test-i': 'vitest',
|
|
144
|
+
}, isAutoRun, 'This will adjust the test-related commands in your \'package.json\'. Continue?')
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('Error adjusting scripts in \'package.json\':\n', error.message)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 7) create sample test files
|
|
150
|
+
const createSampleTests = isAutoRun || await promptUser('Do you want to create sample tests in \'/test\' folder?')
|
|
151
|
+
if (createSampleTests) {
|
|
152
|
+
try {
|
|
153
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/test/browser/vitest-browser.test.ts',
|
|
154
|
+
'test/browser/vitest-browser.test.ts', true)
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Error setting up \'vitest-browser.test.ts\':\n', error.message)
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/test/e2e/nuxt-e2e.test.ts',
|
|
160
|
+
'test/e2e/nuxt-e2e.test.ts', true)
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error('Error setting up \'nuxt-e2e.test.ts\':\n', error.message)
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/test/e2e/nuxt-visual.test.ts',
|
|
166
|
+
'test/e2e/nuxt-visual.test.ts', true)
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error('Error setting up \'nuxt-visual.test.ts\':\n', error.message)
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/test/nuxt/nuxt-unit.test.ts',
|
|
172
|
+
'test/nuxt/nuxt-unit.test.ts', true)
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error('Error setting up \'nuxt-unit.test.ts\':\n', error.message)
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
await createFileFromWebTemplate('https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v0.3.0-alpha/test/unit/vitest-unit.test.ts',
|
|
178
|
+
'test/unit/vitest-unit.test.ts', true)
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error('Error setting up \'vitest-unit.test.ts\':\n', error.message)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 8) clear node_modules and lock file(s)
|
|
185
|
+
const prepareForReinstall = isAutoRun || await promptUser('Dependencies should be re-installed now. Do you want to remove node_modules and the lock file?')
|
|
186
|
+
if (prepareForReinstall) {
|
|
187
|
+
if (pathExists('node_modules')) {
|
|
188
|
+
try {
|
|
189
|
+
await deletePath('node_modules', true)
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error('Error deleting \'node_modules\':\n', error.message)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (pathExists('package-lock.json')) {
|
|
195
|
+
try {
|
|
196
|
+
await deletePath('package-lock.json', true)
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('Error deleting \'package-lock.json\':\n', error.message)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (pathExists('pnpm-lock.yaml')) {
|
|
202
|
+
try {
|
|
203
|
+
await deletePath('pnpm-lock.yaml', true)
|
|
204
|
+
} catch (error) {
|
|
205
|
+
console.error('Error deleting \'pnpm-lock.yaml\':\n', error.message)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (pathExists('yarn.lock')) {
|
|
209
|
+
try {
|
|
210
|
+
await deletePath('yarn.lock', true)
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Error deleting \'yarn.lock\':\n', error.message)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (pathExists('bun.lockb')) {
|
|
216
|
+
try {
|
|
217
|
+
await deletePath('bun.lockb', true)
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error('Error deleting \'bun.lockb\':\n', error.message)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (pathExists('deno.lock')) {
|
|
223
|
+
try {
|
|
224
|
+
await deletePath('deno.lock', true)
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error('Error deleting \'deno.lock\':\n', error.message)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 9) run install command
|
|
232
|
+
const runInstall = isAutoRun || await promptUser(`Fresh \`${packageManager} install\` is required. Do you want to run it now?`)
|
|
233
|
+
if (runInstall) {
|
|
234
|
+
try {
|
|
235
|
+
showMessage(`Running \`${packageManager} install\`...`)
|
|
236
|
+
execSync(`${packageManager} install`, { stdio: 'inherit' })
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error(`Error running \`${packageManager} install\`:\n`, error.message)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// 10) inform user
|
|
243
|
+
showMessage('')
|
|
244
|
+
showMessage('NUXT SPEC SETUP COMPLETE', 2)
|
|
245
|
+
if (!runInstall) {
|
|
246
|
+
showMessage(`Proceed with \`${packageManager} install\` to get started.`)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// force exit to prevent #20
|
|
250
|
+
process.exit(0)
|
|
251
|
+
}
|