@rangojs/router 0.0.0-experimental.1878aa49 → 0.0.0-experimental.190fb30d
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 +8 -4
- package/README.md +303 -741
- package/dist/bin/rango.js +605 -146
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4117 -1211
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +86 -15
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- 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 +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +94 -18
- package/skills/layout/SKILL.md +62 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +57 -16
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +99 -10
- package/skills/ppr/SKILL.md +618 -0
- package/skills/prerender/SKILL.md +178 -124
- package/skills/rango/SKILL.md +318 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +141 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- 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 +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- 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 +1 -66
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +115 -27
- package/src/browser/navigation-client.ts +163 -70
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +186 -135
- package/src/browser/prefetch/cache.ts +246 -71
- package/src/browser/prefetch/fetch.ts +350 -38
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +70 -9
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +44 -27
- package/src/browser/segment-reconciler.ts +44 -12
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +205 -159
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +198 -41
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -101
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -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 +2206 -372
- 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 +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +116 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- 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 +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +104 -34
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +100 -13
- package/src/index.ts +143 -19
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +215 -86
- package/src/redirect-origin.ts +114 -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 +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +461 -304
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +147 -72
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +47 -22
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +85 -62
- package/src/router/loader-resolution.ts +277 -54
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +97 -57
- package/src/router/match-api.ts +178 -218
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +168 -277
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +45 -14
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +113 -45
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- 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 +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +201 -56
- package/src/router/preview-match.ts +35 -103
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +125 -35
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +188 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +155 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +308 -0
- package/src/router/segment-resolution/revalidation.ts +344 -319
- package/src/router/segment-resolution/static-store.ts +19 -5
- 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 +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +170 -72
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +678 -513
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +134 -15
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +497 -77
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +286 -114
- package/src/rsc/shell-capture.ts +1166 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +17 -1
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +54 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +355 -204
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +247 -54
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +502 -161
- package/src/ssr/index.tsx +467 -178
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +120 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +40 -10
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +136 -15
- package/src/urls/include-helper.ts +40 -75
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +102 -23
- package/src/urls/path-helper.ts +62 -111
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +346 -89
- 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 +36 -38
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- 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 +214 -132
- 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 +57 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +15 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +261 -6
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- 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/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -317
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +238 -139
- package/src/vite/router-discovery.ts +1091 -159
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- 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 +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +98 -38
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/dist/bin/rango.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
|
|
4
|
+
var __esm = (fn, res, err) => function __init() {
|
|
5
|
+
if (err) throw err[0];
|
|
6
|
+
try {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
throw err = [e], e;
|
|
10
|
+
}
|
|
6
11
|
};
|
|
7
12
|
var __export = (target, all) => {
|
|
8
13
|
for (var name in all)
|
|
@@ -22,10 +27,10 @@ function extractParamsFromPattern(pattern) {
|
|
|
22
27
|
function formatRouteEntry(key, pattern, _params, search) {
|
|
23
28
|
const hasSearch = search && Object.keys(search).length > 0;
|
|
24
29
|
if (!hasSearch) {
|
|
25
|
-
return ` ${key}:
|
|
30
|
+
return ` ${key}: ${JSON.stringify(pattern)},`;
|
|
26
31
|
}
|
|
27
|
-
const searchBody = Object.entries(search).map(([k, v]) => `${k}:
|
|
28
|
-
return ` ${key}: { path:
|
|
32
|
+
const searchBody = Object.entries(search).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
33
|
+
return ` ${key}: { path: ${JSON.stringify(pattern)}, search: { ${searchBody} } },`;
|
|
29
34
|
}
|
|
30
35
|
var init_param_extraction = __esm({
|
|
31
36
|
"src/build/route-types/param-extraction.ts"() {
|
|
@@ -59,8 +64,8 @@ var init_ast_helpers = __esm({
|
|
|
59
64
|
|
|
60
65
|
// src/build/route-types/ast-route-extraction.ts
|
|
61
66
|
import ts2 from "typescript";
|
|
62
|
-
function extractRoutesFromSource(code) {
|
|
63
|
-
const sourceFile = ts2.createSourceFile(
|
|
67
|
+
function extractRoutesFromSource(code, sourceFileArg) {
|
|
68
|
+
const sourceFile = sourceFileArg ?? ts2.createSourceFile(
|
|
64
69
|
"input.tsx",
|
|
65
70
|
code,
|
|
66
71
|
ts2.ScriptTarget.Latest,
|
|
@@ -139,7 +144,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
139
144
|
const valid = routes.filter(({ name }) => {
|
|
140
145
|
if (!name || /["'\\`\n\r]/.test(name)) {
|
|
141
146
|
console.warn(
|
|
142
|
-
`[
|
|
147
|
+
`[rango] Skipping route with invalid name: ${JSON.stringify(name)}`
|
|
143
148
|
);
|
|
144
149
|
return false;
|
|
145
150
|
}
|
|
@@ -149,7 +154,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
149
154
|
for (const { name, pattern, params, search } of valid) {
|
|
150
155
|
if (deduped.has(name)) {
|
|
151
156
|
console.warn(
|
|
152
|
-
`[
|
|
157
|
+
`[rango] Duplicate route name "${name}" \u2014 keeping first definition`
|
|
153
158
|
);
|
|
154
159
|
continue;
|
|
155
160
|
}
|
|
@@ -185,9 +190,13 @@ export const NamedRoutes = {
|
|
|
185
190
|
${objectBody}
|
|
186
191
|
} as const;
|
|
187
192
|
|
|
193
|
+
// Aliased so the augmentation below does not pay a homomorphic mapped-type
|
|
194
|
+
// instantiation per route; \`as const\` already makes the members readonly.
|
|
195
|
+
type NamedRoutesShape = typeof NamedRoutes;
|
|
196
|
+
|
|
188
197
|
declare global {
|
|
189
|
-
namespace
|
|
190
|
-
interface GeneratedRouteMap extends
|
|
198
|
+
namespace Rango {
|
|
199
|
+
interface GeneratedRouteMap extends NamedRoutesShape {}
|
|
191
200
|
}
|
|
192
201
|
}
|
|
193
202
|
`;
|
|
@@ -211,14 +220,15 @@ function findTsFiles(dir, filter) {
|
|
|
211
220
|
entries = readdirSync(dir, { withFileTypes: true });
|
|
212
221
|
} catch (err) {
|
|
213
222
|
console.warn(
|
|
214
|
-
`[
|
|
223
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
215
224
|
);
|
|
216
225
|
return results;
|
|
217
226
|
}
|
|
218
227
|
for (const entry of entries) {
|
|
219
228
|
const fullPath = join(dir, entry.name);
|
|
220
229
|
if (entry.isDirectory()) {
|
|
221
|
-
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
230
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".") || entry.name === "dist" || entry.name === "build" || entry.name === "coverage")
|
|
231
|
+
continue;
|
|
222
232
|
results.push(...findTsFiles(fullPath, filter));
|
|
223
233
|
} else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".tsx") || entry.name.endsWith(".js") || entry.name.endsWith(".jsx")) && !entry.name.includes(".gen.")) {
|
|
224
234
|
if (filter && !filter(fullPath)) continue;
|
|
@@ -237,6 +247,33 @@ var init_scan_filter = __esm({
|
|
|
237
247
|
import { readFileSync, existsSync } from "node:fs";
|
|
238
248
|
import { dirname, resolve } from "node:path";
|
|
239
249
|
import ts3 from "typescript";
|
|
250
|
+
function createScanMemo() {
|
|
251
|
+
return { files: /* @__PURE__ */ new Map(), blockSourceFiles: /* @__PURE__ */ new Map() };
|
|
252
|
+
}
|
|
253
|
+
function parseBlock(memo, block) {
|
|
254
|
+
if (memo) {
|
|
255
|
+
const cached = memo.blockSourceFiles.get(block);
|
|
256
|
+
if (cached) return cached;
|
|
257
|
+
}
|
|
258
|
+
const sf = ts3.createSourceFile(
|
|
259
|
+
"input.tsx",
|
|
260
|
+
block,
|
|
261
|
+
ts3.ScriptTarget.Latest,
|
|
262
|
+
true,
|
|
263
|
+
ts3.ScriptKind.TSX
|
|
264
|
+
);
|
|
265
|
+
if (memo) memo.blockSourceFiles.set(block, sf);
|
|
266
|
+
return sf;
|
|
267
|
+
}
|
|
268
|
+
function readSourceMemoized(memo, realPath) {
|
|
269
|
+
if (memo) {
|
|
270
|
+
const cached = memo.files.get(realPath);
|
|
271
|
+
if (cached !== void 0) return cached;
|
|
272
|
+
}
|
|
273
|
+
const source = readFileSync(realPath, "utf-8");
|
|
274
|
+
if (memo) memo.files.set(realPath, source);
|
|
275
|
+
return source;
|
|
276
|
+
}
|
|
240
277
|
function extractNamePrefixFromInclude(node) {
|
|
241
278
|
if (node.arguments.length >= 3) {
|
|
242
279
|
const thirdArg = node.arguments[2];
|
|
@@ -252,8 +289,98 @@ function extractNamePrefixFromInclude(node) {
|
|
|
252
289
|
}
|
|
253
290
|
return null;
|
|
254
291
|
}
|
|
255
|
-
function
|
|
256
|
-
const
|
|
292
|
+
function thenSelectsNonDefaultMember(expr) {
|
|
293
|
+
const findThenCall = (e) => {
|
|
294
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression) && e.expression.name.text === "then") {
|
|
295
|
+
return e;
|
|
296
|
+
}
|
|
297
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
|
|
298
|
+
return findThenCall(e.expression.expression);
|
|
299
|
+
}
|
|
300
|
+
if (ts3.isPropertyAccessExpression(e)) return findThenCall(e.expression);
|
|
301
|
+
if (ts3.isParenthesizedExpression(e)) return findThenCall(e.expression);
|
|
302
|
+
if (ts3.isAwaitExpression(e)) return findThenCall(e.expression);
|
|
303
|
+
return null;
|
|
304
|
+
};
|
|
305
|
+
const thenCall = findThenCall(expr);
|
|
306
|
+
if (!thenCall || thenCall.arguments.length === 0) return false;
|
|
307
|
+
const cb = thenCall.arguments[0];
|
|
308
|
+
if (!ts3.isArrowFunction(cb) && !ts3.isFunctionExpression(cb)) return false;
|
|
309
|
+
let ret;
|
|
310
|
+
if (ts3.isBlock(cb.body)) {
|
|
311
|
+
for (const stmt of cb.body.statements) {
|
|
312
|
+
if (ts3.isReturnStatement(stmt) && stmt.expression) {
|
|
313
|
+
ret = stmt.expression;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
ret = cb.body;
|
|
319
|
+
}
|
|
320
|
+
if (!ret) return false;
|
|
321
|
+
if (ts3.isPropertyAccessExpression(ret)) {
|
|
322
|
+
return ret.name.text !== "default";
|
|
323
|
+
}
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
function extractDynamicImportSpecifier(node) {
|
|
327
|
+
let body;
|
|
328
|
+
if (ts3.isArrowFunction(node) || ts3.isFunctionExpression(node)) {
|
|
329
|
+
body = node.body;
|
|
330
|
+
}
|
|
331
|
+
if (!body) return null;
|
|
332
|
+
let expr;
|
|
333
|
+
if (ts3.isBlock(body)) {
|
|
334
|
+
for (const stmt of body.statements) {
|
|
335
|
+
if (ts3.isReturnStatement(stmt) && stmt.expression) {
|
|
336
|
+
expr = stmt.expression;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
expr = body;
|
|
342
|
+
}
|
|
343
|
+
if (!expr) return null;
|
|
344
|
+
const findImportCall = (e) => {
|
|
345
|
+
if (ts3.isCallExpression(e) && e.expression.kind === ts3.SyntaxKind.ImportKeyword) {
|
|
346
|
+
return e;
|
|
347
|
+
}
|
|
348
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
|
|
349
|
+
return findImportCall(e.expression.expression);
|
|
350
|
+
}
|
|
351
|
+
if (ts3.isPropertyAccessExpression(e)) return findImportCall(e.expression);
|
|
352
|
+
if (ts3.isParenthesizedExpression(e)) return findImportCall(e.expression);
|
|
353
|
+
if (ts3.isAwaitExpression(e)) return findImportCall(e.expression);
|
|
354
|
+
return null;
|
|
355
|
+
};
|
|
356
|
+
const importCall = findImportCall(expr);
|
|
357
|
+
if (!importCall || importCall.arguments.length === 0) return null;
|
|
358
|
+
if (thenSelectsNonDefaultMember(expr)) return null;
|
|
359
|
+
return getStringValue(importCall.arguments[0]);
|
|
360
|
+
}
|
|
361
|
+
function resolveDefaultExportTarget(code, sourceFile) {
|
|
362
|
+
let result = null;
|
|
363
|
+
function visit(node) {
|
|
364
|
+
if (result) return;
|
|
365
|
+
if (ts3.isExportAssignment(node) && !node.isExportEquals) {
|
|
366
|
+
const expr = node.expression;
|
|
367
|
+
if (ts3.isIdentifier(expr)) {
|
|
368
|
+
result = { variableName: expr.text };
|
|
369
|
+
} else if (ts3.isCallExpression(expr)) {
|
|
370
|
+
const callee = expr.expression;
|
|
371
|
+
if (ts3.isIdentifier(callee) && callee.text === "urls") {
|
|
372
|
+
result = { inlineBlock: expr.getText(sourceFile) };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
ts3.forEachChild(node, visit);
|
|
378
|
+
}
|
|
379
|
+
visit(sourceFile);
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
382
|
+
function extractIncludesWithDiagnostics(code, sourceFileArg) {
|
|
383
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
257
384
|
"input.tsx",
|
|
258
385
|
code,
|
|
259
386
|
ts3.ScriptTarget.Latest,
|
|
@@ -277,12 +404,19 @@ function extractIncludesWithDiagnostics(code) {
|
|
|
277
404
|
}
|
|
278
405
|
const secondArg = node.arguments[1];
|
|
279
406
|
const namePrefix = extractNamePrefixFromInclude(node);
|
|
407
|
+
const dynamicImportSpec = extractDynamicImportSpecifier(secondArg);
|
|
280
408
|
if (ts3.isIdentifier(secondArg)) {
|
|
281
409
|
resolved.push({
|
|
282
410
|
pathPrefix,
|
|
283
411
|
variableName: secondArg.text,
|
|
284
412
|
namePrefix
|
|
285
413
|
});
|
|
414
|
+
} else if (dynamicImportSpec !== null) {
|
|
415
|
+
resolved.push({
|
|
416
|
+
pathPrefix,
|
|
417
|
+
moduleSpecifier: dynamicImportSpec,
|
|
418
|
+
namePrefix
|
|
419
|
+
});
|
|
286
420
|
} else if (ts3.isCallExpression(secondArg)) {
|
|
287
421
|
const callText = secondArg.expression.getText(sourceFile);
|
|
288
422
|
unresolvable.push({
|
|
@@ -307,7 +441,7 @@ function extractIncludesWithDiagnostics(code) {
|
|
|
307
441
|
return { resolved, unresolvable };
|
|
308
442
|
}
|
|
309
443
|
function resolveImportedVariable(code, localName) {
|
|
310
|
-
const importRegex = /import\s
|
|
444
|
+
const importRegex = /import\s*(?:[\w$]+\s*,\s*)?\{([^}]+)\}\s*from\s*["']([^"']+)["']/g;
|
|
311
445
|
let match;
|
|
312
446
|
while ((match = importRegex.exec(code)) !== null) {
|
|
313
447
|
const imports = match[1];
|
|
@@ -344,8 +478,8 @@ function resolveImportPath(importSpec, fromFile) {
|
|
|
344
478
|
}
|
|
345
479
|
return null;
|
|
346
480
|
}
|
|
347
|
-
function extractUrlsBlockForVariable(code, varName) {
|
|
348
|
-
const sourceFile = ts3.createSourceFile(
|
|
481
|
+
function extractUrlsBlockForVariable(code, varName, sourceFileArg) {
|
|
482
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
349
483
|
"input.tsx",
|
|
350
484
|
code,
|
|
351
485
|
ts3.ScriptTarget.Latest,
|
|
@@ -367,67 +501,113 @@ function extractUrlsBlockForVariable(code, varName) {
|
|
|
367
501
|
visit(sourceFile);
|
|
368
502
|
return result;
|
|
369
503
|
}
|
|
370
|
-
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut) {
|
|
504
|
+
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut, memo) {
|
|
371
505
|
const routeMap = {};
|
|
372
|
-
const
|
|
506
|
+
const blockSourceFile = parseBlock(memo, block);
|
|
507
|
+
const localRoutes = extractRoutesFromSource(block, blockSourceFile);
|
|
373
508
|
for (const { name, pattern, search } of localRoutes) {
|
|
374
509
|
routeMap[name] = pattern;
|
|
375
510
|
if (search && searchSchemasOut) {
|
|
376
511
|
searchSchemasOut[name] = search;
|
|
377
512
|
}
|
|
378
513
|
}
|
|
379
|
-
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
514
|
+
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
515
|
+
block,
|
|
516
|
+
blockSourceFile
|
|
517
|
+
);
|
|
380
518
|
if (diagnosticsOut) {
|
|
381
519
|
for (const entry of unresolvable) {
|
|
382
520
|
diagnosticsOut.push({ ...entry, sourceFile: filePath });
|
|
383
521
|
}
|
|
384
522
|
}
|
|
385
|
-
for (const
|
|
523
|
+
for (const inc of includes) {
|
|
524
|
+
const { pathPrefix, namePrefix } = inc;
|
|
386
525
|
let childResult;
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const targetFile = resolveImportPath(imported.specifier, filePath);
|
|
526
|
+
if (inc.moduleSpecifier) {
|
|
527
|
+
const targetFile = resolveImportPath(inc.moduleSpecifier, filePath);
|
|
390
528
|
if (!targetFile) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
});
|
|
399
|
-
}
|
|
529
|
+
diagnosticsOut?.push({
|
|
530
|
+
pathPrefix,
|
|
531
|
+
namePrefix,
|
|
532
|
+
reason: "file-not-found",
|
|
533
|
+
sourceFile: filePath,
|
|
534
|
+
detail: `import("${inc.moduleSpecifier}") resolved to no file`
|
|
535
|
+
});
|
|
400
536
|
continue;
|
|
401
537
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
diagnosticsOut
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
538
|
+
let targetSource;
|
|
539
|
+
try {
|
|
540
|
+
targetSource = readSourceMemoized(memo, resolve(targetFile));
|
|
541
|
+
} catch (err) {
|
|
542
|
+
diagnosticsOut?.push({
|
|
543
|
+
pathPrefix,
|
|
544
|
+
namePrefix,
|
|
545
|
+
reason: "file-not-found",
|
|
546
|
+
sourceFile: filePath,
|
|
547
|
+
detail: `import("${inc.moduleSpecifier}") resolved to "${targetFile}" but reading it failed: ${err?.message ?? String(err)}`
|
|
548
|
+
});
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
const def = resolveDefaultExportTarget(
|
|
552
|
+
targetSource,
|
|
553
|
+
parseBlock(memo, targetSource)
|
|
412
554
|
);
|
|
413
|
-
if (!
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
});
|
|
422
|
-
}
|
|
555
|
+
if (!def) {
|
|
556
|
+
diagnosticsOut?.push({
|
|
557
|
+
pathPrefix,
|
|
558
|
+
namePrefix,
|
|
559
|
+
reason: "unresolvable-import",
|
|
560
|
+
sourceFile: filePath,
|
|
561
|
+
detail: `import("${inc.moduleSpecifier}") has no resolvable \`export default urls(...)\``
|
|
562
|
+
});
|
|
423
563
|
continue;
|
|
424
564
|
}
|
|
425
|
-
|
|
426
|
-
|
|
565
|
+
if (def.inlineBlock) {
|
|
566
|
+
childResult = buildCombinedRouteMapWithSearch(
|
|
567
|
+
targetFile,
|
|
568
|
+
void 0,
|
|
569
|
+
visited,
|
|
570
|
+
diagnosticsOut,
|
|
571
|
+
def.inlineBlock,
|
|
572
|
+
memo
|
|
573
|
+
);
|
|
574
|
+
} else {
|
|
575
|
+
const variableName = def.variableName;
|
|
576
|
+
const resolved = resolveIncludedVariable({
|
|
577
|
+
variableName,
|
|
578
|
+
resolutionFile: targetFile,
|
|
579
|
+
resolutionSource: targetSource,
|
|
580
|
+
reportFile: filePath,
|
|
581
|
+
memo,
|
|
582
|
+
visited,
|
|
583
|
+
diagnosticsOut,
|
|
584
|
+
pathPrefix,
|
|
585
|
+
namePrefix,
|
|
586
|
+
fileNotFoundDetail: (specifier) => `import("${inc.moduleSpecifier}") default re-exports "${variableName}" from "${specifier}", which resolved to no file`,
|
|
587
|
+
notFoundDetail: () => `import("${inc.moduleSpecifier}") default "${variableName}" not found in its imports or same-file scope`
|
|
588
|
+
});
|
|
589
|
+
if (!resolved) continue;
|
|
590
|
+
childResult = resolved;
|
|
591
|
+
}
|
|
592
|
+
} else if (inc.variableName) {
|
|
593
|
+
const variableName = inc.variableName;
|
|
594
|
+
const resolved = resolveIncludedVariable({
|
|
427
595
|
variableName,
|
|
596
|
+
resolutionFile: filePath,
|
|
597
|
+
resolutionSource: fullSource,
|
|
598
|
+
reportFile: filePath,
|
|
599
|
+
memo,
|
|
428
600
|
visited,
|
|
429
|
-
diagnosticsOut
|
|
430
|
-
|
|
601
|
+
diagnosticsOut,
|
|
602
|
+
pathPrefix,
|
|
603
|
+
namePrefix,
|
|
604
|
+
fileNotFoundDetail: (specifier) => `import "${specifier}" resolved to no file`,
|
|
605
|
+
notFoundDetail: () => `variable "${variableName}" not found in imports or same-file scope`
|
|
606
|
+
});
|
|
607
|
+
if (!resolved) continue;
|
|
608
|
+
childResult = resolved;
|
|
609
|
+
} else {
|
|
610
|
+
continue;
|
|
431
611
|
}
|
|
432
612
|
if (namePrefix === null) {
|
|
433
613
|
continue;
|
|
@@ -450,18 +630,77 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
450
630
|
}
|
|
451
631
|
return routeMap;
|
|
452
632
|
}
|
|
453
|
-
function
|
|
633
|
+
function resolveIncludedVariable(opts) {
|
|
634
|
+
const {
|
|
635
|
+
variableName,
|
|
636
|
+
resolutionFile,
|
|
637
|
+
resolutionSource,
|
|
638
|
+
reportFile,
|
|
639
|
+
memo,
|
|
640
|
+
visited,
|
|
641
|
+
diagnosticsOut,
|
|
642
|
+
pathPrefix,
|
|
643
|
+
namePrefix
|
|
644
|
+
} = opts;
|
|
645
|
+
const imported = resolveImportedVariable(resolutionSource, variableName);
|
|
646
|
+
if (imported) {
|
|
647
|
+
const targetFile = resolveImportPath(imported.specifier, resolutionFile);
|
|
648
|
+
if (!targetFile) {
|
|
649
|
+
diagnosticsOut?.push({
|
|
650
|
+
pathPrefix,
|
|
651
|
+
namePrefix,
|
|
652
|
+
reason: "file-not-found",
|
|
653
|
+
sourceFile: reportFile,
|
|
654
|
+
detail: opts.fileNotFoundDetail(imported.specifier)
|
|
655
|
+
});
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
return buildCombinedRouteMapWithSearch(
|
|
659
|
+
targetFile,
|
|
660
|
+
imported.exportedName,
|
|
661
|
+
visited,
|
|
662
|
+
diagnosticsOut,
|
|
663
|
+
void 0,
|
|
664
|
+
memo
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
const sameFileBlock = extractUrlsBlockForVariable(
|
|
668
|
+
resolutionSource,
|
|
669
|
+
variableName,
|
|
670
|
+
parseBlock(memo, resolutionSource)
|
|
671
|
+
);
|
|
672
|
+
if (!sameFileBlock) {
|
|
673
|
+
diagnosticsOut?.push({
|
|
674
|
+
pathPrefix,
|
|
675
|
+
namePrefix,
|
|
676
|
+
reason: "unresolvable-import",
|
|
677
|
+
sourceFile: reportFile,
|
|
678
|
+
detail: opts.notFoundDetail()
|
|
679
|
+
});
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
return buildCombinedRouteMapWithSearch(
|
|
683
|
+
resolutionFile,
|
|
684
|
+
variableName,
|
|
685
|
+
visited,
|
|
686
|
+
diagnosticsOut,
|
|
687
|
+
void 0,
|
|
688
|
+
memo
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock, memo) {
|
|
454
692
|
visited = visited ?? /* @__PURE__ */ new Set();
|
|
693
|
+
memo = memo ?? createScanMemo();
|
|
455
694
|
const realPath = resolve(filePath);
|
|
456
695
|
const key = variableName ? `${realPath}:${variableName}` : realPath;
|
|
457
696
|
if (visited.has(key)) {
|
|
458
|
-
console.warn(`[
|
|
697
|
+
console.warn(`[rango] Circular include detected, skipping: ${key}`);
|
|
459
698
|
return { routes: {}, searchSchemas: {} };
|
|
460
699
|
}
|
|
461
700
|
visited.add(key);
|
|
462
701
|
let source;
|
|
463
702
|
try {
|
|
464
|
-
source =
|
|
703
|
+
source = readSourceMemoized(memo, realPath);
|
|
465
704
|
} catch {
|
|
466
705
|
return { routes: {}, searchSchemas: {} };
|
|
467
706
|
}
|
|
@@ -469,7 +708,11 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
469
708
|
if (inlineBlock) {
|
|
470
709
|
block = inlineBlock;
|
|
471
710
|
} else if (variableName) {
|
|
472
|
-
const extracted = extractUrlsBlockForVariable(
|
|
711
|
+
const extracted = extractUrlsBlockForVariable(
|
|
712
|
+
source,
|
|
713
|
+
variableName,
|
|
714
|
+
parseBlock(memo, source)
|
|
715
|
+
);
|
|
473
716
|
if (!extracted) return { routes: {}, searchSchemas: {} };
|
|
474
717
|
block = extracted;
|
|
475
718
|
} else {
|
|
@@ -482,7 +725,8 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
482
725
|
realPath,
|
|
483
726
|
visited,
|
|
484
727
|
searchSchemas,
|
|
485
|
-
diagnosticsOut
|
|
728
|
+
diagnosticsOut,
|
|
729
|
+
memo
|
|
486
730
|
);
|
|
487
731
|
visited.delete(key);
|
|
488
732
|
return { routes, searchSchemas };
|
|
@@ -527,8 +771,16 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
527
771
|
let routes;
|
|
528
772
|
if (varNames.length > 0) {
|
|
529
773
|
routes = [];
|
|
774
|
+
const memo = createScanMemo();
|
|
530
775
|
for (const varName of varNames) {
|
|
531
|
-
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
776
|
+
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
777
|
+
filePath,
|
|
778
|
+
varName,
|
|
779
|
+
void 0,
|
|
780
|
+
void 0,
|
|
781
|
+
void 0,
|
|
782
|
+
memo
|
|
783
|
+
);
|
|
532
784
|
for (const [name, pattern] of Object.entries(routeMap)) {
|
|
533
785
|
const params = extractParamsFromPattern(pattern);
|
|
534
786
|
routes.push({
|
|
@@ -542,12 +794,12 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
542
794
|
} else {
|
|
543
795
|
routes = extractRoutesFromSource(source);
|
|
544
796
|
}
|
|
545
|
-
const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
|
|
797
|
+
const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
|
|
546
798
|
if (routes.length === 0) {
|
|
547
799
|
if (varNames.length > 0 && !existsSync2(genPath)) {
|
|
548
800
|
writeFileSync(genPath, generatePerModuleTypesSource([]));
|
|
549
801
|
console.log(
|
|
550
|
-
`[
|
|
802
|
+
`[rango] Generated route types (placeholder) -> ${genPath}`
|
|
551
803
|
);
|
|
552
804
|
}
|
|
553
805
|
return;
|
|
@@ -556,11 +808,11 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
556
808
|
const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
|
|
557
809
|
if (existing !== genSource) {
|
|
558
810
|
writeFileSync(genPath, genSource);
|
|
559
|
-
console.log(`[
|
|
811
|
+
console.log(`[rango] Generated route types -> ${genPath}`);
|
|
560
812
|
}
|
|
561
813
|
} catch (err) {
|
|
562
814
|
console.warn(
|
|
563
|
-
`[
|
|
815
|
+
`[rango] Failed to generate route types for ${filePath}: ${err.message}`
|
|
564
816
|
);
|
|
565
817
|
}
|
|
566
818
|
}
|
|
@@ -575,6 +827,131 @@ var init_per_module_writer = __esm({
|
|
|
575
827
|
}
|
|
576
828
|
});
|
|
577
829
|
|
|
830
|
+
// src/build/route-types/source-scan.ts
|
|
831
|
+
function isLineTerminator(ch) {
|
|
832
|
+
const c = ch.charCodeAt(0);
|
|
833
|
+
return c === 10 || c === 13 || c === 8232 || c === 8233;
|
|
834
|
+
}
|
|
835
|
+
function isRegexPositionAt(code, slashPos, prevChar) {
|
|
836
|
+
if (prevChar === void 0) return true;
|
|
837
|
+
if (prevChar === ")" || prevChar === "]" || prevChar === "}") return false;
|
|
838
|
+
if (!/[\w$]/.test(prevChar)) return true;
|
|
839
|
+
let k = slashPos - 1;
|
|
840
|
+
while (k >= 0 && /\s/.test(code[k])) k--;
|
|
841
|
+
const wordEnd = k + 1;
|
|
842
|
+
while (k >= 0 && /[\w$]/.test(code[k])) k--;
|
|
843
|
+
return REGEX_PRECEDING_KEYWORDS.has(code.slice(k + 1, wordEnd));
|
|
844
|
+
}
|
|
845
|
+
function makeCodeClassifier(code) {
|
|
846
|
+
const n = code.length;
|
|
847
|
+
let i = 0;
|
|
848
|
+
let skipStart = -1;
|
|
849
|
+
let skipEnd = -1;
|
|
850
|
+
let lastSig;
|
|
851
|
+
return (q) => {
|
|
852
|
+
if (q >= skipStart && q < skipEnd) return false;
|
|
853
|
+
while (i < n && i <= q) {
|
|
854
|
+
const c = code[i];
|
|
855
|
+
const d = i + 1 < n ? code[i + 1] : "";
|
|
856
|
+
let end = -1;
|
|
857
|
+
let transparent = false;
|
|
858
|
+
if (c === "/" && d === "/") {
|
|
859
|
+
let j = i + 2;
|
|
860
|
+
while (j < n && !isLineTerminator(code[j])) j++;
|
|
861
|
+
end = j;
|
|
862
|
+
transparent = true;
|
|
863
|
+
} else if (c === "/" && d === "*") {
|
|
864
|
+
let j = i + 2;
|
|
865
|
+
while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
|
|
866
|
+
end = Math.min(n, j + 2);
|
|
867
|
+
transparent = true;
|
|
868
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
869
|
+
let j = i + 1;
|
|
870
|
+
while (j < n) {
|
|
871
|
+
if (code[j] === "\\") {
|
|
872
|
+
j += 2;
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
if (code[j] === c) {
|
|
876
|
+
j++;
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
j++;
|
|
880
|
+
}
|
|
881
|
+
end = j;
|
|
882
|
+
} else if (c === "/" && d !== "/" && d !== "*" && isRegexPositionAt(code, i, lastSig)) {
|
|
883
|
+
let j = i + 1;
|
|
884
|
+
let inClass = false;
|
|
885
|
+
let closed = false;
|
|
886
|
+
while (j < n && !isLineTerminator(code[j])) {
|
|
887
|
+
const r = code[j];
|
|
888
|
+
if (r === "\\") {
|
|
889
|
+
j += 2;
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (r === "[") inClass = true;
|
|
893
|
+
else if (r === "]") inClass = false;
|
|
894
|
+
else if (r === "/" && !inClass) {
|
|
895
|
+
j++;
|
|
896
|
+
closed = true;
|
|
897
|
+
break;
|
|
898
|
+
}
|
|
899
|
+
j++;
|
|
900
|
+
}
|
|
901
|
+
if (closed) {
|
|
902
|
+
while (j < n && /[a-z]/.test(code[j])) j++;
|
|
903
|
+
end = j;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (end >= 0) {
|
|
907
|
+
if (q < end) {
|
|
908
|
+
skipStart = i;
|
|
909
|
+
skipEnd = end;
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
i = end;
|
|
913
|
+
if (!transparent) lastSig = "x";
|
|
914
|
+
} else {
|
|
915
|
+
if (!/\s/.test(c)) lastSig = c;
|
|
916
|
+
i++;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return true;
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
function firstCodeMatchIndex(code, pattern) {
|
|
923
|
+
const inCode = makeCodeClassifier(code);
|
|
924
|
+
pattern.lastIndex = 0;
|
|
925
|
+
let m;
|
|
926
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
927
|
+
if (inCode(m.index)) return m.index;
|
|
928
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
929
|
+
}
|
|
930
|
+
return -1;
|
|
931
|
+
}
|
|
932
|
+
var REGEX_PRECEDING_KEYWORDS;
|
|
933
|
+
var init_source_scan = __esm({
|
|
934
|
+
"src/build/route-types/source-scan.ts"() {
|
|
935
|
+
"use strict";
|
|
936
|
+
REGEX_PRECEDING_KEYWORDS = /* @__PURE__ */ new Set([
|
|
937
|
+
"return",
|
|
938
|
+
"typeof",
|
|
939
|
+
"instanceof",
|
|
940
|
+
"in",
|
|
941
|
+
"of",
|
|
942
|
+
"new",
|
|
943
|
+
"delete",
|
|
944
|
+
"void",
|
|
945
|
+
"do",
|
|
946
|
+
"else",
|
|
947
|
+
"yield",
|
|
948
|
+
"await",
|
|
949
|
+
"case",
|
|
950
|
+
"throw"
|
|
951
|
+
]);
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
578
955
|
// src/build/route-types/router-processing.ts
|
|
579
956
|
import {
|
|
580
957
|
readFileSync as readFileSync3,
|
|
@@ -605,43 +982,50 @@ function countPublicRouteEntries(source) {
|
|
|
605
982
|
function isRoutableSourceFile(name) {
|
|
606
983
|
return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
|
|
607
984
|
}
|
|
608
|
-
function
|
|
985
|
+
function isExcludedScanDir(name) {
|
|
986
|
+
return name === "node_modules" || name === "dist" || name === "coverage" || name === "__tests__" || name === "__mocks__" || name.startsWith(".");
|
|
987
|
+
}
|
|
988
|
+
function findCallSiteFilesRecursive(dir, pattern, patternG, stopAtMatchDir, filter, results) {
|
|
609
989
|
let entries;
|
|
610
990
|
try {
|
|
611
991
|
entries = readdirSync2(dir, { withFileTypes: true });
|
|
612
992
|
} catch (err) {
|
|
613
993
|
console.warn(
|
|
614
|
-
`[
|
|
994
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
615
995
|
);
|
|
616
996
|
return;
|
|
617
997
|
}
|
|
618
998
|
const childDirs = [];
|
|
619
|
-
const
|
|
999
|
+
const matchesInDir = [];
|
|
620
1000
|
for (const entry of entries) {
|
|
621
1001
|
const fullPath = join2(dir, entry.name);
|
|
622
1002
|
if (entry.isDirectory()) {
|
|
623
|
-
if (entry.name
|
|
624
|
-
continue;
|
|
625
|
-
childDirs.push(fullPath);
|
|
1003
|
+
if (!isExcludedScanDir(entry.name)) childDirs.push(fullPath);
|
|
626
1004
|
continue;
|
|
627
1005
|
}
|
|
628
1006
|
if (!isRoutableSourceFile(entry.name)) continue;
|
|
629
1007
|
if (filter && !filter(fullPath)) continue;
|
|
630
1008
|
try {
|
|
631
1009
|
const source = readFileSync3(fullPath, "utf-8");
|
|
632
|
-
if (
|
|
633
|
-
|
|
1010
|
+
if (pattern.test(source) && firstCodeMatchIndex(source, patternG) >= 0) {
|
|
1011
|
+
matchesInDir.push(fullPath);
|
|
634
1012
|
}
|
|
635
1013
|
} catch {
|
|
636
1014
|
continue;
|
|
637
1015
|
}
|
|
638
1016
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
1017
|
+
results.push(...matchesInDir);
|
|
1018
|
+
if (!stopAtMatchDir || matchesInDir.length === 0) {
|
|
1019
|
+
for (const childDir of childDirs) {
|
|
1020
|
+
findCallSiteFilesRecursive(
|
|
1021
|
+
childDir,
|
|
1022
|
+
pattern,
|
|
1023
|
+
patternG,
|
|
1024
|
+
stopAtMatchDir,
|
|
1025
|
+
filter,
|
|
1026
|
+
results
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
645
1029
|
}
|
|
646
1030
|
}
|
|
647
1031
|
function findNestedRouterConflict(routerFiles) {
|
|
@@ -667,7 +1051,7 @@ function findNestedRouterConflict(routerFiles) {
|
|
|
667
1051
|
}
|
|
668
1052
|
return null;
|
|
669
1053
|
}
|
|
670
|
-
function formatNestedRouterConflictError(conflict, prefix = "[
|
|
1054
|
+
function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
|
|
671
1055
|
return `${prefix} Nested router roots are not supported.
|
|
672
1056
|
Router root: ${conflict.ancestor}
|
|
673
1057
|
Nested router: ${conflict.nested}
|
|
@@ -763,19 +1147,38 @@ function extractBasenameFromRouter(code) {
|
|
|
763
1147
|
visit(sourceFile);
|
|
764
1148
|
return result;
|
|
765
1149
|
}
|
|
766
|
-
function applyBasenameToRoutes(result,
|
|
1150
|
+
function applyBasenameToRoutes(result, basename) {
|
|
767
1151
|
const prefixed = {};
|
|
768
1152
|
for (const [name, pattern] of Object.entries(result.routes)) {
|
|
769
1153
|
if (pattern === "/") {
|
|
770
|
-
prefixed[name] =
|
|
771
|
-
} else if (
|
|
772
|
-
prefixed[name] =
|
|
1154
|
+
prefixed[name] = basename;
|
|
1155
|
+
} else if (basename.endsWith("/") && pattern.startsWith("/")) {
|
|
1156
|
+
prefixed[name] = basename + pattern.slice(1);
|
|
773
1157
|
} else {
|
|
774
|
-
prefixed[name] =
|
|
1158
|
+
prefixed[name] = basename + pattern;
|
|
775
1159
|
}
|
|
776
1160
|
}
|
|
777
1161
|
return { routes: prefixed, searchSchemas: result.searchSchemas };
|
|
778
1162
|
}
|
|
1163
|
+
function genFileTsPath(sourceFile) {
|
|
1164
|
+
const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
1165
|
+
return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
|
|
1166
|
+
}
|
|
1167
|
+
function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
|
|
1168
|
+
if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
|
|
1169
|
+
return runtimeSchemas;
|
|
1170
|
+
}
|
|
1171
|
+
const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
|
|
1172
|
+
if (Object.keys(staticParsed.searchSchemas).length === 0) {
|
|
1173
|
+
return runtimeSchemas;
|
|
1174
|
+
}
|
|
1175
|
+
const filtered = {};
|
|
1176
|
+
for (const name of publicRouteNames) {
|
|
1177
|
+
const schema = staticParsed.searchSchemas[name];
|
|
1178
|
+
if (schema) filtered[name] = schema;
|
|
1179
|
+
}
|
|
1180
|
+
return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
|
|
1181
|
+
}
|
|
779
1182
|
function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
780
1183
|
let routerSource;
|
|
781
1184
|
try {
|
|
@@ -788,7 +1191,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
788
1191
|
return { routes: {}, searchSchemas: {} };
|
|
789
1192
|
}
|
|
790
1193
|
const rawBasename = extractBasenameFromRouter(routerSource);
|
|
791
|
-
const
|
|
1194
|
+
const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
|
|
792
1195
|
let result;
|
|
793
1196
|
if (extraction.kind === "inline") {
|
|
794
1197
|
result = buildCombinedRouteMapWithSearch(
|
|
@@ -813,8 +1216,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
813
1216
|
result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
|
|
814
1217
|
}
|
|
815
1218
|
}
|
|
816
|
-
if (
|
|
817
|
-
result = applyBasenameToRoutes(result,
|
|
1219
|
+
if (basename) {
|
|
1220
|
+
result = applyBasenameToRoutes(result, basename);
|
|
818
1221
|
}
|
|
819
1222
|
return result;
|
|
820
1223
|
}
|
|
@@ -887,7 +1290,14 @@ function detectUnresolvableIncludesForUrlsFile(filePath) {
|
|
|
887
1290
|
}
|
|
888
1291
|
function findRouterFiles(root, filter) {
|
|
889
1292
|
const result = [];
|
|
890
|
-
|
|
1293
|
+
findCallSiteFilesRecursive(
|
|
1294
|
+
root,
|
|
1295
|
+
ROUTER_CALL_PATTERN,
|
|
1296
|
+
ROUTER_CALL_PATTERN_G,
|
|
1297
|
+
true,
|
|
1298
|
+
filter,
|
|
1299
|
+
result
|
|
1300
|
+
);
|
|
891
1301
|
return result;
|
|
892
1302
|
}
|
|
893
1303
|
function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
@@ -896,7 +1306,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
896
1306
|
if (existsSync3(oldCombinedPath)) {
|
|
897
1307
|
unlinkSync(oldCombinedPath);
|
|
898
1308
|
console.log(
|
|
899
|
-
`[
|
|
1309
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
900
1310
|
);
|
|
901
1311
|
}
|
|
902
1312
|
} catch {
|
|
@@ -918,18 +1328,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
918
1328
|
}
|
|
919
1329
|
if (!extractUrlsFromRouter(routerSource)) continue;
|
|
920
1330
|
}
|
|
921
|
-
const
|
|
922
|
-
/\.(tsx?|jsx?)$/,
|
|
923
|
-
""
|
|
924
|
-
);
|
|
925
|
-
const outPath = join2(
|
|
926
|
-
dirname2(routerFilePath),
|
|
927
|
-
`${routerBasename}.named-routes.gen.ts`
|
|
928
|
-
);
|
|
1331
|
+
const outPath = genFileTsPath(routerFilePath);
|
|
929
1332
|
const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
|
|
930
1333
|
if (Object.keys(result.routes).length === 0) {
|
|
931
1334
|
if (!existing) {
|
|
932
1335
|
const emptySource = generateRouteTypesSource({});
|
|
1336
|
+
opts?.onWrite?.(outPath, emptySource);
|
|
933
1337
|
writeFileSync2(outPath, emptySource);
|
|
934
1338
|
}
|
|
935
1339
|
continue;
|
|
@@ -949,22 +1353,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
949
1353
|
continue;
|
|
950
1354
|
}
|
|
951
1355
|
}
|
|
1356
|
+
opts?.onWrite?.(outPath, source);
|
|
952
1357
|
writeFileSync2(outPath, source);
|
|
953
1358
|
console.log(
|
|
954
|
-
`[
|
|
1359
|
+
`[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
|
|
955
1360
|
);
|
|
956
1361
|
}
|
|
957
1362
|
}
|
|
958
1363
|
}
|
|
959
|
-
var ROUTER_CALL_PATTERN;
|
|
1364
|
+
var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
|
|
960
1365
|
var init_router_processing = __esm({
|
|
961
1366
|
"src/build/route-types/router-processing.ts"() {
|
|
962
1367
|
"use strict";
|
|
963
1368
|
init_codegen();
|
|
1369
|
+
init_source_scan();
|
|
964
1370
|
init_include_resolution();
|
|
965
1371
|
init_per_module_writer();
|
|
966
1372
|
init_route_name();
|
|
967
1373
|
ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
|
|
1374
|
+
ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
|
|
968
1375
|
}
|
|
969
1376
|
});
|
|
970
1377
|
|
|
@@ -1002,7 +1409,7 @@ import {
|
|
|
1002
1409
|
import { createElement, StrictMode } from "react";
|
|
1003
1410
|
import { hydrateRoot } from "react-dom/client";
|
|
1004
1411
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
1005
|
-
import { initBrowserApp,
|
|
1412
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
1006
1413
|
|
|
1007
1414
|
async function initializeApp() {
|
|
1008
1415
|
const deps = {
|
|
@@ -1013,11 +1420,16 @@ async function initializeApp() {
|
|
|
1013
1420
|
createTemporaryReferenceSet,
|
|
1014
1421
|
};
|
|
1015
1422
|
|
|
1016
|
-
|
|
1423
|
+
// initBrowserApp resolves the initial payload and returns the browser app
|
|
1424
|
+
// context, including strictMode (default true) from createRouter. StrictMode
|
|
1425
|
+
// is the default; createRouter({ strictMode: false }) ships the opt-out in the
|
|
1426
|
+
// payload metadata. StrictMode emits no DOM, so toggling never changes markup.
|
|
1427
|
+
const { strictMode } = await initBrowserApp({ rscStream, deps });
|
|
1017
1428
|
|
|
1429
|
+
const app = createElement(Rango);
|
|
1018
1430
|
hydrateRoot(
|
|
1019
1431
|
document,
|
|
1020
|
-
createElement(StrictMode, null,
|
|
1432
|
+
strictMode === false ? app : createElement(StrictMode, null, app)
|
|
1021
1433
|
);
|
|
1022
1434
|
}
|
|
1023
1435
|
|
|
@@ -1025,9 +1437,14 @@ initializeApp().catch(console.error);
|
|
|
1025
1437
|
`.trim();
|
|
1026
1438
|
VIRTUAL_ENTRY_SSR = `
|
|
1027
1439
|
import { createFromReadableStream } from "@rangojs/router/internal/deps/ssr";
|
|
1028
|
-
import { renderToReadableStream } from "react-dom/server.edge";
|
|
1440
|
+
import { renderToReadableStream, resume } from "react-dom/server.edge";
|
|
1441
|
+
import { prerender } from "react-dom/static.edge";
|
|
1029
1442
|
import { injectRSCPayload } from "@rangojs/router/internal/deps/html-stream-server";
|
|
1030
|
-
import {
|
|
1443
|
+
import {
|
|
1444
|
+
createSSRHandler,
|
|
1445
|
+
createShellCaptureHandler,
|
|
1446
|
+
createShellResumeHandler,
|
|
1447
|
+
} from "@rangojs/router/ssr";
|
|
1031
1448
|
|
|
1032
1449
|
export const renderHTML = createSSRHandler({
|
|
1033
1450
|
createFromReadableStream,
|
|
@@ -1036,6 +1453,26 @@ export const renderHTML = createSSRHandler({
|
|
|
1036
1453
|
loadBootstrapScriptContent: () =>
|
|
1037
1454
|
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1038
1455
|
});
|
|
1456
|
+
|
|
1457
|
+
export const captureShellHTML = createShellCaptureHandler({
|
|
1458
|
+
createFromReadableStream,
|
|
1459
|
+
renderToReadableStream,
|
|
1460
|
+
injectRSCPayload,
|
|
1461
|
+
prerender,
|
|
1462
|
+
resume,
|
|
1463
|
+
loadBootstrapScriptContent: () =>
|
|
1464
|
+
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
export const resumeShellHTML = createShellResumeHandler({
|
|
1468
|
+
createFromReadableStream,
|
|
1469
|
+
renderToReadableStream,
|
|
1470
|
+
injectRSCPayload,
|
|
1471
|
+
prerender,
|
|
1472
|
+
resume,
|
|
1473
|
+
loadBootstrapScriptContent: () =>
|
|
1474
|
+
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1475
|
+
});
|
|
1039
1476
|
`.trim();
|
|
1040
1477
|
VIRTUAL_IDS = {
|
|
1041
1478
|
browser: "virtual:rsc-router/entry.browser.js",
|
|
@@ -1046,12 +1483,37 @@ export const renderHTML = createSSRHandler({
|
|
|
1046
1483
|
}
|
|
1047
1484
|
});
|
|
1048
1485
|
|
|
1486
|
+
// src/vite/utils/directive-prologue.ts
|
|
1487
|
+
import { parseAst } from "vite";
|
|
1488
|
+
function hasUseClientDirective(source) {
|
|
1489
|
+
let program;
|
|
1490
|
+
try {
|
|
1491
|
+
program = parseAst(source, { lang: "tsx" });
|
|
1492
|
+
} catch {
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
for (const node of program.body ?? []) {
|
|
1496
|
+
if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1497
|
+
if (node.expression.value === "use client") return true;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
return false;
|
|
1503
|
+
}
|
|
1504
|
+
var init_directive_prologue = __esm({
|
|
1505
|
+
"src/vite/utils/directive-prologue.ts"() {
|
|
1506
|
+
"use strict";
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1049
1510
|
// src/vite/plugins/version-plugin.ts
|
|
1050
1511
|
var version_plugin_exports = {};
|
|
1051
1512
|
__export(version_plugin_exports, {
|
|
1052
|
-
createVersionPlugin: () => createVersionPlugin
|
|
1513
|
+
createVersionPlugin: () => createVersionPlugin,
|
|
1514
|
+
isViteDepCachePath: () => isViteDepCachePath
|
|
1053
1515
|
});
|
|
1054
|
-
import { parseAst } from "vite";
|
|
1516
|
+
import { parseAst as parseAst2 } from "vite";
|
|
1055
1517
|
function isCodeModule(id) {
|
|
1056
1518
|
return /\.(tsx?|jsx?)($|\?)/.test(id);
|
|
1057
1519
|
}
|
|
@@ -1059,23 +1521,13 @@ function normalizeModuleId(id) {
|
|
|
1059
1521
|
return id.split("?", 1)[0];
|
|
1060
1522
|
}
|
|
1061
1523
|
function getClientModuleSignature(source) {
|
|
1524
|
+
if (!hasUseClientDirective(source)) return void 0;
|
|
1062
1525
|
let program;
|
|
1063
1526
|
try {
|
|
1064
|
-
program =
|
|
1527
|
+
program = parseAst2(source, { lang: "tsx" });
|
|
1065
1528
|
} catch {
|
|
1066
1529
|
return void 0;
|
|
1067
1530
|
}
|
|
1068
|
-
let isUseClient = false;
|
|
1069
|
-
for (const node of program.body ?? []) {
|
|
1070
|
-
if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1071
|
-
if (node.expression.value === "use client") {
|
|
1072
|
-
isUseClient = true;
|
|
1073
|
-
}
|
|
1074
|
-
continue;
|
|
1075
|
-
}
|
|
1076
|
-
break;
|
|
1077
|
-
}
|
|
1078
|
-
if (!isUseClient) return void 0;
|
|
1079
1531
|
const exports = /* @__PURE__ */ new Set();
|
|
1080
1532
|
let hasDefault = false;
|
|
1081
1533
|
let hasExportAll = false;
|
|
@@ -1144,11 +1596,12 @@ function createVersionPlugin() {
|
|
|
1144
1596
|
let currentVersion = buildVersion;
|
|
1145
1597
|
let isDev = false;
|
|
1146
1598
|
let server = null;
|
|
1599
|
+
let resolvedCacheDir;
|
|
1147
1600
|
const clientModuleSignatures = /* @__PURE__ */ new Map();
|
|
1148
1601
|
let versionCounter = 0;
|
|
1149
1602
|
const bumpVersion = (reason) => {
|
|
1150
1603
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
1151
|
-
console.log(`[
|
|
1604
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
1152
1605
|
const rscEnv = server?.environments?.rsc;
|
|
1153
1606
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
1154
1607
|
"\0" + VIRTUAL_IDS.version
|
|
@@ -1162,6 +1615,7 @@ function createVersionPlugin() {
|
|
|
1162
1615
|
enforce: "pre",
|
|
1163
1616
|
configResolved(config) {
|
|
1164
1617
|
isDev = config.command === "serve";
|
|
1618
|
+
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
1165
1619
|
},
|
|
1166
1620
|
configureServer(devServer) {
|
|
1167
1621
|
server = devServer;
|
|
@@ -1198,11 +1652,11 @@ function createVersionPlugin() {
|
|
|
1198
1652
|
}
|
|
1199
1653
|
return null;
|
|
1200
1654
|
},
|
|
1201
|
-
// Track RSC module changes and update version
|
|
1202
1655
|
async hotUpdate(ctx) {
|
|
1203
1656
|
if (!isDev) return;
|
|
1204
1657
|
const isRscModule = this.environment?.name === "rsc";
|
|
1205
1658
|
if (!isRscModule) return;
|
|
1659
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
1206
1660
|
if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
|
|
1207
1661
|
return;
|
|
1208
1662
|
}
|
|
@@ -1232,10 +1686,22 @@ function createVersionPlugin() {
|
|
|
1232
1686
|
}
|
|
1233
1687
|
};
|
|
1234
1688
|
}
|
|
1689
|
+
function isViteDepCachePath(filePath, cacheDir) {
|
|
1690
|
+
if (!filePath) return false;
|
|
1691
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
1692
|
+
if (cacheDir) {
|
|
1693
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1694
|
+
if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
|
|
1699
|
+
}
|
|
1235
1700
|
var init_version_plugin = __esm({
|
|
1236
1701
|
"src/vite/plugins/version-plugin.ts"() {
|
|
1237
1702
|
"use strict";
|
|
1238
1703
|
init_virtual_entries();
|
|
1704
|
+
init_directive_prologue();
|
|
1239
1705
|
}
|
|
1240
1706
|
});
|
|
1241
1707
|
|
|
@@ -1277,7 +1743,7 @@ var runtime_discovery_exports = {};
|
|
|
1277
1743
|
__export(runtime_discovery_exports, {
|
|
1278
1744
|
discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
|
|
1279
1745
|
});
|
|
1280
|
-
import {
|
|
1746
|
+
import { resolve as resolve3 } from "node:path";
|
|
1281
1747
|
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1282
1748
|
async function discoverAndWriteRouteTypes(opts) {
|
|
1283
1749
|
let createViteServer;
|
|
@@ -1363,7 +1829,10 @@ async function discoverAndWriteRouteTypes(opts) {
|
|
|
1363
1829
|
let routerMountIndex = 0;
|
|
1364
1830
|
for (const [id, router] of registry) {
|
|
1365
1831
|
if (!router.urlpatterns) continue;
|
|
1366
|
-
const manifest = generateManifest(
|
|
1832
|
+
const manifest = await generateManifest(
|
|
1833
|
+
router.urlpatterns,
|
|
1834
|
+
routerMountIndex
|
|
1835
|
+
);
|
|
1367
1836
|
routerMountIndex++;
|
|
1368
1837
|
const rawManifest = manifest.routeManifest;
|
|
1369
1838
|
const routeManifest = {};
|
|
@@ -1387,22 +1856,12 @@ This means createRouter() stack trace parsing matched an internal frame.
|
|
|
1387
1856
|
Set an explicit \`id\` on createRouter() or check the call site.`
|
|
1388
1857
|
);
|
|
1389
1858
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
if (schema) filtered[name] = schema;
|
|
1397
|
-
}
|
|
1398
|
-
if (Object.keys(filtered).length > 0) {
|
|
1399
|
-
routeSearchSchemas = filtered;
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
const routerDir = dirname3(sourceFile);
|
|
1404
|
-
const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
1405
|
-
const outPath = join3(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
1859
|
+
routeSearchSchemas = resolveSearchSchemas(
|
|
1860
|
+
Object.keys(routeManifest),
|
|
1861
|
+
routeSearchSchemas,
|
|
1862
|
+
sourceFile
|
|
1863
|
+
);
|
|
1864
|
+
const outPath = genFileTsPath(sourceFile);
|
|
1406
1865
|
const source = generateRouteTypesSource(
|
|
1407
1866
|
routeManifest,
|
|
1408
1867
|
routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
|
|
@@ -1439,7 +1898,7 @@ var init_runtime_discovery = __esm({
|
|
|
1439
1898
|
|
|
1440
1899
|
// src/bin/rango.ts
|
|
1441
1900
|
init_generate_route_types();
|
|
1442
|
-
import { resolve as resolve4, dirname as
|
|
1901
|
+
import { resolve as resolve4, dirname as dirname3 } from "node:path";
|
|
1443
1902
|
import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
|
|
1444
1903
|
var [command, ...rawArgs] = process.argv.slice(2);
|
|
1445
1904
|
if (command === "generate") {
|
|
@@ -1510,12 +1969,12 @@ Examples:
|
|
|
1510
1969
|
);
|
|
1511
1970
|
}
|
|
1512
1971
|
function findProjectRoot(fromPath) {
|
|
1513
|
-
let dir =
|
|
1514
|
-
while (dir !==
|
|
1972
|
+
let dir = dirname3(resolve4(fromPath));
|
|
1973
|
+
while (dir !== dirname3(dir)) {
|
|
1515
1974
|
if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
|
|
1516
1975
|
return dir;
|
|
1517
1976
|
}
|
|
1518
|
-
dir =
|
|
1977
|
+
dir = dirname3(dir);
|
|
1519
1978
|
}
|
|
1520
1979
|
return process.cwd();
|
|
1521
1980
|
}
|