@squadbase/vantage 0.6.1-dev1.354b39b → 0.6.1-dev2.4d699fb

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 (57) hide show
  1. package/dist/add-EISGSZAH.js +6 -0
  2. package/dist/add-EISGSZAH.js.map +1 -0
  3. package/dist/{build-JB4VOMUI.js → build-O5TVNH4E.js} +3 -3
  4. package/dist/{build-JB4VOMUI.js.map → build-O5TVNH4E.js.map} +1 -1
  5. package/dist/{check-ZJYK6RLG.js → check-WFBEDHDR.js} +3 -3
  6. package/dist/{check-ZJYK6RLG.js.map → check-WFBEDHDR.js.map} +1 -1
  7. package/dist/{chunk-QI3XQKHS.js → chunk-3G43C6OL.js} +3 -39
  8. package/dist/chunk-3G43C6OL.js.map +1 -0
  9. package/dist/{chunk-PLST5Q7T.js → chunk-LSRMRIXA.js} +9 -3
  10. package/dist/chunk-LSRMRIXA.js.map +1 -0
  11. package/dist/chunk-PXRX5PEC.js +54 -0
  12. package/dist/chunk-PXRX5PEC.js.map +1 -0
  13. package/dist/{chunk-U2M6HGKQ.js → chunk-QDZA5JSL.js} +3 -3
  14. package/dist/{chunk-U2M6HGKQ.js.map → chunk-QDZA5JSL.js.map} +1 -1
  15. package/dist/{chunk-MXI3PZFT.js → chunk-RPZAALCX.js} +5 -49
  16. package/dist/chunk-RPZAALCX.js.map +1 -0
  17. package/dist/cli.js +11 -14
  18. package/dist/cli.js.map +1 -1
  19. package/dist/components/index.js +3 -2
  20. package/dist/{dev-FCEC3UKQ.js → dev-NZRLOQCL.js} +6 -17
  21. package/dist/dev-NZRLOQCL.js.map +1 -0
  22. package/dist/doc/index.d.ts +4 -0
  23. package/dist/doc/index.js +107 -11
  24. package/dist/doc/index.js.map +1 -1
  25. package/dist/{docs-EJJ3BECT.js → docs-ZGDJUHJI.js} +3 -3
  26. package/dist/{docs-EJJ3BECT.js.map → docs-ZGDJUHJI.js.map} +1 -1
  27. package/dist/{doctor-WHZXPERA.js → doctor-VFKEMR54.js} +4 -4
  28. package/dist/doctor-VFKEMR54.js.map +1 -0
  29. package/dist/{preview-OGMCNQUO.js → preview-QDCIVVSR.js} +4 -12
  30. package/dist/preview-QDCIVVSR.js.map +1 -0
  31. package/dist/{routes-GTFO5PUF.js → routes-RHP5FVGD.js} +3 -3
  32. package/dist/{routes-GTFO5PUF.js.map → routes-RHP5FVGD.js.map} +1 -1
  33. package/dist/{search-6Y422SV6.js → search-RFBELGY7.js} +3 -3
  34. package/dist/{search-6Y422SV6.js.map → search-RFBELGY7.js.map} +1 -1
  35. package/dist/table/index.js +3 -2
  36. package/dist/table/index.js.map +1 -1
  37. package/dist/ui/index.js +2 -1
  38. package/dist/ui/index.js.map +1 -1
  39. package/dist/{upgrade-AL4KZZR4.js → upgrade-GF2P67M6.js} +4 -4
  40. package/dist/{upgrade-AL4KZZR4.js.map → upgrade-GF2P67M6.js.map} +1 -1
  41. package/docs/en/changelog.md +0 -13
  42. package/docs/en/cli-reference.md +0 -30
  43. package/docs/en/routing.md +4 -2
  44. package/docs/ja/changelog.md +0 -13
  45. package/docs/ja/cli-reference.md +0 -29
  46. package/docs/ja/routing.md +4 -2
  47. package/package.json +1 -1
  48. package/templates/agents/doc.md +2 -0
  49. package/theme.css +44 -0
  50. package/dist/add-DY4AXANK.js +0 -6
  51. package/dist/add-DY4AXANK.js.map +0 -1
  52. package/dist/chunk-MXI3PZFT.js.map +0 -1
  53. package/dist/chunk-PLST5Q7T.js.map +0 -1
  54. package/dist/chunk-QI3XQKHS.js.map +0 -1
  55. package/dist/dev-FCEC3UKQ.js.map +0 -1
  56. package/dist/doctor-WHZXPERA.js.map +0 -1
  57. package/dist/preview-OGMCNQUO.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { parseArgs, frameworkVersion, resolveQuickRoot, log, resolveRoot } from './chunk-QI3XQKHS.js';
2
+ import { parseArgs, frameworkVersion, resolveQuickRoot, log, resolveRoot } from './chunk-3G43C6OL.js';
3
3
  import './chunk-C2CX6GLX.js';
4
4
  import path from 'path';
5
5
  import pc from 'picocolors';
@@ -30,9 +30,6 @@ ${pc.bold("Options")}
30
30
  --port <n> Port for dev/preview \u2014 exact: fails when it is taken
31
31
  --strict-port Require the default port too (dev/preview)
32
32
  --no-strict-port Let --port fall through to the next free port
33
- --host [addr] Listen on every interface, or only on <addr> (dev/preview)
34
- --allowed-hosts <h> Hostnames to serve behind a reverse proxy: a,b or true (dev/preview)
35
- (env: VANTAGE_ALLOWED_HOSTS; the flag wins)
36
33
  --no-overlay Hide the full-screen HMR error overlay (dev)
37
34
  --root <dir> Project root (default: cwd)
38
35
  --force Overwrite when scaffolding
@@ -49,16 +46,16 @@ ${pc.bold("Options")}
49
46
  -h, --help Print this help
