@hobui/viui-cli 0.0.5 → 0.0.6
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/dist/cli.js +155 -27
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -281,6 +281,87 @@ function addPostinstallScript(cwd, pm) {
|
|
|
281
281
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
282
282
|
return true;
|
|
283
283
|
}
|
|
284
|
+
const VIUI_THEME_IDS = ['minimalist-2', 'neo-brutalism', 'material'];
|
|
285
|
+
function setEnvTheme(cwd, themeId) {
|
|
286
|
+
const envPath = path.join(cwd, '.env');
|
|
287
|
+
const examplePath = path.join(cwd, '.env.example');
|
|
288
|
+
const line = `VITE_VIUI_THEME=${themeId}`;
|
|
289
|
+
const targets = [envPath, examplePath].filter((p) => fs.existsSync(p));
|
|
290
|
+
if (targets.length === 0) {
|
|
291
|
+
fs.writeFileSync(envPath, line + '\n', 'utf8');
|
|
292
|
+
console.log('Created .env with', line);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
for (const p of targets) {
|
|
296
|
+
let content = fs.readFileSync(p, 'utf8');
|
|
297
|
+
const re = /^\s*VITE_VIUI_THEME=.*/m;
|
|
298
|
+
if (re.test(content)) {
|
|
299
|
+
content = content.replace(re, line);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
content = content.trimEnd() + '\n' + line + '\n';
|
|
303
|
+
}
|
|
304
|
+
fs.writeFileSync(p, content, 'utf8');
|
|
305
|
+
console.log('Set', line, 'in', path.basename(p));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function ensureApplyThemeBodyInVuetify(cwd) {
|
|
309
|
+
const vuetifyPath = path.join(cwd, 'src', 'plugins', 'vuetify.ts');
|
|
310
|
+
if (!fs.existsSync(vuetifyPath))
|
|
311
|
+
return false;
|
|
312
|
+
const content = fs.readFileSync(vuetifyPath, 'utf8');
|
|
313
|
+
if (/apply-theme-body|applyThemeBody/.test(content))
|
|
314
|
+
return false;
|
|
315
|
+
const importLine = "import './viui-conf/apply-theme-body'";
|
|
316
|
+
const defaultsImportMatch = content.match(/import\s+.+\s+from\s+['"]\.\/viui-conf\/defaults[^'"]*['"]/);
|
|
317
|
+
const insert = defaultsImportMatch
|
|
318
|
+
? content.replace(defaultsImportMatch[0], defaultsImportMatch[0] + '\n' + importLine)
|
|
319
|
+
: content.trimStart().replace(/^(\s*)/, `$1${importLine}\n$1`);
|
|
320
|
+
fs.writeFileSync(vuetifyPath, insert, 'utf8');
|
|
321
|
+
console.log('Added apply-theme-body import to src/plugins/vuetify.ts');
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
function showHelpDocs(cwd) {
|
|
325
|
+
console.log('\n--- Design system setup ---');
|
|
326
|
+
console.log('Design themes (viui-themes) are in: src/assets/styles/viui-themes/');
|
|
327
|
+
console.log('Available theme ids: minimalist-2 (default), neo-brutalism, material');
|
|
328
|
+
console.log('To use a theme: set VITE_VIUI_THEME in .env and add in vuetify.ts:');
|
|
329
|
+
console.log(" import './viui-conf/apply-theme-body'");
|
|
330
|
+
console.log('Details: src/plugins/viui-conf/defaults/README.md');
|
|
331
|
+
console.log('CLI docs: pnpm exec viui-cli --help');
|
|
332
|
+
console.log('---\n');
|
|
333
|
+
}
|
|
334
|
+
async function runConfigureTheme(cwd, rl, opts) {
|
|
335
|
+
console.log('\n Design theme (viui-themes)');
|
|
336
|
+
console.log(' Available: minimalist-2 (default), neo-brutalism, material\n');
|
|
337
|
+
console.log(' a) Use minimalist-2 (default) — thin borders, flat');
|
|
338
|
+
console.log(' b) Use neo-brutalism — thick borders, hard shadow');
|
|
339
|
+
console.log(' c) Use material — elevated, standard Material');
|
|
340
|
+
console.log(' d) Skip / configure manually — set .env yourself\n');
|
|
341
|
+
const a = await rl.question(' Choose (a-d, or Enter for a): ');
|
|
342
|
+
const choice = (a.trim().toLowerCase() || 'a')[0];
|
|
343
|
+
const map = {
|
|
344
|
+
a: 'minimalist-2',
|
|
345
|
+
b: 'neo-brutalism',
|
|
346
|
+
c: 'material',
|
|
347
|
+
d: 'skip',
|
|
348
|
+
};
|
|
349
|
+
const themeId = map[choice] ?? map.a;
|
|
350
|
+
if (themeId === 'skip') {
|
|
351
|
+
console.log(' Skipped. Set VITE_VIUI_THEME in .env and add import in vuetify.ts. See src/plugins/viui-conf/defaults/README.md');
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
setEnvTheme(cwd, themeId);
|
|
355
|
+
const vuetifyPath = path.join(cwd, 'src', 'plugins', 'vuetify.ts');
|
|
356
|
+
const hasImport = fs.existsSync(vuetifyPath) && /apply-theme-body|applyThemeBody/.test(fs.readFileSync(vuetifyPath, 'utf8'));
|
|
357
|
+
if (!hasImport && fs.existsSync(vuetifyPath)) {
|
|
358
|
+
const ans = await rl.question(' Add apply-theme-body import to vuetify.ts? (Y/n): ');
|
|
359
|
+
const add = opts.yes || (ans.trim().toLowerCase() === '' || ans.trim().toLowerCase() === 'y' || ans.trim().toLowerCase() === 'yes');
|
|
360
|
+
if (add)
|
|
361
|
+
ensureApplyThemeBodyInVuetify(cwd);
|
|
362
|
+
}
|
|
363
|
+
console.log(' Theme configured:', themeId);
|
|
364
|
+
}
|
|
284
365
|
async function runSetup(cwd, assetsDir, opts) {
|
|
285
366
|
const isPostinstall = opts.postinstall === true;
|
|
286
367
|
if (isPostinstall && !process.stdin.isTTY) {
|
|
@@ -294,50 +375,97 @@ async function runSetup(cwd, assetsDir, opts) {
|
|
|
294
375
|
}
|
|
295
376
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
296
377
|
const ask = async (q, defaultYes) => {
|
|
297
|
-
const
|
|
298
|
-
const a = await rl.question(`${q} (${def}): `);
|
|
378
|
+
const a = await rl.question(`${q} (${defaultYes ? 'Y/n' : 'y/N'}): `);
|
|
299
379
|
const s = a.trim().toLowerCase();
|
|
300
380
|
if (s === '')
|
|
301
381
|
return defaultYes;
|
|
302
382
|
return s === 'y' || s === 'yes';
|
|
303
383
|
};
|
|
304
384
|
console.log(`\n${pkg.name ?? '@viui/cli'} — Setup i-design-system in this repo\n`);
|
|
385
|
+
console.log(' This will: sync .cursor, viui-conf, viui-themes; optional @viui/web, theme config, postinstall.\n');
|
|
305
386
|
const runNow = opts.yes || (await ask('Run setup now?', true));
|
|
306
387
|
if (!runNow) {
|
|
307
388
|
console.log('Skipped. Run later: pnpm exec viui-cli setup');
|
|
308
389
|
rl.close();
|
|
309
390
|
return;
|
|
310
391
|
}
|
|
392
|
+
const pm = detectPackageManager(cwd);
|
|
311
393
|
const cursorDir = path.join(cwd, '.cursor');
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
console.log('
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
394
|
+
for (;;) {
|
|
395
|
+
console.log('\n What do you want to do?\n');
|
|
396
|
+
console.log(' 1) Full setup (recommended) — init/sync .cursor + viui-conf + viui-themes, install @viui/web, configure theme, add postinstall');
|
|
397
|
+
console.log(' 2) Sync only — update .cursor, viui-conf, viui-themes (no npm install)');
|
|
398
|
+
console.log(' 3) Install @viui/web only — add Vi* components dependency');
|
|
399
|
+
console.log(' 4) Configure design theme — set VITE_VIUI_THEME in .env and ensure body class is applied');
|
|
400
|
+
console.log(' 5) Add postinstall script — auto-sync on every pnpm install');
|
|
401
|
+
console.log(' 6) Show help / docs — print links and next steps\n');
|
|
402
|
+
const choiceInput = await rl.question(' Choose (1-6, or Enter for 1): ');
|
|
403
|
+
const choice = (choiceInput.trim() || '1').replace(/[^1-6]/, '1');
|
|
404
|
+
const n = parseInt(choice, 10);
|
|
405
|
+
if (n < 1 || n > 6)
|
|
406
|
+
continue;
|
|
407
|
+
if (n === 1) {
|
|
408
|
+
if (!fs.existsSync(cursorDir)) {
|
|
409
|
+
console.log('\nStep: Initializing .cursor, viui-conf, viui-themes...');
|
|
410
|
+
runInit(cwd, assetsDir, { yes: true, dryRun: false, noPlans: false });
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
console.log('\nStep: Syncing .cursor, viui-conf, viui-themes...');
|
|
414
|
+
runSync(cwd, assetsDir, { dryRun: false, backup: false });
|
|
415
|
+
}
|
|
416
|
+
console.log('\nStep: Installing @viui/web...');
|
|
417
|
+
const { execSync } = await import('node:child_process');
|
|
418
|
+
const addCmd = pm === 'pnpm' ? 'pnpm add @viui/web' : pm === 'yarn' ? 'yarn add @viui/web' : 'npm install @viui/web';
|
|
419
|
+
execSync(addCmd, { cwd, stdio: 'inherit' });
|
|
420
|
+
await runConfigureTheme(cwd, rl, { yes: opts.yes });
|
|
421
|
+
if (!isPostinstall && (opts.yes || (await ask('\nAdd postinstall to auto-sync on install?', false)))) {
|
|
422
|
+
if (addPostinstallScript(cwd, pm))
|
|
423
|
+
console.log('Added postinstall script to package.json.');
|
|
424
|
+
}
|
|
425
|
+
console.log('\nDone. Use: import { ViButton, ViInput, ... } from \'@viui/web\'');
|
|
426
|
+
console.log('Design themes: src/assets/styles/viui-themes/ — set VITE_VIUI_THEME in .env; see src/plugins/viui-conf/defaults/README.md');
|
|
427
|
+
break;
|
|
321
428
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (addPostinstallScript(cwd, pm)) {
|
|
334
|
-
console.log('Added postinstall script to package.json.');
|
|
429
|
+
if (n === 2) {
|
|
430
|
+
if (!fs.existsSync(cursorDir)) {
|
|
431
|
+
console.log('\nInitializing .cursor, viui-conf, viui-themes...');
|
|
432
|
+
runInit(cwd, assetsDir, { yes: true, dryRun: false, noPlans: false });
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
console.log('\nSyncing .cursor, viui-conf, viui-themes...');
|
|
436
|
+
runSync(cwd, assetsDir, { dryRun: false, backup: false });
|
|
437
|
+
}
|
|
438
|
+
console.log('Sync done.');
|
|
439
|
+
break;
|
|
335
440
|
}
|
|
336
|
-
|
|
337
|
-
|
|
441
|
+
if (n === 3) {
|
|
442
|
+
const { execSync } = await import('node:child_process');
|
|
443
|
+
const addCmd = pm === 'pnpm' ? 'pnpm add @viui/web' : pm === 'yarn' ? 'yarn add @viui/web' : 'npm install @viui/web';
|
|
444
|
+
console.log('\nRunning:', addCmd);
|
|
445
|
+
execSync(addCmd, { cwd, stdio: 'inherit' });
|
|
446
|
+
console.log('Done. Use: import { ViButton, ViInput, ... } from \'@viui/web\'');
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
if (n === 4) {
|
|
450
|
+
await runConfigureTheme(cwd, rl, { yes: opts.yes });
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
if (n === 5) {
|
|
454
|
+
if (addPostinstallScript(cwd, pm)) {
|
|
455
|
+
console.log('\nAdded postinstall script to package.json.');
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
console.log('\npostinstall already contains viui-cli or package.json not found.');
|
|
459
|
+
}
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
if (n === 6) {
|
|
463
|
+
showHelpDocs(cwd);
|
|
464
|
+
const again = opts.yes || (await ask('Show menu again?', true));
|
|
465
|
+
if (!again)
|
|
466
|
+
break;
|
|
338
467
|
}
|
|
339
468
|
}
|
|
340
|
-
console.log('\nDone. Use: import { ViButton, ViInput, ... } from \'@viui/web\'');
|
|
341
469
|
rl.close();
|
|
342
470
|
}
|
|
343
471
|
const result = parseArgs({
|