cascivo 0.5.1 → 0.5.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.
@@ -1,5 +1,6 @@
1
1
  import { t as readFileSafe } from "./fs-m7ZvuBBm.mjs";
2
- import { i as sha256, l as findComponent, r as readLock, s as fetchRegistry, t as checkPeerVersions } from "./peer-versions-B2bCgko-.mjs";
2
+ import { c as findComponent, n as readLock, o as fetchRegistry, r as sha256 } from "./lock-CW8UuEPJ.mjs";
3
+ import { t as checkPeerVersions } from "./peer-versions-Cep8Brn3.mjs";
3
4
  //#region src/commands/drift.ts
4
5
  /**
5
6
  * `cascivo doctor --drift` — compares installed components against the
@@ -53,4 +54,4 @@ async function runDoctorDrift(config, cwd = process.cwd()) {
53
54
  //#endregion
54
55
  export { runDoctorDrift };
55
56
 
56
- //# sourceMappingURL=drift-Ciw5qeEt.mjs.map
57
+ //# sourceMappingURL=drift-qTzJ75Ds.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"drift-Ciw5qeEt.mjs","names":[],"sources":["../src/commands/drift.ts"],"sourcesContent":["import type { CascadeConfig } from '../utils/config.js'\nimport { readFileSafe } from '../utils/fs.js'\nimport { readLock, sha256 } from '../utils/lock.js'\nimport { checkPeerVersions } from '../utils/peer-versions.js'\nimport { fetchRegistry, findComponent } from '../utils/registry.js'\n\n/**\n * `cascivo doctor --drift` — compares installed components against the\n * registry. Two drift classes:\n *\n * 1. Local-edit drift: an installed file's content no longer matches what\n * was copied at install time (hand edits, or deleted after install).\n * 2. Peer-version drift: the currently-registered component source needs a\n * newer `@cascivo/*` peer package (per `peerVersions`) than what's\n * actually installed in node_modules — the dashboard-feedback failure\n * mode (DataTable referencing an i18n builtin key an older published\n * @cascivo/i18n build doesn't have).\n */\nexport async function runDoctorDrift(\n config: CascadeConfig,\n cwd: string = process.cwd(),\n): Promise<void> {\n const lock = await readLock(cwd)\n if (!lock || Object.keys(lock.items).length === 0) {\n console.log('No installed components found in cascivo.lock.')\n return\n }\n\n const registry = await fetchRegistry(config.registry)\n let driftCount = 0\n\n for (const [name, entry] of Object.entries(lock.items)) {\n const current = findComponent(registry, name)\n if (!current) continue\n\n for (const [path, lockedHash] of Object.entries(entry.files)) {\n const content = await readFileSafe(path)\n if (content === null) {\n console.log(`${name}: ${path} is missing (installed, then deleted)`)\n driftCount++\n continue\n }\n if (sha256(content) !== lockedHash) {\n console.log(`${name}: ${path} has local edits (differs from the version installed)`)\n driftCount++\n }\n }\n\n if (current.peerVersions) {\n const violations = await checkPeerVersions(cwd, current.peerVersions)\n for (const v of violations) {\n const installedDesc = v.installed ? `${v.installed} is installed` : 'it is not installed'\n console.log(`${name}: needs ${v.pkg} ${v.required}, but ${installedDesc}.`)\n driftCount++\n }\n }\n }\n\n if (driftCount > 0) {\n console.log(`\\n${driftCount} drift issue(s) found.`)\n process.exitCode = 1\n } else {\n console.log('No drift detected — installed components match the registry.')\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,eAAsB,eACpB,QACA,MAAc,QAAQ,IAAI,GACX;CACf,MAAM,OAAO,MAAM,SAAS,GAAG;CAC/B,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG;EACjD,QAAQ,IAAI,gDAAgD;EAC5D;CACF;CAEA,MAAM,WAAW,MAAM,cAAc,OAAO,QAAQ;CACpD,IAAI,aAAa;CAEjB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,KAAK,GAAG;EACtD,MAAM,UAAU,cAAc,UAAU,IAAI;EAC5C,IAAI,CAAC,SAAS;EAEd,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,MAAM,KAAK,GAAG;GAC5D,MAAM,UAAU,MAAM,aAAa,IAAI;GACvC,IAAI,YAAY,MAAM;IACpB,QAAQ,IAAI,GAAG,KAAK,IAAI,KAAK,sCAAsC;IACnE;IACA;GACF;GACA,IAAI,OAAO,OAAO,MAAM,YAAY;IAClC,QAAQ,IAAI,GAAG,KAAK,IAAI,KAAK,sDAAsD;IACnF;GACF;EACF;EAEA,IAAI,QAAQ,cAAc;GACxB,MAAM,aAAa,MAAM,kBAAkB,KAAK,QAAQ,YAAY;GACpE,KAAK,MAAM,KAAK,YAAY;IAC1B,MAAM,gBAAgB,EAAE,YAAY,GAAG,EAAE,UAAU,iBAAiB;IACpE,QAAQ,IAAI,GAAG,KAAK,UAAU,EAAE,IAAI,GAAG,EAAE,SAAS,QAAQ,cAAc,EAAE;IAC1E;GACF;EACF;CACF;CAEA,IAAI,aAAa,GAAG;EAClB,QAAQ,IAAI,KAAK,WAAW,uBAAuB;EACnD,QAAQ,WAAW;CACrB,OACE,QAAQ,IAAI,8DAA8D;AAE9E"}
1
+ {"version":3,"file":"drift-qTzJ75Ds.mjs","names":[],"sources":["../src/commands/drift.ts"],"sourcesContent":["import type { CascadeConfig } from '../utils/config.js'\nimport { readFileSafe } from '../utils/fs.js'\nimport { readLock, sha256 } from '../utils/lock.js'\nimport { checkPeerVersions } from '../utils/peer-versions.js'\nimport { fetchRegistry, findComponent } from '../utils/registry.js'\n\n/**\n * `cascivo doctor --drift` — compares installed components against the\n * registry. Two drift classes:\n *\n * 1. Local-edit drift: an installed file's content no longer matches what\n * was copied at install time (hand edits, or deleted after install).\n * 2. Peer-version drift: the currently-registered component source needs a\n * newer `@cascivo/*` peer package (per `peerVersions`) than what's\n * actually installed in node_modules — the dashboard-feedback failure\n * mode (DataTable referencing an i18n builtin key an older published\n * @cascivo/i18n build doesn't have).\n */\nexport async function runDoctorDrift(\n config: CascadeConfig,\n cwd: string = process.cwd(),\n): Promise<void> {\n const lock = await readLock(cwd)\n if (!lock || Object.keys(lock.items).length === 0) {\n console.log('No installed components found in cascivo.lock.')\n return\n }\n\n const registry = await fetchRegistry(config.registry)\n let driftCount = 0\n\n for (const [name, entry] of Object.entries(lock.items)) {\n const current = findComponent(registry, name)\n if (!current) continue\n\n for (const [path, lockedHash] of Object.entries(entry.files)) {\n const content = await readFileSafe(path)\n if (content === null) {\n console.log(`${name}: ${path} is missing (installed, then deleted)`)\n driftCount++\n continue\n }\n if (sha256(content) !== lockedHash) {\n console.log(`${name}: ${path} has local edits (differs from the version installed)`)\n driftCount++\n }\n }\n\n if (current.peerVersions) {\n const violations = await checkPeerVersions(cwd, current.peerVersions)\n for (const v of violations) {\n const installedDesc = v.installed ? `${v.installed} is installed` : 'it is not installed'\n console.log(`${name}: needs ${v.pkg} ${v.required}, but ${installedDesc}.`)\n driftCount++\n }\n }\n }\n\n if (driftCount > 0) {\n console.log(`\\n${driftCount} drift issue(s) found.`)\n process.exitCode = 1\n } else {\n console.log('No drift detected — installed components match the registry.')\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,eAAsB,eACpB,QACA,MAAc,QAAQ,IAAI,GACX;CACf,MAAM,OAAO,MAAM,SAAS,GAAG;CAC/B,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG;EACjD,QAAQ,IAAI,gDAAgD;EAC5D;CACF;CAEA,MAAM,WAAW,MAAM,cAAc,OAAO,QAAQ;CACpD,IAAI,aAAa;CAEjB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,KAAK,GAAG;EACtD,MAAM,UAAU,cAAc,UAAU,IAAI;EAC5C,IAAI,CAAC,SAAS;EAEd,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,MAAM,KAAK,GAAG;GAC5D,MAAM,UAAU,MAAM,aAAa,IAAI;GACvC,IAAI,YAAY,MAAM;IACpB,QAAQ,IAAI,GAAG,KAAK,IAAI,KAAK,sCAAsC;IACnE;IACA;GACF;GACA,IAAI,OAAO,OAAO,MAAM,YAAY;IAClC,QAAQ,IAAI,GAAG,KAAK,IAAI,KAAK,sDAAsD;IACnF;GACF;EACF;EAEA,IAAI,QAAQ,cAAc;GACxB,MAAM,aAAa,MAAM,kBAAkB,KAAK,QAAQ,YAAY;GACpE,KAAK,MAAM,KAAK,YAAY;IAC1B,MAAM,gBAAgB,EAAE,YAAY,GAAG,EAAE,UAAU,iBAAiB;IACpE,QAAQ,IAAI,GAAG,KAAK,UAAU,EAAE,IAAI,GAAG,EAAE,SAAS,QAAQ,cAAc,EAAE;IAC1E;GACF;EACF;CACF;CAEA,IAAI,aAAa,GAAG;EAClB,QAAQ,IAAI,KAAK,WAAW,uBAAuB;EACnD,QAAQ,WAAW;CACrB,OACE,QAAQ,IAAI,8DAA8D;AAE9E"}
package/dist/index.mjs CHANGED
@@ -2,7 +2,8 @@
2
2
  import { a as detectPackageManager, c as isPackageManager, l as loadConfig, n as DEFAULT_CONFIG$1, o as installCommand, r as THEMES, s as installHint, t as CASCIVO_HOST, u as __exportAll } from "./config-C6GdrbvF.mjs";
3
3
  import { n as resolveOutputPath, r as writeFileSafe, t as readFileSafe } from "./fs-m7ZvuBBm.mjs";
4
4
  import { r as fetchTextRetry, t as fetchJson } from "./http-CJZ5W0Fa.mjs";
5
- import { a as updateLockEntry, c as fileName, i as sha256, l as findComponent, n as createLock, o as writeLock, r as readLock, s as fetchRegistry, t as checkPeerVersions } from "./peer-versions-B2bCgko-.mjs";
5
+ import { a as writeLock, c as findComponent, i as updateLockEntry, n as readLock, o as fetchRegistry, r as sha256, s as fileName, t as createLock } from "./lock-CW8UuEPJ.mjs";
6
+ import { n as readInstalledPackageVersion, r as compareVersions, t as checkPeerVersions } from "./peer-versions-Cep8Brn3.mjs";
6
7
  import { createRequire } from "node:module";
7
8
  import { argv, stdin, stdout } from "node:process";
8
9
  import { pathToFileURL } from "node:url";
@@ -956,6 +957,8 @@ async function create(args, cwd = process.cwd()) {
956
957
  //#region src/commands/doctor.ts
957
958
  var doctor_exports = /* @__PURE__ */ __exportAll({
958
959
  checkProjectDependencies: () => checkProjectDependencies,
960
+ checkSignalsCompat: () => checkSignalsCompat,
961
+ checkSsrConfig: () => checkSsrConfig,
959
962
  isAdopterProject: () => isAdopterProject,
960
963
  runDoctor: () => runDoctor,
961
964
  stripCommentsAndStrings: () => stripCommentsAndStrings
@@ -1011,6 +1014,85 @@ function checkProjectDependencies(cwd) {
1011
1014
  });
1012
1015
  return findings;
1013
1016
  }
1017
+ /**
1018
+ * Checks the installed `@preact/signals-react` against the installed React.
1019
+ * React 19 removed the `__SECRET_INTERNALS…` export that signals-react 2.x
1020
+ * imports, so a 2.x runtime on React 19 dies with a `SyntaxError` at module
1021
+ * evaluation (the 2026-07-20 report's blocker #2). cascivo peer-depends on
1022
+ * `>=3.0.0`, but a lockfile carried over from an earlier install can still pin
1023
+ * 2.x — this turns that into a diagnosed condition with a fix. Returns null when
1024
+ * either package is absent/unreadable (nothing reliable to advise on) or the
1025
+ * pairing is fine.
1026
+ */
1027
+ async function checkSignalsCompat(cwd) {
1028
+ const [signals, react] = await Promise.all([readInstalledPackageVersion(cwd, "@preact/signals-react"), readInstalledPackageVersion(cwd, "react")]);
1029
+ if (signals === null) return null;
1030
+ let signalsBelow3;
1031
+ try {
1032
+ signalsBelow3 = compareVersions(signals, "3.0.0") < 0;
1033
+ } catch {
1034
+ return null;
1035
+ }
1036
+ if (!signalsBelow3) return null;
1037
+ const hint = installHint(detectPackageManager(cwd), ["@preact/signals-react@^3"]);
1038
+ let reactMajor = null;
1039
+ if (react !== null) {
1040
+ const m = /^(\d+)\./.exec(react.trim());
1041
+ reactMajor = m ? Number(m[1]) : null;
1042
+ }
1043
+ if (reactMajor !== null && reactMajor >= 19) return {
1044
+ severity: "error",
1045
+ detail: `@preact/signals-react ${signals} cannot run on React ${react} — React 19 removed an internal signals 2.x imports, so it fails at module load. Upgrade to signals-react 3.x.`,
1046
+ hint
1047
+ };
1048
+ return {
1049
+ severity: "warning",
1050
+ detail: `@preact/signals-react ${signals} is below the required 3.x floor. It works on React 18 today but breaks the moment you move to React 19; upgrade now.`,
1051
+ hint
1052
+ };
1053
+ }
1054
+ /** Vite SSR frameworks whose default setup needs `ssr.noExternal` for cascivo. */
1055
+ const VITE_SSR_MARKERS = [
1056
+ "@tanstack/react-start",
1057
+ "vite-ssr",
1058
+ "@remix-run/dev"
1059
+ ];
1060
+ const VITE_CONFIG_FILES = [
1061
+ "vite.config.ts",
1062
+ "vite.config.js",
1063
+ "vite.config.mjs",
1064
+ "vite.config.mts"
1065
+ ];
1066
+ /**
1067
+ * Advisory: on a Vite SSR framework, cascivo's per-component `.css` side-effect
1068
+ * imports crash a bare server-side ESM loader unless the packages are marked
1069
+ * `ssr.noExternal` (or the `cascivoSsr()` plugin is used). This warns when a known
1070
+ * Vite SSR framework is present but no vite config mentions either — the exact
1071
+ * cliff the 2026-07-20 report hit (blocker #1). A text match, not a gate. Returns
1072
+ * null when there's no Vite SSR framework or the config already handles it.
1073
+ */
1074
+ function checkSsrConfig(cwd) {
1075
+ let deps = {};
1076
+ try {
1077
+ const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
1078
+ deps = {
1079
+ ...pkg.dependencies,
1080
+ ...pkg.devDependencies
1081
+ };
1082
+ } catch {
1083
+ return null;
1084
+ }
1085
+ const framework = VITE_SSR_MARKERS.find((m) => deps[m] !== void 0);
1086
+ if (framework === void 0) return null;
1087
+ for (const file of VITE_CONFIG_FILES) {
1088
+ const path = join(cwd, file);
1089
+ if (!existsSync(path)) continue;
1090
+ const config = readFileSync(path, "utf8");
1091
+ if (/noExternal/.test(config) && /@cascivo/.test(config)) return null;
1092
+ if (/cascivoSsr/.test(config)) return null;
1093
+ }
1094
+ return `${framework} is a Vite SSR framework, but no vite config marks the cascivo packages ssr.noExternal — an unconfigured SSR build crashes with \`Unknown file extension ".css"\`. Add \`ssr: { noExternal: [/^@cascivo\\//] }\` (or the cascivoSsr() plugin from @cascivo/vite-plugin). Recipe: https://cascivo.com/docs/using-with-vite-ssr.md`;
1095
+ }
1014
1096
  const BANNED_HOOKS = [
1015
1097
  "useState",
1016
1098
  "useEffect",
@@ -2436,20 +2518,26 @@ async function run(args) {
2436
2518
  case "doctor": {
2437
2519
  const ci = rest.includes("--ci");
2438
2520
  if (rest.includes("--drift")) {
2439
- const { runDoctorDrift } = await import("./drift-Ciw5qeEt.mjs");
2521
+ const { runDoctorDrift } = await import("./drift-qTzJ75Ds.mjs");
2440
2522
  await runDoctorDrift(await loadConfig());
2441
2523
  } else {
2442
2524
  const cwd = process.cwd();
2443
2525
  const result = await runDoctor(cwd);
2444
- const { checkProjectDependencies, isAdopterProject } = await Promise.resolve().then(() => doctor_exports);
2445
- const deps = isAdopterProject(cwd) ? checkProjectDependencies(cwd) : [];
2526
+ const { checkProjectDependencies, checkSignalsCompat, checkSsrConfig, isAdopterProject } = await Promise.resolve().then(() => doctor_exports);
2527
+ const adopter = isAdopterProject(cwd);
2528
+ const deps = adopter ? checkProjectDependencies(cwd) : [];
2446
2529
  const missingRequired = deps.filter((d) => d.required);
2447
- if (result.passed && deps.length === 0) console.log("No violations found.");
2530
+ const signalsCompat = adopter ? await checkSignalsCompat(cwd) : null;
2531
+ const signalsError = signalsCompat?.severity === "error";
2532
+ const ssrHint = adopter ? checkSsrConfig(cwd) : null;
2533
+ if (result.passed && deps.length === 0 && signalsCompat === null && ssrHint === null) console.log("No violations found.");
2448
2534
  else {
2449
2535
  for (const v of result.violations) console.error(`[${v.rule}] ${v.detail}\n ${v.file}`);
2450
2536
  for (const d of missingRequired) console.error(`[missing-dependency] ${d.package} is not in package.json — copied cascivo source needs it. Install: ${d.hint}`);
2537
+ if (signalsCompat) (signalsError ? console.error : console.log)(`[${signalsError ? "signals-incompatible" : "signals-outdated"}] ${signalsCompat.detail} Upgrade: ${signalsCompat.hint}`);
2538
+ if (ssrHint) console.log(`[ssr-config] ${ssrHint}`);
2451
2539
  for (const d of deps.filter((x) => !x.required)) console.log(`[optional] ${d.package} is not installed; add it when a component or chart needs it: ${d.hint}`);
2452
- if (ci && (result.violations.length > 0 || missingRequired.length > 0)) process.exitCode = 1;
2540
+ if (ci && (result.violations.length > 0 || missingRequired.length > 0 || signalsError)) process.exitCode = 1;
2453
2541
  }
2454
2542
  }
2455
2543
  break;