50
47
  `;
51
48
  var COMMANDS = {
52
- dev: () => import('./dev-FCEC3UKQ.js').then((m) => m.dev),
53
- build: () => import('./build-JB4VOMUI.js').then((m) => m.build),
54
- preview: () => import('./preview-OGMCNQUO.js').then((m) => m.preview),
55
- check: () => import('./check-ZJYK6RLG.js').then((m) => m.check),
56
- routes: () => import('./routes-GTFO5PUF.js').then((m) => m.routes),
57
- add: () => import('./add-DY4AXANK.js').then((m) => m.add),
58
- docs: () => import('./docs-EJJ3BECT.js').then((m) => m.docs),
59
- search: () => import('./search-6Y422SV6.js').then((m) => m.search),
60
- doctor: () => import('./doctor-WHZXPERA.js').then((m) => m.doctor),
61
- upgrade: () => import('./upgrade-AL4KZZR4.js').then((m) => m.upgrade)
49
+ dev: () => import('./dev-NZRLOQCL.js').then((m) => m.dev),
50
+ build: () => import('./build-O5TVNH4E.js').then((m) => m.build),
51
+ preview: () => import('./preview-QDCIVVSR.js').then((m) => m.preview),
52
+ check: () => import('./check-WFBEDHDR.js').then((m) => m.check),
53
+ routes: () => import('./routes-RHP5FVGD.js').then((m) => m.routes),
54
+ add: () => import('./add-EISGSZAH.js').then((m) => m.add),
55
+ docs: () => import('./docs-ZGDJUHJI.js').then((m) => m.docs),
56
+ search: () => import('./search-RFBELGY7.js').then((m) => m.search),
57
+ doctor: () => import('./doctor-VFKEMR54.js').then((m) => m.doctor),
58
+ upgrade: () => import('./upgrade-GF2P67M6.js').then((m) => m.upgrade)
62
59
  };
63
60
  var NO_ROOT_POSITIONAL = /* @__PURE__ */ new Set(["add", "docs", "search"]);
64
61
  async function main() {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\"\nimport pc from \"picocolors\"\nimport {\n frameworkVersion,\n log,\n parseArgs,\n resolveQuickRoot,\n resolveRoot,\n type ParsedArgs,\n} from \"./cli/util\"\n\nconst HELP = `${pc.bold(pc.magenta(\"vantage\"))} — data dashboard framework for Squadbase\n\n${pc.bold(\"Usage\")}\n vantage <command> [path] [options]\n vantage <path> Quick dev shortcut (folder or entry file)\n\n${pc.bold(\"Commands\")}\n dev Start the dev server (HMR + optional API)\n build Build client and optional server into dist/\n preview Run the production build locally\n check Static verification (routes, boundaries, forbidden files)\n routes Show page and API URL map (--pages | --apis | --detail)\n add <kind> <name> Scaffold a page | api | ui | block | skill | agents\n (add skill with no name lists the skills and where they sit;\n add agents places AGENTS.md + agents/*.md)\n docs [name] Show the bundled guide and component reference\n search <query> Find components and docs by meaning, or by regex\n doctor Environment and installation health checks\n upgrade Regenerate artifacts, sync AGENTS.md + agents/ / apply migrations\n\n${pc.bold(\"Options\")}\n --json Machine-readable output (check, routes, doctor, build, docs, search)\n --port <n> Port for dev/preview — exact: fails when it is taken\n --strict-port Require the default port too (dev/preview)\n --no-strict-port Let --port fall through to the next free port\n --host [addr] Listen on every interface, or only on <addr> (dev/preview)\n --allowed-hosts <h> Hostnames to serve behind a reverse proxy: a,b or true (dev/preview)\n (env: VANTAGE_ALLOWED_HOSTS; the flag wins)\n --no-overlay Hide the full-screen HMR error overlay (dev)\n --root <dir> Project root (default: cwd)\n --force Overwrite when scaffolding\n --pages Show only page routes (routes)\n --apis Show only API routes (routes)\n --detail Add each route's static spec (routes)\n --list List pages without showing one (docs)\n --lang <ja|en> Documentation language (docs, search, default: ja)\n --regex Treat the query as a regular expression (search)\n --limit <n> Max results (search, default: 10)\n --all Add every bundled skill (add skill --all) | show every page (docs)\n --dir <path> Where to place skills when none is found (add skill, default: project root)\n -v, --version Print version\n -h, --help Print this help\n`\n\ntype Command = (root: string, args: ParsedArgs) => Promise<number>\n\n/**\n * Commands are loaded on demand, never statically. A static import graph would\n * pull Vite and the Tailwind plugin into *every* invocation — ~165ms of module\n * loading that `check`, `routes`, `docs`, `search` and `add` never use (and\n * that even `--version` used to pay). Keep these as `import()` thunks: tsup's\n * code splitting then emits one chunk per command and the dispatcher stays\n * dependency-free.\n */\ntype CommandLoader = () => Promise<Command>\n\nconst COMMANDS: Record<string, CommandLoader> = {\n dev: () => import(\"./cli/dev\").then((m) => m.dev),\n build: () => import(\"./cli/build\").then((m) => m.build),\n preview: () => import(\"./cli/preview\").then((m) => m.preview),\n check: () => import(\"./cli/check\").then((m) => m.check),\n routes: () => import(\"./cli/routes\").then((m) => m.routes),\n add: () => import(\"./cli/add\").then((m) => m.add),\n docs: () => import(\"./cli/docs\").then((m) => m.docs),\n search: () => import(\"./cli/search\").then((m) => m.search),\n doctor: () => import(\"./cli/doctor\").then((m) => m.doctor),\n upgrade: () => import(\"./cli/upgrade\").then((m) => m.upgrade),\n}\n\n/**\n * Commands whose trailing positionals are their own arguments, not a project\n * root: `add` takes kind/name, `docs` a page name, `search` a query.\n */\nconst NO_ROOT_POSITIONAL = new Set([\"add\", \"docs\", \"search\"])\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2))\n const command = args.positionals[0]\n\n if (args.flags.version || args.flags.v) {\n console.log(frameworkVersion())\n return\n }\n if (!command || args.flags.help || args.flags.h || command === \"help\") {\n console.log(HELP)\n return\n }\n\n let load = COMMANDS[command]\n let root: string\n\n if (load) {\n // Known command. Every root-scoped command may take a trailing path\n // positional as its root, except the ones that use positionals themselves.\n const targetArg = !NO_ROOT_POSITIONAL.has(command) ? args.positionals[1] : undefined\n if (targetArg !== undefined) {\n const quick = resolveQuickRoot(targetArg)\n if (!quick) {\n log.error(`No such file or directory: \"${targetArg}\"`)\n process.exitCode = 1\n return\n }\n root = quick\n } else {\n root = resolveRoot(args.flags)\n }\n } else {\n // Unknown first positional: if it's a path, quick-run dev on it; else error.\n const quick = resolveQuickRoot(command)\n if (!quick) {\n log.error(`Unknown command \"${command}\".`)\n console.log(HELP)\n process.exitCode = 1\n return\n }\n load = COMMANDS.dev!\n root = quick\n log.brand(`quick dev → ${path.relative(process.cwd(), root) || \".\"}`)\n }\n\n try {\n const run = await load()\n const code = await run(root, args)\n process.exitCode = code\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err))\n if (process.env.VANTAGE_DEBUG && err instanceof Error) console.error(err.stack)\n process.exitCode = 1\n }\n}\n\nvoid main()\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\"\nimport pc from \"picocolors\"\nimport {\n frameworkVersion,\n log,\n parseArgs,\n resolveQuickRoot,\n resolveRoot,\n type ParsedArgs,\n} from \"./cli/util\"\n\nconst HELP = `${pc.bold(pc.magenta(\"vantage\"))} — data dashboard framework for Squadbase\n\n${pc.bold(\"Usage\")}\n vantage <command> [path] [options]\n vantage <path> Quick dev shortcut (folder or entry file)\n\n${pc.bold(\"Commands\")}\n dev Start the dev server (HMR + optional API)\n build Build client and optional server into dist/\n preview Run the production build locally\n check Static verification (routes, boundaries, forbidden files)\n routes Show page and API URL map (--pages | --apis | --detail)\n add <kind> <name> Scaffold a page | api | ui | block | skill | agents\n (add skill with no name lists the skills and where they sit;\n add agents places AGENTS.md + agents/*.md)\n docs [name] Show the bundled guide and component reference\n search <query> Find components and docs by meaning, or by regex\n doctor Environment and installation health checks\n upgrade Regenerate artifacts, sync AGENTS.md + agents/ / apply migrations\n\n${pc.bold(\"Options\")}\n --json Machine-readable output (check, routes, doctor, build, docs, search)\n --port <n> Port for dev/preview — exact: fails when it is taken\n --strict-port Require the default port too (dev/preview)\n --no-strict-port Let --port fall through to the next free port\n --no-overlay Hide the full-screen HMR error overlay (dev)\n --root <dir> Project root (default: cwd)\n --force Overwrite when scaffolding\n --pages Show only page routes (routes)\n --apis Show only API routes (routes)\n --detail Add each route's static spec (routes)\n --list List pages without showing one (docs)\n --lang <ja|en> Documentation language (docs, search, default: ja)\n --regex Treat the query as a regular expression (search)\n --limit <n> Max results (search, default: 10)\n --all Add every bundled skill (add skill --all) | show every page (docs)\n --dir <path> Where to place skills when none is found (add skill, default: project root)\n -v, --version Print version\n -h, --help Print this help\n`\n\ntype Command = (root: string, args: ParsedArgs) => Promise<number>\n\n/**\n * Commands are loaded on demand, never statically. A static import graph would\n * pull Vite and the Tailwind plugin into *every* invocation — ~165ms of module\n * loading that `check`, `routes`, `docs`, `search` and `add` never use (and\n * that even `--version` used to pay). Keep these as `import()` thunks: tsup's\n * code splitting then emits one chunk per command and the dispatcher stays\n * dependency-free.\n */\ntype CommandLoader = () => Promise<Command>\n\nconst COMMANDS: Record<string, CommandLoader> = {\n dev: () => import(\"./cli/dev\").then((m) => m.dev),\n build: () => import(\"./cli/build\").then((m) => m.build),\n preview: () => import(\"./cli/preview\").then((m) => m.preview),\n check: () => import(\"./cli/check\").then((m) => m.check),\n routes: () => import(\"./cli/routes\").then((m) => m.routes),\n add: () => import(\"./cli/add\").then((m) => m.add),\n docs: () => import(\"./cli/docs\").then((m) => m.docs),\n search: () => import(\"./cli/search\").then((m) => m.search),\n doctor: () => import(\"./cli/doctor\").then((m) => m.doctor),\n upgrade: () => import(\"./cli/upgrade\").then((m) => m.upgrade),\n}\n\n/**\n * Commands whose trailing positionals are their own arguments, not a project\n * root: `add` takes kind/name, `docs` a page name, `search` a query.\n */\nconst NO_ROOT_POSITIONAL = new Set([\"add\", \"docs\", \"search\"])\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2))\n const command = args.positionals[0]\n\n if (args.flags.version || args.flags.v) {\n console.log(frameworkVersion())\n return\n }\n if (!command || args.flags.help || args.flags.h || command === \"help\") {\n console.log(HELP)\n return\n }\n\n let load = COMMANDS[command]\n let root: string\n\n if (load) {\n // Known command. Every root-scoped command may take a trailing path\n // positional as its root, except the ones that use positionals themselves.\n const targetArg = !NO_ROOT_POSITIONAL.has(command) ? args.positionals[1] : undefined\n if (targetArg !== undefined) {\n const quick = resolveQuickRoot(targetArg)\n if (!quick) {\n log.error(`No such file or directory: \"${targetArg}\"`)\n process.exitCode = 1\n return\n }\n root = quick\n } else {\n root = resolveRoot(args.flags)\n }\n } else {\n // Unknown first positional: if it's a path, quick-run dev on it; else error.\n const quick = resolveQuickRoot(command)\n if (!quick) {\n log.error(`Unknown command \"${command}\".`)\n console.log(HELP)\n process.exitCode = 1\n return\n }\n load = COMMANDS.dev!\n root = quick\n log.brand(`quick dev → ${path.relative(process.cwd(), root) || \".\"}`)\n }\n\n try {\n const run = await load()\n const code = await run(root, args)\n process.exitCode = code\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err))\n if (process.env.VANTAGE_DEBUG && err instanceof Error) console.error(err.stack)\n process.exitCode = 1\n }\n}\n\nvoid main()\n"]}
@@ -1,5 +1,6 @@
1
- export { AppShell, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, EChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, TrendIndicator, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable } from '../chunk-PLST5Q7T.js';
2
- import '../chunk-MXI3PZFT.js';
1
+ export { AppShell, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, EChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, TrendIndicator, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable } from '../chunk-LSRMRIXA.js';
2
+ import '../chunk-RPZAALCX.js';
3
+ import '../chunk-PXRX5PEC.js';
3
4
  import '../chunk-A2UUGASH.js';
4
5
  //# sourceMappingURL=index.js.map
5
6
  //# sourceMappingURL=index.js.map
@@ -6,7 +6,7 @@ import './chunk-KLEIVDUV.js';
6
6
  import { scanProject, timedAsync } from './chunk-ZVANIULZ.js';
7
7
  import './chunk-46QI6GFC.js';
8
8
  import './chunk-B7LLBNLV.js';
9
- import { printDiagnostics, log, applyApiBaseUrlFlag, resolvePortOptions, resolveHostOptions, resolveHmrOverlay, reportPortInUse } from './chunk-QI3XQKHS.js';
9
+ import { printDiagnostics, log, applyApiBaseUrlFlag, resolvePortOptions, resolveHmrOverlay, reportPortInUse } from './chunk-3G43C6OL.js';
10
10
  import './chunk-C2CX6GLX.js';
11
11
  import { loadEnv, createServer } from 'vite';
12
12
 
@@ -28,11 +28,6 @@ async function dev(root, args) {
28
28
  return 1;
29
29
  }
30
30
  const { port, strictPort } = ports;
31
- const hosts = resolveHostOptions(args.flags);
32
- if (!hosts.ok) {
33
- log.error(hosts.error);
34
- return 1;
35
- }
36
31
  const overlay = resolveHmrOverlay(args.flags);
37
32
  const server = await timedAsync(
38
33
  "vite:createServer",
@@ -43,15 +38,9 @@ async function dev(root, args) {
43
38
  // The model was just scanned for diagnostics; hand it over so the plugin
44
39
  // does not walk the project again.
45
40
  plugins: [vantagePlugin({ root, env, model })],
46
- // `host` / `allowedHosts` are only present when asked for, and `hmr` is
47
- // left alone unless the overlay is being turned off, so Vite's own
48
- // defaults (host, port, protocol) keep applying.
49
- server: {
50
- port,
51
- strictPort,
52
- ...hosts.options,
53
- ...overlay ? {} : { hmr: { overlay: false } }
54
- },
41
+ // `hmr` is left alone unless the overlay is being turned off, so Vite's
42
+ // own defaults (host, port, protocol) keep applying.
43
+ server: { port, strictPort, ...overlay ? {} : { hmr: { overlay: false } } },
55
44
  clearScreen: false
56
45
  })
57
46
  );
