@rangojs/router 0.0.0-experimental.49 → 0.0.0-experimental.4fba1c4c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -43
- package/dist/bin/rango.js +269 -96
- package/dist/testing/vitest.js +48 -0
- package/dist/vite/index.js +2659 -883
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +57 -11
- package/skills/breadcrumbs/SKILL.md +3 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +243 -21
- package/skills/caching/SKILL.md +118 -2
- package/skills/composability/SKILL.md +27 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +229 -20
- package/skills/host-router/SKILL.md +45 -20
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +46 -4
- package/skills/layout/SKILL.md +28 -7
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +273 -53
- package/skills/middleware/SKILL.md +49 -12
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +71 -6
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +242 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +66 -9
- package/skills/route/SKILL.md +88 -4
- package/skills/router-setup/SKILL.md +90 -5
- package/skills/server-actions/SKILL.md +751 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/testing/SKILL.md +734 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +34 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/__internal.ts +1 -1
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +86 -70
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/navigation-bridge.ts +101 -13
- package/src/browser/navigation-client.ts +125 -53
- package/src/browser/navigation-store.ts +75 -17
- package/src/browser/navigation-transaction.ts +10 -28
- package/src/browser/partial-update.ts +90 -30
- package/src/browser/prefetch/cache.ts +129 -21
- package/src/browser/prefetch/fetch.ts +156 -18
- package/src/browser/prefetch/queue.ts +92 -29
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +53 -13
- package/src/browser/react/Link.tsx +72 -8
- package/src/browser/react/NavigationProvider.tsx +83 -33
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +51 -7
- package/src/browser/react/index.ts +3 -0
- package/src/browser/react/location-state-shared.ts +175 -4
- package/src/browser/react/location-state.ts +39 -13
- package/src/browser/react/use-handle.ts +23 -64
- package/src/browser/react/use-navigation.ts +22 -2
- package/src/browser/react/use-params.ts +20 -8
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +43 -10
- package/src/browser/react/use-segments.ts +11 -8
- package/src/browser/response-adapter.ts +25 -0
- package/src/browser/rsc-router.tsx +87 -22
- package/src/browser/scroll-restoration.ts +29 -19
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +31 -36
- package/src/browser/types.ts +48 -5
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +2 -0
- package/src/build/route-trie.ts +52 -25
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +266 -86
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-scope.ts +74 -47
- package/src/cache/cf/cf-cache-store.ts +54 -13
- package/src/cache/taint.ts +55 -0
- package/src/client.rsc.tsx +3 -0
- package/src/client.tsx +94 -238
- package/src/context-var.ts +72 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/errors.ts +30 -1
- package/src/handle.ts +65 -12
- package/src/host/index.ts +2 -2
- package/src/host/router.ts +129 -57
- package/src/host/types.ts +31 -2
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +140 -20
- package/src/index.rsc.ts +12 -5
- package/src/index.ts +61 -11
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +21 -6
- package/src/loader.ts +3 -10
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/prerender/store.ts +5 -4
- package/src/prerender.ts +141 -80
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/route-content-wrapper.tsx +6 -28
- package/src/route-definition/dsl-helpers.ts +411 -261
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +110 -34
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +9 -1
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +113 -1
- package/src/router/error-handling.ts +1 -1
- package/src/router/handler-context.ts +77 -38
- package/src/router/intercept-resolution.ts +13 -22
- package/src/router/lazy-includes.ts +8 -8
- package/src/router/loader-resolution.ts +174 -22
- package/src/router/manifest.ts +22 -13
- package/src/router/match-api.ts +128 -192
- package/src/router/match-handlers.ts +63 -20
- package/src/router/match-middleware/cache-lookup.ts +70 -97
- package/src/router/match-middleware/cache-store.ts +8 -2
- package/src/router/match-middleware/segment-resolution.ts +53 -0
- package/src/router/match-result.ts +103 -4
- package/src/router/metrics.ts +1 -1
- package/src/router/middleware-types.ts +21 -34
- package/src/router/middleware.ts +101 -89
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +101 -17
- package/src/router/prerender-match.ts +110 -10
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +286 -0
- package/src/router/revalidation.ts +58 -2
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-interfaces.ts +77 -28
- package/src/router/router-options.ts +76 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +105 -13
- package/src/router/segment-resolution/helpers.ts +29 -24
- package/src/router/segment-resolution/revalidation.ts +236 -112
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry.ts +99 -0
- package/src/router/trie-matching.ts +18 -13
- package/src/router/types.ts +9 -0
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +86 -22
- package/src/rsc/handler-context.ts +2 -2
- package/src/rsc/handler.ts +440 -381
- package/src/rsc/helpers.ts +91 -43
- package/src/rsc/index.ts +1 -1
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +5 -1
- package/src/rsc/origin-guard.ts +28 -10
- package/src/rsc/progressive-enhancement.ts +18 -2
- package/src/rsc/response-route-handler.ts +46 -53
- package/src/rsc/rsc-rendering.ts +41 -48
- package/src/rsc/runtime-warnings.ts +9 -10
- package/src/rsc/server-action.ts +25 -37
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +17 -3
- package/src/search-params.ts +4 -4
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +132 -116
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +190 -51
- package/src/server/cookie-store.ts +28 -4
- package/src/server/handle-store.ts +19 -0
- package/src/server/loader-registry.ts +9 -8
- package/src/server/request-context.ts +195 -57
- package/src/ssr/index.tsx +8 -1
- package/src/static-handler.ts +19 -7
- package/src/testing/cache-status.ts +166 -0
- package/src/testing/collect-handle.ts +63 -0
- package/src/testing/dispatch.ts +440 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +154 -0
- package/src/testing/e2e/index.ts +149 -0
- package/src/testing/e2e/matchers.ts +51 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +306 -0
- package/src/testing/e2e/server.ts +183 -0
- package/src/testing/flight-matchers.ts +104 -0
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/flight.entry.ts +22 -0
- package/src/testing/flight.ts +182 -0
- package/src/testing/generated-routes.ts +223 -0
- package/src/testing/index.ts +106 -0
- package/src/testing/internal/context.ts +304 -0
- package/src/testing/render-route.tsx +565 -0
- package/src/testing/run-loader.ts +341 -0
- package/src/testing/run-middleware.ts +179 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +183 -0
- package/src/types/cache-types.ts +4 -4
- package/src/types/global-namespace.ts +39 -26
- package/src/types/handler-context.ts +103 -67
- package/src/types/index.ts +1 -0
- package/src/types/loader-types.ts +41 -15
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-entry.ts +12 -1
- package/src/types/segments.ts +36 -2
- package/src/urls/include-helper.ts +34 -67
- package/src/urls/index.ts +0 -3
- package/src/urls/path-helper-types.ts +50 -9
- package/src/urls/path-helper.ts +63 -63
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +26 -116
- package/src/urls/urls-function.ts +1 -5
- package/src/use-loader.tsx +487 -44
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +34 -37
- package/src/vite/discovery/discover-routers.ts +105 -51
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +188 -93
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +46 -4
- package/src/vite/discovery/virtual-module-codegen.ts +13 -23
- package/src/vite/index.ts +6 -0
- package/src/vite/plugin-types.ts +126 -4
- package/src/vite/plugins/cjs-to-esm.ts +8 -7
- package/src/vite/plugins/client-ref-dedup.ts +16 -0
- package/src/vite/plugins/client-ref-hashing.ts +28 -5
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/plugins/expose-action-id.ts +54 -30
- package/src/vite/plugins/expose-id-utils.ts +24 -8
- package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
- package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
- package/src/vite/plugins/expose-internal-ids.ts +544 -317
- package/src/vite/plugins/performance-tracks.ts +92 -0
- package/src/vite/plugins/refresh-cmd.ts +88 -26
- package/src/vite/plugins/use-cache-transform.ts +65 -50
- package/src/vite/plugins/version-injector.ts +39 -23
- package/src/vite/plugins/version-plugin.ts +59 -2
- package/src/vite/plugins/virtual-entries.ts +2 -2
- package/src/vite/rango.ts +130 -26
- package/src/vite/router-discovery.ts +920 -129
- package/src/vite/utils/ast-handler-extract.ts +15 -15
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +4 -2
- package/src/vite/utils/client-chunks.ts +190 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +21 -5
- package/src/vite/utils/package-resolution.ts +41 -1
- package/src/vite/utils/prerender-utils.ts +38 -5
- package/src/vite/utils/shared-utils.ts +109 -27
- package/src/browser/action-response-classifier.ts +0 -99
package/dist/bin/rango.js
CHANGED
|
@@ -139,7 +139,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
139
139
|
const valid = routes.filter(({ name }) => {
|
|
140
140
|
if (!name || /["'\\`\n\r]/.test(name)) {
|
|
141
141
|
console.warn(
|
|
142
|
-
`[
|
|
142
|
+
`[rango] Skipping route with invalid name: ${JSON.stringify(name)}`
|
|
143
143
|
);
|
|
144
144
|
return false;
|
|
145
145
|
}
|
|
@@ -149,7 +149,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
149
149
|
for (const { name, pattern, params, search } of valid) {
|
|
150
150
|
if (deduped.has(name)) {
|
|
151
151
|
console.warn(
|
|
152
|
-
`[
|
|
152
|
+
`[rango] Duplicate route name "${name}" \u2014 keeping first definition`
|
|
153
153
|
);
|
|
154
154
|
continue;
|
|
155
155
|
}
|
|
@@ -186,7 +186,7 @@ ${objectBody}
|
|
|
186
186
|
} as const;
|
|
187
187
|
|
|
188
188
|
declare global {
|
|
189
|
-
namespace
|
|
189
|
+
namespace Rango {
|
|
190
190
|
interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
|
|
191
191
|
}
|
|
192
192
|
}
|
|
@@ -211,14 +211,15 @@ function findTsFiles(dir, filter) {
|
|
|
211
211
|
entries = readdirSync(dir, { withFileTypes: true });
|
|
212
212
|
} catch (err) {
|
|
213
213
|
console.warn(
|
|
214
|
-
`[
|
|
214
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
215
215
|
);
|
|
216
216
|
return results;
|
|
217
217
|
}
|
|
218
218
|
for (const entry of entries) {
|
|
219
219
|
const fullPath = join(dir, entry.name);
|
|
220
220
|
if (entry.isDirectory()) {
|
|
221
|
-
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
221
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".") || entry.name === "dist" || entry.name === "build" || entry.name === "coverage")
|
|
222
|
+
continue;
|
|
222
223
|
results.push(...findTsFiles(fullPath, filter));
|
|
223
224
|
} else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".tsx") || entry.name.endsWith(".js") || entry.name.endsWith(".jsx")) && !entry.name.includes(".gen.")) {
|
|
224
225
|
if (filter && !filter(fullPath)) continue;
|
|
@@ -450,12 +451,12 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
450
451
|
}
|
|
451
452
|
return routeMap;
|
|
452
453
|
}
|
|
453
|
-
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut) {
|
|
454
|
+
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock) {
|
|
454
455
|
visited = visited ?? /* @__PURE__ */ new Set();
|
|
455
456
|
const realPath = resolve(filePath);
|
|
456
457
|
const key = variableName ? `${realPath}:${variableName}` : realPath;
|
|
457
458
|
if (visited.has(key)) {
|
|
458
|
-
console.warn(`[
|
|
459
|
+
console.warn(`[rango] Circular include detected, skipping: ${key}`);
|
|
459
460
|
return { routes: {}, searchSchemas: {} };
|
|
460
461
|
}
|
|
461
462
|
visited.add(key);
|
|
@@ -466,7 +467,9 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
466
467
|
return { routes: {}, searchSchemas: {} };
|
|
467
468
|
}
|
|
468
469
|
let block;
|
|
469
|
-
if (
|
|
470
|
+
if (inlineBlock) {
|
|
471
|
+
block = inlineBlock;
|
|
472
|
+
} else if (variableName) {
|
|
470
473
|
const extracted = extractUrlsBlockForVariable(source, variableName);
|
|
471
474
|
if (!extracted) return { routes: {}, searchSchemas: {} };
|
|
472
475
|
block = extracted;
|
|
@@ -540,12 +543,12 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
540
543
|
} else {
|
|
541
544
|
routes = extractRoutesFromSource(source);
|
|
542
545
|
}
|
|
543
|
-
const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
|
|
546
|
+
const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
|
|
544
547
|
if (routes.length === 0) {
|
|
545
548
|
if (varNames.length > 0 && !existsSync2(genPath)) {
|
|
546
549
|
writeFileSync(genPath, generatePerModuleTypesSource([]));
|
|
547
550
|
console.log(
|
|
548
|
-
`[
|
|
551
|
+
`[rango] Generated route types (placeholder) -> ${genPath}`
|
|
549
552
|
);
|
|
550
553
|
}
|
|
551
554
|
return;
|
|
@@ -554,11 +557,11 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
554
557
|
const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
|
|
555
558
|
if (existing !== genSource) {
|
|
556
559
|
writeFileSync(genPath, genSource);
|
|
557
|
-
console.log(`[
|
|
560
|
+
console.log(`[rango] Generated route types -> ${genPath}`);
|
|
558
561
|
}
|
|
559
562
|
} catch (err) {
|
|
560
563
|
console.warn(
|
|
561
|
-
`[
|
|
564
|
+
`[rango] Failed to generate route types for ${filePath}: ${err.message}`
|
|
562
565
|
);
|
|
563
566
|
}
|
|
564
567
|
}
|
|
@@ -573,6 +576,75 @@ var init_per_module_writer = __esm({
|
|
|
573
576
|
}
|
|
574
577
|
});
|
|
575
578
|
|
|
579
|
+
// src/build/route-types/source-scan.ts
|
|
580
|
+
function isLineTerminator(ch) {
|
|
581
|
+
const c = ch.charCodeAt(0);
|
|
582
|
+
return c === 10 || c === 13 || c === 8232 || c === 8233;
|
|
583
|
+
}
|
|
584
|
+
function makeCodeClassifier(code) {
|
|
585
|
+
const n = code.length;
|
|
586
|
+
let i = 0;
|
|
587
|
+
let skipStart = -1;
|
|
588
|
+
let skipEnd = -1;
|
|
589
|
+
return (q) => {
|
|
590
|
+
if (q >= skipStart && q < skipEnd) return false;
|
|
591
|
+
while (i < n && i <= q) {
|
|
592
|
+
const c = code[i];
|
|
593
|
+
const d = i + 1 < n ? code[i + 1] : "";
|
|
594
|
+
let end = -1;
|
|
595
|
+
if (c === "/" && d === "/") {
|
|
596
|
+
let j = i + 2;
|
|
597
|
+
while (j < n && !isLineTerminator(code[j])) j++;
|
|
598
|
+
end = j;
|
|
599
|
+
} else if (c === "/" && d === "*") {
|
|
600
|
+
let j = i + 2;
|
|
601
|
+
while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
|
|
602
|
+
end = Math.min(n, j + 2);
|
|
603
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
604
|
+
let j = i + 1;
|
|
605
|
+
while (j < n) {
|
|
606
|
+
if (code[j] === "\\") {
|
|
607
|
+
j += 2;
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
if (code[j] === c) {
|
|
611
|
+
j++;
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
j++;
|
|
615
|
+
}
|
|
616
|
+
end = j;
|
|
617
|
+
}
|
|
618
|
+
if (end >= 0) {
|
|
619
|
+
if (q < end) {
|
|
620
|
+
skipStart = i;
|
|
621
|
+
skipEnd = end;
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
i = end;
|
|
625
|
+
} else {
|
|
626
|
+
i++;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return true;
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function firstCodeMatchIndex(code, pattern) {
|
|
633
|
+
const inCode = makeCodeClassifier(code);
|
|
634
|
+
pattern.lastIndex = 0;
|
|
635
|
+
let m;
|
|
636
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
637
|
+
if (inCode(m.index)) return m.index;
|
|
638
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
639
|
+
}
|
|
640
|
+
return -1;
|
|
641
|
+
}
|
|
642
|
+
var init_source_scan = __esm({
|
|
643
|
+
"src/build/route-types/source-scan.ts"() {
|
|
644
|
+
"use strict";
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
|
|
576
648
|
// src/build/route-types/router-processing.ts
|
|
577
649
|
import {
|
|
578
650
|
readFileSync as readFileSync3,
|
|
@@ -609,7 +681,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
609
681
|
entries = readdirSync2(dir, { withFileTypes: true });
|
|
610
682
|
} catch (err) {
|
|
611
683
|
console.warn(
|
|
612
|
-
`[
|
|
684
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
613
685
|
);
|
|
614
686
|
return;
|
|
615
687
|
}
|
|
@@ -627,7 +699,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
627
699
|
if (filter && !filter(fullPath)) continue;
|
|
628
700
|
try {
|
|
629
701
|
const source = readFileSync3(fullPath, "utf-8");
|
|
630
|
-
if (ROUTER_CALL_PATTERN.test(source)) {
|
|
702
|
+
if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
|
|
631
703
|
routerFilesInDir.push(fullPath);
|
|
632
704
|
}
|
|
633
705
|
} catch {
|
|
@@ -665,13 +737,13 @@ function findNestedRouterConflict(routerFiles) {
|
|
|
665
737
|
}
|
|
666
738
|
return null;
|
|
667
739
|
}
|
|
668
|
-
function formatNestedRouterConflictError(conflict, prefix = "[
|
|
740
|
+
function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
|
|
669
741
|
return `${prefix} Nested router roots are not supported.
|
|
670
742
|
Router root: ${conflict.ancestor}
|
|
671
743
|
Nested router: ${conflict.nested}
|
|
672
744
|
Move the nested router into a sibling directory or configure it as a separate app root.`;
|
|
673
745
|
}
|
|
674
|
-
function
|
|
746
|
+
function extractUrlsFromRouter(code) {
|
|
675
747
|
const sourceFile = ts5.createSourceFile(
|
|
676
748
|
"router.tsx",
|
|
677
749
|
code,
|
|
@@ -685,24 +757,70 @@ function extractUrlsVariableFromRouter(code) {
|
|
|
685
757
|
const callee = node.expression;
|
|
686
758
|
return ts5.isIdentifier(callee) && callee.text === "createRouter";
|
|
687
759
|
}
|
|
760
|
+
function isInlineBuilder(node) {
|
|
761
|
+
return ts5.isArrowFunction(node) || ts5.isFunctionExpression(node);
|
|
762
|
+
}
|
|
763
|
+
function isRoutesOnCreateRouter(node) {
|
|
764
|
+
if (!ts5.isPropertyAccessExpression(node.expression) || node.expression.name.text !== "routes")
|
|
765
|
+
return false;
|
|
766
|
+
let inner = node.expression.expression;
|
|
767
|
+
while (ts5.isCallExpression(inner) && ts5.isPropertyAccessExpression(inner.expression)) {
|
|
768
|
+
inner = inner.expression.expression;
|
|
769
|
+
}
|
|
770
|
+
return isCreateRouterCall(inner);
|
|
771
|
+
}
|
|
688
772
|
function visit(node) {
|
|
689
773
|
if (result) return;
|
|
690
|
-
if (ts5.isCallExpression(node) &&
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
result = node.arguments[0].text;
|
|
697
|
-
return;
|
|
774
|
+
if (ts5.isCallExpression(node) && node.arguments.length >= 1 && isRoutesOnCreateRouter(node)) {
|
|
775
|
+
const arg = node.arguments[0];
|
|
776
|
+
if (ts5.isIdentifier(arg)) {
|
|
777
|
+
result = { kind: "variable", name: arg.text };
|
|
778
|
+
} else if (isInlineBuilder(arg)) {
|
|
779
|
+
result = { kind: "inline", block: arg.getText(sourceFile) };
|
|
698
780
|
}
|
|
781
|
+
return;
|
|
699
782
|
}
|
|
700
783
|
if (isCreateRouterCall(node)) {
|
|
701
784
|
const callExpr = node;
|
|
702
|
-
for (const
|
|
785
|
+
for (const callArg of callExpr.arguments) {
|
|
786
|
+
if (ts5.isObjectLiteralExpression(callArg)) {
|
|
787
|
+
for (const prop of callArg.properties) {
|
|
788
|
+
if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "urls") {
|
|
789
|
+
if (ts5.isIdentifier(prop.initializer)) {
|
|
790
|
+
result = { kind: "variable", name: prop.initializer.text };
|
|
791
|
+
} else if (isInlineBuilder(prop.initializer)) {
|
|
792
|
+
result = {
|
|
793
|
+
kind: "inline",
|
|
794
|
+
block: prop.initializer.getText(sourceFile)
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
ts5.forEachChild(node, visit);
|
|
804
|
+
}
|
|
805
|
+
visit(sourceFile);
|
|
806
|
+
return result;
|
|
807
|
+
}
|
|
808
|
+
function extractBasenameFromRouter(code) {
|
|
809
|
+
const sourceFile = ts5.createSourceFile(
|
|
810
|
+
"router.tsx",
|
|
811
|
+
code,
|
|
812
|
+
ts5.ScriptTarget.Latest,
|
|
813
|
+
true,
|
|
814
|
+
ts5.ScriptKind.TSX
|
|
815
|
+
);
|
|
816
|
+
let result;
|
|
817
|
+
function visit(node) {
|
|
818
|
+
if (result !== void 0) return;
|
|
819
|
+
if (ts5.isCallExpression(node) && ts5.isIdentifier(node.expression) && node.expression.text === "createRouter") {
|
|
820
|
+
for (const arg of node.arguments) {
|
|
703
821
|
if (ts5.isObjectLiteralExpression(arg)) {
|
|
704
822
|
for (const prop of arg.properties) {
|
|
705
|
-
if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "
|
|
823
|
+
if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "basename" && ts5.isStringLiteral(prop.initializer)) {
|
|
706
824
|
result = prop.initializer.text;
|
|
707
825
|
return;
|
|
708
826
|
}
|
|
@@ -715,6 +833,38 @@ function extractUrlsVariableFromRouter(code) {
|
|
|
715
833
|
visit(sourceFile);
|
|
716
834
|
return result;
|
|
717
835
|
}
|
|
836
|
+
function applyBasenameToRoutes(result, basename) {
|
|
837
|
+
const prefixed = {};
|
|
838
|
+
for (const [name, pattern] of Object.entries(result.routes)) {
|
|
839
|
+
if (pattern === "/") {
|
|
840
|
+
prefixed[name] = basename;
|
|
841
|
+
} else if (basename.endsWith("/") && pattern.startsWith("/")) {
|
|
842
|
+
prefixed[name] = basename + pattern.slice(1);
|
|
843
|
+
} else {
|
|
844
|
+
prefixed[name] = basename + pattern;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return { routes: prefixed, searchSchemas: result.searchSchemas };
|
|
848
|
+
}
|
|
849
|
+
function genFileTsPath(sourceFile) {
|
|
850
|
+
const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
851
|
+
return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
|
|
852
|
+
}
|
|
853
|
+
function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
|
|
854
|
+
if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
|
|
855
|
+
return runtimeSchemas;
|
|
856
|
+
}
|
|
857
|
+
const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
|
|
858
|
+
if (Object.keys(staticParsed.searchSchemas).length === 0) {
|
|
859
|
+
return runtimeSchemas;
|
|
860
|
+
}
|
|
861
|
+
const filtered = {};
|
|
862
|
+
for (const name of publicRouteNames) {
|
|
863
|
+
const schema = staticParsed.searchSchemas[name];
|
|
864
|
+
if (schema) filtered[name] = schema;
|
|
865
|
+
}
|
|
866
|
+
return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
|
|
867
|
+
}
|
|
718
868
|
function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
719
869
|
let routerSource;
|
|
720
870
|
try {
|
|
@@ -722,19 +872,40 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
722
872
|
} catch {
|
|
723
873
|
return { routes: {}, searchSchemas: {} };
|
|
724
874
|
}
|
|
725
|
-
const
|
|
726
|
-
if (!
|
|
875
|
+
const extraction = extractUrlsFromRouter(routerSource);
|
|
876
|
+
if (!extraction) {
|
|
727
877
|
return { routes: {}, searchSchemas: {} };
|
|
728
878
|
}
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
879
|
+
const rawBasename = extractBasenameFromRouter(routerSource);
|
|
880
|
+
const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
|
|
881
|
+
let result;
|
|
882
|
+
if (extraction.kind === "inline") {
|
|
883
|
+
result = buildCombinedRouteMapWithSearch(
|
|
884
|
+
routerFilePath,
|
|
885
|
+
void 0,
|
|
886
|
+
void 0,
|
|
887
|
+
void 0,
|
|
888
|
+
extraction.block
|
|
889
|
+
);
|
|
890
|
+
} else {
|
|
891
|
+
const imported = resolveImportedVariable(routerSource, extraction.name);
|
|
892
|
+
if (imported) {
|
|
893
|
+
const targetFile = resolveImportPath(imported.specifier, routerFilePath);
|
|
894
|
+
if (!targetFile) {
|
|
895
|
+
return { routes: {}, searchSchemas: {} };
|
|
896
|
+
}
|
|
897
|
+
result = buildCombinedRouteMapWithSearch(
|
|
898
|
+
targetFile,
|
|
899
|
+
imported.exportedName
|
|
900
|
+
);
|
|
901
|
+
} else {
|
|
902
|
+
result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
|
|
734
903
|
}
|
|
735
|
-
return buildCombinedRouteMapWithSearch(targetFile, imported.exportedName);
|
|
736
904
|
}
|
|
737
|
-
|
|
905
|
+
if (basename) {
|
|
906
|
+
result = applyBasenameToRoutes(result, basename);
|
|
907
|
+
}
|
|
908
|
+
return result;
|
|
738
909
|
}
|
|
739
910
|
function detectUnresolvableIncludes(routerFilePath) {
|
|
740
911
|
const realPath = resolve2(routerFilePath);
|
|
@@ -744,9 +915,20 @@ function detectUnresolvableIncludes(routerFilePath) {
|
|
|
744
915
|
} catch {
|
|
745
916
|
return [];
|
|
746
917
|
}
|
|
747
|
-
const
|
|
748
|
-
if (!
|
|
749
|
-
const
|
|
918
|
+
const extraction = extractUrlsFromRouter(source);
|
|
919
|
+
if (!extraction) return [];
|
|
920
|
+
const diagnostics = [];
|
|
921
|
+
if (extraction.kind === "inline") {
|
|
922
|
+
buildCombinedRouteMapWithSearch(
|
|
923
|
+
realPath,
|
|
924
|
+
void 0,
|
|
925
|
+
/* @__PURE__ */ new Set(),
|
|
926
|
+
diagnostics,
|
|
927
|
+
extraction.block
|
|
928
|
+
);
|
|
929
|
+
return diagnostics;
|
|
930
|
+
}
|
|
931
|
+
const imported = resolveImportedVariable(source, extraction.name);
|
|
750
932
|
let targetFile;
|
|
751
933
|
let exportedName;
|
|
752
934
|
if (imported) {
|
|
@@ -766,9 +948,8 @@ function detectUnresolvableIncludes(routerFilePath) {
|
|
|
766
948
|
exportedName = imported.exportedName;
|
|
767
949
|
} else {
|
|
768
950
|
targetFile = realPath;
|
|
769
|
-
exportedName =
|
|
951
|
+
exportedName = extraction.name;
|
|
770
952
|
}
|
|
771
|
-
const diagnostics = [];
|
|
772
953
|
buildCombinedRouteMapWithSearch(
|
|
773
954
|
targetFile,
|
|
774
955
|
exportedName,
|
|
@@ -804,7 +985,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
804
985
|
if (existsSync3(oldCombinedPath)) {
|
|
805
986
|
unlinkSync(oldCombinedPath);
|
|
806
987
|
console.log(
|
|
807
|
-
`[
|
|
988
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
808
989
|
);
|
|
809
990
|
}
|
|
810
991
|
} catch {
|
|
@@ -816,38 +997,22 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
816
997
|
throw new Error(formatNestedRouterConflictError(nestedRouterConflict));
|
|
817
998
|
}
|
|
818
999
|
for (const routerFilePath of routerFilePaths) {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
routerSource
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const imported = resolveImportedVariable(routerSource, urlsVarName);
|
|
829
|
-
if (imported) {
|
|
830
|
-
const targetFile = resolveImportPath(imported.specifier, routerFilePath);
|
|
831
|
-
if (!targetFile) continue;
|
|
832
|
-
result = buildCombinedRouteMapWithSearch(
|
|
833
|
-
targetFile,
|
|
834
|
-
imported.exportedName
|
|
835
|
-
);
|
|
836
|
-
} else {
|
|
837
|
-
result = buildCombinedRouteMapWithSearch(routerFilePath, urlsVarName);
|
|
1000
|
+
const result = buildCombinedRouteMapForRouterFile(routerFilePath);
|
|
1001
|
+
if (Object.keys(result.routes).length === 0 && Object.keys(result.searchSchemas).length === 0) {
|
|
1002
|
+
let routerSource;
|
|
1003
|
+
try {
|
|
1004
|
+
routerSource = readFileSync3(routerFilePath, "utf-8");
|
|
1005
|
+
} catch {
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
if (!extractUrlsFromRouter(routerSource)) continue;
|
|
838
1009
|
}
|
|
839
|
-
const
|
|
840
|
-
/\.(tsx?|jsx?)$/,
|
|
841
|
-
""
|
|
842
|
-
);
|
|
843
|
-
const outPath = join2(
|
|
844
|
-
dirname2(routerFilePath),
|
|
845
|
-
`${routerBasename}.named-routes.gen.ts`
|
|
846
|
-
);
|
|
1010
|
+
const outPath = genFileTsPath(routerFilePath);
|
|
847
1011
|
const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
|
|
848
1012
|
if (Object.keys(result.routes).length === 0) {
|
|
849
1013
|
if (!existing) {
|
|
850
1014
|
const emptySource = generateRouteTypesSource({});
|
|
1015
|
+
opts?.onWrite?.(outPath, emptySource);
|
|
851
1016
|
writeFileSync2(outPath, emptySource);
|
|
852
1017
|
}
|
|
853
1018
|
continue;
|
|
@@ -867,22 +1032,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
867
1032
|
continue;
|
|
868
1033
|
}
|
|
869
1034
|
}
|
|
1035
|
+
opts?.onWrite?.(outPath, source);
|
|
870
1036
|
writeFileSync2(outPath, source);
|
|
871
1037
|
console.log(
|
|
872
|
-
`[
|
|
1038
|
+
`[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
|
|
873
1039
|
);
|
|
874
1040
|
}
|
|
875
1041
|
}
|
|
876
1042
|
}
|
|
877
|
-
var ROUTER_CALL_PATTERN;
|
|
1043
|
+
var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
|
|
878
1044
|
var init_router_processing = __esm({
|
|
879
1045
|
"src/build/route-types/router-processing.ts"() {
|
|
880
1046
|
"use strict";
|
|
881
1047
|
init_codegen();
|
|
1048
|
+
init_source_scan();
|
|
882
1049
|
init_include_resolution();
|
|
883
1050
|
init_per_module_writer();
|
|
884
1051
|
init_route_name();
|
|
885
1052
|
ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
|
|
1053
|
+
ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
|
|
886
1054
|
}
|
|
887
1055
|
});
|
|
888
1056
|
|
|
@@ -920,7 +1088,7 @@ import {
|
|
|
920
1088
|
import { createElement, StrictMode } from "react";
|
|
921
1089
|
import { hydrateRoot } from "react-dom/client";
|
|
922
1090
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
923
|
-
import { initBrowserApp,
|
|
1091
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
924
1092
|
|
|
925
1093
|
async function initializeApp() {
|
|
926
1094
|
const deps = {
|
|
@@ -935,7 +1103,7 @@ async function initializeApp() {
|
|
|
935
1103
|
|
|
936
1104
|
hydrateRoot(
|
|
937
1105
|
document,
|
|
938
|
-
createElement(StrictMode, null, createElement(
|
|
1106
|
+
createElement(StrictMode, null, createElement(Rango))
|
|
939
1107
|
);
|
|
940
1108
|
}
|
|
941
1109
|
|
|
@@ -967,7 +1135,8 @@ export const renderHTML = createSSRHandler({
|
|
|
967
1135
|
// src/vite/plugins/version-plugin.ts
|
|
968
1136
|
var version_plugin_exports = {};
|
|
969
1137
|
__export(version_plugin_exports, {
|
|
970
|
-
createVersionPlugin: () => createVersionPlugin
|
|
1138
|
+
createVersionPlugin: () => createVersionPlugin,
|
|
1139
|
+
isViteDepCachePath: () => isViteDepCachePath
|
|
971
1140
|
});
|
|
972
1141
|
import { parseAst } from "vite";
|
|
973
1142
|
function isCodeModule(id) {
|
|
@@ -979,7 +1148,7 @@ function normalizeModuleId(id) {
|
|
|
979
1148
|
function getClientModuleSignature(source) {
|
|
980
1149
|
let program;
|
|
981
1150
|
try {
|
|
982
|
-
program = parseAst(source, {
|
|
1151
|
+
program = parseAst(source, { lang: "tsx" });
|
|
983
1152
|
} catch {
|
|
984
1153
|
return void 0;
|
|
985
1154
|
}
|
|
@@ -1062,11 +1231,12 @@ function createVersionPlugin() {
|
|
|
1062
1231
|
let currentVersion = buildVersion;
|
|
1063
1232
|
let isDev = false;
|
|
1064
1233
|
let server = null;
|
|
1234
|
+
let resolvedCacheDir;
|
|
1065
1235
|
const clientModuleSignatures = /* @__PURE__ */ new Map();
|
|
1066
1236
|
let versionCounter = 0;
|
|
1067
1237
|
const bumpVersion = (reason) => {
|
|
1068
1238
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
1069
|
-
console.log(`[
|
|
1239
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
1070
1240
|
const rscEnv = server?.environments?.rsc;
|
|
1071
1241
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
1072
1242
|
"\0" + VIRTUAL_IDS.version
|
|
@@ -1080,6 +1250,7 @@ function createVersionPlugin() {
|
|
|
1080
1250
|
enforce: "pre",
|
|
1081
1251
|
configResolved(config) {
|
|
1082
1252
|
isDev = config.command === "serve";
|
|
1253
|
+
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
1083
1254
|
},
|
|
1084
1255
|
configureServer(devServer) {
|
|
1085
1256
|
server = devServer;
|
|
@@ -1121,6 +1292,7 @@ function createVersionPlugin() {
|
|
|
1121
1292
|
if (!isDev) return;
|
|
1122
1293
|
const isRscModule = this.environment?.name === "rsc";
|
|
1123
1294
|
if (!isRscModule) return;
|
|
1295
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
1124
1296
|
if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
|
|
1125
1297
|
return;
|
|
1126
1298
|
}
|
|
@@ -1150,6 +1322,17 @@ function createVersionPlugin() {
|
|
|
1150
1322
|
}
|
|
1151
1323
|
};
|
|
1152
1324
|
}
|
|
1325
|
+
function isViteDepCachePath(filePath, cacheDir) {
|
|
1326
|
+
if (!filePath) return false;
|
|
1327
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
1328
|
+
if (cacheDir) {
|
|
1329
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1330
|
+
if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
|
|
1331
|
+
return true;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
|
|
1335
|
+
}
|
|
1153
1336
|
var init_version_plugin = __esm({
|
|
1154
1337
|
"src/vite/plugins/version-plugin.ts"() {
|
|
1155
1338
|
"use strict";
|
|
@@ -1195,7 +1378,7 @@ var runtime_discovery_exports = {};
|
|
|
1195
1378
|
__export(runtime_discovery_exports, {
|
|
1196
1379
|
discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
|
|
1197
1380
|
});
|
|
1198
|
-
import {
|
|
1381
|
+
import { resolve as resolve3 } from "node:path";
|
|
1199
1382
|
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1200
1383
|
async function discoverAndWriteRouteTypes(opts) {
|
|
1201
1384
|
let createViteServer;
|
|
@@ -1305,22 +1488,12 @@ This means createRouter() stack trace parsing matched an internal frame.
|
|
|
1305
1488
|
Set an explicit \`id\` on createRouter() or check the call site.`
|
|
1306
1489
|
);
|
|
1307
1490
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
if (schema) filtered[name] = schema;
|
|
1315
|
-
}
|
|
1316
|
-
if (Object.keys(filtered).length > 0) {
|
|
1317
|
-
routeSearchSchemas = filtered;
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
const routerDir = dirname3(sourceFile);
|
|
1322
|
-
const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
1323
|
-
const outPath = join3(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
1491
|
+
routeSearchSchemas = resolveSearchSchemas(
|
|
1492
|
+
Object.keys(routeManifest),
|
|
1493
|
+
routeSearchSchemas,
|
|
1494
|
+
sourceFile
|
|
1495
|
+
);
|
|
1496
|
+
const outPath = genFileTsPath(sourceFile);
|
|
1324
1497
|
const source = generateRouteTypesSource(
|
|
1325
1498
|
routeManifest,
|
|
1326
1499
|
routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
|
|
@@ -1357,7 +1530,7 @@ var init_runtime_discovery = __esm({
|
|
|
1357
1530
|
|
|
1358
1531
|
// src/bin/rango.ts
|
|
1359
1532
|
init_generate_route_types();
|
|
1360
|
-
import { resolve as resolve4, dirname as
|
|
1533
|
+
import { resolve as resolve4, dirname as dirname3 } from "node:path";
|
|
1361
1534
|
import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
|
|
1362
1535
|
var [command, ...rawArgs] = process.argv.slice(2);
|
|
1363
1536
|
if (command === "generate") {
|
|
@@ -1428,12 +1601,12 @@ Examples:
|
|
|
1428
1601
|
);
|
|
1429
1602
|
}
|
|
1430
1603
|
function findProjectRoot(fromPath) {
|
|
1431
|
-
let dir =
|
|
1432
|
-
while (dir !==
|
|
1604
|
+
let dir = dirname3(resolve4(fromPath));
|
|
1605
|
+
while (dir !== dirname3(dir)) {
|
|
1433
1606
|
if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
|
|
1434
1607
|
return dir;
|
|
1435
1608
|
}
|
|
1436
|
-
dir =
|
|
1609
|
+
dir = dirname3(dir);
|
|
1437
1610
|
}
|
|
1438
1611
|
return process.cwd();
|
|
1439
1612
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/testing/vitest.ts
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
function here(relativeFromRoot) {
|
|
4
|
+
return fileURLToPath(new URL(`../../${relativeFromRoot}`, import.meta.url));
|
|
5
|
+
}
|
|
6
|
+
function rangoTestAliases(opts = {}) {
|
|
7
|
+
const aliases = [
|
|
8
|
+
// Real impls (index.rsc.ts) for the bare specifier ONLY — exact regex so
|
|
9
|
+
// subpaths (/testing, /client, /cache, ...) are untouched. React stays the
|
|
10
|
+
// client build, so createContext and "use client" modules work.
|
|
11
|
+
{ find: /^@rangojs\/router$/, replacement: here("src/index.rsc.ts") },
|
|
12
|
+
{
|
|
13
|
+
find: "@rangojs/router:version",
|
|
14
|
+
replacement: here("src/testing/vitest-stubs/version.ts")
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
find: /^@vitejs\/plugin-rsc\/rsc$/,
|
|
18
|
+
replacement: here("src/testing/vitest-stubs/plugin-rsc.ts")
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
|
+
if (opts.cloudflare) {
|
|
22
|
+
aliases.push(
|
|
23
|
+
{
|
|
24
|
+
find: "cloudflare:workers",
|
|
25
|
+
replacement: here("src/testing/vitest-stubs/cloudflare-workers.ts")
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
find: "cloudflare:email",
|
|
29
|
+
replacement: here("src/testing/vitest-stubs/cloudflare-email.ts")
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
return aliases;
|
|
34
|
+
}
|
|
35
|
+
var rangoInlineDeps = [/@rangojs[/\\]router/];
|
|
36
|
+
function rangoTestConfig(opts = {}) {
|
|
37
|
+
return {
|
|
38
|
+
alias: rangoTestAliases(opts),
|
|
39
|
+
// fresh copy so the shared rangoInlineDeps const is never aliased into (or
|
|
40
|
+
// mutated through) a consumer's resolved config
|
|
41
|
+
server: { deps: { inline: [...rangoInlineDeps] } }
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
rangoInlineDeps,
|
|
46
|
+
rangoTestAliases,
|
|
47
|
+
rangoTestConfig
|
|
48
|
+
};
|