@squadbase/vantage 0.6.2-dev1.3e69e88 → 0.6.2-dev1.48b34e1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/add-4GHF2TX2.js +6 -0
- package/dist/add-4GHF2TX2.js.map +1 -0
- package/dist/{build-JB4VOMUI.js → build-U7GO26HR.js} +9 -9
- package/dist/{build-JB4VOMUI.js.map → build-U7GO26HR.js.map} +1 -1
- package/dist/{check-ZJYK6RLG.js → check-MRVAIHG5.js} +7 -7
- package/dist/{check-ZJYK6RLG.js.map → check-MRVAIHG5.js.map} +1 -1
- package/dist/chunk-2IAPIOPS.js +152 -0
- package/dist/chunk-2IAPIOPS.js.map +1 -0
- package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
- package/dist/chunk-2N72FKLB.js.map +1 -0
- package/dist/chunk-57GHR5LN.js +163 -0
- package/dist/chunk-57GHR5LN.js.map +1 -0
- package/dist/chunk-6OTTGAPO.js +44 -0
- package/dist/chunk-6OTTGAPO.js.map +1 -0
- package/dist/{chunk-RPZAALCX.js → chunk-7S52M2SL.js} +256 -165
- package/dist/chunk-7S52M2SL.js.map +1 -0
- package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
- package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
- package/dist/{chunk-PVTHHV7X.js → chunk-ANZLVSEP.js} +28 -7
- package/dist/chunk-ANZLVSEP.js.map +1 -0
- package/dist/chunk-CKWPK4RO.js +50 -0
- package/dist/chunk-CKWPK4RO.js.map +1 -0
- package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
- package/dist/chunk-GNXCX4WE.js.map +1 -0
- package/dist/chunk-JXFCSF3K.js +673 -0
- package/dist/chunk-JXFCSF3K.js.map +1 -0
- package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
- package/dist/chunk-PDOBHMUQ.js.map +1 -0
- package/dist/{chunk-BCE22JSM.js → chunk-PJ4SPXHS.js} +52 -16
- package/dist/chunk-PJ4SPXHS.js.map +1 -0
- package/dist/chunk-QOXXOFGL.js +7051 -0
- package/dist/chunk-QOXXOFGL.js.map +1 -0
- package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
- package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
- package/dist/chunk-S5MDTHH7.js +466 -0
- package/dist/chunk-S5MDTHH7.js.map +1 -0
- package/dist/chunk-SDJTTMLK.js +1877 -0
- package/dist/chunk-SDJTTMLK.js.map +1 -0
- package/dist/{chunk-EP6JHXSR.js → chunk-SHZM3EXB.js} +68 -12
- package/dist/chunk-SHZM3EXB.js.map +1 -0
- package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
- package/dist/chunk-U736PVHY.js.map +1 -0
- package/dist/{chunk-JGRMRXXZ.js → chunk-UWSQUHX6.js} +4 -99
- package/dist/chunk-UWSQUHX6.js.map +1 -0
- package/dist/cli.js +12 -11
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +34 -3
- package/dist/client/index.js +211 -12
- package/dist/client/index.js.map +1 -1
- package/dist/components/index.d.ts +1740 -29
- package/dist/components/index.js +7 -4
- package/dist/delta-text-CvwBGJ95.d.ts +15 -0
- package/dist/{dev-FCEC3UKQ.js → dev-O42JFQ64.js} +10 -10
- package/dist/dev-O42JFQ64.js.map +1 -0
- package/dist/doc/index.d.ts +215 -2
- package/dist/doc/index.js +309 -5
- package/dist/doc/index.js.map +1 -1
- package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
- package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
- package/dist/{doctor-WHZXPERA.js → doctor-YD3XAAOT.js} +7 -7
- package/dist/{doctor-WHZXPERA.js.map → doctor-YD3XAAOT.js.map} +1 -1
- package/dist/format-U0cQl069.d.ts +243 -0
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
- package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
- package/dist/query/index.d.ts +0 -11
- package/dist/query/index.js +2 -2
- package/dist/{routes-GTFO5PUF.js → routes-PVKNT777.js} +6 -6
- package/dist/{routes-GTFO5PUF.js.map → routes-PVKNT777.js.map} +1 -1
- package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
- package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
- package/dist/slide/index.d.ts +272 -1
- package/dist/slide/index.js +974 -4
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +14 -10
- package/dist/table/index.js.map +1 -1
- package/dist/ui/index.d.ts +148 -12
- package/dist/ui/index.js +1340 -88
- package/dist/ui/index.js.map +1 -1
- package/dist/{upgrade-AL4KZZR4.js → upgrade-6DT7ADRP.js} +7 -7
- package/dist/{upgrade-AL4KZZR4.js.map → upgrade-6DT7ADRP.js.map} +1 -1
- package/dist/vite/index.d.ts +10 -0
- package/dist/vite/index.js +4 -4
- package/docs/en/agent-skills.md +1 -1
- package/docs/en/changelog.md +2 -0
- package/docs/en/components.md +42 -17
- package/docs/en/doc/delta-text.md +40 -0
- package/docs/en/doc/doc-action-items.md +49 -0
- package/docs/en/doc/doc-callout.md +38 -0
- package/docs/en/doc/doc-data-table.md +60 -0
- package/docs/en/doc/doc-executive-summary.md +64 -0
- package/docs/en/doc/doc-figure.md +56 -0
- package/docs/en/doc/doc-key-findings.md +61 -0
- package/docs/en/doc/doc-kpi-scorecard.md +80 -0
- package/docs/en/doc/doc-notes-and-sources.md +43 -0
- package/docs/en/doc/doc-report-header.md +46 -0
- package/docs/en/pages-and-metadata.md +15 -0
- package/docs/en/parts/area-chart.md +99 -0
- package/docs/en/parts/bar-chart.md +91 -0
- package/docs/en/parts/bar-list.md +50 -0
- package/docs/en/parts/category-bar.md +37 -0
- package/docs/en/parts/chart-frame.md +39 -0
- package/docs/en/parts/data-table.md +22 -0
- package/docs/en/parts/delta.md +51 -0
- package/docs/en/parts/donut-chart.md +72 -0
- package/docs/en/parts/format.md +43 -0
- package/docs/en/parts/funnel-steps.md +2 -1
- package/docs/en/parts/heatmap.md +53 -0
- package/docs/en/parts/kpi-card.md +58 -0
- package/docs/en/parts/legend.md +35 -0
- package/docs/en/parts/line-chart.md +94 -0
- package/docs/en/parts/metric-value.md +3 -2
- package/docs/en/parts/progress-circle.md +33 -0
- package/docs/en/parts/sample-data.md +39 -0
- package/docs/en/parts/scatter-chart.md +56 -0
- package/docs/en/parts/sparkline.md +1 -1
- package/docs/en/parts/tracker.md +36 -0
- package/docs/en/parts/trend-indicator.md +17 -1
- package/docs/en/parts/updated-at.md +30 -0
- package/docs/en/parts/waterfall-chart.md +56 -0
- package/docs/en/slide/slide-chart-full.md +48 -0
- package/docs/en/slide/slide-chart-insight.md +52 -0
- package/docs/en/slide/slide-columns.md +46 -0
- package/docs/en/slide/slide-comparison.md +68 -0
- package/docs/en/slide/slide-cover.md +39 -0
- package/docs/en/slide/slide-exec-summary.md +47 -0
- package/docs/en/slide/slide-heading.md +38 -0
- package/docs/en/slide/slide-kpi-grid.md +55 -0
- package/docs/en/slide/slide-kpi-hero.md +58 -0
- package/docs/en/slide/slide-next-actions.md +49 -0
- package/docs/en/slide/slide-scorecard-table.md +54 -0
- package/docs/en/slide/slide-section.md +44 -0
- package/docs/en/slide/slide-source-line.md +34 -0
- package/docs/en/ui/alert-dialog.md +42 -0
- package/docs/en/ui/avatar.md +31 -0
- package/docs/en/ui/combobox.md +74 -0
- package/docs/en/ui/drawer.md +41 -0
- package/docs/en/ui/empty.md +1 -1
- package/docs/en/ui/error-state.md +4 -3
- package/docs/en/ui/field.md +42 -0
- package/docs/en/ui/hover-card.md +21 -0
- package/docs/en/ui/kbd.md +17 -0
- package/docs/en/ui/loading.md +1 -1
- package/docs/en/ui/pagination.md +36 -0
- package/docs/en/ui/radio-group.md +21 -0
- package/docs/en/ui/toast.md +44 -0
- package/docs/en/ui/toggle-group.md +4 -3
- package/docs/en/ui-and-theming.md +1 -1
- package/docs/index.json +1184 -114
- package/docs/ja/agent-skills.md +1 -1
- package/docs/ja/changelog.md +33 -0
- package/docs/ja/components.md +68 -101
- package/docs/ja/doc/delta-text.md +40 -0
- package/docs/ja/doc/doc-action-items.md +49 -0
- package/docs/ja/doc/doc-callout.md +38 -0
- package/docs/ja/doc/doc-data-table.md +60 -0
- package/docs/ja/doc/doc-executive-summary.md +64 -0
- package/docs/ja/doc/doc-figure.md +56 -0
- package/docs/ja/doc/doc-key-findings.md +61 -0
- package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
- package/docs/ja/doc/doc-notes-and-sources.md +43 -0
- package/docs/ja/doc/doc-report-header.md +46 -0
- package/docs/ja/page-types/csv.md +83 -0
- package/docs/ja/page-types/doc.md +83 -0
- package/docs/ja/page-types/excel.md +82 -0
- package/docs/ja/page-types/slide.md +133 -0
- package/docs/ja/page-types.md +47 -0
- package/docs/ja/pages-and-metadata.md +15 -0
- package/docs/ja/parts/area-chart.md +85 -0
- package/docs/ja/parts/bar-chart.md +95 -0
- package/docs/ja/parts/bar-list.md +58 -0
- package/docs/ja/parts/category-bar.md +36 -0
- package/docs/ja/parts/chart-frame.md +36 -0
- package/docs/ja/parts/data-table.md +22 -0
- package/docs/ja/parts/delta.md +51 -0
- package/docs/ja/parts/donut-chart.md +66 -0
- package/docs/ja/parts/echart.md +3 -0
- package/docs/ja/parts/format.md +44 -0
- package/docs/ja/parts/funnel-steps.md +27 -8
- package/docs/ja/parts/heatmap.md +45 -0
- package/docs/ja/parts/kpi-card.md +56 -0
- package/docs/ja/parts/legend.md +36 -0
- package/docs/ja/parts/line-chart.md +84 -0
- package/docs/ja/parts/metric-value.md +3 -2
- package/docs/ja/parts/progress-circle.md +34 -0
- package/docs/ja/parts/sample-data.md +61 -0
- package/docs/ja/parts/scatter-chart.md +69 -0
- package/docs/ja/parts/sparkline.md +2 -2
- package/docs/ja/parts/tracker.md +32 -0
- package/docs/ja/parts/trend-indicator.md +17 -1
- package/docs/ja/parts/updated-at.md +27 -0
- package/docs/ja/parts/waterfall-chart.md +61 -0
- package/docs/ja/routing.md +8 -86
- package/docs/ja/slide/slide-chart-full.md +48 -0
- package/docs/ja/slide/slide-chart-insight.md +52 -0
- package/docs/ja/slide/slide-columns.md +46 -0
- package/docs/ja/slide/slide-comparison.md +68 -0
- package/docs/ja/slide/slide-cover.md +39 -0
- package/docs/ja/slide/slide-exec-summary.md +47 -0
- package/docs/ja/slide/slide-heading.md +38 -0
- package/docs/ja/slide/slide-kpi-grid.md +55 -0
- package/docs/ja/slide/slide-kpi-hero.md +58 -0
- package/docs/ja/slide/slide-next-actions.md +49 -0
- package/docs/ja/slide/slide-scorecard-table.md +54 -0
- package/docs/ja/slide/slide-section.md +44 -0
- package/docs/ja/slide/slide-source-line.md +34 -0
- package/docs/ja/ui/alert-dialog.md +41 -0
- package/docs/ja/ui/avatar.md +31 -0
- package/docs/ja/ui/combobox.md +74 -0
- package/docs/ja/ui/drawer.md +41 -0
- package/docs/ja/ui/empty.md +1 -1
- package/docs/ja/ui/error-state.md +4 -3
- package/docs/ja/ui/field.md +42 -0
- package/docs/ja/ui/hover-card.md +21 -0
- package/docs/ja/ui/kbd.md +16 -0
- package/docs/ja/ui/loading.md +1 -1
- package/docs/ja/ui/pagination.md +36 -0
- package/docs/ja/ui/radio-group.md +21 -0
- package/docs/ja/ui/toast.md +46 -0
- package/docs/ja/ui/toggle-group.md +4 -3
- package/docs/ja/ui-and-theming.md +14 -7
- package/package.json +41 -31
- package/registry/ui/accordion.tsx +76 -0
- package/registry/ui/alert-dialog.tsx +189 -0
- package/registry/ui/alert.tsx +80 -0
- package/registry/ui/app-shell.tsx +287 -0
- package/registry/ui/area-chart.tsx +3701 -0
- package/registry/ui/attention-list.tsx +303 -0
- package/registry/ui/avatar.tsx +110 -0
- package/registry/ui/badge.tsx +56 -0
- package/registry/ui/bar-chart.tsx +3698 -0
- package/registry/ui/bar-list.tsx +3743 -0
- package/registry/ui/box-plot-chart.tsx +3906 -0
- package/registry/ui/breadcrumb.tsx +128 -0
- package/registry/ui/button.tsx +62 -0
- package/registry/ui/calendar.tsx +223 -0
- package/registry/ui/card.tsx +107 -0
- package/registry/ui/category-bar.tsx +1290 -0
- package/registry/ui/chart-frame.tsx +1393 -0
- package/registry/ui/checkbox.tsx +30 -0
- package/registry/ui/collapsible.tsx +23 -0
- package/registry/ui/combobox.tsx +310 -0
- package/registry/ui/command.tsx +198 -0
- package/registry/ui/dashboard-card.tsx +217 -0
- package/registry/ui/data-table.tsx +693 -146
- package/registry/ui/date-range-picker.tsx +390 -0
- package/registry/ui/delta.tsx +191 -0
- package/registry/ui/dialog.tsx +161 -0
- package/registry/ui/donut-chart.tsx +3751 -0
- package/registry/ui/drawer.tsx +229 -0
- package/registry/ui/dropdown-menu.tsx +274 -0
- package/registry/ui/echart.tsx +1040 -0
- package/registry/ui/field.tsx +240 -0
- package/registry/ui/filter-bar.tsx +392 -0
- package/registry/ui/funnel-steps.tsx +3569 -0
- package/registry/ui/heatmap.tsx +1786 -0
- package/registry/ui/histogram-chart.tsx +3986 -0
- package/registry/ui/hover-card.tsx +52 -0
- package/registry/ui/input-group.tsx +160 -0
- package/registry/ui/input.tsx +24 -0
- package/registry/ui/kbd.tsx +30 -0
- package/registry/ui/kpi-card.tsx +704 -0
- package/registry/ui/label.tsx +22 -0
- package/registry/ui/legend.tsx +3563 -0
- package/registry/ui/line-chart.tsx +3699 -0
- package/registry/ui/metric-value.tsx +62 -0
- package/registry/ui/multi-select.tsx +232 -0
- package/registry/ui/page-shell.tsx +282 -0
- package/registry/ui/pagination.tsx +140 -0
- package/registry/ui/paired-chart.tsx +3827 -0
- package/registry/ui/placeholder.tsx +36 -0
- package/registry/ui/popover.tsx +92 -0
- package/registry/ui/progress-circle.tsx +867 -0
- package/registry/ui/progress.tsx +85 -0
- package/registry/ui/radio-group.tsx +39 -0
- package/registry/ui/sample-data.tsx +86 -0
- package/registry/ui/scatter-chart.tsx +4212 -0
- package/registry/ui/scroll-area.tsx +56 -0
- package/registry/ui/searchable-select.tsx +214 -0
- package/registry/ui/section-header.tsx +43 -0
- package/registry/ui/segmented-control.tsx +76 -0
- package/registry/ui/select.tsx +255 -0
- package/registry/ui/separator.tsx +27 -0
- package/registry/ui/sheet.tsx +139 -0
- package/registry/ui/sidebar.tsx +725 -0
- package/registry/ui/skeleton.tsx +17 -0
- package/registry/ui/slider.tsx +56 -0
- package/registry/ui/sparkline.tsx +230 -0
- package/registry/ui/spinner.tsx +14 -0
- package/registry/ui/states.tsx +90 -0
- package/registry/ui/status-badge.tsx +121 -0
- package/registry/ui/switch.tsx +34 -0
- package/registry/ui/table.tsx +118 -0
- package/registry/ui/tabs.tsx +84 -0
- package/registry/ui/textarea.tsx +22 -0
- package/registry/ui/toast.tsx +250 -0
- package/registry/ui/toggle-group.tsx +91 -0
- package/registry/ui/toggle.tsx +47 -0
- package/registry/ui/tooltip.tsx +72 -0
- package/registry/ui/tracker.tsx +849 -0
- package/registry/ui/trend-indicator.tsx +74 -0
- package/registry/ui/updated-at.tsx +122 -0
- package/registry/ui/waterfall-chart.tsx +4248 -0
- package/skills/vantage-add-feature/SKILL.md +9 -7
- package/skills/vantage-design/SKILL.md +62 -52
- package/skills/vantage-design/references/extract.md +26 -27
- package/skills/vantage-design/references/format.md +12 -172
- package/skills/vantage-design/references/presets.md +50 -110
- package/skills/vantage-pitfalls/SKILL.md +10 -1
- package/skills/vantage-slide/SKILL.md +71 -36
- package/templates/AGENTS.md +51 -15
- package/templates/agents/api.md +29 -0
- package/templates/agents/csv.md +2 -1
- package/templates/agents/doc.md +52 -3
- package/templates/agents/page.md +55 -10
- package/templates/agents/slide.md +90 -4
- package/templates/agents/xlsx.md +2 -1
- package/theme.css +247 -132
- package/dist/add-DY4AXANK.js +0 -6
- package/dist/add-DY4AXANK.js.map +0 -1
- package/dist/chunk-5ZOP4SQR.js.map +0 -1
- package/dist/chunk-A2UUGASH.js.map +0 -1
- package/dist/chunk-BCE22JSM.js.map +0 -1
- package/dist/chunk-DTDVSFRY.js +0 -29
- package/dist/chunk-DTDVSFRY.js.map +0 -1
- package/dist/chunk-EP6JHXSR.js.map +0 -1
- package/dist/chunk-JGRMRXXZ.js.map +0 -1
- package/dist/chunk-KLEIVDUV.js +0 -165
- package/dist/chunk-KLEIVDUV.js.map +0 -1
- package/dist/chunk-MP3QSOXL.js +0 -2232
- package/dist/chunk-MP3QSOXL.js.map +0 -1
- package/dist/chunk-PVTHHV7X.js.map +0 -1
- package/dist/chunk-PXRX5PEC.js.map +0 -1
- package/dist/chunk-QI3XQKHS.js.map +0 -1
- package/dist/chunk-RPZAALCX.js.map +0 -1
- package/dist/chunk-T3FLAGI6.js +0 -316
- package/dist/chunk-T3FLAGI6.js.map +0 -1
- package/dist/dev-FCEC3UKQ.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SRC_DIR,
|
|
1
|
+
import { PAGE_VARIANTS, SRC_DIR, PAGE_EXTENSIONS, RESERVED_PAGE_NAMES, UNSUPPORTED_PAGE_EXTENSIONS, API_EXTENSIONS, NON_ROUTE_DIRS, FILE_PAGE_EXTENSIONS } from './chunk-C2CX6GLX.js';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
@@ -244,6 +244,6 @@ function scanProject(root) {
|
|
|
244
244
|
});
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
export { resolvePageRoot, scanProject, timed, timedAsync };
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
249
|
-
//# sourceMappingURL=chunk-
|
|
247
|
+
export { displayPath, fileToSegments, resolvePageRoot, routeSortKey, scanProject, splitPageVariant, stripExt, timed, timedAsync };
|
|
248
|
+
//# sourceMappingURL=chunk-RNTDBX6S.js.map
|
|
249
|
+
//# sourceMappingURL=chunk-RNTDBX6S.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/profile.ts","../src/core/scan.ts"],"names":[],"mappings":"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","file":"chunk-ZVANIULZ.js","sourcesContent":["/**\n * Opt-in phase timing, enabled with `VANTAGE_PROFILE=1`.\n *\n * Every line goes to **stderr**, so turning it on never corrupts the `--json`\n * payloads other commands write to stdout. Disabled, `timed()` is a direct call\n * through — no timers, no allocation.\n */\n\nconst ENABLED = Boolean(process.env.VANTAGE_PROFILE)\n\n/** Whether profiling output is on. Cheap enough to branch on in hot paths. */\nexport const profiling = ENABLED\n\nfunction report(label: string, ms: number): void {\n const since = (performance.now() / 1000).toFixed(3)\n process.stderr.write(`[vantage:profile] ${label.padEnd(24)} ${ms.toFixed(1).padStart(8)}ms @${since}s\\n`)\n}\n\n/** Time a synchronous phase. */\nexport function timed<T>(label: string, fn: () => T): T {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Time an asynchronous phase. */\nexport async function timedAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return await fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Record a one-off duration measured by the caller. */\nexport function note(label: string, ms: number): void {\n if (ENABLED) report(label, ms)\n}\n","import fs from \"node:fs\"\nimport path from \"node:path\"\nimport {\n API_EXTENSIONS,\n FILE_PAGE_EXTENSIONS,\n NON_ROUTE_DIRS,\n PAGE_EXTENSIONS,\n PAGE_VARIANTS,\n RESERVED_PAGE_NAMES,\n SRC_DIR,\n UNSUPPORTED_PAGE_EXTENSIONS,\n} from \"./constants\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { timed } from \"./profile\"\nimport type {\n ApiRoute,\n LayoutRoute,\n PageRoute,\n RouteModel,\n Segment,\n UnroutedFile,\n} from \"./types\"\n\n/** Convert an absolute path to a project-relative POSIX path. */\nfunction toPosix(root: string, abs: string): string {\n return path.relative(root, abs).split(path.sep).join(\"/\")\n}\n\n/** Parse one raw path token into a segment descriptor. */\nfunction parseRawSegment(raw: string): Segment {\n const catchall = raw.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return { kind: \"catchall\", name: catchall[1]! }\n const param = raw.match(/^\\[(.+)\\]$/)\n if (param) return { kind: \"param\", name: param[1]! }\n return { kind: \"static\", value: raw }\n}\n\n/** Build a human/display route path from segments. */\nfunction displayPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `:${s.name}`\n return \"*\"\n })\n return \"/\" + parts.join(\"/\")\n}\n\n/** Split a relative POSIX file (without extension) into route segments. */\nfunction fileToSegments(relNoExt: string): Segment[] {\n const raw = relNoExt.split(\"/\")\n // A trailing `index` maps to its directory (drop it).\n if (raw[raw.length - 1] === \"index\") raw.pop()\n return raw.map(parseRawSegment)\n}\n\n/** Strip a known extension from a filename. */\nfunction stripExt(file: string, exts: string[]): string {\n for (const ext of exts) {\n if (file.endsWith(ext)) return file.slice(0, -ext.length)\n }\n return file\n}\n\n/**\n * Split a page-kind suffix off a name that has already lost its extension:\n * `june.slide` -> `{ base: \"june\", variant: \"slide\" }`, `june` -> variant null.\n * A bare `.slide.tsx` (empty base) is a nameless page, not a variant.\n */\nexport function splitPageVariant(nameNoExt: string): { base: string; variant: PageVariant | null } {\n for (const variant of PAGE_VARIANTS) {\n const suffix = `.${variant}`\n if (nameNoExt.endsWith(suffix) && nameNoExt.length > suffix.length) {\n return { base: nameNoExt.slice(0, -suffix.length), variant }\n }\n }\n return { base: nameNoExt, variant: null }\n}\n\n/**\n * Case-insensitive match against the data-file extensions, returning the\n * canonical (lowercased) form. `stripExt` cannot be reused here: it matches\n * case-sensitively, and `REPORT.CSV` must still lose exactly its extension\n * while its stem keeps its own case.\n */\nfunction matchFilePageExt(base: string): FilePageExt | undefined {\n const lower = base.toLowerCase()\n return FILE_PAGE_EXTENSIONS.find((ext) => lower.endsWith(ext))\n}\n\n/** Excel and Numbers drop a `~$book.xlsx` lock file while a workbook is open. */\nfunction isLockFile(base: string): boolean {\n return base.startsWith(\"~$\")\n}\n\nfunction hasExt(file: string, exts: string[]): boolean {\n return exts.some((ext) => file.endsWith(ext))\n}\n\n/** Recursively collect files under a directory, respecting ignore rules. */\nfunction walk(dir: string, root: string, out: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (NON_ROUTE_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n walk(abs, root, out)\n } else if (entry.isFile()) {\n out.push(abs)\n }\n }\n}\n\n/**\n * Decide where pages are scanned from: `<root>/src` when that directory exists,\n * the project root otherwise. The two never mix — a project that has `src/`\n * keeps every page inside it (`SRC_DIR_SPLIT` reports the leftovers).\n */\nexport function resolvePageRoot(root: string): { dir: string; abs: string } {\n const abs = path.join(root, SRC_DIR)\n try {\n if (fs.statSync(abs).isDirectory()) return { dir: SRC_DIR, abs }\n } catch {\n /* no src/ — pages live at the project root */\n }\n return { dir: \"\", abs: root }\n}\n\n/**\n * Discover page and layout routes under the page root. `file` stays relative to\n * the *project* root (generated imports resolve from `.vantage/`), while\n * `dir`/`segments`/`routePath` are relative to the *page* root so that `src/`\n * never leaks into a URL — and so `dir` keeps matching `segments` one-to-one,\n * which is how `buildRouteTree` pairs pages with their layouts.\n */\nfunction scanPages(\n root: string,\n pageRoot: string,\n): {\n pages: PageRoute[]\n layouts: LayoutRoute[]\n notFound: string | null\n error: string | null\n unrouted: UnroutedFile[]\n} {\n const files: string[] = []\n walk(pageRoot, pageRoot, files)\n\n const pages: PageRoute[] = []\n const layouts: LayoutRoute[] = []\n const unrouted: UnroutedFile[] = []\n let notFound: string | null = null\n let error: string | null = null\n\n for (const abs of files) {\n const file = toPosix(root, abs)\n const rel = toPosix(pageRoot, abs)\n const base = path.posix.basename(rel)\n const dir = path.posix.dirname(rel)\n const dirPosix = dir === \".\" ? \"\" : dir\n\n if (hasExt(base, PAGE_EXTENSIONS)) {\n const nameNoExt = stripExt(base, PAGE_EXTENSIONS)\n // Reserved modules are matched on the full name: `_layout.slide` is not\n // `_layout`, and a variant on a reserved module is an error the\n // diagnostics report rather than a route.\n if (nameNoExt === RESERVED_PAGE_NAMES.layout) {\n layouts.push({ file, absFile: abs, dir: dirPosix })\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.notFound) {\n if (dirPosix === \"\") notFound = file\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.error) {\n if (dirPosix === \"\") error = file\n continue\n }\n\n const { base: pageName, variant } = splitPageVariant(nameNoExt)\n // Any other underscore-prefixed file is a private module, not a route.\n // The test runs on the name with its variant suffix removed, so\n // `_layout.slide.tsx` and `_draft.slide.tsx` both drop out here.\n if (pageName.startsWith(\"_\")) {\n if (variant) unrouted.push({ file, reason: \"variant\", variant })\n continue\n }\n\n const relNoExt = stripExt(rel, PAGE_EXTENSIONS)\n // The variant suffix always sits at the end of the final token, so\n // trimming the tail is enough to keep it out of the URL.\n const relForSegments = variant ? relNoExt.slice(0, -(variant.length + 1)) : relNoExt\n const segments = fileToSegments(relForSegments)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"module\",\n ...(variant ? { variant } : {}),\n })\n continue\n }\n\n const fileExt = matchFilePageExt(base)\n if (fileExt) {\n // Same privacy rules as page modules, plus spreadsheet lock files.\n if (base.startsWith(\"_\") || base.startsWith(\".\") || isLockFile(base)) continue\n const relNoExt = rel.slice(0, -fileExt.length)\n const segments = fileToSegments(relNoExt)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"file\",\n fileExt,\n })\n continue\n }\n\n const lower = base.toLowerCase()\n // A page-kind suffix on something that is not a page module at all\n // (`deck.slide.ts`, `deck.slide.css`) is a typo worth naming.\n const strayVariant = PAGE_VARIANTS.find((v) => lower.includes(`.${v}.`))\n if (strayVariant) {\n unrouted.push({ file, reason: \"variant\", variant: strayVariant })\n } else if (UNSUPPORTED_PAGE_EXTENSIONS.some((ext) => lower.endsWith(ext))) {\n unrouted.push({ file, reason: \"extension\" })\n }\n }\n\n // Stable ordering: shallow before deep, static before dynamic, alpha. Data\n // files share the key, so they interleave with modules instead of clumping.\n pages.sort((a, b) => routeSortKey(a).localeCompare(routeSortKey(b)))\n layouts.sort((a, b) => a.dir.localeCompare(b.dir))\n unrouted.sort((a, b) => a.file.localeCompare(b.file))\n return { pages, layouts, notFound, error, unrouted }\n}\n\n/** Sort key that keeps static routes ahead of dynamic ones at each depth. */\nfunction routeSortKey(p: PageRoute): string {\n return p.segments\n .map((s) => (s.kind === \"static\" ? \"0\" + s.value : s.kind === \"param\" ? \"1\" : \"2\"))\n .join(\"/\")\n}\n\n/** Discover server API routes under `server/api`. */\nfunction scanApis(root: string): ApiRoute[] {\n const apiDir = path.join(root, \"server\", \"api\")\n if (!fs.existsSync(apiDir)) return []\n\n const files: string[] = []\n const walkApi = (dir: string) => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) walkApi(abs)\n else if (entry.isFile()) files.push(abs)\n }\n }\n walkApi(apiDir)\n\n const apis: ApiRoute[] = []\n for (const abs of files) {\n const base = path.basename(abs)\n if (!hasExt(base, API_EXTENSIONS)) continue\n const nameNoExt = stripExt(base, API_EXTENSIONS)\n // Type declaration files and private helpers are not routes.\n if (base.endsWith(\".d.ts\")) continue\n if (nameNoExt.startsWith(\"_\")) continue\n\n const relFromServer = toPosix(path.join(root, \"server\"), abs) // e.g. api/customers/[id].ts\n const relNoExt = stripExt(relFromServer, API_EXTENSIONS) // api/customers/[id]\n const withoutApiPrefix = relNoExt.replace(/^api\\/?/, \"\") // customers/[id] or \"\" for api/index\n const segTokens = withoutApiPrefix === \"\" ? [] : withoutApiPrefix.split(\"/\")\n if (segTokens[segTokens.length - 1] === \"index\") segTokens.pop()\n const segments = segTokens.map(parseRawSegment)\n const routePath = \"/api\" + (segments.length ? displayPath(segments) : \"\")\n const params = segments\n .filter((s) => s.kind !== \"static\")\n .map((s) => (s as { name: string }).name)\n\n apis.push({\n file: toPosix(root, abs),\n absFile: abs,\n routePath,\n pattern: routePath,\n segments,\n params,\n })\n }\n\n apis.sort((a, b) => a.routePath.localeCompare(b.routePath))\n return apis\n}\n\n/** Scan a project into a full route model. */\nexport function scanProject(root: string): RouteModel {\n return timed(\"scan\", () => {\n const pageRoot = resolvePageRoot(root)\n const { pages, layouts, notFound, error, unrouted } = scanPages(root, pageRoot.abs)\n // server/ is always at the project root: it is the other side of the\n // client/server boundary, not part of the client source tree.\n const hasServer = fs.existsSync(path.join(root, \"server\"))\n const apis = hasServer ? scanApis(root) : []\n return { pages, layouts, notFound, error, apis, hasServer, pageDir: pageRoot.dir, unrouted }\n })\n}\n\n/** Convert a display route path segment list into a TanStack Router path. */\nexport function toRouterPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\" // TanStack splat\n })\n return \"/\" + parts.join(\"/\")\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/profile.ts","../src/core/scan.ts"],"names":[],"mappings":"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","file":"chunk-RNTDBX6S.js","sourcesContent":["/**\n * Opt-in phase timing, enabled with `VANTAGE_PROFILE=1`.\n *\n * Every line goes to **stderr**, so turning it on never corrupts the `--json`\n * payloads other commands write to stdout. Disabled, `timed()` is a direct call\n * through — no timers, no allocation.\n */\n\nconst ENABLED = Boolean(process.env.VANTAGE_PROFILE)\n\n/** Whether profiling output is on. Cheap enough to branch on in hot paths. */\nexport const profiling = ENABLED\n\nfunction report(label: string, ms: number): void {\n const since = (performance.now() / 1000).toFixed(3)\n process.stderr.write(`[vantage:profile] ${label.padEnd(24)} ${ms.toFixed(1).padStart(8)}ms @${since}s\\n`)\n}\n\n/** Time a synchronous phase. */\nexport function timed<T>(label: string, fn: () => T): T {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Time an asynchronous phase. */\nexport async function timedAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return await fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Record a one-off duration measured by the caller. */\nexport function note(label: string, ms: number): void {\n if (ENABLED) report(label, ms)\n}\n","import fs from \"node:fs\"\nimport path from \"node:path\"\nimport {\n API_EXTENSIONS,\n FILE_PAGE_EXTENSIONS,\n NON_ROUTE_DIRS,\n PAGE_EXTENSIONS,\n PAGE_VARIANTS,\n RESERVED_PAGE_NAMES,\n SRC_DIR,\n UNSUPPORTED_PAGE_EXTENSIONS,\n} from \"./constants\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { timed } from \"./profile\"\nimport type {\n ApiRoute,\n LayoutRoute,\n PageRoute,\n RouteModel,\n Segment,\n UnroutedFile,\n} from \"./types\"\n\n/** Convert an absolute path to a project-relative POSIX path. */\nfunction toPosix(root: string, abs: string): string {\n return path.relative(root, abs).split(path.sep).join(\"/\")\n}\n\n/** Parse one raw path token into a segment descriptor. */\nfunction parseRawSegment(raw: string): Segment {\n const catchall = raw.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return { kind: \"catchall\", name: catchall[1]! }\n const param = raw.match(/^\\[(.+)\\]$/)\n if (param) return { kind: \"param\", name: param[1]! }\n return { kind: \"static\", value: raw }\n}\n\n/** Build a human/display route path from segments. */\nexport function displayPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `:${s.name}`\n return \"*\"\n })\n return \"/\" + parts.join(\"/\")\n}\n\n/** Split a relative POSIX file (without extension) into route segments. */\nexport function fileToSegments(relNoExt: string): Segment[] {\n const raw = relNoExt.split(\"/\")\n // A trailing `index` maps to its directory (drop it).\n if (raw[raw.length - 1] === \"index\") raw.pop()\n return raw.map(parseRawSegment)\n}\n\n/** Strip a known extension from a filename. */\nexport function stripExt(file: string, exts: string[]): string {\n for (const ext of exts) {\n if (file.endsWith(ext)) return file.slice(0, -ext.length)\n }\n return file\n}\n\n/**\n * Split a page-kind suffix off a name that has already lost its extension:\n * `june.slide` -> `{ base: \"june\", variant: \"slide\" }`, `june` -> variant null.\n * A bare `.slide.tsx` (empty base) is a nameless page, not a variant.\n */\nexport function splitPageVariant(nameNoExt: string): { base: string; variant: PageVariant | null } {\n for (const variant of PAGE_VARIANTS) {\n const suffix = `.${variant}`\n if (nameNoExt.endsWith(suffix) && nameNoExt.length > suffix.length) {\n return { base: nameNoExt.slice(0, -suffix.length), variant }\n }\n }\n return { base: nameNoExt, variant: null }\n}\n\n/**\n * Case-insensitive match against the data-file extensions, returning the\n * canonical (lowercased) form. `stripExt` cannot be reused here: it matches\n * case-sensitively, and `REPORT.CSV` must still lose exactly its extension\n * while its stem keeps its own case.\n */\nfunction matchFilePageExt(base: string): FilePageExt | undefined {\n const lower = base.toLowerCase()\n return FILE_PAGE_EXTENSIONS.find((ext) => lower.endsWith(ext))\n}\n\n/** Excel and Numbers drop a `~$book.xlsx` lock file while a workbook is open. */\nfunction isLockFile(base: string): boolean {\n return base.startsWith(\"~$\")\n}\n\nfunction hasExt(file: string, exts: string[]): boolean {\n return exts.some((ext) => file.endsWith(ext))\n}\n\n/** Recursively collect files under a directory, respecting ignore rules. */\nfunction walk(dir: string, root: string, out: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (NON_ROUTE_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n walk(abs, root, out)\n } else if (entry.isFile()) {\n out.push(abs)\n }\n }\n}\n\n/**\n * Decide where pages are scanned from: `<root>/src` when that directory exists,\n * the project root otherwise. The two never mix — a project that has `src/`\n * keeps every page inside it (`SRC_DIR_SPLIT` reports the leftovers).\n */\nexport function resolvePageRoot(root: string): { dir: string; abs: string } {\n const abs = path.join(root, SRC_DIR)\n try {\n if (fs.statSync(abs).isDirectory()) return { dir: SRC_DIR, abs }\n } catch {\n /* no src/ — pages live at the project root */\n }\n return { dir: \"\", abs: root }\n}\n\n/**\n * Discover page and layout routes under the page root. `file` stays relative to\n * the *project* root (generated imports resolve from `.vantage/`), while\n * `dir`/`segments`/`routePath` are relative to the *page* root so that `src/`\n * never leaks into a URL — and so `dir` keeps matching `segments` one-to-one,\n * which is how `buildRouteTree` pairs pages with their layouts.\n */\nfunction scanPages(\n root: string,\n pageRoot: string,\n): {\n pages: PageRoute[]\n layouts: LayoutRoute[]\n notFound: string | null\n error: string | null\n unrouted: UnroutedFile[]\n} {\n const files: string[] = []\n walk(pageRoot, pageRoot, files)\n\n const pages: PageRoute[] = []\n const layouts: LayoutRoute[] = []\n const unrouted: UnroutedFile[] = []\n let notFound: string | null = null\n let error: string | null = null\n\n for (const abs of files) {\n const file = toPosix(root, abs)\n const rel = toPosix(pageRoot, abs)\n const base = path.posix.basename(rel)\n const dir = path.posix.dirname(rel)\n const dirPosix = dir === \".\" ? \"\" : dir\n\n if (hasExt(base, PAGE_EXTENSIONS)) {\n const nameNoExt = stripExt(base, PAGE_EXTENSIONS)\n // Reserved modules are matched on the full name: `_layout.slide` is not\n // `_layout`, and a variant on a reserved module is an error the\n // diagnostics report rather than a route.\n if (nameNoExt === RESERVED_PAGE_NAMES.layout) {\n layouts.push({ file, absFile: abs, dir: dirPosix })\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.notFound) {\n if (dirPosix === \"\") notFound = file\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.error) {\n if (dirPosix === \"\") error = file\n continue\n }\n\n const { base: pageName, variant } = splitPageVariant(nameNoExt)\n // Any other underscore-prefixed file is a private module, not a route.\n // The test runs on the name with its variant suffix removed, so\n // `_layout.slide.tsx` and `_draft.slide.tsx` both drop out here.\n if (pageName.startsWith(\"_\")) {\n if (variant) unrouted.push({ file, reason: \"variant\", variant })\n continue\n }\n\n const relNoExt = stripExt(rel, PAGE_EXTENSIONS)\n // The variant suffix always sits at the end of the final token, so\n // trimming the tail is enough to keep it out of the URL.\n const relForSegments = variant ? relNoExt.slice(0, -(variant.length + 1)) : relNoExt\n const segments = fileToSegments(relForSegments)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"module\",\n ...(variant ? { variant } : {}),\n })\n continue\n }\n\n const fileExt = matchFilePageExt(base)\n if (fileExt) {\n // Same privacy rules as page modules, plus spreadsheet lock files.\n if (base.startsWith(\"_\") || base.startsWith(\".\") || isLockFile(base)) continue\n const relNoExt = rel.slice(0, -fileExt.length)\n const segments = fileToSegments(relNoExt)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"file\",\n fileExt,\n })\n continue\n }\n\n const lower = base.toLowerCase()\n // A page-kind suffix on something that is not a page module at all\n // (`deck.slide.ts`, `deck.slide.css`) is a typo worth naming.\n const strayVariant = PAGE_VARIANTS.find((v) => lower.includes(`.${v}.`))\n if (strayVariant) {\n unrouted.push({ file, reason: \"variant\", variant: strayVariant })\n } else if (UNSUPPORTED_PAGE_EXTENSIONS.some((ext) => lower.endsWith(ext))) {\n unrouted.push({ file, reason: \"extension\" })\n }\n }\n\n // Stable ordering: shallow before deep, static before dynamic, alpha. Data\n // files share the key, so they interleave with modules instead of clumping.\n pages.sort((a, b) => routeSortKey(a).localeCompare(routeSortKey(b)))\n layouts.sort((a, b) => a.dir.localeCompare(b.dir))\n unrouted.sort((a, b) => a.file.localeCompare(b.file))\n return { pages, layouts, notFound, error, unrouted }\n}\n\n/** Sort key that keeps static routes ahead of dynamic ones at each depth. */\nexport function routeSortKey(p: PageRoute): string {\n return p.segments\n .map((s) => (s.kind === \"static\" ? \"0\" + s.value : s.kind === \"param\" ? \"1\" : \"2\"))\n .join(\"/\")\n}\n\n/** Discover server API routes under `server/api`. */\nfunction scanApis(root: string): ApiRoute[] {\n const apiDir = path.join(root, \"server\", \"api\")\n if (!fs.existsSync(apiDir)) return []\n\n const files: string[] = []\n const walkApi = (dir: string) => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) walkApi(abs)\n else if (entry.isFile()) files.push(abs)\n }\n }\n walkApi(apiDir)\n\n const apis: ApiRoute[] = []\n for (const abs of files) {\n const base = path.basename(abs)\n if (!hasExt(base, API_EXTENSIONS)) continue\n const nameNoExt = stripExt(base, API_EXTENSIONS)\n // Type declaration files and private helpers are not routes.\n if (base.endsWith(\".d.ts\")) continue\n if (nameNoExt.startsWith(\"_\")) continue\n\n const relFromServer = toPosix(path.join(root, \"server\"), abs) // e.g. api/customers/[id].ts\n const relNoExt = stripExt(relFromServer, API_EXTENSIONS) // api/customers/[id]\n const withoutApiPrefix = relNoExt.replace(/^api\\/?/, \"\") // customers/[id] or \"\" for api/index\n const segTokens = withoutApiPrefix === \"\" ? [] : withoutApiPrefix.split(\"/\")\n if (segTokens[segTokens.length - 1] === \"index\") segTokens.pop()\n const segments = segTokens.map(parseRawSegment)\n const routePath = \"/api\" + (segments.length ? displayPath(segments) : \"\")\n const params = segments\n .filter((s) => s.kind !== \"static\")\n .map((s) => (s as { name: string }).name)\n\n apis.push({\n file: toPosix(root, abs),\n absFile: abs,\n routePath,\n pattern: routePath,\n segments,\n params,\n })\n }\n\n apis.sort((a, b) => a.routePath.localeCompare(b.routePath))\n return apis\n}\n\n/** Scan a project into a full route model. */\nexport function scanProject(root: string): RouteModel {\n return timed(\"scan\", () => {\n const pageRoot = resolvePageRoot(root)\n const { pages, layouts, notFound, error, unrouted } = scanPages(root, pageRoot.abs)\n // server/ is always at the project root: it is the other side of the\n // client/server boundary, not part of the client source tree.\n const hasServer = fs.existsSync(path.join(root, \"server\"))\n const apis = hasServer ? scanApis(root) : []\n return { pages, layouts, notFound, error, apis, hasServer, pageDir: pageRoot.dir, unrouted }\n })\n}\n\n/** Convert a display route path segment list into a TanStack Router path. */\nexport function toRouterPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\" // TanStack splat\n })\n return \"/\" + parts.join(\"/\")\n}\n"]}
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { createHash } from 'crypto';
|
|
4
|
+
|
|
5
|
+
// @squadbase/vantage — generated build. Do not edit.
|
|
6
|
+
|
|
7
|
+
function humanize(stem) {
|
|
8
|
+
return stem.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[-_\s]+/).filter(Boolean).map((word) => word === word.toUpperCase() ? word : word[0].toUpperCase() + word.slice(1)).join(" ");
|
|
9
|
+
}
|
|
10
|
+
function filePageMeta(page) {
|
|
11
|
+
const base = path.posix.basename(page.file);
|
|
12
|
+
let stem = page.fileExt ? base.slice(0, -page.fileExt.length) : base;
|
|
13
|
+
if (stem.toLowerCase() === "index") stem = page.dir.split("/").filter(Boolean).pop() ?? "";
|
|
14
|
+
if (stem === "") return {};
|
|
15
|
+
return { title: humanize(stem) };
|
|
16
|
+
}
|
|
17
|
+
function filePageKind(page) {
|
|
18
|
+
return (page.fileExt ?? "").slice(1);
|
|
19
|
+
}
|
|
20
|
+
function filePageModuleName(page) {
|
|
21
|
+
const slug = page.file.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "").toLowerCase();
|
|
22
|
+
const hash = createHash("sha256").update(page.file).digest("hex").slice(0, 8);
|
|
23
|
+
return `${slug}-${hash}.tsx`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/core/placeholder.ts
|
|
27
|
+
var PLACEHOLDER_HOME_PAGE = `import { definePage } from "@squadbase/vantage"
|
|
28
|
+
import {
|
|
29
|
+
DashboardCardPreset,
|
|
30
|
+
EChart,
|
|
31
|
+
PageShell,
|
|
32
|
+
PageShellContent,
|
|
33
|
+
PageShellDescription,
|
|
34
|
+
PageShellHeader,
|
|
35
|
+
PageShellHeading,
|
|
36
|
+
PageShellTitle,
|
|
37
|
+
Placeholder,
|
|
38
|
+
Sparkline,
|
|
39
|
+
type EChartsOption,
|
|
40
|
+
} from "@squadbase/vantage/components"
|
|
41
|
+
|
|
42
|
+
export const page = definePage({
|
|
43
|
+
title: "Dashboard",
|
|
44
|
+
description: "Sample data \u2014 replace with your own to get started.",
|
|
45
|
+
navLabel: "Home",
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const METRICS = [
|
|
49
|
+
{ label: "Metric 1", value: "1,234", trend: [3, 4, 3, 5, 6, 5, 7] },
|
|
50
|
+
{ label: "Metric 2", value: "5,678", trend: [6, 5, 6, 4, 5, 6, 6] },
|
|
51
|
+
{ label: "Metric 3", value: "90.1%", trend: [2, 3, 5, 4, 6, 7, 8] },
|
|
52
|
+
{ label: "Metric 4", value: "$12.3k", trend: [5, 6, 4, 6, 5, 7, 6] },
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
// Sample charts. \`EChart\` paints series with \`--chart-1..5\` and the sparklines
|
|
56
|
+
// use \`--primary\` (both from \`styles.css\`), so a theme change shows up here.
|
|
57
|
+
const BAR_OPTION: EChartsOption = {
|
|
58
|
+
legend: { top: 0 },
|
|
59
|
+
grid: { top: 36, right: 8, bottom: 24, left: 36 },
|
|
60
|
+
xAxis: { type: "category", data: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] },
|
|
61
|
+
yAxis: { type: "value" },
|
|
62
|
+
series: [
|
|
63
|
+
{ name: "Series A", type: "bar", data: [12, 18, 15, 22, 26, 24] },
|
|
64
|
+
{ name: "Series B", type: "bar", data: [8, 11, 13, 12, 16, 19] },
|
|
65
|
+
{ name: "Series C", type: "bar", data: [5, 7, 6, 9, 8, 11] },
|
|
66
|
+
],
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const PIE_OPTION: EChartsOption = {
|
|
70
|
+
legend: { bottom: 0 },
|
|
71
|
+
series: [
|
|
72
|
+
{
|
|
73
|
+
type: "pie",
|
|
74
|
+
radius: ["45%", "70%"],
|
|
75
|
+
center: ["50%", "45%"],
|
|
76
|
+
label: { show: false },
|
|
77
|
+
data: [
|
|
78
|
+
{ name: "Category A", value: 35 },
|
|
79
|
+
{ name: "Category B", value: 25 },
|
|
80
|
+
{ name: "Category C", value: 18 },
|
|
81
|
+
{ name: "Category D", value: 12 },
|
|
82
|
+
{ name: "Category E", value: 10 },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const CHARTS = [
|
|
89
|
+
{ title: "Chart 1", option: BAR_OPTION },
|
|
90
|
+
{ title: "Chart 2", option: PIE_OPTION },
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
export default function HomePage() {
|
|
94
|
+
return (
|
|
95
|
+
<PageShell>
|
|
96
|
+
<PageShellHeader>
|
|
97
|
+
<PageShellHeading>
|
|
98
|
+
<PageShellTitle>Dashboard</PageShellTitle>
|
|
99
|
+
<PageShellDescription>
|
|
100
|
+
Sample data \u2014 replace with your own to get started.
|
|
101
|
+
</PageShellDescription>
|
|
102
|
+
</PageShellHeading>
|
|
103
|
+
</PageShellHeader>
|
|
104
|
+
|
|
105
|
+
<PageShellContent>
|
|
106
|
+
<section className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
107
|
+
{METRICS.map((metric) => (
|
|
108
|
+
<DashboardCardPreset key={metric.label} title={metric.label}>
|
|
109
|
+
<Placeholder className="text-2xl font-bold">{metric.value}</Placeholder>
|
|
110
|
+
<Sparkline
|
|
111
|
+
className="mt-2"
|
|
112
|
+
data={metric.trend.map((value) => ({ value }))}
|
|
113
|
+
color="text-primary"
|
|
114
|
+
area
|
|
115
|
+
/>
|
|
116
|
+
</DashboardCardPreset>
|
|
117
|
+
))}
|
|
118
|
+
</section>
|
|
119
|
+
|
|
120
|
+
<section className="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
|
121
|
+
{CHARTS.map((chart) => (
|
|
122
|
+
<DashboardCardPreset key={chart.title} title={chart.title}>
|
|
123
|
+
<EChart option={chart.option} height={256} ariaLabel={chart.title} />
|
|
124
|
+
</DashboardCardPreset>
|
|
125
|
+
))}
|
|
126
|
+
</section>
|
|
127
|
+
</PageShellContent>
|
|
128
|
+
</PageShell>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
`;
|
|
132
|
+
function isPlaceholderHomePage(content) {
|
|
133
|
+
if (/\bplaceholder\s*:\s*true\b/.test(content)) return true;
|
|
134
|
+
return content.trim() === PLACEHOLDER_HOME_PAGE.trim();
|
|
135
|
+
}
|
|
136
|
+
function isHomePagePath(file) {
|
|
137
|
+
return file === "index.tsx" || file === "src/index.tsx";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/core/source.ts
|
|
141
|
+
function stripComments(src) {
|
|
142
|
+
return src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'`\\])\/\/[^\n]*/g, "$1");
|
|
143
|
+
}
|
|
144
|
+
var OPENERS = { "(": ")", "[": "]", "{": "}" };
|
|
145
|
+
function readBracketBody(src, openIndex) {
|
|
146
|
+
const open = src[openIndex];
|
|
147
|
+
if (!open || !OPENERS[open]) return null;
|
|
148
|
+
let depth2 = 0;
|
|
149
|
+
let quote = null;
|
|
150
|
+
for (let i = openIndex; i < src.length; i++) {
|
|
151
|
+
const c = src[i];
|
|
152
|
+
if (quote) {
|
|
153
|
+
if (c === "\\") i++;
|
|
154
|
+
else if (c === quote) quote = null;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
158
|
+
quote = c;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (OPENERS[c]) depth2++;
|
|
162
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
163
|
+
if (--depth2 === 0) return src.slice(openIndex + 1, i);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
function splitTopLevel(body) {
|
|
169
|
+
const parts = [];
|
|
170
|
+
let depth2 = 0;
|
|
171
|
+
let quote = null;
|
|
172
|
+
let start = 0;
|
|
173
|
+
for (let i = 0; i < body.length; i++) {
|
|
174
|
+
const c = body[i];
|
|
175
|
+
if (quote) {
|
|
176
|
+
if (c === "\\") i++;
|
|
177
|
+
else if (c === quote) quote = null;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
181
|
+
quote = c;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (OPENERS[c]) depth2++;
|
|
185
|
+
else if (c === ")" || c === "]" || c === "}") depth2--;
|
|
186
|
+
else if (c === "," && depth2 === 0) {
|
|
187
|
+
parts.push(body.slice(start, i));
|
|
188
|
+
start = i + 1;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
parts.push(body.slice(start));
|
|
192
|
+
return parts.map((p) => p.trim()).filter(Boolean);
|
|
193
|
+
}
|
|
194
|
+
function maskSource(src) {
|
|
195
|
+
const out = src.split("");
|
|
196
|
+
const inString = new Uint8Array(src.length);
|
|
197
|
+
let i = 0;
|
|
198
|
+
while (i < src.length) {
|
|
199
|
+
const c = src[i];
|
|
200
|
+
const next = src[i + 1];
|
|
201
|
+
if (c === "/" && next === "/" && src[i - 1] !== ":") {
|
|
202
|
+
while (i < src.length && src[i] !== "\n") out[i++] = " ";
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (c === "/" && next === "*") {
|
|
206
|
+
const end = src.indexOf("*/", i + 2);
|
|
207
|
+
const stop = end === -1 ? src.length : end + 2;
|
|
208
|
+
for (; i < stop; i++) if (src[i] !== "\n") out[i] = " ";
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
212
|
+
i++;
|
|
213
|
+
while (i < src.length) {
|
|
214
|
+
const d = src[i];
|
|
215
|
+
if (d === "\\") {
|
|
216
|
+
inString[i] = 1;
|
|
217
|
+
inString[i + 1] = 1;
|
|
218
|
+
i += 2;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (d === c) break;
|
|
222
|
+
if (d === "\n" && c !== "`") break;
|
|
223
|
+
inString[i++] = 1;
|
|
224
|
+
}
|
|
225
|
+
i++;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
i++;
|
|
229
|
+
}
|
|
230
|
+
return { code: out.join(""), inString };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/core/route-tree.ts
|
|
234
|
+
function segToRouter(s) {
|
|
235
|
+
if (s.kind === "static") return s.value;
|
|
236
|
+
if (s.kind === "param") return `$${s.name}`;
|
|
237
|
+
return "$";
|
|
238
|
+
}
|
|
239
|
+
function dirToRouterPath(relDir) {
|
|
240
|
+
return relDir.split("/").filter(Boolean).map((token) => {
|
|
241
|
+
const catchall = token.match(/^\[\.\.\.(.+)\]$/);
|
|
242
|
+
if (catchall) return "$";
|
|
243
|
+
const param = token.match(/^\[(.+)\]$/);
|
|
244
|
+
if (param) return `$${param[1]}`;
|
|
245
|
+
return token;
|
|
246
|
+
}).join("/");
|
|
247
|
+
}
|
|
248
|
+
function isAncestorDir(ancestor, dir) {
|
|
249
|
+
if (ancestor === "") return true;
|
|
250
|
+
return dir === ancestor || dir.startsWith(ancestor + "/");
|
|
251
|
+
}
|
|
252
|
+
function isStrictAncestorDir(ancestor, dir) {
|
|
253
|
+
return dir.startsWith(ancestor + "/");
|
|
254
|
+
}
|
|
255
|
+
function depth(dir) {
|
|
256
|
+
return dir === "" ? 0 : dir.split("/").length;
|
|
257
|
+
}
|
|
258
|
+
function extractDefinePageArgs(src) {
|
|
259
|
+
const call = src.match(/\bdefinePage\s*\(/);
|
|
260
|
+
if (!call) return null;
|
|
261
|
+
let i = (call.index ?? 0) + call[0].length;
|
|
262
|
+
while (i < src.length && /\s/.test(src[i])) i++;
|
|
263
|
+
if (src[i] !== "{") return null;
|
|
264
|
+
const start = i;
|
|
265
|
+
let depth2 = 0;
|
|
266
|
+
for (; i < src.length; i++) {
|
|
267
|
+
const c = src[i];
|
|
268
|
+
if (c === "{") depth2++;
|
|
269
|
+
else if (c === "}" && --depth2 === 0) return src.slice(start + 1, i);
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
function matchStringField(scope, key) {
|
|
274
|
+
const re = new RegExp(
|
|
275
|
+
`\\b${key}\\s*:\\s*(?:"((?:\\\\.|[^"\\\\])*)"|'((?:\\\\.|[^'\\\\])*)'|\`((?:\\\\.|[^\`\\\\])*)\`)`
|
|
276
|
+
);
|
|
277
|
+
const m = scope.match(re);
|
|
278
|
+
if (!m) return void 0;
|
|
279
|
+
return (m[1] ?? m[2] ?? m[3] ?? "").replace(/\\(.)/g, "$1");
|
|
280
|
+
}
|
|
281
|
+
var metaCache = /* @__PURE__ */ new Map();
|
|
282
|
+
function parsePageMeta(src) {
|
|
283
|
+
const args = extractDefinePageArgs(src);
|
|
284
|
+
if (args == null) return {};
|
|
285
|
+
const meta = {};
|
|
286
|
+
const title = matchStringField(args, "title");
|
|
287
|
+
const description = matchStringField(args, "description");
|
|
288
|
+
const navLabel = matchStringField(args, "navLabel");
|
|
289
|
+
if (title) meta.title = title;
|
|
290
|
+
if (description) meta.description = description;
|
|
291
|
+
if (navLabel) meta.navLabel = navLabel;
|
|
292
|
+
if (/\bplaceholder\s*:\s*true\b/.test(args)) meta.placeholder = true;
|
|
293
|
+
return meta;
|
|
294
|
+
}
|
|
295
|
+
function extractPageMeta(absFile) {
|
|
296
|
+
let stat;
|
|
297
|
+
try {
|
|
298
|
+
stat = fs.statSync(absFile);
|
|
299
|
+
} catch {
|
|
300
|
+
return {};
|
|
301
|
+
}
|
|
302
|
+
const hit = metaCache.get(absFile);
|
|
303
|
+
if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.meta;
|
|
304
|
+
let src;
|
|
305
|
+
try {
|
|
306
|
+
src = fs.readFileSync(absFile, "utf8");
|
|
307
|
+
} catch {
|
|
308
|
+
return {};
|
|
309
|
+
}
|
|
310
|
+
const meta = parsePageMeta(src);
|
|
311
|
+
const fileName = absFile.split(/[/\\]/).pop() ?? "";
|
|
312
|
+
const relPath = absFile.includes("/src/") ? `src/${fileName}` : fileName;
|
|
313
|
+
if (isHomePagePath(relPath) && isPlaceholderHomePage(src)) {
|
|
314
|
+
meta.placeholder = true;
|
|
315
|
+
}
|
|
316
|
+
metaCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, meta });
|
|
317
|
+
return meta;
|
|
318
|
+
}
|
|
319
|
+
var DEFAULT_APP_LANG = "en";
|
|
320
|
+
var LANG_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
321
|
+
function isValidLang(lang) {
|
|
322
|
+
return LANG_TAG.test(lang);
|
|
323
|
+
}
|
|
324
|
+
var LANG_DECL = /\bexport\s+const\s+lang\b/g;
|
|
325
|
+
var LANG_LITERAL = /^(?:"((?:\\.|[^"\\\n])*)"|'((?:\\.|[^'\\\n])*)'|`((?:\\.|[^`\\$])*)`)/;
|
|
326
|
+
function parseLangExport(src) {
|
|
327
|
+
const { code, inString } = maskSource(src);
|
|
328
|
+
const depthAt = new Int32Array(src.length + 1);
|
|
329
|
+
let depth2 = 0;
|
|
330
|
+
for (let i = 0; i < src.length; i++) {
|
|
331
|
+
depthAt[i] = depth2;
|
|
332
|
+
if (inString[i]) continue;
|
|
333
|
+
const c = code[i];
|
|
334
|
+
if (c === "{" || c === "(" || c === "[") depth2++;
|
|
335
|
+
else if (c === "}" || c === ")" || c === "]") depth2--;
|
|
336
|
+
}
|
|
337
|
+
LANG_DECL.lastIndex = 0;
|
|
338
|
+
for (let m = LANG_DECL.exec(code); m; m = LANG_DECL.exec(code)) {
|
|
339
|
+
if (inString[m.index] || depthAt[m.index] !== 0) continue;
|
|
340
|
+
let i = m.index + m[0].length;
|
|
341
|
+
const annotation = /^\s*:\s*string\s*/.exec(code.slice(i));
|
|
342
|
+
if (annotation) i += annotation[0].length;
|
|
343
|
+
const eq = /^\s*=\s*/.exec(code.slice(i));
|
|
344
|
+
if (!eq) continue;
|
|
345
|
+
i += eq[0].length;
|
|
346
|
+
const lit = LANG_LITERAL.exec(src.slice(i));
|
|
347
|
+
if (!lit) continue;
|
|
348
|
+
const tail = code.slice(i + lit[0].length);
|
|
349
|
+
const end = /^[ \t]*(?:as\s+const|satisfies\s+string)?[ \t]*(;|\r?\n|$)/.exec(tail);
|
|
350
|
+
if (!end) continue;
|
|
351
|
+
const term = end[1] ?? "";
|
|
352
|
+
if (term !== ";") {
|
|
353
|
+
const next = /^\s*(\S)/.exec(tail.slice(end[0].length - term.length));
|
|
354
|
+
if (next && /[-+*/%&|^<>=?.,([`!~:]/.test(next[1])) continue;
|
|
355
|
+
}
|
|
356
|
+
return (lit[1] ?? lit[2] ?? lit[3] ?? "").replace(/\\(.)/g, "$1");
|
|
357
|
+
}
|
|
358
|
+
return void 0;
|
|
359
|
+
}
|
|
360
|
+
var langCache = /* @__PURE__ */ new Map();
|
|
361
|
+
function readLayoutLang(absFile) {
|
|
362
|
+
let stat;
|
|
363
|
+
try {
|
|
364
|
+
stat = fs.statSync(absFile);
|
|
365
|
+
} catch {
|
|
366
|
+
return void 0;
|
|
367
|
+
}
|
|
368
|
+
const hit = langCache.get(absFile);
|
|
369
|
+
if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.lang;
|
|
370
|
+
let lang;
|
|
371
|
+
try {
|
|
372
|
+
lang = parseLangExport(fs.readFileSync(absFile, "utf8"));
|
|
373
|
+
} catch {
|
|
374
|
+
return void 0;
|
|
375
|
+
}
|
|
376
|
+
langCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, lang });
|
|
377
|
+
return lang;
|
|
378
|
+
}
|
|
379
|
+
function extractAppLang(model) {
|
|
380
|
+
const root = model.layouts.find((l) => l.dir === "");
|
|
381
|
+
if (!root) return DEFAULT_APP_LANG;
|
|
382
|
+
const lang = readLayoutLang(root.absFile);
|
|
383
|
+
return lang !== void 0 && isValidLang(lang) ? lang : DEFAULT_APP_LANG;
|
|
384
|
+
}
|
|
385
|
+
function buildRouteTree(model) {
|
|
386
|
+
const rootLayoutRoute = model.layouts.find((l) => l.dir === "") ?? null;
|
|
387
|
+
const nestedLayouts = model.layouts.filter((l) => l.dir !== "").sort((a, b) => depth(a.dir) - depth(b.dir));
|
|
388
|
+
const built = [];
|
|
389
|
+
const dirToId = /* @__PURE__ */ new Map();
|
|
390
|
+
nestedLayouts.forEach((layout, i) => {
|
|
391
|
+
const id = `L${i}`;
|
|
392
|
+
let parent = null;
|
|
393
|
+
for (const cand of built) {
|
|
394
|
+
if (isStrictAncestorDir(cand.dir, layout.dir)) {
|
|
395
|
+
if (!parent || depth(cand.dir) > depth(parent.dir)) parent = { id: cand.id, dir: cand.dir };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
const parentDir = parent ? parent.dir : "";
|
|
399
|
+
const relDir = parentDir === "" ? layout.dir : layout.dir.slice(parentDir.length + 1);
|
|
400
|
+
built.push({
|
|
401
|
+
id,
|
|
402
|
+
dir: layout.dir,
|
|
403
|
+
parentId: parent ? parent.id : null,
|
|
404
|
+
path: dirToRouterPath(relDir),
|
|
405
|
+
file: layout.file
|
|
406
|
+
});
|
|
407
|
+
dirToId.set(layout.dir, id);
|
|
408
|
+
});
|
|
409
|
+
const pages = model.pages.map((page) => {
|
|
410
|
+
let owner = null;
|
|
411
|
+
for (const l of built) {
|
|
412
|
+
if (isAncestorDir(l.dir, page.dir)) {
|
|
413
|
+
if (!owner || depth(l.dir) > depth(owner.dir)) owner = l;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const ownerSegCount = owner ? depth(owner.dir) : 0;
|
|
417
|
+
const remaining = page.segments.slice(ownerSegCount);
|
|
418
|
+
const index = remaining.length === 0;
|
|
419
|
+
const path2 = index ? "/" : remaining.map(segToRouter).join("/");
|
|
420
|
+
const meta = page.kind === "file" ? filePageMeta(page) : extractPageMeta(page.absFile);
|
|
421
|
+
const builtPage = {
|
|
422
|
+
file: page.file,
|
|
423
|
+
routePath: page.routePath,
|
|
424
|
+
parentLayoutId: owner ? owner.id : null,
|
|
425
|
+
path: path2,
|
|
426
|
+
index,
|
|
427
|
+
kind: page.kind
|
|
428
|
+
};
|
|
429
|
+
if (meta.title) builtPage.title = meta.title;
|
|
430
|
+
if (meta.description) builtPage.description = meta.description;
|
|
431
|
+
if (meta.navLabel) builtPage.navLabel = meta.navLabel;
|
|
432
|
+
if (page.fileExt) builtPage.fileExt = page.fileExt;
|
|
433
|
+
if (page.variant) builtPage.variant = page.variant;
|
|
434
|
+
if (meta.placeholder) builtPage.placeholder = meta.placeholder;
|
|
435
|
+
return builtPage;
|
|
436
|
+
});
|
|
437
|
+
const byRoutePath = /* @__PURE__ */ new Map();
|
|
438
|
+
for (const page of pages) {
|
|
439
|
+
const group = byRoutePath.get(page.routePath) ?? { placeholder: [], nonPlaceholder: [] };
|
|
440
|
+
if (page.placeholder) {
|
|
441
|
+
group.placeholder.push(page);
|
|
442
|
+
} else {
|
|
443
|
+
group.nonPlaceholder.push(page);
|
|
444
|
+
}
|
|
445
|
+
byRoutePath.set(page.routePath, group);
|
|
446
|
+
}
|
|
447
|
+
const filteredPages = [];
|
|
448
|
+
for (const group of byRoutePath.values()) {
|
|
449
|
+
if (group.nonPlaceholder.length > 0) {
|
|
450
|
+
filteredPages.push(...group.nonPlaceholder);
|
|
451
|
+
} else {
|
|
452
|
+
filteredPages.push(...group.placeholder);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
rootLayout: rootLayoutRoute ? rootLayoutRoute.file : null,
|
|
457
|
+
notFound: model.notFound,
|
|
458
|
+
error: model.error,
|
|
459
|
+
layouts: built,
|
|
460
|
+
pages: filteredPages
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export { DEFAULT_APP_LANG, buildRouteTree, extractAppLang, extractPageMeta, filePageKind, filePageMeta, filePageModuleName, isHomePagePath, isPlaceholderHomePage, isValidLang, maskSource, readBracketBody, readLayoutLang, splitTopLevel, stripComments };
|
|
465
|
+
//# sourceMappingURL=chunk-S5MDTHH7.js.map
|
|
466
|
+
//# sourceMappingURL=chunk-S5MDTHH7.js.map
|