@nuvio/cli 0.5.1 → 0.5.3

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.
Files changed (2) hide show
  1. package/dist/cli-entry.js +155 -27
  2. package/package.json +1 -1
package/dist/cli-entry.js CHANGED
@@ -212,6 +212,75 @@ function hasNuvioPluginCall(ast) {
212
212
  });
213
213
  return found;
214
214
  }
215
+ var OVERLAY_DEP = "@nuvio/overlay";
216
+ function excludeListsOverlay(expr) {
217
+ if (!expr || !t.isArrayExpression(expr)) return false;
218
+ return expr.elements.some(
219
+ (el) => t.isStringLiteral(el) && el.value === OVERLAY_DEP
220
+ );
221
+ }
222
+ function ensureOptimizeDepsExclude(ast) {
223
+ let patched = false;
224
+ babel_traverse_default(ast, {
225
+ CallExpression(path) {
226
+ const callee = path.node.callee;
227
+ if (!t.isIdentifier(callee, { name: "defineConfig" })) return;
228
+ const arg = path.node.arguments[0];
229
+ if (!t.isObjectExpression(arg)) return;
230
+ let optimizeDeps;
231
+ for (const prop of arg.properties) {
232
+ if (t.isObjectProperty(prop) && t.isIdentifier(prop.key, { name: "optimizeDeps" })) {
233
+ optimizeDeps = prop;
234
+ break;
235
+ }
236
+ }
237
+ if (!optimizeDeps) {
238
+ arg.properties.push(
239
+ t.objectProperty(
240
+ t.identifier("optimizeDeps"),
241
+ t.objectExpression([
242
+ t.objectProperty(
243
+ t.identifier("exclude"),
244
+ t.arrayExpression([t.stringLiteral(OVERLAY_DEP)])
245
+ )
246
+ ])
247
+ )
248
+ );
249
+ patched = true;
250
+ return;
251
+ }
252
+ if (!t.isObjectExpression(optimizeDeps.value)) return;
253
+ let excludeProp;
254
+ for (const p of optimizeDeps.value.properties) {
255
+ if (t.isObjectProperty(p) && t.isIdentifier(p.key, { name: "exclude" })) {
256
+ excludeProp = p;
257
+ break;
258
+ }
259
+ }
260
+ if (!excludeProp) {
261
+ optimizeDeps.value.properties.push(
262
+ t.objectProperty(
263
+ t.identifier("exclude"),
264
+ t.arrayExpression([t.stringLiteral(OVERLAY_DEP)])
265
+ )
266
+ );
267
+ patched = true;
268
+ return;
269
+ }
270
+ if (t.isArrayExpression(excludeProp.value) && !excludeListsOverlay(excludeProp.value)) {
271
+ excludeProp.value.elements.push(t.stringLiteral(OVERLAY_DEP));
272
+ patched = true;
273
+ }
274
+ }
275
+ });
276
+ return patched;
277
+ }
278
+ function viteConfigHasOverlayOptimizeExclude(filePath) {
279
+ const source = readFileSync3(filePath, "utf8");
280
+ return /optimizeDeps\s*:\s*\{[^}]*exclude\s*:\s*\[[^\]]*@nuvio\/overlay/.test(
281
+ source
282
+ ) || /exclude\s*:\s*\[[^\]]*["']@nuvio\/overlay["']/.test(source);
283
+ }
215
284
  function appendNuvioPlugin(ast) {
216
285
  let patched = false;
217
286
  babel_traverse_default(ast, {
@@ -232,7 +301,9 @@ function patchViteConfigFile(filePath) {
232
301
  } catch {
233
302
  return { ok: false, error: "parse failed" };
234
303
  }
235
- if (hasNuvioImport(ast) && hasNuvioPluginCall(ast)) {
304
+ const depsPatched = ensureOptimizeDepsExclude(ast);
305
+ const alreadyPlugin = hasNuvioImport(ast) && hasNuvioPluginCall(ast);
306
+ if (alreadyPlugin && !depsPatched) {
236
307
  return { ok: true, skipped: true };
237
308
  }
238
309
  if (!hasNuvioImport(ast)) {
@@ -249,7 +320,7 @@ function patchViteConfigFile(filePath) {
249
320
  }
250
321
  }
251
322
  writeFileSync(filePath, printTs(ast, source), "utf8");
252
- return { ok: true };
323
+ return { ok: true, skipped: alreadyPlugin && depsPatched };
253
324
  }
254
325
  function viteConfigHasNuvio(filePath) {
255
326
  const source = readFileSync3(filePath, "utf8");
@@ -372,19 +443,61 @@ function appHasDevShell(filePath) {
372
443
  }
373
444
  }
374
445
 
446
+ // src/patch-main-styles.ts
447
+ import { existsSync as existsSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
448
+ import { join as join4 } from "path";
449
+ var MAIN_CANDIDATES = ["src/main.tsx", "src/main.jsx", "main.tsx", "main.jsx"];
450
+ var STYLE_IMPORT = 'import "@nuvio/overlay/style.css";';
451
+ function overlayInstalledFromNpm(packageJsonPath) {
452
+ const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
453
+ const dev = pkg.devDependencies;
454
+ const raw = dev?.["@nuvio/overlay"];
455
+ if (!raw) return false;
456
+ return !raw.startsWith("workspace:") && !raw.startsWith("link:") && !raw.startsWith("file:");
457
+ }
458
+ function resolveMainEntry(root) {
459
+ for (const rel of MAIN_CANDIDATES) {
460
+ const p = join4(root, rel);
461
+ if (existsSync4(p)) return p;
462
+ }
463
+ return null;
464
+ }
465
+ function mainHasOverlayStyles(mainPath) {
466
+ const text = readFileSync5(mainPath, "utf8");
467
+ return text.includes("@nuvio/overlay/style.css") || text.includes("@nuvio/overlay/dist/style.css");
468
+ }
469
+ function patchMainOverlayStyles(mainPath) {
470
+ const text = readFileSync5(mainPath, "utf8");
471
+ if (text.includes("@nuvio/overlay/style.css") || text.includes("@nuvio/overlay/dist/style.css")) {
472
+ return { ok: true, skipped: true };
473
+ }
474
+ const lines = text.split("\n");
475
+ let lastImport = -1;
476
+ for (let i = 0; i < lines.length; i++) {
477
+ if (/^\s*import\s/.test(lines[i])) lastImport = i;
478
+ }
479
+ if (lastImport >= 0) {
480
+ lines.splice(lastImport + 1, 0, STYLE_IMPORT);
481
+ } else {
482
+ lines.unshift(STYLE_IMPORT, "");
483
+ }
484
+ writeFileSync3(mainPath, lines.join("\n"));
485
+ return { ok: true };
486
+ }
487
+
375
488
  // src/patch-starter-id.ts
376
489
  import * as t3 from "@babel/types";
377
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
490
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
378
491
 
379
492
  // src/scan-ids.ts
380
- import { readFileSync as readFileSync5 } from "fs";
381
- import { join as join4 } from "path";
493
+ import { readFileSync as readFileSync6 } from "fs";
494
+ import { join as join5 } from "path";
382
495
  import fg from "fast-glob";
383
496
  var ID_GLOB = ["src/**/*.{tsx,jsx}"];
384
497
  function projectHasPageTitleId(root) {
385
498
  const files = fg.sync(ID_GLOB, { cwd: root, absolute: true });
386
499
  for (const file of files) {
387
- const text = readFileSync5(file, "utf8");
500
+ const text = readFileSync6(file, "utf8");
388
501
  if (/data-nuvio-id=["']page\.title["']/.test(text)) {
389
502
  return true;
390
503
  }
@@ -394,8 +507,8 @@ function projectHasPageTitleId(root) {
394
507
  function findHeadingFiles(root) {
395
508
  const files = fg.sync(ID_GLOB, { cwd: root, absolute: true });
396
509
  const ordered = [
397
- join4(root, "src/App.tsx"),
398
- join4(root, "src/App.jsx"),
510
+ join5(root, "src/App.tsx"),
511
+ join5(root, "src/App.jsx"),
399
512
  ...files.filter(
400
513
  (f) => !f.endsWith("App.tsx") && !f.endsWith("App.jsx")
401
514
  )
@@ -416,7 +529,7 @@ function findHeadingFiles(root) {
416
529
 
417
530
  // src/patch-starter-id.ts
418
531
  function patchFirstHeading(filePath) {
419
- const source = readFileSync6(filePath, "utf8");
532
+ const source = readFileSync7(filePath, "utf8");
420
533
  let ast;
421
534
  try {
422
535
  ast = parseTs(source, filePath);
@@ -445,13 +558,13 @@ function patchFirstHeading(filePath) {
445
558
  }
446
559
  });
447
560
  if (!patched) return { ok: false, error: "no h1/h2" };
448
- writeFileSync3(filePath, printTs(ast, source), "utf8");
561
+ writeFileSync4(filePath, printTs(ast, source), "utf8");
449
562
  return { ok: true };
450
563
  }
451
564
  function patchStarterId(root) {
452
565
  const files = findHeadingFiles(root);
453
566
  for (const file of files) {
454
- const source = readFileSync6(file, "utf8");
567
+ const source = readFileSync7(file, "utf8");
455
568
  if (!/<h[12][\s>]/.test(source) && !/<>[\s\S]*<h[12]/.test(source)) {
456
569
  try {
457
570
  const ast = parseTs(source, file);
@@ -496,12 +609,12 @@ var require2 = createRequire(import.meta.url);
496
609
  var NUVIO_VERSION = require2("../package.json").version;
497
610
 
498
611
  // src/write-nuvio-folder.ts
499
- import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
500
- import { dirname, join as join5 } from "path";
612
+ import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
613
+ import { dirname, join as join6 } from "path";
501
614
  import { fileURLToPath } from "url";
502
- var CLI_ROOT = join5(dirname(fileURLToPath(import.meta.url)), "..");
615
+ var CLI_ROOT = join6(dirname(fileURLToPath(import.meta.url)), "..");
503
616
  function loadTemplate(name) {
504
- return readFileSync7(join5(CLI_ROOT, "templates", name), "utf8");
617
+ return readFileSync8(join6(CLI_ROOT, "templates", name), "utf8");
505
618
  }
506
619
  function render(tpl, vars) {
507
620
  let out = tpl;
@@ -511,7 +624,7 @@ function render(tpl, vars) {
511
624
  return out;
512
625
  }
513
626
  function writeNuvioFolder(opts) {
514
- const dir = join5(opts.root, "nuvio");
627
+ const dir = join6(opts.root, "nuvio");
515
628
  const created = [];
516
629
  mkdirSync(dir, { recursive: true });
517
630
  const vars = {
@@ -519,28 +632,28 @@ function writeNuvioFolder(opts) {
519
632
  PM_RUN: opts.pmRun,
520
633
  FAILED_STEPS: opts.failedSteps.join(", ") || "(none)"
521
634
  };
522
- const startHere = join5(dir, "START_HERE.md");
523
- writeFileSync4(
635
+ const startHere = join6(dir, "START_HERE.md");
636
+ writeFileSync5(
524
637
  startHere,
525
638
  render(loadTemplate("START_HERE.md.tpl"), vars),
526
639
  "utf8"
527
640
  );
528
641
  created.push("nuvio/START_HERE.md");
529
- const readme = join5(dir, "README.md");
530
- writeFileSync4(
642
+ const readme = join6(dir, "README.md");
643
+ writeFileSync5(
531
644
  readme,
532
645
  render(loadTemplate("README.pointer.md.tpl"), vars),
533
646
  "utf8"
534
647
  );
535
648
  created.push("nuvio/README.md");
536
- const agent = join5(dir, "AGENT.md");
537
- if (!existsSync4(agent) || opts.forceAgent) {
538
- writeFileSync4(agent, render(loadTemplate("AGENT.md.tpl"), vars), "utf8");
649
+ const agent = join6(dir, "AGENT.md");
650
+ if (!existsSync5(agent) || opts.forceAgent) {
651
+ writeFileSync5(agent, render(loadTemplate("AGENT.md.tpl"), vars), "utf8");
539
652
  created.push("nuvio/AGENT.md");
540
653
  }
541
654
  if (opts.failedSteps.length > 0) {
542
- const todo = join5(dir, "SETUP_TODO.md");
543
- writeFileSync4(
655
+ const todo = join6(dir, "SETUP_TODO.md");
656
+ writeFileSync5(
544
657
  todo,
545
658
  render(loadTemplate("SETUP_TODO.md.tpl"), vars),
546
659
  "utf8"
@@ -551,15 +664,18 @@ function writeNuvioFolder(opts) {
551
664
  }
552
665
 
553
666
  // src/verify.ts
554
- import { readFileSync as readFileSync8 } from "fs";
667
+ import { readFileSync as readFileSync9 } from "fs";
555
668
  function verifyProject(root, packageJsonPath, viteConfigPath) {
556
- const pkg = JSON.parse(readFileSync8(packageJsonPath, "utf8"));
669
+ const pkg = JSON.parse(readFileSync9(packageJsonPath, "utf8"));
557
670
  const dev = pkg.devDependencies;
558
671
  const depsOk = Boolean(dev?.["@nuvio/vite-plugin"]) && Boolean(dev?.["@nuvio/overlay"]);
559
672
  const appFile = resolveAppFile(root);
673
+ const mainEntry = resolveMainEntry(root);
560
674
  return {
561
675
  deps: depsOk ? "OK" : "MISSING",
562
676
  vite: viteConfigHasNuvio(viteConfigPath) ? "OK" : "TODO",
677
+ overlayCss: mainEntry && (mainHasOverlayStyles(mainEntry) || !overlayInstalledFromNpm(packageJsonPath)) ? "OK" : "TODO",
678
+ optimizeDeps: viteConfigHasOverlayOptimizeExclude(viteConfigPath) ? "OK" : "TODO",
563
679
  shell: appFile && appHasDevShell(appFile) ? "OK" : "TODO",
564
680
  starterId: projectHasPageTitleId(root) ? "OK" : "MISSING"
565
681
  };
@@ -570,6 +686,8 @@ function printVerification(v) {
570
686
  ` devDependencies: @nuvio/vite-plugin, @nuvio/overlay \u2014 ${v.deps}`
571
687
  );
572
688
  console.log(` vite.config: nuvio() \u2014 ${v.vite}`);
689
+ console.log(` main.tsx: @nuvio/overlay/style.css \u2014 ${v.overlayCss}`);
690
+ console.log(` vite.config: optimizeDeps exclude overlay \u2014 ${v.optimizeDeps}`);
573
691
  console.log(` App shell: NuvioDevShell \u2014 ${v.shell}`);
574
692
  console.log(` Starter id page.title \u2014 ${v.starterId}`);
575
693
  }
@@ -665,7 +783,11 @@ async function runInit(opts) {
665
783
  plan.warnings.push(msg);
666
784
  }
667
785
  const appFile = resolveAppFile(root);
786
+ const mainEntry = resolveMainEntry(root);
668
787
  if (appFile) plan.modify.push(appFile.replace(`${root}/`, ""));
788
+ if (mainEntry && overlayInstalledFromNpm(project.packageJsonPath)) {
789
+ plan.modify.push(mainEntry.replace(`${root}/`, ""));
790
+ }
669
791
  plan.modify.push(project.viteConfigName);
670
792
  plan.create.push(
671
793
  "nuvio/START_HERE.md",
@@ -724,6 +846,12 @@ async function runInit(opts) {
724
846
  } else {
725
847
  plan.failedSteps.push("app (no App.tsx/main.tsx)");
726
848
  }
849
+ if (mainEntry && overlayInstalledFromNpm(project.packageJsonPath)) {
850
+ const mainStyles = patchMainOverlayStyles(mainEntry);
851
+ if (mainStyles.ok && !mainStyles.skipped) {
852
+ plan.modify.push(mainEntry.replace(`${root}/`, ""));
853
+ }
854
+ }
727
855
  let starterOk = false;
728
856
  let starterFile;
729
857
  if (!projectHasPageTitleId(root)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuvio/cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Nuvio CLI: one-command Vite + React onboarding (nuvio init).",
5
5
  "license": "MIT",
6
6
  "repository": {