@@ -77,5 +66,5 @@ async function dev(root, args) {
77
66
  }
78
67
 
79
68
  export { dev };
80
- //# sourceMappingURL=dev-FCEC3UKQ.js.map
81
- //# sourceMappingURL=dev-FCEC3UKQ.js.map
69
+ //# sourceMappingURL=dev-NZRLOQCL.js.map
70
+ //# sourceMappingURL=dev-NZRLOQCL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/dev.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAgBA,eAAsB,GAAA,CAAI,MAAc,IAAA,EAAmC;AACzE,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA;AAC/E,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,gBAAA,CAAiB,MAAM,CAAA;AACvB,IAAA,GAAA,CAAI,MAAM,sDAAsD,CAAA;AAChE,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,aAAA;AACb,EAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,OAAA,CAAQ,GAAA,EAAK,GAAG,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,EAAE,CAAA,EAAE;AACzD,EAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AACjD,EAAA,IAAI,CAAC,MAAM,EAAA,EAAI;AACb,IAAA,GAAA,CAAI,KAAA,CAAM,MAAM,KAAK,CAAA;AACrB,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAW,GAAI,KAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,IAAA,CAAK,KAAK,CAAA;AAE5C,EAAA,MAAM,SAAS,MAAM,UAAA;AAAA,IAAW,mBAAA;AAAA,IAAqB,MACnD,YAAA,CAAa;AAAA,MACX,UAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MACA,IAAA;AAAA;AAAA;AAAA,MAGA,OAAA,EAAS,CAAC,aAAA,CAAc,EAAE,MAAM,GAAA,EAAK,KAAA,EAAO,CAAC,CAAA;AAAA;AAAA;AAAA,MAG7C,MAAA,EAAQ,EAAE,IAAA,EAAM,UAAA,EAAY,GAAI,OAAA,GAAU,EAAC,GAAI,EAAE,GAAA,EAAK,EAAE,OAAA,EAAS,KAAA,IAAQ,EAAG;AAAA,MAC5E,WAAA,EAAa;AAAA,KACd;AAAA,GACH;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,CAAW,aAAA,EAAe,MAAM,MAAA,CAAO,QAAQ,CAAA;AAAA,EACvD,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,MAAA,CAAO,KAAA,EAAM,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AACnC,IAAA,IAAI,eAAA,CAAgB,GAAA,EAAK,IAAA,EAAM,UAAU,GAAG,OAAO,CAAA;AACnD,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,GAAA,CAAI,MAAM,kBAAkB,CAAA;AAC5B,EAAA,MAAA,CAAO,SAAA,EAAU;AACjB,EAAA,IAAI,KAAA,CAAM,SAAA,EAAW,GAAA,CAAI,IAAA,CAAK,sBAA2B,CAAA;AAEzD,EAAA,MAAM,WAAW,YAAY;AAC3B,IAAA,MAAM,OAAO,KAAA,EAAM;AACnB,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB,CAAA;AACA,EAAA,OAAA,CAAQ,EAAA,CAAG,UAAU,QAAQ,CAAA;AAC7B,EAAA,OAAA,CAAQ,EAAA,CAAG,WAAW,QAAQ,CAAA;AAG9B,EAAA,OAAO,IAAI,QAAgB,MAAM;AAAA,EAAC,CAAC,CAAA;AACrC","file":"dev-NZRLOQCL.js","sourcesContent":["import { createServer, loadEnv } from \"vite\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { timedAsync } from \"../core/profile\"\nimport { scanProject } from \"../core/scan\"\nimport { vantagePlugin } from \"../vite/index\"\nimport {\n applyApiBaseUrlFlag,\n log,\n printDiagnostics,\n reportPortInUse,\n resolveHmrOverlay,\n resolvePortOptions,\n type ParsedArgs,\n} from \"./util\"\n\n/** `vantage dev` — start the dev server with HMR and the optional API server. */\nexport async function dev(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n if (errors.length) {\n printDiagnostics(errors)\n log.error(\"Fix the errors above before starting the dev server.\")\n return 1\n }\n\n const mode = \"development\"\n applyApiBaseUrlFlag(args)\n const env = { ...process.env, ...loadEnv(mode, root, \"\") }\n const ports = resolvePortOptions(args.flags, 5173)\n if (!ports.ok) {\n log.error(ports.error)\n return 1\n }\n const { port, strictPort } = ports\n const overlay = resolveHmrOverlay(args.flags)\n\n const server = await timedAsync(\"vite:createServer\", () =>\n createServer({\n configFile: false,\n root,\n mode,\n // The model was just scanned for diagnostics; hand it over so the plugin\n // does not walk the project again.\n plugins: [vantagePlugin({ root, env, model })],\n // `hmr` is left alone unless the overlay is being turned off, so Vite's\n // own defaults (host, port, protocol) keep applying.\n server: { port, strictPort, ...(overlay ? {} : { hmr: { overlay: false } }) },\n clearScreen: false,\n }),\n )\n\n try {\n await timedAsync(\"vite:listen\", () => server.listen())\n } catch (err) {\n await server.close().catch(() => {})\n if (reportPortInUse(err, port, strictPort)) return 1\n throw err\n }\n log.brand(\"dev server ready\")\n server.printUrls()\n if (model.hasServer) log.info(\" \" + \"server/api enabled\")\n\n const shutdown = async () => {\n await server.close()\n process.exit(0)\n }\n process.on(\"SIGINT\", shutdown)\n process.on(\"SIGTERM\", shutdown)\n\n // Keep the process alive; the listening server owns the lifecycle.\n return new Promise<number>(() => {})\n}\n"]}
@@ -33,6 +33,10 @@ interface DocumentProps extends HTMLAttributes<HTMLElement> {
33
33
  * the `[data-slot="document"]` rules in theme.css, so the page body needs no
34
34
  * classes. Those rules sit in `@layer components`, below Tailwind utilities, so
35
35
  * a `className` on any element still wins.
36
+ *
37
+ * It also carries its own way out: a button that opens the print dialog, where
38
+ * "Save as PDF" is the download. The print rules in theme.css leave only the
39
+ * document on paper.
36
40
  */
37
41
  declare const Document: React.ForwardRefExoticComponent<DocumentProps & React.RefAttributes<HTMLElement>>;
38
42
 
package/dist/doc/index.js CHANGED
@@ -1,8 +1,80 @@
1
- import { forwardRef } from 'react';
2
- import { jsx } from 'react/jsx-runtime';
1
+ import { Button } from '../chunk-PXRX5PEC.js';
2
+ import '../chunk-A2UUGASH.js';
3
+ import { forwardRef, useEffect } from 'react';
4
+ import { PrinterIcon } from 'lucide-react';
5
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
6
 
4
7
  // @squadbase/vantage — generated build. Do not edit.
5
8
 
9
+ // src/doc/print.ts
10
+ var DARK_CLASS = "dark";
11
+ var THEME_ATTR = "data-theme";
12
+ var restore = null;
13
+ function forceLight() {
14
+ if (restore) return;
15
+ const undo = [];
16
+ for (const el of [document.documentElement, document.body]) {
17
+ if (!el) continue;
18
+ if (el.classList.contains(DARK_CLASS)) {
19
+ el.classList.remove(DARK_CLASS);
20
+ undo.push(() => el.classList.add(DARK_CLASS));
21
+ }
22
+ if (el.getAttribute(THEME_ATTR) === "dark") {
23
+ el.setAttribute(THEME_ATTR, "light");
24
+ undo.push(() => el.setAttribute(THEME_ATTR, "dark"));
25
+ }
26
+ }
27
+ restore = () => {
28
+ for (const fn of undo) fn();
29
+ };
30
+ }
31
+ function restoreTheme() {
32
+ restore?.();
33
+ restore = null;
34
+ }
35
+ function nextFrame() {
36
+ return new Promise((resolve) => {
37
+ let settled = false;
38
+ const settle = () => {
39
+ if (settled) return;
40
+ settled = true;
41
+ resolve();
42
+ };
43
+ requestAnimationFrame(settle);
44
+ setTimeout(settle, 50);
45
+ });
46
+ }
47
+ var REPAINT_FRAMES = 4;
48
+ var CHART_TIMEOUT_MS = 3e3;
49
+ async function waitForCharts() {
50
+ const deadline = performance.now() + CHART_TIMEOUT_MS;
51
+ while (performance.now() < deadline) {
52
+ if (!document.querySelector('[data-slot="echart-canvas"][data-rendering]')) return;
53
+ await nextFrame();
54
+ }
55
+ }
56
+ async function printDocument() {
57
+ const wasForced = restore !== null;
58
+ forceLight();
59
+ try {
60
+ if (!wasForced && restore) {
61
+ for (let i = 0; i < REPAINT_FRAMES; i++) await nextFrame();
62
+ }
63
+ await waitForCharts();
64
+ window.print();
65
+ } catch (error) {
66
+ restoreTheme();
67
+ throw error;
68
+ }
69
+ }
70
+ function watchPrintEvents() {
71
+ window.addEventListener("beforeprint", forceLight);
72
+ window.addEventListener("afterprint", restoreTheme);
73
+ return () => {
74
+ window.removeEventListener("beforeprint", forceLight);
75
+ window.removeEventListener("afterprint", restoreTheme);
76
+ };
77
+ }
6
78
  function themeToCssVars(theme) {
7
79
  if (!theme) return void 0;
8
80
  const vars = {};
@@ -19,17 +91,41 @@ function themeToCssVars(theme) {
19
91
  if (theme.maxWidth) vars["--doc-max-width"] = theme.maxWidth;
20
92
  return Object.keys(vars).length > 0 ? vars : void 0;
21
93
  }
94
+ var PRINT_PAGE_CSS = "@media print { @page { margin: 0 } }";
95
+ function printLabel() {
96
+ return navigator.language.toLowerCase().startsWith("ja") ? "PDF \u3068\u3057\u3066\u4FDD\u5B58" : "Save as PDF";
97
+ }
22
98
  var Document = forwardRef(function Document2({ theme, style, ...props }, ref) {
23
99
  const themeVars = themeToCssVars(theme);
24
- return /* @__PURE__ */ jsx(
25
- "article",
26
- {
27
- ref,
28
- "data-slot": "document",
29
- style: themeVars || style ? { ...themeVars, ...style } : void 0,
30
- ...props
31
- }
32
- );
100
+ const label = printLabel();
101
+ useEffect(() => watchPrintEvents(), []);
102
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
103
+ /* @__PURE__ */ jsx(
104
+ "article",
105
+ {
106
+ ref,
107
+ "data-slot": "document",
108
+ style: themeVars || style ? { ...themeVars, ...style } : void 0,
109
+ ...props
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsx("style", { children: PRINT_PAGE_CSS }),
113
+ /* @__PURE__ */ jsxs(
114
+ Button,
115
+ {
116
+ "data-slot": "document-print",
117
+ variant: "outline",
118
+ size: "sm",
119
+ className: "fixed right-4 bottom-4 z-10 shadow-sm",
120
+ onClick: () => void printDocument(),
121
+ title: label,
122
+ children: [
123
+ /* @__PURE__ */ jsx(PrinterIcon, { "aria-hidden": "true" }),
124
+ label
125
+ ]
126
+ }
127
+ )
128
+ ] });
33
129
  });
34
130
  Document.displayName = "Document";
35
131
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/doc/document.tsx"],"names":["Document"],"mappings":";;;;;AAeA,SAAS,eAAe,KAAA,EAA6D;AACnF,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,OAA+B,EAAC;AACtC,EAAA,IAAI,KAAA,CAAM,EAAA,EAAI,IAAA,CAAK,UAAU,IAAI,KAAA,CAAM,EAAA;AACvC,EAAA,IAAI,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,aAAa,IAAI,KAAA,CAAM,KAAA;AAC7C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,WAAA,EAAa,IAAA,CAAK,oBAAoB,IAAI,KAAA,CAAM,WAAA;AAC1D,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,IAAA,CAAK,mBAAmB,IAAI,KAAA,CAAM,UAAA;AACxD,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAK,IAAA,GAAyB,MAAA;AAClE;AASO,IAAM,QAAA,GAAW,UAAA,CAAuC,SAASA,SAAAA,CACtE,EAAE,OAAO,KAAA,EAAO,GAAG,KAAA,EAAM,EACzB,GAAA,EACA;AACA,EAAA,MAAM,SAAA,GAAY,eAAe,KAAK,CAAA;AACtC,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,UAAA;AAAA,MACV,KAAA,EAAO,aAAa,KAAA,GAAQ,EAAE,GAAG,SAAA,EAAW,GAAG,OAAM,GAAI,MAAA;AAAA,MACxD,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"index.js","sourcesContent":["import { forwardRef } from \"react\"\nimport type { CSSProperties, HTMLAttributes } from \"react\"\n\nimport type { DocumentTheme } from \"./types\"\n\nexport interface DocumentProps extends HTMLAttributes<HTMLElement> {\n /** Token overrides for this document; anything omitted follows the app's theme. */\n theme?: DocumentTheme\n}\n\n/**\n * Only the keys the document set are emitted — the rest resolve up the\n * cascade to `--doc-*` in theme.css. Writing defaults here would freeze every\n * document to light.\n */\nfunction themeToCssVars(theme: DocumentTheme | undefined): CSSProperties | undefined {\n if (!theme) return undefined\n const vars: Record<string, string> = {}\n if (theme.fg) vars[\"--doc-fg\"] = theme.fg\n if (theme.muted) vars[\"--doc-muted\"] = theme.muted\n if (theme.accent) vars[\"--doc-accent\"] = theme.accent\n if (theme.border) vars[\"--doc-border\"] = theme.border\n if (theme.subtle) vars[\"--doc-subtle\"] = theme.subtle\n if (theme.fontBody) vars[\"--doc-font-body\"] = theme.fontBody\n if (theme.fontHeading) vars[\"--doc-font-heading\"] = theme.fontHeading\n if (theme.fontMono) vars[\"--doc-font-mono\"] = theme.fontMono\n if (theme.sizeBody) vars[\"--doc-size-body\"] = theme.sizeBody\n if (theme.lineHeight) vars[\"--doc-line-height\"] = theme.lineHeight\n if (theme.maxWidth) vars[\"--doc-max-width\"] = theme.maxWidth\n return Object.keys(vars).length > 0 ? (vars as CSSProperties) : undefined\n}\n\n/**\n * The container of a document page. Plain elements written inside it —\n * headings, paragraphs, lists, tables, quotes, code, figures — are typeset by\n * the `[data-slot=\"document\"]` rules in theme.css, so the page body needs no\n * classes. Those rules sit in `@layer components`, below Tailwind utilities, so\n * a `className` on any element still wins.\n */\nexport const Document = forwardRef<HTMLElement, DocumentProps>(function Document(\n { theme, style, ...props },\n ref,\n) {\n const themeVars = themeToCssVars(theme)\n return (\n <article\n ref={ref}\n data-slot=\"document\"\n style={themeVars || style ? { ...themeVars, ...style } : undefined}\n {...props}\n />\n )\n})\nDocument.displayName = \"Document\"\n"]}
1
+ {"version":3,"sources":["../../src/doc/print.ts","../../src/doc/document.tsx"],"names":["Document"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Printing a document — the browser's own print dialog, where \"Save as PDF\"\n * is the download. Paper is white and backgrounds are dropped by default, so a\n * dark theme would print pale text on nothing: the page is switched to light\n * for the duration and put back afterwards.\n */\n\nconst DARK_CLASS = \"dark\"\nconst THEME_ATTR = \"data-theme\"\n\ntype Restore = () => void\n\nlet restore: Restore | null = null\n\n/** Drop every dark marker on `<html>`/`<body>`, remembering exactly what was there. */\nfunction forceLight(): void {\n if (restore) return\n const undo: Restore[] = []\n for (const el of [document.documentElement, document.body]) {\n if (!el) continue\n if (el.classList.contains(DARK_CLASS)) {\n el.classList.remove(DARK_CLASS)\n undo.push(() => el.classList.add(DARK_CLASS))\n }\n if (el.getAttribute(THEME_ATTR) === \"dark\") {\n el.setAttribute(THEME_ATTR, \"light\")\n undo.push(() => el.setAttribute(THEME_ATTR, \"dark\"))\n }\n }\n restore = () => {\n for (const fn of undo) fn()\n }\n}\n\nfunction restoreTheme(): void {\n restore?.()\n restore = null\n}\n\nfunction nextFrame(): Promise<void> {\n return new Promise((resolve) => {\n let settled = false\n const settle = () => {\n if (settled) return\n settled = true\n resolve()\n }\n requestAnimationFrame(settle)\n setTimeout(settle, 50)\n })\n}\n\n/**\n * Canvas charts keep the colours they were painted with, and a CSS switch at\n * print time does not repaint them. Their tokens are re-read a frame after the\n * theme flips, then React re-inits the chart, which animates in from empty —\n * printed mid-way, the bars are missing. So wait a few frames for the re-init\n * to start, then for every chart to report its paint done.\n */\nconst REPAINT_FRAMES = 4\nconst CHART_TIMEOUT_MS = 3000\n\nasync function waitForCharts(): Promise<void> {\n const deadline = performance.now() + CHART_TIMEOUT_MS\n while (performance.now() < deadline) {\n if (!document.querySelector('[data-slot=\"echart-canvas\"][data-rendering]')) return\n await nextFrame()\n }\n}\n\n/**\n * The theme comes back on `afterprint` (see `watchPrintEvents`), not after\n * `window.print()` returns — not every browser blocks on the dialog.\n */\nexport async function printDocument(): Promise<void> {\n const wasForced = restore !== null\n forceLight()\n try {\n if (!wasForced && restore) {\n for (let i = 0; i < REPAINT_FRAMES; i++) await nextFrame()\n }\n await waitForCharts()\n window.print()\n } catch (error) {\n restoreTheme()\n throw error\n }\n}\n\n/**\n * Must be mounted while a document is on screen. It also covers the browser's\n * own Print command, which skips the button: flipping the theme in\n * `beforeprint` still gets the text and rules right, though canvas charts\n * cannot repaint in time on that path.\n */\nexport function watchPrintEvents(): () => void {\n window.addEventListener(\"beforeprint\", forceLight)\n window.addEventListener(\"afterprint\", restoreTheme)\n return () => {\n window.removeEventListener(\"beforeprint\", forceLight)\n window.removeEventListener(\"afterprint\", restoreTheme)\n }\n}\n","import { forwardRef, useEffect } from \"react\"\nimport type { CSSProperties, HTMLAttributes } from \"react\"\nimport { PrinterIcon } from \"lucide-react\"\n\nimport { Button } from \"../ui/button\"\nimport { printDocument, watchPrintEvents } from \"./print\"\nimport type { DocumentTheme } from \"./types\"\n\nexport interface DocumentProps extends HTMLAttributes<HTMLElement> {\n /** Token overrides for this document; anything omitted follows the app's theme. */\n theme?: DocumentTheme\n}\n\n/**\n * Only the keys the document set are emitted — the rest resolve up the\n * cascade to `--doc-*` in theme.css. Writing defaults here would freeze every\n * document to light.\n */\nfunction themeToCssVars(theme: DocumentTheme | undefined): CSSProperties | undefined {\n if (!theme) return undefined\n const vars: Record<string, string> = {}\n if (theme.fg) vars[\"--doc-fg\"] = theme.fg\n if (theme.muted) vars[\"--doc-muted\"] = theme.muted\n if (theme.accent) vars[\"--doc-accent\"] = theme.accent\n if (theme.border) vars[\"--doc-border\"] = theme.border\n if (theme.subtle) vars[\"--doc-subtle\"] = theme.subtle\n if (theme.fontBody) vars[\"--doc-font-body\"] = theme.fontBody\n if (theme.fontHeading) vars[\"--doc-font-heading\"] = theme.fontHeading\n if (theme.fontMono) vars[\"--doc-font-mono\"] = theme.fontMono\n if (theme.sizeBody) vars[\"--doc-size-body\"] = theme.sizeBody\n if (theme.lineHeight) vars[\"--doc-line-height\"] = theme.lineHeight\n if (theme.maxWidth) vars[\"--doc-max-width\"] = theme.maxWidth\n return Object.keys(vars).length > 0 ? (vars as CSSProperties) : undefined\n}\n\n/**\n * With no page margin the browser has nowhere to print its date / URL header\n * and footer. Rendered by `<Document>` rather than put in theme.css because an\n * `@page` rule cannot be scoped — there it would reach every dashboard too.\n */\nconst PRINT_PAGE_CSS = \"@media print { @page { margin: 0 } }\"\n\n/** The one piece of chrome a document shows: English, Japanese for a Japanese browser. */\nfunction printLabel(): string {\n return navigator.language.toLowerCase().startsWith(\"ja\") ? \"PDF として保存\" : \"Save as PDF\"\n}\n\n/**\n * The container of a document page. Plain elements written inside it —\n * headings, paragraphs, lists, tables, quotes, code, figures — are typeset by\n * the `[data-slot=\"document\"]` rules in theme.css, so the page body needs no\n * classes. Those rules sit in `@layer components`, below Tailwind utilities, so\n * a `className` on any element still wins.\n *\n * It also carries its own way out: a button that opens the print dialog, where\n * \"Save as PDF\" is the download. The print rules in theme.css leave only the\n * document on paper.\n */\nexport const Document = forwardRef<HTMLElement, DocumentProps>(function Document(\n { theme, style, ...props },\n ref,\n) {\n const themeVars = themeToCssVars(theme)\n const label = printLabel()\n useEffect(() => watchPrintEvents(), [])\n return (\n <>\n <article\n ref={ref}\n data-slot=\"document\"\n style={themeVars || style ? { ...themeVars, ...style } : undefined}\n {...props}\n />\n <style>{PRINT_PAGE_CSS}</style>\n <Button\n data-slot=\"document-print\"\n variant=\"outline\"\n size=\"sm\"\n className=\"fixed right-4 bottom-4 z-10 shadow-sm\"\n onClick={() => void printDocument()}\n title={label}\n >\n <PrinterIcon aria-hidden=\"true\" />\n {label}\n </Button>\n </>\n )\n})\nDocument.displayName = \"Document\"\n"]}
@@ -1,5 +1,5 @@
1
1
  import { loadCatalog, isDocLang, DOC_LANGS, DEFAULT_DOC_LANG, docsForLang, readDoc, resolveDoc, groupBySection } from './chunk-2KRCGXBY.js';
2
- import { log, printJson } from './chunk-QI3XQKHS.js';
2
+ import { log, printJson } from './chunk-3G43C6OL.js';
3
3
  import './chunk-C2CX6GLX.js';
4
4
  import pc from 'picocolors';
5
5
 
@@ -110,5 +110,5 @@ async function docs(_root, args) {
110
110
  }
111
111
 
112
112
  export { docs };
113
- //# sourceMappingURL=docs-EJJ3BECT.js.map
114
- //# sourceMappingURL=docs-EJJ3BECT.js.map
113
+ //# sourceMappingURL=docs-ZGDJUHJI.js.map
114
+ //# sourceMappingURL=docs-ZGDJUHJI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/docs.ts"],"names":["content"],"mappings":"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","file":"docs-EJJ3BECT.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n DEFAULT_DOC_LANG,\n DOC_LANGS,\n docsForLang,\n groupBySection,\n isDocLang,\n loadCatalog,\n readDoc,\n resolveDoc,\n type DocEntry,\n type DocLang,\n} from \"./docs-catalog\"\nimport { log, printJson, type ParsedArgs } from \"./util\"\n\n/** Highlight Markdown for a terminal. Piped output stays untouched. */\nfunction paint(markdown: string): string {\n if (!process.stdout.isTTY) return markdown\n let inFence = false\n return markdown\n .split(\"\\n\")\n .map((line) => {\n if (/^\\s*(```|~~~)/.test(line)) {\n inFence = !inFence\n return pc.dim(line)\n }\n if (inFence) return line\n if (/^#{1,6}\\s/.test(line)) return pc.bold(pc.magenta(line))\n if (/^>\\s?/.test(line)) return pc.dim(line)\n return line\n })\n .join(\"\\n\")\n}\n\nfunction printList(entries: DocEntry[]): void {\n const width = Math.max(...entries.map((doc) => doc.slug.length), 0)\n for (const group of groupBySection(entries)) {\n console.log(\"\")\n console.log(pc.bold(group.title))\n for (const doc of group.docs) {\n const slug = doc.slug.padEnd(width)\n console.log(` ${pc.cyan(slug)} ${doc.description || doc.title}`)\n }\n }\n console.log(\"\")\n console.log(pc.dim(\"vantage docs <name> show one page --json machine-readable\"))\n console.log(pc.dim(\"vantage docs --all show every page --lang ja | en\"))\n}\n\nfunction toJson(doc: DocEntry, content: string) {\n return {\n slug: doc.slug,\n lang: doc.lang,\n title: doc.title,\n description: doc.description,\n section: doc.section,\n sectionTitle: doc.sectionTitle,\n content,\n }\n}\n\n/** `vantage docs [name] [--list] [--all] [--json] [--lang ja|en]` */\nexport async function docs(_root: string, args: ParsedArgs): Promise<number> {\n const catalog = loadCatalog()\n if (!catalog) {\n log.error(\"The bundled documentation is missing. Reinstall @squadbase/vantage, or run `pnpm build` in the framework repo.\")\n return 1\n }\n\n const langFlag = args.flags.lang\n if (langFlag !== undefined && !isDocLang(langFlag)) {\n log.error(`Unknown --lang \"${String(langFlag)}\". Available: ${DOC_LANGS.join(\", \")}`)\n return 1\n }\n const lang: DocLang = isDocLang(langFlag) ? langFlag : DEFAULT_DOC_LANG\n\n const entries = docsForLang(catalog, lang)\n if (entries.length === 0) {\n log.error(`No documentation bundled for \"${lang}\".`)\n return 1\n }\n\n const json = Boolean(args.flags.json)\n const name = args.positionals[1]\n\n if (args.flags.all) {\n const pages = entries.map((doc) => ({ doc, content: readDoc(doc) }))\n if (json) {\n printJson({ lang, docs: pages.map(({ doc, content }) => toJson(doc, content)) })\n return 0\n }\n process.stdout.write(pages.map(({ content }) => content.trimEnd()).join(\"\\n\\n---\\n\\n\") + \"\\n\")\n return 0\n }\n\n if (!name || args.flags.list) {\n if (json) {\n printJson({\n lang,\n docs: entries.map(({ slug, title, description, section, sectionTitle }) => ({\n slug,\n title,\n description,\n section,\n sectionTitle,\n })),\n })\n return 0\n }\n printList(entries)\n return 0\n }\n\n const found = resolveDoc(entries, name)\n if (found.kind === \"ambiguous\") {\n log.error(`\"${name}\" matches several pages: ${found.matches.map((d) => d.slug).join(\", \")}`)\n return 1\n }\n if (found.kind === \"missing\") {\n const suggestions = found.suggestions.map((d) => d.slug)\n log.error(\n suggestions.length\n ? `No page named \"${name}\". Did you mean: ${suggestions.slice(0, 8).join(\", \")}?`\n : `No page named \"${name}\". Run \\`vantage docs\\` to list every page.`,\n )\n return 1\n }\n\n const content = readDoc(found.doc)\n if (json) {\n printJson(toJson(found.doc, content))\n return 0\n }\n process.stdout.write(paint(content.trimEnd()) + \"\\n\")\n return 0\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/docs.ts"],"names":["content"],"mappings":"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","file":"docs-ZGDJUHJI.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n DEFAULT_DOC_LANG,\n DOC_LANGS,\n docsForLang,\n groupBySection,\n isDocLang,\n loadCatalog,\n readDoc,\n resolveDoc,\n type DocEntry,\n type DocLang,\n} from \"./docs-catalog\"\nimport { log, printJson, type ParsedArgs } from \"./util\"\n\n/** Highlight Markdown for a terminal. Piped output stays untouched. */\nfunction paint(markdown: string): string {\n if (!process.stdout.isTTY) return markdown\n let inFence = false\n return markdown\n .split(\"\\n\")\n .map((line) => {\n if (/^\\s*(```|~~~)/.test(line)) {\n inFence = !inFence\n return pc.dim(line)\n }\n if (inFence) return line\n if (/^#{1,6}\\s/.test(line)) return pc.bold(pc.magenta(line))\n if (/^>\\s?/.test(line)) return pc.dim(line)\n return line\n })\n .join(\"\\n\")\n}\n\nfunction printList(entries: DocEntry[]): void {\n const width = Math.max(...entries.map((doc) => doc.slug.length), 0)\n for (const group of groupBySection(entries)) {\n console.log(\"\")\n console.log(pc.bold(group.title))\n for (const doc of group.docs) {\n const slug = doc.slug.padEnd(width)\n console.log(` ${pc.cyan(slug)} ${doc.description || doc.title}`)\n }\n }\n console.log(\"\")\n console.log(pc.dim(\"vantage docs <name> show one page --json machine-readable\"))\n console.log(pc.dim(\"vantage docs --all show every page --lang ja | en\"))\n}\n\nfunction toJson(doc: DocEntry, content: string) {\n return {\n slug: doc.slug,\n lang: doc.lang,\n title: doc.title,\n description: doc.description,\n section: doc.section,\n sectionTitle: doc.sectionTitle,\n content,\n }\n}\n\n/** `vantage docs [name] [--list] [--all] [--json] [--lang ja|en]` */\nexport async function docs(_root: string, args: ParsedArgs): Promise<number> {\n const catalog = loadCatalog()\n if (!catalog) {\n log.error(\"The bundled documentation is missing. Reinstall @squadbase/vantage, or run `pnpm build` in the framework repo.\")\n return 1\n }\n\n const langFlag = args.flags.lang\n if (langFlag !== undefined && !isDocLang(langFlag)) {\n log.error(`Unknown --lang \"${String(langFlag)}\". Available: ${DOC_LANGS.join(\", \")}`)\n return 1\n }\n const lang: DocLang = isDocLang(langFlag) ? langFlag : DEFAULT_DOC_LANG\n\n const entries = docsForLang(catalog, lang)\n if (entries.length === 0) {\n log.error(`No documentation bundled for \"${lang}\".`)\n return 1\n }\n\n const json = Boolean(args.flags.json)\n const name = args.positionals[1]\n\n if (args.flags.all) {\n const pages = entries.map((doc) => ({ doc, content: readDoc(doc) }))\n if (json) {\n printJson({ lang, docs: pages.map(({ doc, content }) => toJson(doc, content)) })\n return 0\n }\n process.stdout.write(pages.map(({ content }) => content.trimEnd()).join(\"\\n\\n---\\n\\n\") + \"\\n\")\n return 0\n }\n\n if (!name || args.flags.list) {\n if (json) {\n printJson({\n lang,\n docs: entries.map(({ slug, title, description, section, sectionTitle }) => ({\n slug,\n title,\n description,\n section,\n sectionTitle,\n })),\n })\n return 0\n }\n printList(entries)\n return 0\n }\n\n const found = resolveDoc(entries, name)\n if (found.kind === \"ambiguous\") {\n log.error(`\"${name}\" matches several pages: ${found.matches.map((d) => d.slug).join(\", \")}`)\n return 1\n }\n if (found.kind === \"missing\") {\n const suggestions = found.suggestions.map((d) => d.slug)\n log.error(\n suggestions.length\n ? `No page named \"${name}\". Did you mean: ${suggestions.slice(0, 8).join(\", \")}?`\n : `No page named \"${name}\". Run \\`vantage docs\\` to list every page.`,\n )\n return 1\n }\n\n const content = readDoc(found.doc)\n if (json) {\n printJson(toJson(found.doc, content))\n return 0\n }\n process.stdout.write(paint(content.trimEnd()) + \"\\n\")\n return 0\n}\n"]}
@@ -2,7 +2,7 @@ import { runDiagnostics } from './chunk-BCE22JSM.js';
2
2
  import './chunk-JGRMRXXZ.js';
3
3
  import './chunk-KLEIVDUV.js';
4
4
  import { scanProject } from './chunk-ZVANIULZ.js';
5
- import { printJson, frameworkVersion, log } from './chunk-QI3XQKHS.js';
5
+ import { printJson, frameworkVersion, log } from './chunk-3G43C6OL.js';
6
6
  import './chunk-C2CX6GLX.js';
7
7
  import fs from 'fs';
8
8
  import path from 'path';
@@ -19,7 +19,7 @@ async function doctor(root, args) {
19
19
  });
