gridsum-vue3-pc 1.0.7 → 1.1.0
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/bin/create-vue3-pc.mjs +86 -83
- package/package.json +1 -1
package/bin/create-vue3-pc.mjs
CHANGED
|
@@ -45,7 +45,6 @@ ${pc.bold('Options:')}
|
|
|
45
45
|
--auto-start Auto start dev server after creation
|
|
46
46
|
--no-auto-install Skip automatic dependency installation
|
|
47
47
|
--no-interactive Run in non-interactive mode
|
|
48
|
-
--no-git Skip git initialization
|
|
49
48
|
-h, --help Display this message
|
|
50
49
|
-v, --version Display version number
|
|
51
50
|
|
|
@@ -60,13 +59,9 @@ ${pc.bold('Examples:')}
|
|
|
60
59
|
${pc.green('gsvue my-app')} ${pc.yellow('--no-interactive --name my-app --title "My App"')}
|
|
61
60
|
`;
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
function formatTargetDir(targetDir) {
|
|
68
|
-
const dir = targetDir.trim().replace(/\/+$/g, '');
|
|
69
|
-
if (/[<>:"\\|?*\x00-\x1f]/.test(dir) || dir.includes('..') || dir.includes('/') || dir.includes('\\')) {
|
|
62
|
+
function formatTargetDir(input) {
|
|
63
|
+
const dir = input.trim().replace(/[\/\\]+$/g, '');
|
|
64
|
+
if (!dir || /[<>:"|?*\x00-\x1f]/.test(dir) || dir.includes('..') || dir.includes('/') || dir.includes('\\')) {
|
|
70
65
|
return '';
|
|
71
66
|
}
|
|
72
67
|
return dir;
|
|
@@ -119,12 +114,10 @@ function copyDir(srcDir, destDir) {
|
|
|
119
114
|
}
|
|
120
115
|
|
|
121
116
|
function detectPackageManager() {
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
if (userAgent.startsWith('yarn')) return 'yarn';
|
|
127
|
-
if (userAgent.startsWith('bun')) return 'bun';
|
|
117
|
+
const ua = process.env.npm_config_user_agent || '';
|
|
118
|
+
if (ua.startsWith('pnpm')) return 'pnpm';
|
|
119
|
+
if (ua.startsWith('yarn')) return 'yarn';
|
|
120
|
+
if (ua.startsWith('bun')) return 'bun';
|
|
128
121
|
return 'npm';
|
|
129
122
|
}
|
|
130
123
|
|
|
@@ -134,6 +127,17 @@ function getInstallCommand(pkgManager) {
|
|
|
134
127
|
return args;
|
|
135
128
|
}
|
|
136
129
|
|
|
130
|
+
function getRunCommand(pkgManager, script) {
|
|
131
|
+
switch (pkgManager) {
|
|
132
|
+
case 'yarn':
|
|
133
|
+
case 'pnpm':
|
|
134
|
+
case 'bun':
|
|
135
|
+
return [pkgManager, script];
|
|
136
|
+
default:
|
|
137
|
+
return [pkgManager, 'run', script];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
137
141
|
function runCommand(command, options = {}) {
|
|
138
142
|
const [cmd, ...args] = command;
|
|
139
143
|
const result = spawn.sync(cmd, args, {
|
|
@@ -141,52 +145,13 @@ function runCommand(command, options = {}) {
|
|
|
141
145
|
stdio: 'inherit',
|
|
142
146
|
});
|
|
143
147
|
|
|
144
|
-
if (result.status != null && result.status > 0) {
|
|
145
|
-
process.exit(result.status);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
148
|
if (result.error) {
|
|
149
|
-
|
|
150
|
-
process.exit(1);
|
|
149
|
+
throw new Error(`Failed to execute "${cmd}": ${result.error.message}`);
|
|
151
150
|
}
|
|
152
|
-
}
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const child = spawn(cmd, args, {
|
|
158
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
159
|
-
windowsHide: false,
|
|
160
|
-
...options,
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
child.stdout.on('data', () => {});
|
|
164
|
-
let stderr = '';
|
|
165
|
-
child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
|
|
166
|
-
|
|
167
|
-
let i = 0;
|
|
168
|
-
const timer = setInterval(() => {
|
|
169
|
-
process.stdout.write(`\r${pc.cyan(SPINNER_FRAMES[i])} Installing dependencies...`);
|
|
170
|
-
i = (i + 1) % SPINNER_FRAMES.length;
|
|
171
|
-
}, 100);
|
|
172
|
-
|
|
173
|
-
child.on('close', (code) => {
|
|
174
|
-
clearInterval(timer);
|
|
175
|
-
process.stdout.write('\r\x1b[K');
|
|
176
|
-
if (code !== null && code > 0) {
|
|
177
|
-
if (stderr) process.stderr.write(stderr);
|
|
178
|
-
reject(new Error(`exit code ${code}`));
|
|
179
|
-
} else {
|
|
180
|
-
resolve();
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
child.on('error', (err) => {
|
|
184
|
-
clearInterval(timer);
|
|
185
|
-
process.stdout.write('\r\x1b[K');
|
|
186
|
-
if (stderr) process.stderr.write(stderr);
|
|
187
|
-
reject(err);
|
|
188
|
-
});
|
|
189
|
-
});
|
|
152
|
+
if (result.status != null && result.status > 0) {
|
|
153
|
+
throw new Error(`"${cmd}" exited with code ${result.status}`);
|
|
154
|
+
}
|
|
190
155
|
}
|
|
191
156
|
|
|
192
157
|
function checkNodeVersion() {
|
|
@@ -205,7 +170,7 @@ Please upgrade Node.js:
|
|
|
205
170
|
|
|
206
171
|
function parseArgs() {
|
|
207
172
|
const argv = mri(process.argv.slice(2), {
|
|
208
|
-
boolean: ['help', 'version', 'force', 'auto-start', 'no-interactive', 'no-auto-install'
|
|
173
|
+
boolean: ['help', 'version', 'force', 'auto-start', 'no-interactive', 'no-auto-install'],
|
|
209
174
|
string: ['name', 'title', 'cicd'],
|
|
210
175
|
alias: {
|
|
211
176
|
h: 'help',
|
|
@@ -240,25 +205,37 @@ function scaffoldProject(root, answers, packageName) {
|
|
|
240
205
|
|
|
241
206
|
const pkgPath = path.join(root, 'package.json');
|
|
242
207
|
if (fs.existsSync(pkgPath)) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
208
|
+
try {
|
|
209
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
210
|
+
pkg.name = packageName;
|
|
211
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
212
|
+
} catch (e) {
|
|
213
|
+
throw new Error(`Failed to update package.json: ${e.message}`);
|
|
214
|
+
}
|
|
246
215
|
}
|
|
247
216
|
|
|
248
|
-
['.env', '.env.production']
|
|
217
|
+
for (const file of ['.env', '.env.production']) {
|
|
249
218
|
const filePath = path.join(root, file);
|
|
250
219
|
if (fs.existsSync(filePath)) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
220
|
+
try {
|
|
221
|
+
let content = fs.readFileSync(filePath, 'utf-8');
|
|
222
|
+
content = content.replace(/^VITE_APP_TITLE=.*$/m, `VITE_APP_TITLE=${answers.title}`);
|
|
223
|
+
fs.writeFileSync(filePath, content);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
throw new Error(`Failed to update ${file}: ${e.message}`);
|
|
226
|
+
}
|
|
254
227
|
}
|
|
255
|
-
}
|
|
228
|
+
}
|
|
256
229
|
|
|
257
230
|
const indexPath = path.join(root, 'index.html');
|
|
258
231
|
if (fs.existsSync(indexPath)) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
232
|
+
try {
|
|
233
|
+
let content = fs.readFileSync(indexPath, 'utf-8');
|
|
234
|
+
content = content.replace(/<title>[^<]*<\/title>/, `<title>${answers.title}</title>`);
|
|
235
|
+
fs.writeFileSync(indexPath, content);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
throw new Error(`Failed to update index.html: ${e.message}`);
|
|
238
|
+
}
|
|
262
239
|
}
|
|
263
240
|
}
|
|
264
241
|
|
|
@@ -270,7 +247,11 @@ function validateOptions(options) {
|
|
|
270
247
|
}
|
|
271
248
|
|
|
272
249
|
if (options.cicd && !VALID_CICD.includes(options.cicd)) {
|
|
273
|
-
errors.push(`Invalid
|
|
250
|
+
errors.push(`Invalid CI/CD type "${options.cicd}". Valid: ${VALID_CICD.join(', ')}`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (options.title && !/^[a-zA-Z0-9_\-\u4e00-\u9fa5 ]+$/.test(options.title)) {
|
|
254
|
+
errors.push('Project title contains invalid characters (allowed: letters, numbers, Chinese, spaces, dash, underscore)');
|
|
274
255
|
}
|
|
275
256
|
|
|
276
257
|
return errors;
|
|
@@ -398,11 +379,6 @@ async function main() {
|
|
|
398
379
|
cicd: argv.cicd || 'none',
|
|
399
380
|
};
|
|
400
381
|
|
|
401
|
-
if (argv.title && !/^[a-zA-Z0-9_\-\u4e00-\u9fa5 ]+$/.test(argv.title)) {
|
|
402
|
-
console.error(`\n${pc.red('Error:')} Project title contains invalid characters\n`);
|
|
403
|
-
process.exit(1);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
382
|
if (isInteractive) {
|
|
407
383
|
const title = await prompts.text({
|
|
408
384
|
message: 'Project title:',
|
|
@@ -457,26 +433,53 @@ async function main() {
|
|
|
457
433
|
autoInstall = result;
|
|
458
434
|
}
|
|
459
435
|
|
|
436
|
+
let autoStart = argv['auto-start'];
|
|
437
|
+
if (autoStart === undefined && isInteractive && autoInstall) {
|
|
438
|
+
const result = await prompts.confirm({
|
|
439
|
+
message: 'Start dev server now?',
|
|
440
|
+
initialValue: false,
|
|
441
|
+
});
|
|
442
|
+
if (prompts.isCancel(result)) return cancel();
|
|
443
|
+
autoStart = result;
|
|
444
|
+
}
|
|
445
|
+
|
|
460
446
|
if (autoInstall && !process.env._CREATE_VUE3_PC_TEST) {
|
|
461
447
|
process.stdout.write(`\r\x1b[K${pc.dim('Installing dependencies...')}\n`);
|
|
462
|
-
|
|
463
|
-
|
|
448
|
+
try {
|
|
449
|
+
runCommand(getInstallCommand(pkgManager), { cwd: root });
|
|
450
|
+
process.stdout.write(`${pc.green('✓')} Dependencies installed!\n`);
|
|
451
|
+
} catch (e) {
|
|
452
|
+
process.stdout.write(`\n${pc.red('✗')} Installation failed\n`);
|
|
453
|
+
console.error(` ${pc.dim('You can retry manually:')}`);
|
|
454
|
+
console.error(` ${pc.cyan(`cd ${targetDir} && ${pkgManager} install${pkgManager === 'npm' ? ' --legacy-peer-deps' : ''}`)}\n`);
|
|
455
|
+
process.exit(1);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (autoStart) {
|
|
460
|
+
prompts.log.step(`Starting dev server... (press ${pc.bold('Ctrl+C')} to stop)`);
|
|
461
|
+
runCommand(getRunCommand(pkgManager, 'dev'), { cwd: root });
|
|
462
|
+
return;
|
|
464
463
|
}
|
|
465
464
|
|
|
466
|
-
const
|
|
467
|
-
|
|
465
|
+
const cdPath = path.relative(process.cwd(), root);
|
|
466
|
+
const lines = [];
|
|
468
467
|
|
|
469
468
|
if (root !== process.cwd()) {
|
|
470
|
-
|
|
469
|
+
const quoted = cdPath.includes(' ') ? `"${cdPath}"` : cdPath;
|
|
470
|
+
lines.push(` ${pc.bold(pc.cyan('cd'))} ${quoted}`);
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
if (!autoInstall) {
|
|
474
|
-
|
|
474
|
+
const cmd = pkgManager === 'yarn' ? pkgManager : `${pkgManager} install`;
|
|
475
|
+
const flag = pkgManager === 'npm' ? ' --legacy-peer-deps' : '';
|
|
476
|
+
lines.push(` ${pc.bold(pc.cyan(cmd))}${pc.dim(flag)}`);
|
|
475
477
|
}
|
|
476
478
|
|
|
477
|
-
|
|
479
|
+
const runCmd = pkgManager === 'yarn' ? 'yarn dev' : `${pkgManager} run dev`;
|
|
480
|
+
lines.push(` ${pc.bold(pc.cyan(runCmd))}`);
|
|
478
481
|
|
|
479
|
-
prompts.outro(`${pc.green('Done!')} Now run
|
|
482
|
+
prompts.outro(`${pc.green('Done!')} Now run:\n${lines.join('\n')}`);
|
|
480
483
|
}
|
|
481
484
|
|
|
482
485
|
main().catch((e) => {
|