rizzo-css 0.0.61 → 0.0.62
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/README.md +1 -1
- package/bin/rizzo-css.js +323 -54
- package/package.json +1 -1
- package/scaffold/vanilla/README-RIZZO.md +1 -1
- package/scaffold/vanilla/components/accordion.html +10 -0
- package/scaffold/vanilla/components/alert-dialog.html +10 -0
- package/scaffold/vanilla/components/alert.html +10 -0
- package/scaffold/vanilla/components/aspect-ratio.html +10 -0
- package/scaffold/vanilla/components/avatar.html +10 -0
- package/scaffold/vanilla/components/back-to-top.html +10 -0
- package/scaffold/vanilla/components/badge.html +10 -0
- package/scaffold/vanilla/components/breadcrumb.html +10 -0
- package/scaffold/vanilla/components/button-group.html +10 -0
- package/scaffold/vanilla/components/button.html +10 -0
- package/scaffold/vanilla/components/cards.html +10 -0
- package/scaffold/vanilla/components/collapsible.html +10 -0
- package/scaffold/vanilla/components/context-menu.html +10 -0
- package/scaffold/vanilla/components/copy-to-clipboard.html +10 -0
- package/scaffold/vanilla/components/dashboard.html +10 -0
- package/scaffold/vanilla/components/divider.html +10 -0
- package/scaffold/vanilla/components/docs-sidebar.html +10 -0
- package/scaffold/vanilla/components/dropdown.html +10 -0
- package/scaffold/vanilla/components/empty.html +10 -0
- package/scaffold/vanilla/components/font-switcher.html +10 -0
- package/scaffold/vanilla/components/footer.html +10 -0
- package/scaffold/vanilla/components/forms.html +10 -0
- package/scaffold/vanilla/components/hover-card.html +10 -0
- package/scaffold/vanilla/components/icons.html +10 -0
- package/scaffold/vanilla/components/index.html +10 -0
- package/scaffold/vanilla/components/kbd.html +10 -0
- package/scaffold/vanilla/components/label.html +10 -0
- package/scaffold/vanilla/components/modal.html +10 -0
- package/scaffold/vanilla/components/navbar.html +10 -0
- package/scaffold/vanilla/components/pagination.html +10 -0
- package/scaffold/vanilla/components/popover.html +10 -0
- package/scaffold/vanilla/components/progress-bar.html +10 -0
- package/scaffold/vanilla/components/resizable.html +10 -0
- package/scaffold/vanilla/components/scroll-area.html +10 -0
- package/scaffold/vanilla/components/search.html +10 -0
- package/scaffold/vanilla/components/separator.html +10 -0
- package/scaffold/vanilla/components/settings.html +10 -0
- package/scaffold/vanilla/components/sheet.html +10 -0
- package/scaffold/vanilla/components/skeleton.html +10 -0
- package/scaffold/vanilla/components/slider.html +10 -0
- package/scaffold/vanilla/components/sound-effects.html +10 -0
- package/scaffold/vanilla/components/spinner.html +10 -0
- package/scaffold/vanilla/components/switch.html +10 -0
- package/scaffold/vanilla/components/table.html +10 -0
- package/scaffold/vanilla/components/tabs.html +10 -0
- package/scaffold/vanilla/components/theme-switcher.html +10 -0
- package/scaffold/vanilla/components/toast.html +10 -0
- package/scaffold/vanilla/components/toggle-group.html +10 -0
- package/scaffold/vanilla/components/toggle.html +10 -0
- package/scaffold/vanilla/components/tooltip.html +10 -0
- package/scaffold/vanilla/index.html +10 -0
package/bin/rizzo-css.js
CHANGED
|
@@ -193,6 +193,7 @@ const LIGHT_THEMES = [
|
|
|
193
193
|
'semi-light-purple',
|
|
194
194
|
];
|
|
195
195
|
const THEMES = [...DARK_THEMES, ...LIGHT_THEMES];
|
|
196
|
+
const VALID_THEME_VALUES = ['system', ...THEMES];
|
|
196
197
|
// Components available for scaffold (must match scaffold/svelte and scaffold/astro; missing files are skipped on copy)
|
|
197
198
|
const SVELTE_COMPONENTS = [
|
|
198
199
|
'Button', 'Badge', 'Card', 'Dashboard', 'Divider', 'DocsSidebar', 'Footer', 'Spinner', 'ProgressBar', 'Avatar', 'Alert',
|
|
@@ -316,11 +317,57 @@ function getCssPath() {
|
|
|
316
317
|
return join(getPackageRoot(), 'dist', 'rizzo.min.css');
|
|
317
318
|
}
|
|
318
319
|
|
|
319
|
-
/**
|
|
320
|
-
function
|
|
320
|
+
/** Simple semver comparison: true if a > b (e.g. "1.2.3" > "1.2.2"). */
|
|
321
|
+
function semverGt(a, b) {
|
|
322
|
+
const pa = a.split('.').map((n) => parseInt(n, 10) || 0);
|
|
323
|
+
const pb = b.split('.').map((n) => parseInt(n, 10) || 0);
|
|
324
|
+
for (let i = 0; i < 3; i++) {
|
|
325
|
+
const na = pa[i] || 0, nb = pb[i] || 0;
|
|
326
|
+
if (na > nb) return true;
|
|
327
|
+
if (na < nb) return false;
|
|
328
|
+
}
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** Optional version check: if not --offline, fetch latest from registry and print one line if newer. Non-blocking (2s timeout). */
|
|
333
|
+
async function checkNewerVersion(argv) {
|
|
334
|
+
if (hasFlag(argv, '--offline')) return;
|
|
335
|
+
let current;
|
|
336
|
+
try {
|
|
337
|
+
const pkgPath = join(getPackageRoot(), 'package.json');
|
|
338
|
+
current = JSON.parse(readFileSync(pkgPath, 'utf8')).version;
|
|
339
|
+
} catch (_) { return; }
|
|
340
|
+
try {
|
|
341
|
+
const ac = new AbortController();
|
|
342
|
+
const timeout = setTimeout(() => ac.abort(), 2500);
|
|
343
|
+
const res = await fetch('https://registry.npmjs.org/rizzo-css/latest', { signal: ac.signal }).finally(() => clearTimeout(timeout));
|
|
344
|
+
if (!res || !res.ok) return;
|
|
345
|
+
const data = await res.json();
|
|
346
|
+
const latest = data.version;
|
|
347
|
+
if (latest && semverGt(latest, current)) {
|
|
348
|
+
console.log('\n \u2139 A newer version of rizzo-css is available: ' + latest + ' (you have ' + current + '). Run npm update rizzo-css or re-run npx rizzo-css add to use it.');
|
|
349
|
+
}
|
|
350
|
+
} catch (_) { /* ignore network or parse errors */ }
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Copy package dist/fonts into <cssTargetDir>/fonts so CSS url(./fonts/...) resolves. cssTargetDir is framework-specific (static/css | css). Not used for Astro; use copyRizzoCssAndFontsForAstro instead. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite (projectDir must be cwd). */
|
|
354
|
+
function copyRizzoFonts(cssTargetDir, opts) {
|
|
321
355
|
const fontsSrc = join(getPackageRoot(), 'dist', 'fonts');
|
|
322
356
|
if (!existsSync(fontsSrc)) return;
|
|
323
357
|
const dest = join(cssTargetDir, 'fonts');
|
|
358
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
359
|
+
if (plan) {
|
|
360
|
+
function collectPaths(src, d) {
|
|
361
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
362
|
+
for (const e of entries) {
|
|
363
|
+
const destPath = join(d, e.name);
|
|
364
|
+
if (e.isDirectory()) collectPaths(join(src, e.name), destPath);
|
|
365
|
+
else plan.wouldWrite.push(pathRelative(process.cwd(), destPath));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
collectPaths(fontsSrc, dest);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
324
371
|
mkdirSync(dest, { recursive: true });
|
|
325
372
|
const entries = readdirSync(fontsSrc, { withFileTypes: true });
|
|
326
373
|
for (const e of entries) {
|
|
@@ -334,11 +381,19 @@ function copyRizzoFonts(cssTargetDir) {
|
|
|
334
381
|
}
|
|
335
382
|
}
|
|
336
383
|
|
|
337
|
-
/** Copy package dist/sfx (click.mp3 or click.wav) into projectDir/assets/sfx so sound-effects-inline.js can play the click sound. Used for Vanilla init and add. */
|
|
338
|
-
function copyRizzoSfx(projectDir) {
|
|
384
|
+
/** Copy package dist/sfx (click.mp3 or click.wav) into projectDir/assets/sfx so sound-effects-inline.js can play the click sound. Used for Vanilla init and add. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite. */
|
|
385
|
+
function copyRizzoSfx(projectDir, opts) {
|
|
339
386
|
const sfxSrc = join(getPackageRoot(), 'dist', 'sfx');
|
|
340
387
|
if (!existsSync(sfxSrc)) return;
|
|
341
388
|
const dest = join(projectDir, 'assets', 'sfx');
|
|
389
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
390
|
+
if (plan) {
|
|
391
|
+
readdirSync(sfxSrc, { withFileTypes: true }).forEach((e) => {
|
|
392
|
+
if (!e.isDirectory() && (/\.mp3$/i.test(e.name) || /\.wav$/i.test(e.name)))
|
|
393
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(dest, e.name)));
|
|
394
|
+
});
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
342
397
|
mkdirSync(dest, { recursive: true });
|
|
343
398
|
const entries = readdirSync(sfxSrc, { withFileTypes: true });
|
|
344
399
|
for (const e of entries) {
|
|
@@ -348,12 +403,34 @@ function copyRizzoSfx(projectDir) {
|
|
|
348
403
|
}
|
|
349
404
|
}
|
|
350
405
|
|
|
351
|
-
/** Astro only: copy rizzo.min.css to public/css with font URLs rewritten to ../assets/fonts/ (relative so base path works), and copy fonts to public/assets/fonts. */
|
|
352
|
-
function copyRizzoCssAndFontsForAstro(projectDir, cssSource) {
|
|
406
|
+
/** Astro only: copy rizzo.min.css to public/css with font URLs rewritten to ../assets/fonts/ (relative so base path works), and copy fonts to public/assets/fonts. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite. */
|
|
407
|
+
function copyRizzoCssAndFontsForAstro(projectDir, cssSource, opts) {
|
|
353
408
|
const cssDir = join(projectDir, 'public', 'css');
|
|
354
409
|
const cssTarget = join(cssDir, 'rizzo.min.css');
|
|
355
410
|
const fontsDest = join(projectDir, 'public', 'assets', 'fonts');
|
|
356
411
|
const sfxDest = join(projectDir, 'public', 'assets', 'sfx');
|
|
412
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
413
|
+
if (plan) {
|
|
414
|
+
plan.wouldWrite.push(pathRelative(projectDir, cssTarget));
|
|
415
|
+
function collectPaths(src, dest) {
|
|
416
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
417
|
+
for (const e of entries) {
|
|
418
|
+
const destPath = join(dest, e.name);
|
|
419
|
+
if (e.isDirectory()) collectPaths(join(src, e.name), destPath);
|
|
420
|
+
else plan.wouldWrite.push(pathRelative(projectDir, destPath));
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const fontsSrc = join(getPackageRoot(), 'dist', 'fonts');
|
|
424
|
+
if (existsSync(fontsSrc)) collectPaths(fontsSrc, fontsDest);
|
|
425
|
+
const sfxSrc = join(getPackageRoot(), 'dist', 'sfx');
|
|
426
|
+
if (existsSync(sfxSrc)) {
|
|
427
|
+
readdirSync(sfxSrc, { withFileTypes: true }).forEach((e) => {
|
|
428
|
+
if (!e.isDirectory() && (/\.mp3$/i.test(e.name) || /\.wav$/i.test(e.name)))
|
|
429
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(sfxDest, e.name)));
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
357
434
|
mkdirSync(cssDir, { recursive: true });
|
|
358
435
|
mkdirSync(fontsDest, { recursive: true });
|
|
359
436
|
mkdirSync(sfxDest, { recursive: true });
|
|
@@ -382,12 +459,34 @@ function copyRizzoCssAndFontsForAstro(projectDir, cssSource) {
|
|
|
382
459
|
}
|
|
383
460
|
}
|
|
384
461
|
|
|
385
|
-
/** SvelteKit only: copy rizzo.min.css to static/css with font URLs rewritten to ../assets/fonts/ (relative so base path works), and copy fonts to static/assets/fonts. */
|
|
386
|
-
function copyRizzoCssAndFontsForSvelte(projectDir, cssSource) {
|
|
462
|
+
/** SvelteKit only: copy rizzo.min.css to static/css with font URLs rewritten to ../assets/fonts/ (relative so base path works), and copy fonts to static/assets/fonts. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite. */
|
|
463
|
+
function copyRizzoCssAndFontsForSvelte(projectDir, cssSource, opts) {
|
|
387
464
|
const cssDir = join(projectDir, 'static', 'css');
|
|
388
465
|
const cssTarget = join(cssDir, 'rizzo.min.css');
|
|
389
466
|
const fontsDest = join(projectDir, 'static', 'assets', 'fonts');
|
|
390
467
|
const sfxDest = join(projectDir, 'static', 'assets', 'sfx');
|
|
468
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
469
|
+
if (plan) {
|
|
470
|
+
plan.wouldWrite.push(pathRelative(projectDir, cssTarget));
|
|
471
|
+
function collectPaths(src, dest) {
|
|
472
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
473
|
+
for (const e of entries) {
|
|
474
|
+
const destPath = join(dest, e.name);
|
|
475
|
+
if (e.isDirectory()) collectPaths(join(src, e.name), destPath);
|
|
476
|
+
else plan.wouldWrite.push(pathRelative(projectDir, destPath));
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const fontsSrc = join(getPackageRoot(), 'dist', 'fonts');
|
|
480
|
+
if (existsSync(fontsSrc)) collectPaths(fontsSrc, fontsDest);
|
|
481
|
+
const sfxSrc = join(getPackageRoot(), 'dist', 'sfx');
|
|
482
|
+
if (existsSync(sfxSrc)) {
|
|
483
|
+
readdirSync(sfxSrc, { withFileTypes: true }).forEach((e) => {
|
|
484
|
+
if (!e.isDirectory() && (/\.mp3$/i.test(e.name) || /\.wav$/i.test(e.name)))
|
|
485
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(sfxDest, e.name)));
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
391
490
|
mkdirSync(cssDir, { recursive: true });
|
|
392
491
|
mkdirSync(fontsDest, { recursive: true });
|
|
393
492
|
mkdirSync(sfxDest, { recursive: true });
|
|
@@ -416,12 +515,16 @@ function copyRizzoCssAndFontsForSvelte(projectDir, cssSource) {
|
|
|
416
515
|
}
|
|
417
516
|
}
|
|
418
517
|
|
|
419
|
-
/** Copy the package LICENSE into the project dir as LICENSE-RIZZO so we do not overwrite an existing LICENSE. */
|
|
420
|
-
function copyPackageLicense(projectDir) {
|
|
518
|
+
/** Copy the package LICENSE into the project dir as LICENSE-RIZZO so we do not overwrite an existing LICENSE. opts: optional { dryRun, plan }; when dryRun push relative path to plan.wouldWrite. */
|
|
519
|
+
function copyPackageLicense(projectDir, opts) {
|
|
421
520
|
const licensePath = join(getPackageRoot(), 'LICENSE');
|
|
422
|
-
if (existsSync(licensePath))
|
|
423
|
-
|
|
521
|
+
if (!existsSync(licensePath)) return;
|
|
522
|
+
const dest = join(projectDir, SCAFFOLD_LICENSE_FILENAME);
|
|
523
|
+
if (opts && opts.dryRun && opts.plan) {
|
|
524
|
+
opts.plan.wouldWrite.push(pathRelative(projectDir, dest));
|
|
525
|
+
return;
|
|
424
526
|
}
|
|
527
|
+
copyFileSync(licensePath, dest);
|
|
425
528
|
}
|
|
426
529
|
|
|
427
530
|
/** Name of the scaffold gitignore file (no leading dot so npm pack includes it). Copied to project as .gitignore. */
|
|
@@ -615,11 +718,11 @@ function copyVariantOverlay(projectDir, framework, variation, replacements) {
|
|
|
615
718
|
copyDirRecursiveWithReplacements(variantDir, projectDir, replacements);
|
|
616
719
|
}
|
|
617
720
|
|
|
618
|
-
/** Copy variant overlay with no-overwrite (for add to existing). Returns { skipped } like copyDirRecursiveWithReplacementsNoOverwrite. */
|
|
619
|
-
function copyVariantOverlayNoOverwrite(projectDir, framework, variation, replacements) {
|
|
721
|
+
/** Copy variant overlay with no-overwrite (for add to existing). Returns { skipped } like copyDirRecursiveWithReplacementsNoOverwrite. opts: optional { dryRun, plan }. */
|
|
722
|
+
function copyVariantOverlayNoOverwrite(projectDir, framework, variation, replacements, opts) {
|
|
620
723
|
const variantDir = getVariantDir(framework, variation);
|
|
621
724
|
if (!variantDir) return { skipped: [] };
|
|
622
|
-
return copyDirRecursiveWithReplacementsNoOverwrite(variantDir, projectDir, replacements, projectDir);
|
|
725
|
+
return copyDirRecursiveWithReplacementsNoOverwrite(variantDir, projectDir, replacements, projectDir, opts);
|
|
623
726
|
}
|
|
624
727
|
|
|
625
728
|
function question(prompt) {
|
|
@@ -975,7 +1078,7 @@ Available commands: init, add, theme, doctor, help
|
|
|
975
1078
|
|
|
976
1079
|
Flags summary:
|
|
977
1080
|
init --yes --path <dir> --framework <fw> --template <t> --package-manager <pm> --install --no-install --no-git
|
|
978
|
-
add --path <dir> --framework <fw> --template css-only|landing|docs|dashboard|full --no-snippet --readme --force --vanilla-js
|
|
1081
|
+
add --path <dir> --framework <fw> --template css-only|landing|docs|dashboard|full --dry-run --no-snippet --readme --force --vanilla-js
|
|
979
1082
|
theme (no flags)
|
|
980
1083
|
doctor Check config, CSS file, and optional layout link
|
|
981
1084
|
help (no flags)
|
|
@@ -1000,6 +1103,7 @@ Options (init):
|
|
|
1000
1103
|
--package-manager <pm> npm | pnpm | yarn | bun (with --yes, or skip PM prompt when interactive)
|
|
1001
1104
|
--install After scaffolding, run package manager install in project directory (no prompt)
|
|
1002
1105
|
--no-install Do not run install; do not prompt (skip "Run <pm> install? (Y/n)")
|
|
1106
|
+
--offline Use package manager cache only (no network). Passed to install/add when running PM.
|
|
1003
1107
|
--no-git With --yes, skip initializing a git repository (default with --yes is to run git init)
|
|
1004
1108
|
(Git: only init offers or runs git init. Interactive init: "Initialize git? (Y/n)". With --yes, git init runs unless --no-git. Add does not prompt for git. Init (create new): "Run <pm> install? (Y/n)" uses the package manager you selected (npm, pnpm, yarn, bun). Add: "Run <pm> add rizzo-css? (Y/n)" same. Vanilla has no package manager. rizzo-css.json is written only when the project does not already have one.)
|
|
1005
1109
|
|
|
@@ -1007,9 +1111,11 @@ Options (add) — run from your existing project root; you will choose a templat
|
|
|
1007
1111
|
--template <t> css-only | landing | docs | dashboard | full (CSS only = stylesheet only; others = component picker)
|
|
1008
1112
|
--path <dir> Target directory for rizzo.min.css (overrides config and framework default)
|
|
1009
1113
|
--framework <fw> vanilla | astro | svelte (overrides config and detection)
|
|
1114
|
+
--dry-run Preview which files would be written without writing; show RIZZO-SETUP.md snippet for skipped files
|
|
1010
1115
|
--package-manager <pm> npm | pnpm | yarn | bun (override detection for install/print commands)
|
|
1011
1116
|
--install-package After copying CSS, run package manager add rizzo-css
|
|
1012
1117
|
--no-install Do not run install or add (overrides --install-package)
|
|
1118
|
+
--offline Use package manager cache only (no network). Passed to add when running PM.
|
|
1013
1119
|
--no-snippet (Full only) Do not write RIZZO-SNIPPET.txt (link + theme copy-paste)
|
|
1014
1120
|
--readme Write README-RIZZO.md into the project
|
|
1015
1121
|
--force Overwrite existing rizzo.min.css without prompting
|
|
@@ -1102,12 +1208,12 @@ function cmdTheme() {
|
|
|
1102
1208
|
process.stdout.write('\nExample: <html lang="en" data-theme="github-dark-classic">\n\n');
|
|
1103
1209
|
}
|
|
1104
1210
|
|
|
1105
|
-
/** Check project for Rizzo CSS: config, CSS file,
|
|
1211
|
+
/** Check project for Rizzo CSS: config, CSS file, layout link, theme, fonts/sfx paths, and optional outdated-CSS hint. */
|
|
1106
1212
|
function cmdDoctor() {
|
|
1107
1213
|
const cwd = process.cwd();
|
|
1108
1214
|
const config = readRizzoConfig(cwd);
|
|
1109
1215
|
console.log(getBanner());
|
|
1110
|
-
console.log(' Doctor — check config, CSS path,
|
|
1216
|
+
console.log(' Doctor — check config, CSS path, layout link, theme, and assets\n');
|
|
1111
1217
|
let ok = true;
|
|
1112
1218
|
if (!config) {
|
|
1113
1219
|
console.log(' ✗ No ' + RIZZO_CONFIG_FILE + '. Run: npx rizzo-css add or init');
|
|
@@ -1123,6 +1229,48 @@ function cmdDoctor() {
|
|
|
1123
1229
|
ok = false;
|
|
1124
1230
|
} else {
|
|
1125
1231
|
console.log(' ✓ CSS at ' + cssPath);
|
|
1232
|
+
const cssSize = statSync(cssPath).size;
|
|
1233
|
+
if (cssSize < 5000) {
|
|
1234
|
+
console.log(' ? CSS file is very small (' + cssSize + ' B). Run pnpm build:css in the repo or re-run npx rizzo-css add to refresh.');
|
|
1235
|
+
ok = false;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
if (config.theme != null && config.theme !== '') {
|
|
1239
|
+
if (VALID_THEME_VALUES.includes(config.theme)) {
|
|
1240
|
+
console.log(' ✓ Theme (from config): ' + config.theme);
|
|
1241
|
+
} else {
|
|
1242
|
+
console.log(' ✗ Invalid theme in config: "' + config.theme + '". Use one of: system, ' + THEMES.slice(0, 5).join(', ') + ', ... (run npx rizzo-css theme for full list)');
|
|
1243
|
+
ok = false;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
const fontsDir = fw === 'astro' ? join(cwd, 'public', 'assets', 'fonts') : fw === 'svelte' ? join(cwd, 'static', 'assets', 'fonts') : join(cwd, targetDir, 'fonts');
|
|
1247
|
+
if (!existsSync(fontsDir)) {
|
|
1248
|
+
console.log(' ? Fonts path not found: ' + pathRelative(cwd, fontsDir) + ' (CSS may reference ../assets/fonts/ or ./fonts/; add fonts if you use theme typography)');
|
|
1249
|
+
} else {
|
|
1250
|
+
try {
|
|
1251
|
+
const entries = readdirSync(fontsDir, { withFileTypes: true });
|
|
1252
|
+
const hasFiles = entries.some((e) => e.isFile() && /\.(woff2?|ttf|otf)$/i.test(e.name));
|
|
1253
|
+
if (!hasFiles) {
|
|
1254
|
+
console.log(' ? Fonts dir exists but is empty or has no font files: ' + pathRelative(cwd, fontsDir));
|
|
1255
|
+
} else {
|
|
1256
|
+
console.log(' ✓ Fonts at ' + pathRelative(cwd, fontsDir));
|
|
1257
|
+
}
|
|
1258
|
+
} catch (_) {
|
|
1259
|
+
console.log(' ? Could not read fonts dir: ' + pathRelative(cwd, fontsDir));
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
const sfxDir = fw === 'astro' ? join(cwd, 'public', 'assets', 'sfx') : fw === 'svelte' ? join(cwd, 'static', 'assets', 'sfx') : join(cwd, 'assets', 'sfx');
|
|
1263
|
+
if (!existsSync(sfxDir)) {
|
|
1264
|
+
console.log(' ? Sound effects path not found: ' + pathRelative(cwd, sfxDir) + ' (optional; needed if you use Settings or SoundEffects with click sounds)');
|
|
1265
|
+
} else {
|
|
1266
|
+
try {
|
|
1267
|
+
const entries = readdirSync(sfxDir, { withFileTypes: true });
|
|
1268
|
+
const hasSfx = entries.some((e) => e.isFile() && (/\.(mp3|wav)$/i.test(e.name)));
|
|
1269
|
+
if (hasSfx) console.log(' ✓ Sound effects at ' + pathRelative(cwd, sfxDir));
|
|
1270
|
+
else console.log(' ? Sfx dir exists but has no .mp3/.wav: ' + pathRelative(cwd, sfxDir));
|
|
1271
|
+
} catch (_) {
|
|
1272
|
+
console.log(' ? Could not read sfx dir: ' + pathRelative(cwd, sfxDir));
|
|
1273
|
+
}
|
|
1126
1274
|
}
|
|
1127
1275
|
const layoutPaths = fw === 'svelte' ? ['src/app.html'] : fw === 'astro' ? ['src/layouts/Layout.astro', 'src/layouts/BaseLayout.astro'] : [];
|
|
1128
1276
|
for (const lp of layoutPaths) {
|
|
@@ -1134,11 +1282,25 @@ function cmdDoctor() {
|
|
|
1134
1282
|
} else {
|
|
1135
1283
|
console.log(' ✓ Layout ' + lp + ' includes Rizzo link');
|
|
1136
1284
|
}
|
|
1285
|
+
if (content.includes('data-theme=')) {
|
|
1286
|
+
const match = content.match(/data-theme=["']([^"']+)["']/);
|
|
1287
|
+
if (match && !VALID_THEME_VALUES.includes(match[1])) {
|
|
1288
|
+
console.log(' ? Layout has data-theme="' + match[1] + '" which is not a known theme. Use: npx rizzo-css theme');
|
|
1289
|
+
ok = false;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1137
1292
|
break;
|
|
1138
1293
|
}
|
|
1139
1294
|
}
|
|
1295
|
+
const pkgPath = join(cwd, 'node_modules', 'rizzo-css', 'package.json');
|
|
1296
|
+
if (existsSync(pkgPath)) {
|
|
1297
|
+
try {
|
|
1298
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
1299
|
+
const ver = pkg.version;
|
|
1300
|
+
if (ver) console.log(' ℹ rizzo-css in node_modules: v' + ver + '. Re-run npx rizzo-css add to refresh CSS if needed.');
|
|
1301
|
+
} catch (_) { /* ignore */ }
|
|
1302
|
+
}
|
|
1140
1303
|
}
|
|
1141
|
-
if (config && config.theme) console.log(' Theme (from config): ' + config.theme);
|
|
1142
1304
|
console.log(ok ? '\nAll checks passed.\n' : '\nFix the items above, then run your dev server.\n');
|
|
1143
1305
|
}
|
|
1144
1306
|
|
|
@@ -1266,6 +1428,7 @@ async function cmdAdd(argv) {
|
|
|
1266
1428
|
const writeReadme = hasFlag(argv, '--readme');
|
|
1267
1429
|
const force = hasFlag(argv, '--force');
|
|
1268
1430
|
const copyVanillaJs = hasFlag(argv, '--vanilla-js');
|
|
1431
|
+
const dryRun = hasFlag(argv, '--dry-run');
|
|
1269
1432
|
const positionals = getPositionalArgs(argv, 3);
|
|
1270
1433
|
|
|
1271
1434
|
const cwd = process.cwd();
|
|
@@ -1283,21 +1446,25 @@ async function cmdAdd(argv) {
|
|
|
1283
1446
|
copyVanillaJs,
|
|
1284
1447
|
installPackage: installPackage || undefined,
|
|
1285
1448
|
noInstall: noInstall || undefined,
|
|
1449
|
+
dryRun: dryRun || undefined,
|
|
1450
|
+
plan: dryRun ? { wouldWrite: [], skipped: [] } : undefined,
|
|
1286
1451
|
};
|
|
1287
1452
|
await runAddToExisting(explicitFramework, options);
|
|
1453
|
+
if (options.dryRun) return;
|
|
1288
1454
|
if (installPackage && !noInstall) {
|
|
1289
1455
|
const pm = (pmOverride
|
|
1290
1456
|
? getPackageManagerCommands({ agent: pmOverride, command: pmOverride })
|
|
1291
1457
|
: (config && config.packageManager)
|
|
1292
1458
|
? getPackageManagerCommands({ agent: config.packageManager, command: config.packageManager })
|
|
1293
1459
|
: resolvePackageManager(cwd));
|
|
1294
|
-
const addPkg = pm.add('rizzo-css');
|
|
1460
|
+
const addPkg = pm.add('rizzo-css') + (hasFlag(argv, '--offline') ? ' --offline' : '');
|
|
1295
1461
|
console.log('\nRunning: ' + addPkg);
|
|
1296
1462
|
const code = runInDir(cwd, addPkg);
|
|
1297
1463
|
if (code !== 0) {
|
|
1298
1464
|
console.error('\nInstall failed (exit ' + code + '). You can run manually: ' + addPkg);
|
|
1299
1465
|
}
|
|
1300
1466
|
}
|
|
1467
|
+
await checkNewerVersion(argv).catch(() => {});
|
|
1301
1468
|
}
|
|
1302
1469
|
|
|
1303
1470
|
function getScaffoldSvelteDir() {
|
|
@@ -1372,8 +1539,8 @@ function getNavbarHtmlVanilla(title, brandHref) {
|
|
|
1372
1539
|
return html.replace(/\{\{TITLE\}\}/g, title || 'App').replace(/\{\{NAVBAR_BRAND_HREF\}\}/g, brandHref || '#');
|
|
1373
1540
|
}
|
|
1374
1541
|
|
|
1375
|
-
/** Copy selected Vanilla component HTML files into projectDir/components/, with replacements. Writes a simple components/index.html. */
|
|
1376
|
-
function copyVanillaComponents(projectDir, selectedNames, replacements) {
|
|
1542
|
+
/** Copy selected Vanilla component HTML files into projectDir/components/, with replacements. Writes a simple components/index.html. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite. */
|
|
1543
|
+
function copyVanillaComponents(projectDir, selectedNames, replacements, opts) {
|
|
1377
1544
|
const srcDir = getScaffoldVanillaComponentsDir();
|
|
1378
1545
|
if (!existsSync(srcDir)) return;
|
|
1379
1546
|
const linkHref = replacements['{{LINK_HREF}}'] || 'css/rizzo.min.css';
|
|
@@ -1392,6 +1559,12 @@ function copyVanillaComponents(projectDir, selectedNames, replacements) {
|
|
|
1392
1559
|
}
|
|
1393
1560
|
if (slugsToCopy.length === 0) return;
|
|
1394
1561
|
const destDir = join(projectDir, 'components');
|
|
1562
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
1563
|
+
if (plan) {
|
|
1564
|
+
slugsToCopy.forEach((slug) => plan.wouldWrite.push(pathRelative(projectDir, join(destDir, slug + '.html'))));
|
|
1565
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(destDir, 'index.html')));
|
|
1566
|
+
return;
|
|
1567
|
+
}
|
|
1395
1568
|
mkdirSync(destDir, { recursive: true });
|
|
1396
1569
|
for (const slug of slugsToCopy) {
|
|
1397
1570
|
const src = join(srcDir, slug + '.html');
|
|
@@ -1430,24 +1603,45 @@ ${indexLinks}
|
|
|
1430
1603
|
writeFileSync(join(destDir, 'index.html'), indexHtml, 'utf8');
|
|
1431
1604
|
}
|
|
1432
1605
|
|
|
1433
|
-
/** Copy Rizzo icons into the project for the given framework. */
|
|
1434
|
-
function copyRizzoIcons(projectDir, framework) {
|
|
1606
|
+
/** Copy Rizzo icons into the project for the given framework. opts: optional { dryRun, plan }; when dryRun push relative paths to plan.wouldWrite. */
|
|
1607
|
+
function copyRizzoIcons(projectDir, framework, opts) {
|
|
1608
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
1609
|
+
function collectIconPaths(src, dest) {
|
|
1610
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
1611
|
+
for (const e of entries) {
|
|
1612
|
+
const destPath = join(dest, e.name);
|
|
1613
|
+
if (e.isDirectory()) collectIconPaths(join(src, e.name), destPath);
|
|
1614
|
+
else plan.wouldWrite.push(pathRelative(projectDir, destPath));
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1435
1617
|
if (framework === 'astro') {
|
|
1436
1618
|
const iconsSrc = join(getScaffoldAstroDir(), 'icons');
|
|
1437
1619
|
if (!existsSync(iconsSrc)) return;
|
|
1438
1620
|
const targetDir = join(projectDir, 'src', 'components', 'rizzo', 'icons');
|
|
1621
|
+
if (plan) {
|
|
1622
|
+
collectIconPaths(iconsSrc, targetDir);
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1439
1625
|
mkdirSync(targetDir, { recursive: true });
|
|
1440
1626
|
copyDirRecursive(iconsSrc, targetDir);
|
|
1441
1627
|
} else if (framework === 'svelte') {
|
|
1442
1628
|
const iconsSrc = join(getScaffoldSvelteDir(), 'icons');
|
|
1443
1629
|
if (!existsSync(iconsSrc)) return;
|
|
1444
1630
|
const targetDir = join(projectDir, 'src', 'lib', 'rizzo', 'icons');
|
|
1631
|
+
if (plan) {
|
|
1632
|
+
collectIconPaths(iconsSrc, targetDir);
|
|
1633
|
+
return;
|
|
1634
|
+
}
|
|
1445
1635
|
mkdirSync(targetDir, { recursive: true });
|
|
1446
1636
|
copyDirRecursive(iconsSrc, targetDir);
|
|
1447
1637
|
} else if (framework === 'vanilla') {
|
|
1448
1638
|
const iconsSrc = getScaffoldVanillaIconsDir();
|
|
1449
1639
|
if (!existsSync(iconsSrc)) return;
|
|
1450
1640
|
const targetDir = join(projectDir, 'icons');
|
|
1641
|
+
if (plan) {
|
|
1642
|
+
collectIconPaths(iconsSrc, targetDir);
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1451
1645
|
mkdirSync(targetDir, { recursive: true });
|
|
1452
1646
|
copyDirRecursive(iconsSrc, targetDir);
|
|
1453
1647
|
}
|
|
@@ -1504,13 +1698,15 @@ function copyDirRecursiveWithReplacements(src, dest, replacements) {
|
|
|
1504
1698
|
* Like copyDirRecursiveWithReplacements but never overwrites existing files.
|
|
1505
1699
|
* Returns { skipped: Array<{ relativePath, content }> } for files that already existed (so caller can write RIZZO-SETUP.md).
|
|
1506
1700
|
* relativePath is from projectDir (dest).
|
|
1701
|
+
* opts: optional { dryRun, plan: { wouldWrite: string[], skipped: [] } }. When dryRun, no I/O; plan.wouldWrite gets new file paths, plan.skipped gets skipped entries (merged with returned skipped).
|
|
1507
1702
|
*/
|
|
1508
|
-
function copyDirRecursiveWithReplacementsNoOverwrite(src, dest, replacements, projectDir) {
|
|
1703
|
+
function copyDirRecursiveWithReplacementsNoOverwrite(src, dest, replacements, projectDir, opts) {
|
|
1509
1704
|
const skipped = [];
|
|
1510
1705
|
projectDir = projectDir || dest;
|
|
1706
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
1511
1707
|
const textExtensions = new Set(['.html', '.astro', '.svelte', '.ts', '.js', '.mjs', '.json', '.css', '.md']);
|
|
1512
1708
|
function recurse(s, d) {
|
|
1513
|
-
mkdirSync(d, { recursive: true });
|
|
1709
|
+
if (!plan) mkdirSync(d, { recursive: true });
|
|
1514
1710
|
const entries = readdirSync(s, { withFileTypes: true });
|
|
1515
1711
|
for (const e of entries) {
|
|
1516
1712
|
const srcPath = join(s, e.name);
|
|
@@ -1518,8 +1714,8 @@ function copyDirRecursiveWithReplacementsNoOverwrite(src, dest, replacements, pr
|
|
|
1518
1714
|
if (e.isDirectory()) {
|
|
1519
1715
|
recurse(srcPath, destPath);
|
|
1520
1716
|
} else {
|
|
1717
|
+
const rel = pathRelative(projectDir, destPath);
|
|
1521
1718
|
if (existsSync(destPath)) {
|
|
1522
|
-
const rel = pathRelative(projectDir, destPath);
|
|
1523
1719
|
let content = '';
|
|
1524
1720
|
const ext = srcPath.slice(srcPath.lastIndexOf('.'));
|
|
1525
1721
|
if (textExtensions.has(ext)) {
|
|
@@ -1531,6 +1727,10 @@ function copyDirRecursiveWithReplacementsNoOverwrite(src, dest, replacements, pr
|
|
|
1531
1727
|
skipped.push({ relativePath: rel, content });
|
|
1532
1728
|
continue;
|
|
1533
1729
|
}
|
|
1730
|
+
if (plan) {
|
|
1731
|
+
plan.wouldWrite.push(rel);
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1534
1734
|
const ext = srcPath.slice(srcPath.lastIndexOf('.'));
|
|
1535
1735
|
if (textExtensions.has(ext)) {
|
|
1536
1736
|
let content = readFileSync(srcPath, 'utf8');
|
|
@@ -1548,7 +1748,7 @@ function copyDirRecursiveWithReplacementsNoOverwrite(src, dest, replacements, pr
|
|
|
1548
1748
|
return { skipped };
|
|
1549
1749
|
}
|
|
1550
1750
|
|
|
1551
|
-
function copySvelteComponents(projectDir, selectedNames) {
|
|
1751
|
+
function copySvelteComponents(projectDir, selectedNames, opts) {
|
|
1552
1752
|
const scaffoldDir = getScaffoldSvelteDir();
|
|
1553
1753
|
if (!existsSync(scaffoldDir)) {
|
|
1554
1754
|
console.log('\n Component templates not in this package; use CSS only or copy from repo: https://github.com/mingleusa/rizzo-css/tree/main/src/components/svelte');
|
|
@@ -1563,6 +1763,28 @@ function copySvelteComponents(projectDir, selectedNames) {
|
|
|
1563
1763
|
return;
|
|
1564
1764
|
}
|
|
1565
1765
|
const targetDir = join(projectDir, 'src', 'lib', 'rizzo');
|
|
1766
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
1767
|
+
if (plan) {
|
|
1768
|
+
toCopy.forEach((name) => { plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, name + '.svelte'))); });
|
|
1769
|
+
const iconsSrc = join(scaffoldDir, 'icons');
|
|
1770
|
+
if (existsSync(iconsSrc) && (toCopy.length > 0 || copyIconsOnly)) {
|
|
1771
|
+
(function collect(s, d) {
|
|
1772
|
+
readdirSync(s, { withFileTypes: true }).forEach((e) => {
|
|
1773
|
+
const destPath = join(d, e.name);
|
|
1774
|
+
if (e.isDirectory()) collect(join(s, e.name), destPath);
|
|
1775
|
+
else plan.wouldWrite.push(pathRelative(projectDir, destPath));
|
|
1776
|
+
});
|
|
1777
|
+
})(iconsSrc, join(targetDir, 'icons'));
|
|
1778
|
+
}
|
|
1779
|
+
if (toCopy.includes('ThemeSwitcher') || toCopy.includes('ThemeIcon')) {
|
|
1780
|
+
if (existsSync(join(scaffoldDir, 'themes.ts'))) plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, 'themes.ts')));
|
|
1781
|
+
if (existsSync(join(scaffoldDir, 'theme.ts'))) plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, 'theme.ts')));
|
|
1782
|
+
}
|
|
1783
|
+
if (toCopy.includes('Settings') && existsSync(join(getScaffoldConfigDir(), 'fonts.ts')))
|
|
1784
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(projectDir, 'src', 'lib', 'config', 'fonts.ts')));
|
|
1785
|
+
if (toCopy.length > 0) plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, 'index.ts')));
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1566
1788
|
mkdirSync(targetDir, { recursive: true });
|
|
1567
1789
|
const exports = [];
|
|
1568
1790
|
for (const name of toCopy) {
|
|
@@ -1602,7 +1824,7 @@ function copySvelteComponents(projectDir, selectedNames) {
|
|
|
1602
1824
|
}
|
|
1603
1825
|
}
|
|
1604
1826
|
|
|
1605
|
-
function copyAstroComponents(projectDir, selectedNames) {
|
|
1827
|
+
function copyAstroComponents(projectDir, selectedNames, opts) {
|
|
1606
1828
|
const scaffoldDir = getScaffoldAstroDir();
|
|
1607
1829
|
if (!existsSync(scaffoldDir)) {
|
|
1608
1830
|
console.log('\n Astro component templates not in this package; use CSS only or copy from repo: https://github.com/mingleusa/rizzo-css/tree/main/src/components');
|
|
@@ -1617,6 +1839,27 @@ function copyAstroComponents(projectDir, selectedNames) {
|
|
|
1617
1839
|
return;
|
|
1618
1840
|
}
|
|
1619
1841
|
const targetDir = join(projectDir, 'src', 'components', 'rizzo');
|
|
1842
|
+
const plan = opts && opts.dryRun && opts.plan ? opts.plan : null;
|
|
1843
|
+
if (plan) {
|
|
1844
|
+
toCopy.forEach((name) => { plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, name + '.astro'))); });
|
|
1845
|
+
const iconsSrc = join(scaffoldDir, 'icons');
|
|
1846
|
+
if (existsSync(iconsSrc) && (toCopy.length > 0 || copyIconsOnly)) {
|
|
1847
|
+
(function collect(s, d) {
|
|
1848
|
+
readdirSync(s, { withFileTypes: true }).forEach((e) => {
|
|
1849
|
+
const destPath = join(d, e.name);
|
|
1850
|
+
if (e.isDirectory()) collect(join(s, e.name), destPath);
|
|
1851
|
+
else plan.wouldWrite.push(pathRelative(projectDir, destPath));
|
|
1852
|
+
});
|
|
1853
|
+
})(iconsSrc, join(targetDir, 'icons'));
|
|
1854
|
+
}
|
|
1855
|
+
if (toCopy.includes('ThemeSwitcher') || toCopy.includes('ThemeIcon')) {
|
|
1856
|
+
if (existsSync(join(scaffoldDir, 'themes.ts'))) plan.wouldWrite.push(pathRelative(projectDir, join(targetDir, 'themes.ts')));
|
|
1857
|
+
if (existsSync(join(getScaffoldUtilsDir(), 'theme.ts'))) plan.wouldWrite.push(pathRelative(projectDir, join(projectDir, 'src', 'components', 'utils', 'theme.ts')));
|
|
1858
|
+
}
|
|
1859
|
+
if (toCopy.includes('Settings') && existsSync(join(getScaffoldConfigDir(), 'fonts.ts')))
|
|
1860
|
+
plan.wouldWrite.push(pathRelative(projectDir, join(projectDir, 'src', 'components', 'config', 'fonts.ts')));
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1620
1863
|
mkdirSync(targetDir, { recursive: true });
|
|
1621
1864
|
let count = 0;
|
|
1622
1865
|
for (const name of toCopy) {
|
|
@@ -1758,7 +2001,9 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1758
2001
|
cssTarget = join(targetDir, 'rizzo.min.css');
|
|
1759
2002
|
}
|
|
1760
2003
|
const cssExists = existsSync(cssTarget);
|
|
1761
|
-
if (
|
|
2004
|
+
if (options.dryRun) {
|
|
2005
|
+
options._overwriteCss = true;
|
|
2006
|
+
} else if (cssExists && !options.force) {
|
|
1762
2007
|
const answer = await question('\nCSS already exists at ' + cssTarget + '. Overwrite? (y/N) ');
|
|
1763
2008
|
if (answer !== '' && !/^y(es)?$/i.test(answer)) {
|
|
1764
2009
|
console.log('Skipping CSS copy. Updating config and components only.');
|
|
@@ -1776,9 +2021,10 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1776
2021
|
const astroCoreDir = getScaffoldAstroCoreDir();
|
|
1777
2022
|
const svelteCoreDir = getScaffoldSvelteCoreDir();
|
|
1778
2023
|
const themeCommentAdd = ' <!-- Initial: ' + theme + '; dark: ' + defaultDark + '; light: ' + defaultLight + ' (all 14 themes in CSS) -->';
|
|
2024
|
+
const copyOpts = options.dryRun && options.plan ? options : undefined;
|
|
1779
2025
|
if (framework === 'vanilla' && getVariantDir('vanilla', selectedVariation)) {
|
|
1780
2026
|
const vanillaRepl = { '{{LINK_HREF}}': 'css/rizzo.min.css', '{{TITLE}}': 'App', '{{DATA_THEME}}': theme, '{{THEME_LIST_COMMENT}}': themeCommentAdd };
|
|
1781
|
-
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'vanilla', selectedVariation, vanillaRepl);
|
|
2027
|
+
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'vanilla', selectedVariation, vanillaRepl, copyOpts);
|
|
1782
2028
|
if (variantResult && variantResult.skipped) addSkippedFiles = variantResult.skipped;
|
|
1783
2029
|
} else if (selectedVariation !== 'css-only' && ((framework === 'astro' && existsSync(astroCoreDir)) || (framework === 'svelte' && existsSync(svelteCoreDir)))) {
|
|
1784
2030
|
const themeComment = themeCommentAdd;
|
|
@@ -1818,48 +2064,54 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1818
2064
|
}
|
|
1819
2065
|
}
|
|
1820
2066
|
}
|
|
1821
|
-
mkdirSync(cwd, { recursive: true });
|
|
2067
|
+
if (!options.dryRun) mkdirSync(cwd, { recursive: true });
|
|
1822
2068
|
if (framework === 'astro') {
|
|
1823
|
-
const baseResult = copyDirRecursiveWithReplacementsNoOverwrite(astroCoreDir, cwd, replacements, cwd);
|
|
1824
|
-
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'astro', selectedVariation, replacements);
|
|
2069
|
+
const baseResult = copyDirRecursiveWithReplacementsNoOverwrite(astroCoreDir, cwd, replacements, cwd, copyOpts);
|
|
2070
|
+
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'astro', selectedVariation, replacements, copyOpts);
|
|
1825
2071
|
addSkippedFiles = baseResult.skipped.concat(variantResult.skipped || []);
|
|
1826
2072
|
} else if (framework === 'svelte') {
|
|
1827
|
-
const baseResult = copyDirRecursiveWithReplacementsNoOverwrite(svelteCoreDir, cwd, replacements, cwd);
|
|
1828
|
-
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'svelte', selectedVariation, replacements);
|
|
2073
|
+
const baseResult = copyDirRecursiveWithReplacementsNoOverwrite(svelteCoreDir, cwd, replacements, cwd, copyOpts);
|
|
2074
|
+
const variantResult = copyVariantOverlayNoOverwrite(cwd, 'svelte', selectedVariation, replacements, copyOpts);
|
|
1829
2075
|
addSkippedFiles = baseResult.skipped.concat(variantResult.skipped || []);
|
|
1830
2076
|
}
|
|
1831
2077
|
}
|
|
1832
2078
|
|
|
1833
2079
|
if (options._overwriteCss) {
|
|
1834
2080
|
if (framework === 'astro') {
|
|
1835
|
-
copyRizzoCssAndFontsForAstro(cwd, cssSource);
|
|
2081
|
+
copyRizzoCssAndFontsForAstro(cwd, cssSource, copyOpts);
|
|
1836
2082
|
} else if (framework === 'svelte') {
|
|
1837
|
-
copyRizzoCssAndFontsForSvelte(cwd, cssSource);
|
|
2083
|
+
copyRizzoCssAndFontsForSvelte(cwd, cssSource, copyOpts);
|
|
1838
2084
|
} else {
|
|
1839
2085
|
const targetDir = join(cwd, targetDirRaw);
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
2086
|
+
if (copyOpts && copyOpts.plan) {
|
|
2087
|
+
copyOpts.plan.wouldWrite.push(pathRelative(cwd, cssTarget));
|
|
2088
|
+
copyRizzoFonts(dirname(cssTarget), copyOpts);
|
|
2089
|
+
if (framework === 'vanilla' && selectedVariation !== 'css-only') copyRizzoSfx(cwd, copyOpts);
|
|
2090
|
+
} else {
|
|
2091
|
+
mkdirSync(targetDir, { recursive: true });
|
|
2092
|
+
copyFileSync(cssSource, cssTarget);
|
|
2093
|
+
copyRizzoFonts(dirname(cssTarget));
|
|
2094
|
+
if (framework === 'vanilla' && selectedVariation !== 'css-only') copyRizzoSfx(cwd);
|
|
2095
|
+
}
|
|
1844
2096
|
}
|
|
1845
2097
|
}
|
|
1846
2098
|
|
|
1847
|
-
if (selectedVariation !== 'css-only') copyRizzoIcons(cwd, framework);
|
|
2099
|
+
if (selectedVariation !== 'css-only') copyRizzoIcons(cwd, framework, copyOpts);
|
|
1848
2100
|
if (framework === 'svelte' && selectedComponents.length > 0) {
|
|
1849
2101
|
const expanded = expandWithDeps('svelte', selectedComponents);
|
|
1850
2102
|
logAddedDeps(selectedComponents, expanded, 'svelte');
|
|
1851
|
-
copySvelteComponents(cwd, expanded);
|
|
2103
|
+
copySvelteComponents(cwd, expanded, copyOpts);
|
|
1852
2104
|
} else if (framework === 'astro' && selectedComponents.length > 0) {
|
|
1853
2105
|
const expanded = expandWithDeps('astro', selectedComponents);
|
|
1854
2106
|
logAddedDeps(selectedComponents, expanded, 'astro');
|
|
1855
|
-
copyAstroComponents(cwd, expanded);
|
|
2107
|
+
copyAstroComponents(cwd, expanded, copyOpts);
|
|
1856
2108
|
} else if (framework === 'vanilla' && selectedComponents.length > 0) {
|
|
1857
2109
|
const linkHrefForVanilla = (options && options.targetDir) ? getLinkHrefForTargetDir(framework, options.targetDir) : paths.linkHref;
|
|
1858
2110
|
const vanillaRepl = { '{{LINK_HREF}}': linkHrefForVanilla, '{{DATA_THEME}}': theme };
|
|
1859
|
-
copyVanillaComponents(cwd, selectedComponents, vanillaRepl);
|
|
2111
|
+
copyVanillaComponents(cwd, selectedComponents, vanillaRepl, copyOpts);
|
|
1860
2112
|
const needsJs = selectedComponents.some((c) => VANILLA_JS_COMPONENTS.includes(c));
|
|
1861
2113
|
const vanillaJsPath = join(cwd, 'js', 'main.js');
|
|
1862
|
-
if (needsJs && !existsSync(vanillaJsPath) && (options.copyVanillaJs || (!preselected && (await confirmCopyVanillaJs())))) {
|
|
2114
|
+
if (!options.dryRun && needsJs && !existsSync(vanillaJsPath) && (options.copyVanillaJs || (!preselected && (await confirmCopyVanillaJs())))) {
|
|
1863
2115
|
const vanillaJsSrc = join(getPackageRoot(), 'scaffold', 'vanilla', 'js', 'main.js');
|
|
1864
2116
|
if (existsSync(vanillaJsSrc)) {
|
|
1865
2117
|
mkdirSync(join(cwd, 'js'), { recursive: true });
|
|
@@ -1880,6 +2132,7 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1880
2132
|
} else if (needsJs && !existsSync(vanillaJsPath)) {
|
|
1881
2133
|
options._vanillaJsHint = true;
|
|
1882
2134
|
}
|
|
2135
|
+
if (options.dryRun && needsJs && !existsSync(vanillaJsPath) && options.plan) options.plan.wouldWrite.push('js/main.js');
|
|
1883
2136
|
}
|
|
1884
2137
|
|
|
1885
2138
|
const linkHref = (framework === 'astro' || framework === 'svelte') ? paths.linkHref : ((options && options.targetDir) ? getLinkHrefForTargetDir(framework, options.targetDir) : paths.linkHref);
|
|
@@ -1893,6 +2146,20 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1893
2146
|
const configTargetDir = framework === 'astro' ? 'public/css' : framework === 'svelte' ? 'static/css' : targetDirRaw;
|
|
1894
2147
|
const configPath = join(cwd, RIZZO_CONFIG_FILE);
|
|
1895
2148
|
const hadConfig = existsSync(configPath);
|
|
2149
|
+
if (options.dryRun) {
|
|
2150
|
+
if (!hadConfig) options.plan.wouldWrite.push(RIZZO_CONFIG_FILE);
|
|
2151
|
+
options.plan.wouldWrite.push(RIZZO_SETUP_FILE);
|
|
2152
|
+
if (options.writeSnippet !== false) options.plan.wouldWrite.push(RIZZO_SNIPPET_FILE);
|
|
2153
|
+
if (options.writeReadme) options.plan.wouldWrite.push(SCAFFOLD_README_FILENAME);
|
|
2154
|
+
copyPackageLicense(cwd, copyOpts);
|
|
2155
|
+
console.log('\n Dry run — no files written.');
|
|
2156
|
+
console.log(' Would write (' + options.plan.wouldWrite.length + ' paths):');
|
|
2157
|
+
options.plan.wouldWrite.sort().forEach((p) => console.log(' ' + p));
|
|
2158
|
+
const setupMdContent = buildRizzoSetupMd(framework, { linkHref, theme, defaultDark, defaultLight, skippedFiles: addSkippedFiles.length > 0 ? addSkippedFiles : undefined });
|
|
2159
|
+
console.log('\n --- RIZZO-SETUP.md snippet (for skipped files) ---\n');
|
|
2160
|
+
console.log(setupMdContent);
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
1896
2163
|
if (!hadConfig) {
|
|
1897
2164
|
writeRizzoConfig(cwd, { targetDir: configTargetDir, framework, packageManager: pm.agent, theme });
|
|
1898
2165
|
}
|
|
@@ -2569,12 +2836,13 @@ async function cmdInit(argv) {
|
|
|
2569
2836
|
}
|
|
2570
2837
|
|
|
2571
2838
|
// Package manager install: only for Astro/Svelte (Vanilla has no package.json)
|
|
2839
|
+
const installCmd = pm.install + (hasFlag(argv, '--offline') ? ' --offline' : '');
|
|
2572
2840
|
if (runInstallAfterScaffold && !noInstall && hasPackageJson) {
|
|
2573
2841
|
const dirLabel = projectDir !== cwd ? ' in ' + pathRelative(cwd, projectDir) : ' (current directory)';
|
|
2574
|
-
console.log('\n Running' + dirLabel + ': ' +
|
|
2575
|
-
const code = runInDir(projectDir,
|
|
2842
|
+
console.log('\n Running' + dirLabel + ': ' + installCmd);
|
|
2843
|
+
const code = runInDir(projectDir, installCmd);
|
|
2576
2844
|
if (code !== 0) {
|
|
2577
|
-
console.error('\n Install failed (exit ' + code + '). Run manually: ' + runPrefix +
|
|
2845
|
+
console.error('\n Install failed (exit ' + code + '). Run manually: ' + runPrefix + installCmd);
|
|
2578
2846
|
} else {
|
|
2579
2847
|
console.log(' ✓ Dependencies installed.');
|
|
2580
2848
|
}
|
|
@@ -2582,15 +2850,15 @@ async function cmdInit(argv) {
|
|
|
2582
2850
|
const shouldRun = await confirmRunInstall(pm);
|
|
2583
2851
|
if (shouldRun) {
|
|
2584
2852
|
const dirLabel = projectDir !== cwd ? ' in ' + pathRelative(cwd, projectDir) : ' here';
|
|
2585
|
-
console.log('\n Running' + dirLabel + ': ' +
|
|
2586
|
-
const code = runInDir(projectDir,
|
|
2853
|
+
console.log('\n Running' + dirLabel + ': ' + installCmd);
|
|
2854
|
+
const code = runInDir(projectDir, installCmd);
|
|
2587
2855
|
if (code !== 0) {
|
|
2588
|
-
console.error('\n Install failed (exit ' + code + '). Run manually: ' + runPrefix +
|
|
2856
|
+
console.error('\n Install failed (exit ' + code + '). Run manually: ' + runPrefix + installCmd);
|
|
2589
2857
|
} else {
|
|
2590
2858
|
console.log(' ✓ Dependencies installed.');
|
|
2591
2859
|
}
|
|
2592
2860
|
} else {
|
|
2593
|
-
console.log('\n Skipped. When ready, run: ' + runPrefix +
|
|
2861
|
+
console.log('\n Skipped. When ready, run: ' + runPrefix + installCmd);
|
|
2594
2862
|
}
|
|
2595
2863
|
}
|
|
2596
2864
|
|
|
@@ -2621,6 +2889,7 @@ async function cmdInit(argv) {
|
|
|
2621
2889
|
: 'open index.html or serve the folder (e.g. npx serve .)';
|
|
2622
2890
|
console.log('\n Next: ' + vanillaNext);
|
|
2623
2891
|
}
|
|
2892
|
+
await checkNewerVersion(argv).catch(() => {});
|
|
2624
2893
|
console.log('\n Docs: https://rizzo-css.vercel.app\n');
|
|
2625
2894
|
}
|
|
2626
2895
|
|