20
20
  const pkgPath = path.join(root, "package.json");
21
21
  facets.push({ name: "package.json", ok: fs.existsSync(pkgPath), detail: fs.existsSync(pkgPath) ? "found" : "missing" });
22
- const lockfiles = ["bun.lock", "bun.lockb", "pnpm-lock.yaml", "package-lock.json", "yarn.lock"];
22
+ const lockfiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock"];
23
23
  const lock = lockfiles.find((f) => fs.existsSync(path.join(root, f)) || fs.existsSync(path.join(root, "..", f)) || fs.existsSync(path.join(root, "..", "..", f)));
24
24
  facets.push({ name: "lockfile", ok: Boolean(lock), detail: lock ?? "none found" });
25
25
  let installedVantage = "not installed";
@@ -54,5 +54,5 @@ async function doctor(root, args) {
54
54
  }
55
55
 
56
56
  export { doctor };
57
- //# sourceMappingURL=doctor-WHZXPERA.js.map
58
- //# sourceMappingURL=doctor-WHZXPERA.js.map
57
+ //# sourceMappingURL=doctor-VFKEMR54.js.map
58
+ //# sourceMappingURL=doctor-VFKEMR54.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/doctor.ts"],"names":["require"],"mappings":"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","file":"doctor-VFKEMR54.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { scanProject } from \"../core/scan\"\nimport { frameworkVersion, log, printJson, type ParsedArgs } from \"./util\"\n\ninterface Facet {\n name: string\n ok: boolean\n detail: string\n}\n\n/** `vantage doctor` — environment and installation health checks. */\nexport async function doctor(root: string, args: ParsedArgs): Promise<number> {\n const facets: Facet[] = []\n\n const nodeMajor = Number(process.versions.node.split(\".\")[0])\n facets.push({\n name: \"node\",\n ok: nodeMajor >= 20,\n detail: `v${process.versions.node}${nodeMajor >= 20 ? \"\" : \" (requires >= 20)\"}`,\n })\n\n const pkgPath = path.join(root, \"package.json\")\n facets.push({ name: \"package.json\", ok: fs.existsSync(pkgPath), detail: fs.existsSync(pkgPath) ? \"found\" : \"missing\" })\n\n const lockfiles = [\"pnpm-lock.yaml\", \"package-lock.json\", \"yarn.lock\"]\n const lock = lockfiles.find((f) => fs.existsSync(path.join(root, f)) || fs.existsSync(path.join(root, \"..\", f)) || fs.existsSync(path.join(root, \"..\", \"..\", f)))\n facets.push({ name: \"lockfile\", ok: Boolean(lock), detail: lock ?? \"none found\" })\n\n let installedVantage = \"not installed\"\n let vantageOk = false\n try {\n const require = createRequire(path.join(root, \"noop.js\"))\n const p = require.resolve(\"@squadbase/vantage/package.json\")\n installedVantage = (JSON.parse(fs.readFileSync(p, \"utf8\")) as { version: string }).version\n vantageOk = true\n } catch {\n /* not resolvable */\n }\n facets.push({ name: \"@squadbase/vantage\", ok: vantageOk, detail: installedVantage })\n\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n facets.push({\n name: \"project\",\n ok: errors.length === 0,\n detail: errors.length === 0 ? \"no blocking errors\" : `${errors.length} error(s) (run \\`vantage check\\`)`,\n })\n\n const allOk = facets.every((f) => f.ok)\n\n if (args.flags.json) {\n printJson({ ok: allOk, cli: frameworkVersion(), facets })\n return allOk ? 0 : 1\n }\n\n log.brand(`doctor (cli v${frameworkVersion()})`)\n for (const f of facets) {\n const line = `${f.name.padEnd(22)} ${f.detail}`\n if (f.ok) log.ok(line)\n else log.error(line)\n }\n return allOk ? 0 : 1\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { log, resolvePortOptions, resolveHostOptions, reportPortInUse } from './chunk-QI3XQKHS.js';
1
+ import { log, resolvePortOptions, reportPortInUse } from './chunk-3G43C6OL.js';
2
2
  import './chunk-C2CX6GLX.js';
