@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140
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/AGENTS.md +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +426 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2500 -158
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +29 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-cache.ts +386 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +156 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1102 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +177 -35
- package/src/index.ts +255 -71
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +337 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +439 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +452 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/live.ts +130 -0
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +842 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +412 -136
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -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 +305 -0
- package/src/theme/ThemeProvider.tsx +40 -72
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +43 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +275 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- 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 +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-neutral Response shape utilities.
|
|
3
|
+
*
|
|
4
|
+
* Kept at the src/ root so both `router/` and `rsc/` can depend on it
|
|
5
|
+
* without creating a cross-layer import cycle.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* True when a Response represents a WebSocket upgrade handoff and must not
|
|
10
|
+
* be reconstructed or mutated:
|
|
11
|
+
*
|
|
12
|
+
* - Status 101 (Switching Protocols) is outside the standard Response
|
|
13
|
+
* constructor's 200–599 range, so `new Response(body, { status: 101 })`
|
|
14
|
+
* throws RangeError on Node/undici and any spec-compliant runtime.
|
|
15
|
+
* - Cloudflare's workerd attaches a non-standard `webSocket` property on
|
|
16
|
+
* the upgrade Response (e.g. from `acceptWebSocket`/`handleWebSocketUpgrade`
|
|
17
|
+
* or the `agents` library's `routeAgentRequest`). That property is dropped
|
|
18
|
+
* by a `new Response(...)` copy, breaking the upgrade even on workerd
|
|
19
|
+
* where the status range is relaxed.
|
|
20
|
+
*
|
|
21
|
+
* Callers should short-circuit header/body merges for these responses.
|
|
22
|
+
*/
|
|
23
|
+
export function isWebSocketUpgradeResponse(response: Response): boolean {
|
|
24
|
+
return (
|
|
25
|
+
response.status === 101 ||
|
|
26
|
+
(response as unknown as { webSocket?: unknown }).webSocket != null
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Append `Accept` to a response's `Vary` header without duplicating it.
|
|
32
|
+
*
|
|
33
|
+
* Content-negotiated responses already carry `Vary: Accept` from the
|
|
34
|
+
* upstream layer (response-route-handler's callHandlerWithVary, or
|
|
35
|
+
* handleRscRendering baking `accept` into its vary list). The negotiated
|
|
36
|
+
* post-append in the handler would otherwise emit `Vary: Accept, Accept`,
|
|
37
|
+
* a redundant token some proxies/CDNs treat as a distinct cache key.
|
|
38
|
+
* Token match is case-insensitive (HTTP field tokens are case-insensitive)
|
|
39
|
+
* and whitespace-tolerant.
|
|
40
|
+
*/
|
|
41
|
+
export function appendVaryAccept(response: Response): void {
|
|
42
|
+
const existing = response.headers.get("Vary");
|
|
43
|
+
if (!existing) {
|
|
44
|
+
response.headers.set("Vary", "Accept");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const hasAccept = existing
|
|
48
|
+
.split(",")
|
|
49
|
+
.some((token) => token.trim().toLowerCase() === "accept");
|
|
50
|
+
if (!hasAccept) {
|
|
51
|
+
response.headers.append("Vary", "Accept");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Location truthiness (not presence) so an empty `Location: ""` is not a redirect.
|
|
56
|
+
export function isRedirectResponse(response: Response): boolean {
|
|
57
|
+
return (
|
|
58
|
+
response.status >= 300 &&
|
|
59
|
+
response.status < 400 &&
|
|
60
|
+
Boolean(response.headers.get("Location"))
|
|
61
|
+
);
|
|
62
|
+
}
|
package/src/reverse.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtractParams } from "./types.js";
|
|
2
2
|
import type { SearchSchema, ResolveSearchSchema } from "./search-params.js";
|
|
3
3
|
import { serializeSearchParams } from "./search-params.js";
|
|
4
|
+
import { substitutePatternParams } from "./router/substitute-pattern-params.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Sanitize prefix string by removing leading slash
|
|
@@ -10,92 +11,38 @@ export type SanitizePrefix<T extends string> = T extends `/${infer P}` ? P : T;
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Helper type to merge multiple route definitions into a single accumulated type.
|
|
13
|
-
* Note: When using createRouter, types accumulate automatically through the
|
|
14
|
-
* builder chain, so this type is typically not needed.
|
|
15
14
|
*
|
|
16
15
|
* @example
|
|
17
16
|
* ```typescript
|
|
18
|
-
*
|
|
19
|
-
* type AppRoutes = MergeRoutes<[
|
|
20
|
-
* typeof homeRoutes,
|
|
21
|
-
* PrefixRoutePatterns<typeof blogRoutes, "/blog">,
|
|
22
|
-
* ]>;
|
|
23
|
-
*
|
|
24
|
-
* // Preferred: Let router accumulate types automatically
|
|
25
|
-
* const router = createRouter<AppEnv>()
|
|
26
|
-
* .routes(homeRoutes).map(...)
|
|
27
|
-
* .routes("/blog", blogRoutes).map(...);
|
|
28
|
-
* type AppRoutes = typeof router.routeMap;
|
|
17
|
+
* type AppRoutes = MergeRoutes<[typeof siteRoutes, typeof apiRoutes]>;
|
|
29
18
|
* ```
|
|
30
19
|
*/
|
|
31
20
|
export type MergeRoutes<T extends unknown[]> = T extends [
|
|
32
21
|
infer First,
|
|
33
|
-
...infer Rest
|
|
22
|
+
...infer Rest,
|
|
34
23
|
]
|
|
35
24
|
? First & MergeRoutes<Rest>
|
|
36
25
|
: {};
|
|
37
26
|
|
|
38
|
-
/**
|
|
39
|
-
* Add key prefix to all entries in a route map
|
|
40
|
-
* { "cart": "/cart" } with prefix "shop" -> { "shop.cart": "/shop/cart" }
|
|
41
|
-
*/
|
|
42
|
-
export type PrefixRouteKeys<
|
|
43
|
-
T,
|
|
44
|
-
Prefix extends string
|
|
45
|
-
> = Prefix extends ""
|
|
46
|
-
? T
|
|
47
|
-
: { [K in keyof T as `${Prefix}.${K & string}`]: T[K] };
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Add path prefix to all patterns in a route map
|
|
51
|
-
* { "cart": "/cart" } with prefix "/shop" -> { "cart": "/shop/cart" }
|
|
52
|
-
*/
|
|
53
|
-
export type PrefixRoutePatterns<
|
|
54
|
-
T,
|
|
55
|
-
PathPrefix extends string
|
|
56
|
-
> = {
|
|
57
|
-
[K in keyof T]: PathPrefix extends "" | "/"
|
|
58
|
-
? T[K]
|
|
59
|
-
: T[K] extends "/"
|
|
60
|
-
? PathPrefix
|
|
61
|
-
: T[K] extends string
|
|
62
|
-
? `${PathPrefix}${T[K]}`
|
|
63
|
-
: T[K];
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Combined: prefix both keys and patterns
|
|
68
|
-
* Used for module augmentation registration
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```typescript
|
|
72
|
-
* // Given shopRoutes = { "index": "/", "cart": "/cart", "products.detail": "/product/:slug" }
|
|
73
|
-
* // PrefixedRoutes<typeof shopRoutes, "shop"> produces:
|
|
74
|
-
* // { "shop.index": "/shop", "shop.cart": "/shop/cart", "shop.products.detail": "/shop/product/:slug" }
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export type PrefixedRoutes<
|
|
78
|
-
T,
|
|
79
|
-
KeyPrefix extends string,
|
|
80
|
-
PathPrefix extends string = KeyPrefix extends "" ? "" : `/${KeyPrefix}`
|
|
81
|
-
> = PrefixRouteKeys<PrefixRoutePatterns<T, PathPrefix>, KeyPrefix>;
|
|
82
|
-
|
|
83
27
|
/**
|
|
84
28
|
* Helper to safely extract route patterns from a routes object
|
|
85
29
|
* Handles string values, { path, response } objects, and interface types (like RegisteredRoutes)
|
|
86
30
|
*/
|
|
87
|
-
type RoutePatternFor<
|
|
88
|
-
TRoutes
|
|
89
|
-
|
|
90
|
-
|
|
31
|
+
type RoutePatternFor<
|
|
32
|
+
TRoutes,
|
|
33
|
+
TName extends keyof TRoutes,
|
|
34
|
+
> = TRoutes[TName] extends string
|
|
35
|
+
? TRoutes[TName]
|
|
36
|
+
: TRoutes[TName] extends { readonly path: infer P extends string }
|
|
37
|
+
? P
|
|
38
|
+
: string;
|
|
91
39
|
|
|
92
40
|
/**
|
|
93
41
|
* Extract params type for a route
|
|
94
42
|
*/
|
|
95
|
-
export type ParamsFor<
|
|
96
|
-
TRoutes,
|
|
97
|
-
|
|
98
|
-
> = ExtractParams<RoutePatternFor<TRoutes, TName>>;
|
|
43
|
+
export type ParamsFor<TRoutes, TName extends keyof TRoutes> = ExtractParams<
|
|
44
|
+
RoutePatternFor<TRoutes, TName>
|
|
45
|
+
>;
|
|
99
46
|
|
|
100
47
|
/**
|
|
101
48
|
* Check if an object type has any keys
|
|
@@ -106,10 +53,12 @@ type IsEmptyObject<T> = keyof T extends never ? true : false;
|
|
|
106
53
|
* Extract search schema from a route entry.
|
|
107
54
|
* Returns {} if no search schema is defined.
|
|
108
55
|
*/
|
|
109
|
-
type ExtractSearchSchema<
|
|
110
|
-
TRoutes
|
|
111
|
-
|
|
112
|
-
|
|
56
|
+
type ExtractSearchSchema<
|
|
57
|
+
TRoutes,
|
|
58
|
+
TName extends keyof TRoutes,
|
|
59
|
+
> = TRoutes[TName] extends { readonly search: infer S extends SearchSchema }
|
|
60
|
+
? S
|
|
61
|
+
: {};
|
|
113
62
|
|
|
114
63
|
/**
|
|
115
64
|
* Type-safe reverse function signature (Django-style URL reversal)
|
|
@@ -128,7 +77,11 @@ export type ReverseFunction<TRoutes> = {
|
|
|
128
77
|
* Route without params - validates route name exists
|
|
129
78
|
*/
|
|
130
79
|
<TName extends keyof TRoutes & string>(
|
|
131
|
-
name: IsEmptyObject<
|
|
80
|
+
name: IsEmptyObject<
|
|
81
|
+
ExtractParams<RoutePatternFor<TRoutes, TName>>
|
|
82
|
+
> extends true
|
|
83
|
+
? TName
|
|
84
|
+
: never,
|
|
132
85
|
): string;
|
|
133
86
|
|
|
134
87
|
/**
|
|
@@ -136,7 +89,7 @@ export type ReverseFunction<TRoutes> = {
|
|
|
136
89
|
*/
|
|
137
90
|
<TName extends keyof TRoutes & string>(
|
|
138
91
|
name: TName,
|
|
139
|
-
params: ExtractParams<RoutePatternFor<TRoutes, TName
|
|
92
|
+
params: ExtractParams<RoutePatternFor<TRoutes, TName>>,
|
|
140
93
|
): string;
|
|
141
94
|
|
|
142
95
|
/**
|
|
@@ -145,48 +98,112 @@ export type ReverseFunction<TRoutes> = {
|
|
|
145
98
|
<TName extends keyof TRoutes & string>(
|
|
146
99
|
name: TName,
|
|
147
100
|
params: ExtractParams<RoutePatternFor<TRoutes, TName>>,
|
|
148
|
-
search: ResolveSearchSchema<ExtractSearchSchema<TRoutes, TName
|
|
101
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TRoutes, TName>>,
|
|
102
|
+
): string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Dot-prefixed route without params - strictly local resolution
|
|
106
|
+
*/
|
|
107
|
+
<TName extends keyof TRoutes & string>(
|
|
108
|
+
name: IsEmptyObject<
|
|
109
|
+
ExtractParams<RoutePatternFor<TRoutes, TName>>
|
|
110
|
+
> extends true
|
|
111
|
+
? `.${TName}`
|
|
112
|
+
: never,
|
|
113
|
+
): string;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Dot-prefixed route with params - strictly local resolution
|
|
117
|
+
*/
|
|
118
|
+
<TName extends keyof TRoutes & string>(
|
|
119
|
+
name: `.${TName}`,
|
|
120
|
+
params: ExtractParams<RoutePatternFor<TRoutes, TName>>,
|
|
121
|
+
): string;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Dot-prefixed route with params and search - strictly local resolution
|
|
125
|
+
*/
|
|
126
|
+
<TName extends keyof TRoutes & string>(
|
|
127
|
+
name: `.${TName}`,
|
|
128
|
+
params: ExtractParams<RoutePatternFor<TRoutes, TName>>,
|
|
129
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TRoutes, TName>>,
|
|
149
130
|
): string;
|
|
150
131
|
};
|
|
151
132
|
|
|
152
133
|
/**
|
|
153
|
-
* Type-safe scoped reverse function
|
|
134
|
+
* Type-safe scoped reverse function with separate local and global namespaces.
|
|
154
135
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
136
|
+
* - `.name` — local resolution within the current include() scope
|
|
137
|
+
* - `name` — global resolution against the named-routes definition
|
|
157
138
|
*
|
|
158
139
|
* @example
|
|
159
140
|
* ```typescript
|
|
160
|
-
* reverse("
|
|
161
|
-
* reverse("
|
|
162
|
-
* reverse("
|
|
141
|
+
* reverse(".article", { slug: "hello" }) // ✓ Local route (resolves with mount prefix)
|
|
142
|
+
* reverse(".index") // ✓ Local route (no params)
|
|
143
|
+
* reverse("magazine.index") // ✓ Global route (fully qualified)
|
|
144
|
+
* reverse("blog.post", { slug: "hello" }) // ✓ Global route + params
|
|
145
|
+
* reverse(".typo") // ✗ Compile error (not in local routes)
|
|
146
|
+
* reverse("typo") // ✗ Compile error (not in global routes)
|
|
163
147
|
* ```
|
|
164
148
|
*/
|
|
165
|
-
export type ScopedReverseFunction<
|
|
149
|
+
export type ScopedReverseFunction<
|
|
150
|
+
TLocalRoutes,
|
|
151
|
+
TGlobalRoutes = TLocalRoutes,
|
|
152
|
+
> = {
|
|
166
153
|
/**
|
|
167
|
-
*
|
|
168
|
-
|
|
154
|
+
* Global route without params
|
|
155
|
+
*/
|
|
156
|
+
<TName extends keyof TGlobalRoutes & string>(
|
|
157
|
+
name: IsEmptyObject<
|
|
158
|
+
ExtractParams<RoutePatternFor<TGlobalRoutes, TName>>
|
|
159
|
+
> extends true
|
|
160
|
+
? TName
|
|
161
|
+
: never,
|
|
162
|
+
): string;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Global route with params
|
|
166
|
+
*/
|
|
167
|
+
<TName extends keyof TGlobalRoutes & string>(
|
|
168
|
+
name: TName,
|
|
169
|
+
params: ExtractParams<RoutePatternFor<TGlobalRoutes, TName>>,
|
|
170
|
+
): string;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Global route with params and search
|
|
174
|
+
*/
|
|
175
|
+
<TName extends keyof TGlobalRoutes & string>(
|
|
176
|
+
name: TName,
|
|
177
|
+
params: ExtractParams<RoutePatternFor<TGlobalRoutes, TName>>,
|
|
178
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TGlobalRoutes, TName>>,
|
|
179
|
+
): string;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Dot-prefixed local route without params
|
|
169
183
|
*/
|
|
170
184
|
<TName extends keyof TLocalRoutes & string>(
|
|
171
|
-
name: IsEmptyObject<
|
|
185
|
+
name: IsEmptyObject<
|
|
186
|
+
ExtractParams<RoutePatternFor<TLocalRoutes, TName>>
|
|
187
|
+
> extends true
|
|
188
|
+
? `.${TName}`
|
|
189
|
+
: never,
|
|
172
190
|
): string;
|
|
173
191
|
|
|
174
192
|
/**
|
|
175
|
-
*
|
|
176
|
-
* @recommended Use this for type-safe URL generation with parameters
|
|
193
|
+
* Dot-prefixed local route with params
|
|
177
194
|
*/
|
|
178
195
|
<TName extends keyof TLocalRoutes & string>(
|
|
179
|
-
name: TName
|
|
180
|
-
params: ExtractParams<RoutePatternFor<TLocalRoutes, TName
|
|
196
|
+
name: `.${TName}`,
|
|
197
|
+
params: ExtractParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
181
198
|
): string;
|
|
182
199
|
|
|
183
200
|
/**
|
|
184
|
-
*
|
|
201
|
+
* Dot-prefixed local route with params and search
|
|
185
202
|
*/
|
|
186
203
|
<TName extends keyof TLocalRoutes & string>(
|
|
187
|
-
name: TName
|
|
204
|
+
name: `.${TName}`,
|
|
188
205
|
params: ExtractParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
189
|
-
search: ResolveSearchSchema<ExtractSearchSchema<TLocalRoutes, TName
|
|
206
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TLocalRoutes, TName>>,
|
|
190
207
|
): string;
|
|
191
208
|
};
|
|
192
209
|
|
|
@@ -194,12 +211,74 @@ export type ScopedReverseFunction<TLocalRoutes> = {
|
|
|
194
211
|
* Extract local routes type from UrlPatterns
|
|
195
212
|
* Used with scopedReverse() to get the routes type from patterns
|
|
196
213
|
*/
|
|
197
|
-
export type ExtractLocalRoutes<TPatterns> =
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
214
|
+
export type ExtractLocalRoutes<TPatterns> = TPatterns extends {
|
|
215
|
+
readonly _routes?: infer TRoutes;
|
|
216
|
+
}
|
|
217
|
+
? TRoutes
|
|
218
|
+
: TPatterns extends Record<string, string>
|
|
219
|
+
? TPatterns
|
|
220
|
+
: Record<string, string>;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Params accepted by `useReverse(routes)`. The route's own params are
|
|
224
|
+
* required, and additional string keys are permitted so callers can
|
|
225
|
+
* override values that would otherwise be auto-filled from the matched
|
|
226
|
+
* route's `useParams()` (e.g. an enclosing `:tenantId` mount segment).
|
|
227
|
+
*/
|
|
228
|
+
export type LocalReverseParams<TPattern extends string> =
|
|
229
|
+
ExtractParams<TPattern> & {
|
|
230
|
+
readonly [extra: string]: string | undefined;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Type-safe local reverse function.
|
|
235
|
+
*
|
|
236
|
+
* Returned by `useReverse(routes)` on the client. The route map is the
|
|
237
|
+
* exposure boundary (a generated `routes` from a `urls()` module) and the
|
|
238
|
+
* scope is implicit from that import. Names may be written with or without a
|
|
239
|
+
* leading dot — `reverse("post")` and `reverse(".post")` are identical. The dot
|
|
240
|
+
* is a cosmetic readability convention (and parity with `ctx.reverse(".name")`);
|
|
241
|
+
* there is no separate global namespace here, so it carries no meaning.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const reverse = useReverse(blogRoutes);
|
|
246
|
+
* reverse("index"); // ✓ no params (dot optional)
|
|
247
|
+
* reverse(".index"); // ✓ identical to the above
|
|
248
|
+
* reverse("post", { postId: "hello" }); // ✓ with params
|
|
249
|
+
* reverse("search", {}, { q: "hi" }); // ✓ with search schema
|
|
250
|
+
* reverse("typo"); // ✗ compile error
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export type LocalReverseFunction<TLocalRoutes> = {
|
|
254
|
+
/**
|
|
255
|
+
* Route without params (leading dot optional)
|
|
256
|
+
*/
|
|
257
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
258
|
+
name: IsEmptyObject<
|
|
259
|
+
ExtractParams<RoutePatternFor<TLocalRoutes, TName>>
|
|
260
|
+
> extends true
|
|
261
|
+
? TName | `.${TName}`
|
|
262
|
+
: never,
|
|
263
|
+
): string;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Route with params (leading dot optional)
|
|
267
|
+
*/
|
|
268
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
269
|
+
name: TName | `.${TName}`,
|
|
270
|
+
params: LocalReverseParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
271
|
+
): string;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Route with params and search (leading dot optional)
|
|
275
|
+
*/
|
|
276
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
277
|
+
name: TName | `.${TName}`,
|
|
278
|
+
params: LocalReverseParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
279
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TLocalRoutes, TName>>,
|
|
280
|
+
): string;
|
|
281
|
+
};
|
|
203
282
|
|
|
204
283
|
/**
|
|
205
284
|
* Extract the response data type for a named route from a UrlPatterns instance.
|
|
@@ -210,24 +289,23 @@ export type { RouteResponse } from "./urls.js";
|
|
|
210
289
|
/**
|
|
211
290
|
* Get a locally-typed reverse function from ctx.reverse for composable modules.
|
|
212
291
|
*
|
|
213
|
-
* This is a type-only cast - ctx.reverse already resolves
|
|
214
|
-
*
|
|
215
|
-
*
|
|
292
|
+
* This is a type-only cast - ctx.reverse already resolves names at runtime.
|
|
293
|
+
* Provides type safety: `.name` validates against local routes,
|
|
294
|
+
* `name` validates against global named-routes.
|
|
216
295
|
*
|
|
217
296
|
* @param reverse - The ctx.reverse function from HandlerContext
|
|
218
|
-
* @returns The same reverse function,
|
|
297
|
+
* @returns The same reverse function, typed with local + global routes
|
|
219
298
|
*
|
|
220
299
|
* @example
|
|
221
300
|
* ```typescript
|
|
222
301
|
* // urls/blog.tsx
|
|
223
302
|
* export const blogPatterns = urls(({ path }) => [
|
|
224
303
|
* path("/", (ctx) => {
|
|
225
|
-
* // Get locally-typed reverse for this module's routes
|
|
226
304
|
* const reverse = scopedReverse<typeof blogPatterns>(ctx.reverse);
|
|
227
305
|
*
|
|
228
|
-
* reverse("index"); // ✓
|
|
229
|
-
* reverse("post", { slug: "x" }); // ✓
|
|
230
|
-
* reverse("shop.cart");
|
|
306
|
+
* reverse(".index"); // ✓ Local route
|
|
307
|
+
* reverse(".post", { slug: "x" }); // ✓ Local with params
|
|
308
|
+
* reverse("shop.cart"); // ✓ Global route
|
|
231
309
|
*
|
|
232
310
|
* return <BlogIndex />;
|
|
233
311
|
* }, { name: "index" }),
|
|
@@ -237,7 +315,7 @@ export type { RouteResponse } from "./urls.js";
|
|
|
237
315
|
* ```
|
|
238
316
|
*/
|
|
239
317
|
export function scopedReverse<TPatterns>(
|
|
240
|
-
reverse: (
|
|
318
|
+
reverse: (...args: any[]) => string,
|
|
241
319
|
): ScopedReverseFunction<ExtractLocalRoutes<TPatterns>> {
|
|
242
320
|
return reverse as ScopedReverseFunction<ExtractLocalRoutes<TPatterns>>;
|
|
243
321
|
}
|
|
@@ -258,24 +336,24 @@ export function scopedReverse<TPatterns>(
|
|
|
258
336
|
*/
|
|
259
337
|
type RouteMapEntry = string | { path: string; search?: Record<string, string> };
|
|
260
338
|
|
|
261
|
-
function resolveRoutePattern(
|
|
339
|
+
function resolveRoutePattern(
|
|
340
|
+
entry: RouteMapEntry | undefined,
|
|
341
|
+
): string | undefined {
|
|
262
342
|
if (!entry) return undefined;
|
|
263
343
|
return typeof entry === "string" ? entry : entry.path;
|
|
264
344
|
}
|
|
265
345
|
|
|
266
346
|
export function createReverse<TRoutes extends Record<string, string>>(
|
|
267
347
|
routeMap: TRoutes,
|
|
268
|
-
getFallbackMap?: () => Record<string, RouteMapEntry> | undefined,
|
|
269
348
|
): ReverseFunction<TRoutes & Record<string, string>> {
|
|
270
|
-
return ((
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
349
|
+
return ((
|
|
350
|
+
name: string,
|
|
351
|
+
params?: Record<string, string>,
|
|
352
|
+
search?: Record<string, unknown>,
|
|
353
|
+
) => {
|
|
354
|
+
const pattern = resolveRoutePattern(
|
|
355
|
+
routeMap[name] as unknown as RouteMapEntry,
|
|
356
|
+
);
|
|
279
357
|
if (!pattern) {
|
|
280
358
|
// During build-time discovery, lazy includes haven't resolved yet.
|
|
281
359
|
// Return a placeholder instead of crashing the build.
|
|
@@ -285,17 +363,9 @@ export function createReverse<TRoutes extends Record<string, string>>(
|
|
|
285
363
|
throw new Error(`Unknown route: ${name}`);
|
|
286
364
|
}
|
|
287
365
|
|
|
288
|
-
let result =
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
result = result.replace(/:([^/]+)/g, (_: string, key: string) => {
|
|
292
|
-
const value = params[key];
|
|
293
|
-
if (value === undefined) {
|
|
294
|
-
throw new Error(`Missing param "${key}" for route "${name}"`);
|
|
295
|
-
}
|
|
296
|
-
return encodeURIComponent(value);
|
|
297
|
-
});
|
|
298
|
-
}
|
|
366
|
+
let result = params
|
|
367
|
+
? substitutePatternParams(pattern, params, name)
|
|
368
|
+
: pattern;
|
|
299
369
|
|
|
300
370
|
// Append search params as query string
|
|
301
371
|
if (search) {
|