3
3
  import fs from 'fs';
4
4
  import path from 'path';
@@ -18,11 +18,6 @@ async function preview(root, args) {
18
18
  return 1;
19
19
  }
20
20
  const { port, strictPort } = ports;
21
- const hosts = resolveHostOptions(args.flags);
22
- if (!hosts.ok) {
23
- log.error(hosts.error);
24
- return 1;
25
- }
26
21
  if (manifest.mode === "fullstack") {
27
22
  const serverPath = path.join(root, "dist", "server", "index.mjs");
28
23
  if (!fs.existsSync(serverPath)) {
@@ -30,9 +25,6 @@ async function preview(root, args) {
30
25
  return 1;
31
26
  }
32
27
  if (!strictPort) log.info(" --no-strict-port has no effect on a fullstack preview");
33
- if (Object.keys(hosts.options).length) {
34
- log.info(" --host / --allowed-hosts have no effect on a fullstack preview");
35
- }
36
28
  log.brand(`preview (fullstack) \u2192 http://localhost:${port}`);
37
29
  const child = spawn(process.execPath, [serverPath], {
38
30
  stdio: "inherit",
@@ -52,7 +44,7 @@ async function preview(root, args) {
52
44
  configFile: false,
53
45
  root,
54
46
  build: { outDir: path.join(root, "dist", "client") },
55
- preview: { port, strictPort, ...hosts.options }
47
+ preview: { port, strictPort }
56
48
  });
57
49
  } catch (err) {
58
50
  if (reportPortInUse(err, port, strictPort)) return 1;
@@ -65,5 +57,5 @@ async function preview(root, args) {
65
57
  }
66
58
 
67
59
  export { preview };
68
- //# sourceMappingURL=preview-OGMCNQUO.js.map
69
- //# sourceMappingURL=preview-OGMCNQUO.js.map
60
+ //# sourceMappingURL=preview-QDCIVVSR.js.map
61
+ //# sourceMappingURL=preview-QDCIVVSR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/preview.ts"],"names":[],"mappings":";;;;;;;AAMA,eAAsB,OAAA,CAAQ,MAAc,IAAA,EAAmC;AAC7E,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,QAAQ,uBAAuB,CAAA;AACpE,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,YAAY,CAAA,EAAG;AAChC,IAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,GAAG,YAAA,CAAa,YAAA,EAAc,MAAM,CAAC,CAAA;AACjE,EAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AACjD,EAAA,IAAI,CAAC,MAAM,EAAA,EAAI;AACb,IAAA,GAAA,CAAI,KAAA,CAAM,MAAM,KAAK,CAAA;AACrB,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAW,GAAI,KAAA;AAE7B,EAAA,IAAI,QAAA,CAAS,SAAS,WAAA,EAAa;AACjC,IAAA,MAAM,aAAa,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,UAAU,WAAW,CAAA;AAChE,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,MAAA,GAAA,CAAI,MAAM,gDAAgD,CAAA;AAC1D,MAAA,OAAO,CAAA;AAAA,IACT;AAGA,IAAA,IAAI,CAAC,UAAA,EAAY,GAAA,CAAI,IAAA,CAAK,yDAAyD,CAAA;AACnF,IAAA,GAAA,CAAI,KAAA,CAAM,CAAA,4CAAA,EAA0C,IAAI,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,CAAC,UAAU,CAAA,EAAG;AAAA,MAClD,KAAA,EAAO,SAAA;AAAA,MACP,GAAA,EAAK,EAAE,GAAG,OAAA,CAAQ,KAAK,IAAA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAE,KAC3C,CAAA;AACD,IAAA,OAAO,IAAI,OAAA,CAAgB,CAAC,OAAA,KAAY;AACtC,MAAA,KAAA,CAAM,GAAG,MAAA,EAAQ,CAAC,SAAS,OAAA,CAAQ,IAAA,IAAQ,CAAC,CAAC,CAAA;AAC7C,MAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AACtC,MAAA,OAAA,CAAQ,EAAA,CAAG,UAAU,IAAI,CAAA;AACzB,MAAA,OAAA,CAAQ,EAAA,CAAG,WAAW,IAAI,CAAA;AAAA,IAC5B,CAAC,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAY,GAAI,MAAM,OAAO,MAAM,CAAA;AACpD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,MAAM,WAAA,CAAY;AAAA,MACzB,UAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MACA,KAAA,EAAO,EAAE,MAAA,EAAQ,IAAA,CAAK,KAAK,IAAA,EAAM,MAAA,EAAQ,QAAQ,CAAA,EAAE;AAAA,MACnD,OAAA,EAAS,EAAE,IAAA,EAAM,UAAA;AAAW,KAC7B,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI,eAAA,CAAgB,GAAA,EAAK,IAAA,EAAM,UAAU,GAAG,OAAO,CAAA;AACnD,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,GAAA,CAAI,MAAM,eAAe,CAAA;AACzB,EAAA,MAAA,CAAO,SAAA,EAAU;AACjB,EAAA,OAAO,IAAI,QAAgB,MAAM;AAAA,EAAC,CAAC,CAAA;AACrC","file":"preview-QDCIVVSR.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { spawn } from \"node:child_process\"\nimport { log, reportPortInUse, resolvePortOptions, type ParsedArgs } from \"./util\"\n\n/** `vantage preview` — run the production build locally. */\nexport async function preview(root: string, args: ParsedArgs): Promise<number> {\n const manifestPath = path.join(root, \"dist\", \"vantage-manifest.json\")\n if (!fs.existsSync(manifestPath)) {\n log.error(\"No build found. Run `vantage build` first.\")\n return 1\n }\n const manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as { mode: string }\n const ports = resolvePortOptions(args.flags, 4173)\n if (!ports.ok) {\n log.error(ports.error)\n return 1\n }\n const { port, strictPort } = ports\n\n if (manifest.mode === \"fullstack\") {\n const serverPath = path.join(root, \"dist\", \"server\", \"index.mjs\")\n if (!fs.existsSync(serverPath)) {\n log.error(\"Server bundle missing. Re-run `vantage build`.\")\n return 1\n }\n // The production Node server binds exactly one port and exits on EADDRINUSE,\n // so a fullstack preview is always strict — there is no walk to opt out of.\n if (!strictPort) log.info(\" --no-strict-port has no effect on a fullstack preview\")\n log.brand(`preview (fullstack) → http://localhost:${port}`)\n const child = spawn(process.execPath, [serverPath], {\n stdio: \"inherit\",\n env: { ...process.env, PORT: String(port) },\n })\n return new Promise<number>((resolve) => {\n child.on(\"exit\", (code) => resolve(code ?? 0))\n const stop = () => child.kill(\"SIGINT\")\n process.on(\"SIGINT\", stop)\n process.on(\"SIGTERM\", stop)\n })\n }\n\n // SPA-only preview via Vite's static preview server.\n const { preview: vitePreview } = await import(\"vite\")\n let server: Awaited<ReturnType<typeof vitePreview>>\n try {\n server = await vitePreview({\n configFile: false,\n root,\n build: { outDir: path.join(root, \"dist\", \"client\") },\n preview: { port, strictPort },\n })\n } catch (err) {\n if (reportPortInUse(err, port, strictPort)) return 1\n throw err\n }\n log.brand(\"preview (spa)\")\n server.printUrls()\n return new Promise<number>(() => {})\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { extractPageSpec, extractApiSpec } from './chunk-JGRMRXXZ.js';
2
2
  import './chunk-KLEIVDUV.js';
3
3
  import { scanProject } from './chunk-ZVANIULZ.js';
4
- import { printJson } from './chunk-QI3XQKHS.js';
4
+ import { printJson } from './chunk-3G43C6OL.js';
5
5
  import './chunk-C2CX6GLX.js';
6
6
  import pc from 'picocolors';
7
7
 
@@ -124,5 +124,5 @@ async function routes(root, args) {
124
124
  }
125
125
 
126
126
  export { routes };
127
- //# sourceMappingURL=routes-GTFO5PUF.js.map
128
- //# sourceMappingURL=routes-GTFO5PUF.js.map
127
+ //# sourceMappingURL=routes-RHP5FVGD.js.map
128
+ //# sourceMappingURL=routes-RHP5FVGD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/routes.ts"],"names":[],"mappings":"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","file":"routes-GTFO5PUF.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n extractApiSpec,\n extractPageSpec,\n type ApiMethodSpec,\n type PageSpec,\n type RouteParam,\n} from \"../core/route-spec\"\nimport { scanProject } from \"../core/scan\"\nimport type { ApiRoute, PageRoute, RouteModel } from \"../core/types\"\nimport { printJson, type ParsedArgs } from \"./util\"\n\nconst ROUTE_COLUMN = 28\nconst LABEL_COLUMN = 9\n\n/** Print an indented `label value` line under a route. */\nfunction detailLine(indent: string, label: string, value: string): void {\n console.log(`${indent}${pc.dim(label.padEnd(LABEL_COLUMN))}${value}`)\n}\n\n/** Render params as `:id`, `*rest`. */\nfunction formatParams(params: RouteParam[]): string {\n return params.map((p) => (p.kind === \"catchall\" ? `*${p.name}` : `:${p.name}`)).join(\", \")\n}\n\nfunction formatKeys(keys: string[] | undefined): string {\n return keys?.length ? ` { ${keys.join(\", \")} }` : \"\"\n}\n\nfunction printPageSpec(spec: PageSpec): void {\n const indent = \" \"\n if (spec.title) detailLine(indent, \"title\", spec.title)\n if (spec.navLabel) detailLine(indent, \"nav\", spec.navLabel)\n if (spec.description) detailLine(indent, \"desc\", spec.description)\n if (spec.params.length) detailLine(indent, \"params\", formatParams(spec.params))\n}\n\nfunction printApiMethodSpec(method: ApiMethodSpec, params: RouteParam[]): void {\n const indent = \" \"\n console.log(` ${pc.bold(method.method)}`)\n if (params.length) detailLine(indent, \"path\", formatParams(params))\n if (method.query.length) detailLine(indent, \"query\", method.query.join(\", \"))\n if (method.body) detailLine(indent, \"body\", method.body.format + formatKeys(method.body.keys))\n for (const res of method.responses) {\n const parts = [String(res.status), res.contentType].filter(Boolean).join(\" \")\n detailLine(indent, \"response\", parts + formatKeys(res.keys))\n }\n for (const err of method.errors) {\n detailLine(indent, \"error\", `${err.status}${err.message ? ` \"${err.message}\"` : \"\"}`)\n }\n}\n\n/**\n * How a page is rendered, when it is not the plain case. Without this a\n * `.slide.tsx` and a `.tsx` that resolve to the same URL look identical here,\n * and the whole point of `routes` is to show what the scan understood.\n */\nfunction pageBadge(page: PageRoute): string {\n if (page.kind === \"file\") return pc.magenta(` (${(page.fileExt ?? \"\").slice(1)})`)\n if (page.variant) return pc.magenta(` (${page.variant})`)\n return \"\"\n}\n\nfunction printPages(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nPages\"))\n if (model.pages.length === 0) console.log(pc.dim(\" (none)\"))\n for (const p of model.pages) {\n console.log(` ${pc.green(p.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(p.file)}${pageBadge(p)}`)\n if (detail) printPageSpec(extractPageSpec(p))\n }\n\n if (model.layouts.length || model.notFound || model.error) {\n console.log(pc.bold(\"\\nSpecial\"))\n for (const l of model.layouts) {\n const label = \"layout \" + (l.dir === \"\" ? \"/\" : \"/\" + l.dir)\n console.log(` ${pc.cyan(label.padEnd(ROUTE_COLUMN))} ${pc.dim(l.file)}`)\n }\n if (model.notFound) console.log(` ${pc.cyan(\"404\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.notFound)}`)\n if (model.error) console.log(` ${pc.cyan(\"error\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.error)}`)\n }\n}\n\nfunction printApis(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nAPI\"))\n if (!model.hasServer) {\n console.log(pc.dim(\" (none — this project has no server/ directory)\"))\n return\n }\n if (model.apis.length === 0) console.log(pc.dim(\" (none)\"))\n for (const a of model.apis) {\n console.log(` ${pc.yellow(a.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(a.file)}`)\n if (!detail) continue\n const spec = extractApiSpec(a)\n if (spec.methods.length === 0) console.log(` ${pc.dim(\"(no HTTP method handler exported)\")}`)\n for (const method of spec.methods) printApiMethodSpec(method, spec.params)\n }\n}\n\nfunction pageJson(p: PageRoute, detail: boolean) {\n return {\n route: p.routePath,\n file: p.file,\n dynamic: p.dynamic,\n kind: p.kind,\n ...(p.fileExt ? { fileExt: p.fileExt } : {}),\n ...(p.variant ? { variant: p.variant } : {}),\n ...(detail ? { spec: extractPageSpec(p) } : {}),\n }\n}\n\nfunction apiJson(a: ApiRoute, detail: boolean) {\n return {\n route: a.routePath,\n file: a.file,\n params: a.params,\n ...(detail ? { spec: extractApiSpec(a) } : {}),\n }\n}\n\n/**\n * `vantage routes` — show the page and API URL map.\n * `--pages` / `--apis` narrow the map to one side; `--detail` adds the static\n * spec of each route (page path params + definePage meta, API methods with\n * their request input and response shape).\n */\nexport async function routes(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const onlyPages = Boolean(args.flags.pages)\n const onlyApis = Boolean(args.flags.apis)\n // Neither flag (or both) means \"everything\", so the two are never exclusive.\n const showPages = onlyPages || !onlyApis\n const showApis = onlyApis || !onlyPages\n const detail = Boolean(args.flags.detail)\n\n if (args.flags.json) {\n const payload: Record<string, unknown> = {}\n if (showPages) {\n payload.pages = model.pages.map((p) => pageJson(p, detail))\n payload.layouts = model.layouts.map((l) => ({ dir: l.dir === \"\" ? \"/\" : l.dir, file: l.file }))\n payload.notFound = model.notFound\n payload.error = model.error\n // Files the scan skipped. `check` explains them; listing them here means\n // an agent reading `routes --json` sees them without a second command.\n payload.unrouted = model.unrouted\n }\n if (showApis) {\n payload.apis = model.apis.map((a) => apiJson(a, detail))\n payload.hasServer = model.hasServer\n }\n printJson(payload)\n return 0\n }\n\n if (showPages) printPages(model, detail)\n // Without --apis, an API-less project stays silent (nothing to say about it).\n if (showApis && (model.hasServer || onlyApis)) printApis(model, detail)\n console.log(\"\")\n return 0\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/routes.ts"],"names":[],"mappings":"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","file":"routes-RHP5FVGD.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n extractApiSpec,\n extractPageSpec,\n type ApiMethodSpec,\n type PageSpec,\n type RouteParam,\n} from \"../core/route-spec\"\nimport { scanProject } from \"../core/scan\"\nimport type { ApiRoute, PageRoute, RouteModel } from \"../core/types\"\nimport { printJson, type ParsedArgs } from \"./util\"\n\nconst ROUTE_COLUMN = 28\nconst LABEL_COLUMN = 9\n\n/** Print an indented `label value` line under a route. */\nfunction detailLine(indent: string, label: string, value: string): void {\n console.log(`${indent}${pc.dim(label.padEnd(LABEL_COLUMN))}${value}`)\n}\n\n/** Render params as `:id`, `*rest`. */\nfunction formatParams(params: RouteParam[]): string {\n return params.map((p) => (p.kind === \"catchall\" ? `*${p.name}` : `:${p.name}`)).join(\", \")\n}\n\nfunction formatKeys(keys: string[] | undefined): string {\n return keys?.length ? ` { ${keys.join(\", \")} }` : \"\"\n}\n\nfunction printPageSpec(spec: PageSpec): void {\n const indent = \" \"\n if (spec.title) detailLine(indent, \"title\", spec.title)\n if (spec.navLabel) detailLine(indent, \"nav\", spec.navLabel)\n if (spec.description) detailLine(indent, \"desc\", spec.description)\n if (spec.params.length) detailLine(indent, \"params\", formatParams(spec.params))\n}\n\nfunction printApiMethodSpec(method: ApiMethodSpec, params: RouteParam[]): void {\n const indent = \" \"\n console.log(` ${pc.bold(method.method)}`)\n if (params.length) detailLine(indent, \"path\", formatParams(params))\n if (method.query.length) detailLine(indent, \"query\", method.query.join(\", \"))\n if (method.body) detailLine(indent, \"body\", method.body.format + formatKeys(method.body.keys))\n for (const res of method.responses) {\n const parts = [String(res.status), res.contentType].filter(Boolean).join(\" \")\n detailLine(indent, \"response\", parts + formatKeys(res.keys))\n }\n for (const err of method.errors) {\n detailLine(indent, \"error\", `${err.status}${err.message ? ` \"${err.message}\"` : \"\"}`)\n }\n}\n\n/**\n * How a page is rendered, when it is not the plain case. Without this a\n * `.slide.tsx` and a `.tsx` that resolve to the same URL look identical here,\n * and the whole point of `routes` is to show what the scan understood.\n */\nfunction pageBadge(page: PageRoute): string {\n if (page.kind === \"file\") return pc.magenta(` (${(page.fileExt ?? \"\").slice(1)})`)\n if (page.variant) return pc.magenta(` (${page.variant})`)\n return \"\"\n}\n\nfunction printPages(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nPages\"))\n if (model.pages.length === 0) console.log(pc.dim(\" (none)\"))\n for (const p of model.pages) {\n console.log(` ${pc.green(p.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(p.file)}${pageBadge(p)}`)\n if (detail) printPageSpec(extractPageSpec(p))\n }\n\n if (model.layouts.length || model.notFound || model.error) {\n console.log(pc.bold(\"\\nSpecial\"))\n for (const l of model.layouts) {\n const label = \"layout \" + (l.dir === \"\" ? \"/\" : \"/\" + l.dir)\n console.log(` ${pc.cyan(label.padEnd(ROUTE_COLUMN))} ${pc.dim(l.file)}`)\n }\n if (model.notFound) console.log(` ${pc.cyan(\"404\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.notFound)}`)\n if (model.error) console.log(` ${pc.cyan(\"error\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.error)}`)\n }\n}\n\nfunction printApis(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nAPI\"))\n if (!model.hasServer) {\n console.log(pc.dim(\" (none — this project has no server/ directory)\"))\n return\n }\n if (model.apis.length === 0) console.log(pc.dim(\" (none)\"))\n for (const a of model.apis) {\n console.log(` ${pc.yellow(a.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(a.file)}`)\n if (!detail) continue\n const spec = extractApiSpec(a)\n if (spec.methods.length === 0) console.log(` ${pc.dim(\"(no HTTP method handler exported)\")}`)\n for (const method of spec.methods) printApiMethodSpec(method, spec.params)\n }\n}\n\nfunction pageJson(p: PageRoute, detail: boolean) {\n return {\n route: p.routePath,\n file: p.file,\n dynamic: p.dynamic,\n kind: p.kind,\n ...(p.fileExt ? { fileExt: p.fileExt } : {}),\n ...(p.variant ? { variant: p.variant } : {}),\n ...(detail ? { spec: extractPageSpec(p) } : {}),\n }\n}\n\nfunction apiJson(a: ApiRoute, detail: boolean) {\n return {\n route: a.routePath,\n file: a.file,\n params: a.params,\n ...(detail ? { spec: extractApiSpec(a) } : {}),\n }\n}\n\n/**\n * `vantage routes` — show the page and API URL map.\n * `--pages` / `--apis` narrow the map to one side; `--detail` adds the static\n * spec of each route (page path params + definePage meta, API methods with\n * their request input and response shape).\n */\nexport async function routes(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const onlyPages = Boolean(args.flags.pages)\n const onlyApis = Boolean(args.flags.apis)\n // Neither flag (or both) means \"everything\", so the two are never exclusive.\n const showPages = onlyPages || !onlyApis\n const showApis = onlyApis || !onlyPages\n const detail = Boolean(args.flags.detail)\n\n if (args.flags.json) {\n const payload: Record<string, unknown> = {}\n if (showPages) {\n payload.pages = model.pages.map((p) => pageJson(p, detail))\n payload.layouts = model.layouts.map((l) => ({ dir: l.dir === \"\" ? \"/\" : l.dir, file: l.file }))\n payload.notFound = model.notFound\n payload.error = model.error\n // Files the scan skipped. `check` explains them; listing them here means\n // an agent reading `routes --json` sees them without a second command.\n payload.unrouted = model.unrouted\n }\n if (showApis) {\n payload.apis = model.apis.map((a) => apiJson(a, detail))\n payload.hasServer = model.hasServer\n }\n printJson(payload)\n return 0\n }\n\n if (showPages) printPages(model, detail)\n // Without --apis, an API-less project stays silent (nothing to say about it).\n if (showApis && (model.hasServer || onlyApis)) printApis(model, detail)\n console.log(\"\")\n return 0\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { loadCatalog, isDocLang, DOC_LANGS, DEFAULT_DOC_LANG, docsForLang, readDoc } from './chunk-2KRCGXBY.js';
2
- import { log, printJson } from './chunk-QI3XQKHS.js';
2
+ import { log, printJson } from './chunk-3G43C6OL.js';
3
3
  import './chunk-C2CX6GLX.js';
4
4
  import pc from 'picocolors';
5
5
 
@@ -321,5 +321,5 @@ async function search(_root, args) {
321
321
  }
322
322
 
323
323
  export { search };
324
- //# sourceMappingURL=search-6Y422SV6.js.map
325
- //# sourceMappingURL=search-6Y422SV6.js.map
324
+ //# sourceMappingURL=search-RFBELGY7.js.map
325
+ //# sourceMappingURL=search-RFBELGY7.js.map