vinext 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/dist/build/assets-ignore.js +1 -1
- package/dist/build/clean-output.js +1 -1
- package/dist/build/client-build-config.js +7 -4
- package/dist/build/css-url-assets.js +3 -3
- package/dist/build/google-fonts/fallback-metrics.js +1 -1
- package/dist/build/google-fonts/font-metadata.js +1 -1
- package/dist/build/inject-pregenerated-paths.js +1 -1
- package/dist/build/inline-css.js +2 -5
- package/dist/build/module-dependency-cache.d.ts +4 -0
- package/dist/build/module-dependency-cache.js +13 -0
- package/dist/build/next-client-runtime-manifests.js +1 -1
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/precompress.js +7 -7
- package/dist/build/prerender-paths.d.ts +2 -2
- package/dist/build/prerender-paths.js +10 -15
- package/dist/build/prerender-server-pool.js +2 -2
- package/dist/build/prerender.js +1 -1
- package/dist/build/preview-credentials.d.ts +11 -0
- package/dist/build/preview-credentials.js +19 -0
- package/dist/build/report.d.ts +8 -4
- package/dist/build/report.js +14 -6
- package/dist/build/run-prerender.d.ts +2 -11
- package/dist/build/run-prerender.js +2 -10
- package/dist/build/server-manifest.js +1 -1
- package/dist/build/ssr-manifest.d.ts +4 -0
- package/dist/build/ssr-manifest.js +10 -6
- package/dist/build/standalone.js +37 -37
- package/dist/cache/cache-adapters-virtual.d.ts +1 -17
- package/dist/cache/cache-adapters-virtual.js +20 -11
- package/dist/check.d.ts +0 -16
- package/dist/check.js +27 -36
- package/dist/cli.js +61 -55
- package/dist/client/instrumentation-client-inject.js +1 -1
- package/dist/client/pages-router-link-navigation.js +1 -1
- package/dist/config/config-matchers.d.ts +13 -37
- package/dist/config/config-matchers.js +33 -123
- package/dist/config/dotenv.js +1 -1
- package/dist/config/next-config.d.ts +7 -3
- package/dist/config/next-config.js +84 -15
- package/dist/config/prerender.d.ts +2 -2
- package/dist/config/prerender.js +7 -15
- package/dist/config/request-context.d.ts +14 -0
- package/dist/config/request-context.js +26 -0
- package/dist/config/server-external-packages.js +1 -1
- package/dist/config/tsconfig-paths.js +2 -2
- package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
- package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
- package/dist/entries/app-rsc-entry.js +39 -14
- package/dist/entries/app-rsc-manifest.js +21 -4
- package/dist/entries/pages-client-entry.js +6 -5
- package/dist/entries/pages-server-entry.js +18 -28
- package/dist/entries/runtime-entry-module.js +2 -2
- package/dist/index.js +314 -230
- package/dist/init-cloudflare.js +1 -1
- package/dist/init-platform.js +1 -1
- package/dist/init.d.ts +6 -4
- package/dist/init.js +25 -27
- package/dist/plugins/ast-utils.js +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +7 -7
- package/dist/plugins/extensionless-dynamic-import.js +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +13 -8
- package/dist/plugins/import-meta-url.js +16 -17
- package/dist/plugins/middleware-export-validation.js +1 -1
- package/dist/plugins/middleware-server-only.js +2 -2
- package/dist/plugins/og-asset-ownership.js +7 -6
- package/dist/plugins/og-assets.js +5 -6
- package/dist/plugins/optimize-imports.js +12 -13
- package/dist/plugins/postcss.js +1 -1
- package/dist/plugins/remove-console.js +1 -1
- package/dist/plugins/require-context.js +1 -1
- package/dist/plugins/sass.js +2 -2
- package/dist/plugins/server-externals-manifest.js +1 -1
- package/dist/plugins/strip-server-exports.js +1 -1
- package/dist/plugins/styled-jsx.js +3 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/routing/app-route-graph.d.ts +16 -15
- package/dist/routing/app-route-graph.js +86 -88
- package/dist/routing/app-router.d.ts +0 -5
- package/dist/routing/app-router.js +12 -11
- package/dist/routing/file-matcher.d.ts +13 -28
- package/dist/routing/file-matcher.js +31 -44
- package/dist/routing/pages-router.js +26 -32
- package/dist/routing/route-matching.d.ts +14 -1
- package/dist/routing/route-matching.js +13 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +7 -4
- package/dist/routing/route-trie.d.ts +5 -1
- package/dist/routing/route-trie.js +5 -2
- package/dist/server/api-handler.js +41 -33
- package/dist/server/app-browser-entry.js +18 -11
- package/dist/server/app-browser-history-controller.d.ts +1 -1
- package/dist/server/app-browser-history-controller.js +3 -3
- package/dist/server/app-browser-navigation-controller.js +4 -2
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-elements-wire.d.ts +2 -1
- package/dist/server/app-fallback-renderer.d.ts +11 -0
- package/dist/server/app-fallback-renderer.js +16 -2
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +26 -2
- package/dist/server/app-page-boundary-render.js +190 -55
- package/dist/server/app-page-cache-finalizer.d.ts +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-dispatch.d.ts +12 -2
- package/dist/server/app-page-dispatch.js +37 -51
- package/dist/server/app-page-element-builder.d.ts +8 -2
- package/dist/server/app-page-element-builder.js +112 -27
- package/dist/server/app-page-execution.d.ts +3 -1
- package/dist/server/app-page-execution.js +31 -39
- package/dist/server/app-page-head.d.ts +54 -2
- package/dist/server/app-page-head.js +164 -78
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
- package/dist/server/app-page-render.d.ts +2 -2
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-request.d.ts +12 -0
- package/dist/server/app-page-request.js +134 -14
- package/dist/server/app-page-route-wiring.d.ts +9 -0
- package/dist/server/app-page-route-wiring.js +44 -4
- package/dist/server/app-post-middleware-context.d.ts +1 -1
- package/dist/server/app-post-middleware-context.js +1 -1
- package/dist/server/app-route-handler-dispatch.js +31 -17
- package/dist/server/app-route-handler-execution.d.ts +6 -1
- package/dist/server/app-route-handler-execution.js +41 -15
- package/dist/server/app-route-handler-policy.d.ts +2 -0
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-module-loader.d.ts +3 -1
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-route-tree-prefetch.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +1 -1
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.d.ts +1 -1
- package/dist/server/app-rsc-errors.js +12 -2
- package/dist/server/app-rsc-handler.d.ts +10 -5
- package/dist/server/app-rsc-handler.js +51 -23
- package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
- package/dist/server/app-rsc-redirect-flight.js +71 -0
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +8 -2
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
- package/dist/server/app-rsc-response-finalizer.js +5 -11
- package/dist/server/app-rsc-route-matching.d.ts +20 -0
- package/dist/server/app-rsc-route-matching.js +87 -11
- package/dist/server/app-segment-config.js +15 -5
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +8 -6
- package/dist/server/app-ssr-entry.js +4 -1
- package/dist/server/app-ssr-stream.d.ts +2 -7
- package/dist/server/app-ssr-stream.js +5 -10
- package/dist/server/cache-proof.js +1 -1
- package/dist/server/config-headers.d.ts +24 -0
- package/dist/server/config-headers.js +52 -0
- package/dist/server/default-global-error-module.d.ts +3 -1
- package/dist/server/default-not-found-module.d.ts +3 -1
- package/dist/server/dev-initial-server-error.d.ts +1 -1
- package/dist/server/dev-lockfile.js +2 -3
- package/dist/server/dev-route-files.js +1 -1
- package/dist/server/dev-server.js +281 -173
- package/dist/server/dev-stack-sourcemap.js +4 -3
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +3 -1
- package/dist/server/image-optimization.js +2 -2
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/instrumentation.js +2 -2
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/metadata-routes.js +4 -4
- package/dist/server/middleware-matcher-pattern.d.ts +22 -0
- package/dist/server/middleware-matcher-pattern.js +219 -0
- package/dist/server/middleware-matcher.d.ts +2 -7
- package/dist/server/middleware-matcher.js +13 -60
- package/dist/server/middleware-path-to-regexp.d.ts +14 -0
- package/dist/server/middleware-path-to-regexp.js +228 -0
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-runtime.js +5 -4
- package/dist/server/middleware.d.ts +2 -1
- package/dist/server/middleware.js +3 -2
- package/dist/server/navigation-planner.d.ts +2 -0
- package/dist/server/navigation-planner.js +8 -2
- package/dist/server/next-error-digest.d.ts +9 -24
- package/dist/server/next-error-digest.js +23 -15
- package/dist/server/operation-token.js +1 -1
- package/dist/server/pages-body-parser-config.js +2 -1
- package/dist/server/pages-data-route.d.ts +11 -1
- package/dist/server/pages-data-route.js +16 -1
- package/dist/server/pages-dev-hydration.d.ts +14 -0
- package/dist/server/pages-dev-hydration.js +83 -0
- package/dist/server/pages-dev-module-url.js +2 -2
- package/dist/server/pages-get-initial-props.d.ts +15 -2
- package/dist/server/pages-get-initial-props.js +16 -6
- package/dist/server/pages-node-compat.d.ts +13 -6
- package/dist/server/pages-node-compat.js +44 -45
- package/dist/server/pages-page-data.d.ts +4 -2
- package/dist/server/pages-page-data.js +20 -10
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +74 -43
- package/dist/server/pages-page-response.d.ts +2 -2
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-preview.d.ts +26 -0
- package/dist/server/pages-preview.js +165 -0
- package/dist/server/pages-readiness.d.ts +5 -4
- package/dist/server/pages-readiness.js +4 -2
- package/dist/server/pages-request-pipeline.d.ts +1 -0
- package/dist/server/pages-request-pipeline.js +25 -11
- package/dist/server/pages-router-entry.js +6 -0
- package/dist/server/prerender-route-params.js +2 -2
- package/dist/server/prod-server.d.ts +1 -4
- package/dist/server/prod-server.js +44 -30
- package/dist/server/request-pipeline.d.ts +15 -29
- package/dist/server/request-pipeline.js +25 -60
- package/dist/server/rsc-stream-hints.js +122 -18
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/server/static-file-cache.js +7 -8
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/app.d.ts +1 -1
- package/dist/shims/cache-request-state.d.ts +27 -1
- package/dist/shims/cache-request-state.js +60 -1
- package/dist/shims/cache-runtime.d.ts +12 -1
- package/dist/shims/cache-runtime.js +22 -7
- package/dist/shims/cache.d.ts +5 -5
- package/dist/shims/cache.js +28 -11
- package/dist/shims/constants.js +1 -1
- package/dist/shims/document.d.ts +42 -83
- package/dist/shims/document.js +62 -53
- package/dist/shims/dynamic.d.ts +5 -25
- package/dist/shims/dynamic.js +29 -8
- package/dist/shims/error-boundary.d.ts +4 -4
- package/dist/shims/error.d.ts +22 -6
- package/dist/shims/error.js +53 -15
- package/dist/shims/fetch-cache.js +13 -4
- package/dist/shims/font-google-base.d.ts +11 -4
- package/dist/shims/font-local.d.ts +10 -3
- package/dist/shims/font-utils.js +1 -1
- package/dist/shims/form.d.ts +1 -1
- package/dist/shims/head.d.ts +13 -2
- package/dist/shims/head.js +6 -6
- package/dist/shims/headers.d.ts +28 -31
- package/dist/shims/headers.js +115 -53
- package/dist/shims/image.d.ts +27 -37
- package/dist/shims/image.js +21 -14
- package/dist/shims/internal/cookie-serialize.d.ts +3 -1
- package/dist/shims/internal/cookie-serialize.js +3 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
- package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
- package/dist/shims/internal/utils.d.ts +3 -3
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/legacy-image.d.ts +3 -37
- package/dist/shims/legacy-image.js +6 -16
- package/dist/shims/link.d.ts +16 -21
- package/dist/shims/link.js +25 -13
- package/dist/shims/navigation-context-state.d.ts +1 -1
- package/dist/shims/navigation-errors.d.ts +2 -1
- package/dist/shims/navigation-errors.js +9 -13
- package/dist/shims/navigation.d.ts +8 -4
- package/dist/shims/navigation.js +29 -18
- package/dist/shims/next-shims-augmentations.d.ts +1 -0
- package/dist/shims/next-shims-public.d.ts +1 -0
- package/dist/shims/public-shim-map.json.js +103 -0
- package/dist/shims/readonly-url-search-params.d.ts +3 -3
- package/dist/shims/readonly-url-search-params.js +3 -3
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router.d.ts +57 -22
- package/dist/shims/router.js +178 -46
- package/dist/shims/script.d.ts +6 -10
- package/dist/shims/script.js +7 -4
- package/dist/shims/server.d.ts +45 -22
- package/dist/shims/server.js +46 -7
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/thenable-params.js +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-safety.d.ts +1 -1
- package/dist/shims/url-safety.js +2 -2
- package/dist/typegen.d.ts +8 -2
- package/dist/typegen.js +84 -25
- package/dist/utils/client-build-manifest.js +2 -2
- package/dist/utils/client-entry-manifest.js +1 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/commonjs-loader.js +3 -3
- package/dist/utils/domain-locale.d.ts +2 -2
- package/dist/utils/external-url.d.ts +5 -0
- package/dist/utils/external-url.js +7 -0
- package/dist/utils/mdx-scan.js +1 -1
- package/dist/utils/path.d.ts +1 -13
- package/dist/utils/path.js +1 -15
- package/dist/utils/plugin-options.d.ts +4 -0
- package/dist/utils/plugin-options.js +8 -0
- package/dist/utils/project.d.ts +0 -6
- package/dist/utils/project.js +2 -8
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/redirect-digest.d.ts +9 -0
- package/dist/utils/redirect-digest.js +25 -0
- package/dist/utils/regex-safety.d.ts +8 -0
- package/dist/utils/regex-safety.js +737 -0
- package/dist/utils/vinext-root.js +1 -1
- package/dist/utils/vite-version.d.ts +5 -2
- package/dist/utils/vite-version.js +43 -17
- package/package.json +16 -4
- /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
- /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
- /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
|
@@ -20,7 +20,9 @@ import { buildAppRouteGraph, computeAppRouteStaticSiblings, computeRootParamName
|
|
|
20
20
|
let cachedGraph = null;
|
|
21
21
|
let cachedAppDir = null;
|
|
22
22
|
let cachedPageExtensionsKey = null;
|
|
23
|
+
let cacheGeneration = 0;
|
|
23
24
|
function invalidateAppRouteCache() {
|
|
25
|
+
cacheGeneration++;
|
|
24
26
|
cachedGraph = null;
|
|
25
27
|
cachedAppDir = null;
|
|
26
28
|
cachedPageExtensionsKey = null;
|
|
@@ -30,25 +32,24 @@ function invalidateAppRouteCache() {
|
|
|
30
32
|
* TODO(#726): Layer 4 should consume this read model directly once the
|
|
31
33
|
* navigation planner owns route graph facts.
|
|
32
34
|
*
|
|
33
|
-
* `appDir` must be forward-slash — callers normalize it at their entry, and it
|
|
34
|
-
* flows into `buildAppRouteGraph`, which builds every path with `path.posix.*`.
|
|
35
|
-
*
|
|
36
35
|
* @internal
|
|
37
36
|
*/
|
|
38
37
|
async function appRouteGraph(appDir, pageExtensions, matcher) {
|
|
39
38
|
matcher ??= createValidFileMatcher(pageExtensions);
|
|
40
39
|
const pageExtensionsKey = JSON.stringify(matcher.extensions);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
while (true) {
|
|
41
|
+
if (cachedGraph && cachedAppDir === appDir && cachedPageExtensionsKey === pageExtensionsKey) return cachedGraph;
|
|
42
|
+
const scanGeneration = cacheGeneration;
|
|
43
|
+
const graph = await buildAppRouteGraph(appDir, matcher);
|
|
44
|
+
if (scanGeneration !== cacheGeneration) continue;
|
|
45
|
+
cachedGraph = graph;
|
|
46
|
+
cachedAppDir = appDir;
|
|
47
|
+
cachedPageExtensionsKey = pageExtensionsKey;
|
|
48
|
+
return graph;
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* Scan the app/ directory and return a list of routes.
|
|
50
|
-
*
|
|
51
|
-
* `appDir` must be forward-slash — it is forwarded to `appRouteGraph`.
|
|
52
53
|
*/
|
|
53
54
|
async function appRouter(appDir, pageExtensions, matcher) {
|
|
54
55
|
return (await appRouteGraph(appDir, pageExtensions, matcher)).routes;
|
|
@@ -21,38 +21,24 @@ declare function findFileWithExtensions(basePath: string, matcher: ValidFileMatc
|
|
|
21
21
|
/**
|
|
22
22
|
* Find a file by basename and configured page extension in a directory.
|
|
23
23
|
* Returns the first matching absolute path, or null if not found.
|
|
24
|
-
*
|
|
25
|
-
* `dir` must be forward-slash. The returned path is built with `path.posix.join`,
|
|
26
|
-
* so it is forward-slash too.
|
|
27
24
|
*/
|
|
28
25
|
declare function findFileWithExts(dir: string, name: string, matcher: ValidFileMatcher): string | null;
|
|
29
26
|
/**
|
|
30
|
-
*
|
|
31
|
-
* `.mjs/.mts`). When the user configures `pageExtensions` with values Vite
|
|
32
|
-
* does not know about — e.g. `["platform.tsx", "tsx", "mdx"]` from the
|
|
33
|
-
* Next.js `resolve-extensions` fixture — extensionless imports of those
|
|
34
|
-
* files fail to resolve, and the build crashes with "Custom deploy script
|
|
35
|
-
* failed: undefined (1)".
|
|
36
|
-
*
|
|
37
|
-
* Build the merged extension list that Vite should use:
|
|
27
|
+
* Add the config extensions produced by `vinext init` to vinext's resolver.
|
|
38
28
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* user's pageExtensions include them, but `vinext init` renames CJS config
|
|
44
|
-
* files (e.g. `tailwind.config.js` → `tailwind.config.cjs`) when it adds
|
|
45
|
-
* `"type": "module"`, and app code imports those extensionlessly
|
|
46
|
-
* (`import cfg from "../tailwind.config"`). Without these, the bundle fails
|
|
47
|
-
* with "[UNRESOLVED_IMPORT] Could not resolve '../tailwind.config'".
|
|
29
|
+
* `pageExtensions` is intentionally not part of module resolution. Next.js
|
|
30
|
+
* uses it to discover route files; custom module extensions are configured
|
|
31
|
+
* separately through `turbopack.resolveExtensions` or webpack
|
|
32
|
+
* `resolve.extensions`.
|
|
48
33
|
*
|
|
49
|
-
* The
|
|
50
|
-
* Next.js
|
|
34
|
+
* The default order preserves vinext's existing module-resolution behavior
|
|
35
|
+
* and matches Next.js Turbopack for overlapping JavaScript and TypeScript
|
|
36
|
+
* extensions.
|
|
51
37
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
38
|
+
* `.cjs`/`.cts` go last because `vinext init` renames CJS config files when it
|
|
39
|
+
* adds `"type": "module"`, and app code may import those files extensionlessly.
|
|
54
40
|
*/
|
|
55
|
-
declare function buildViteResolveExtensions(
|
|
41
|
+
declare function buildViteResolveExtensions(viteExtensions?: readonly string[]): string[];
|
|
56
42
|
/**
|
|
57
43
|
* Normalize an explicit Next.js resolver extension list for Vite.
|
|
58
44
|
*
|
|
@@ -66,9 +52,8 @@ declare function normalizeViteResolveExtensions(extensions: readonly string[]):
|
|
|
66
52
|
* Use function-form exclude for Node < 22.14 compatibility.
|
|
67
53
|
*
|
|
68
54
|
* Yields forward-slash relative paths: node's glob emits native (backslash)
|
|
69
|
-
* separators on Windows, so each match
|
|
70
|
-
*
|
|
71
|
-
* forward-slash ids.
|
|
55
|
+
* separators on Windows, so each match goes through `toSlash` — this is the
|
|
56
|
+
* boundary where external fs output enters the canonical forward-slash space.
|
|
72
57
|
*/
|
|
73
58
|
declare function scanWithExtensions(stem: string, cwd: string, extensions: readonly string[], exclude?: (name: string) => boolean): AsyncGenerator<string>;
|
|
74
59
|
//#endregion
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { escapeRegExp } from "../utils/regex.js";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
4
|
import { glob } from "node:fs/promises";
|
|
6
5
|
//#region src/routing/file-matcher.ts
|
|
7
6
|
const DEFAULT_PAGE_EXTENSIONS = [
|
|
@@ -10,6 +9,15 @@ const DEFAULT_PAGE_EXTENSIONS = [
|
|
|
10
9
|
"jsx",
|
|
11
10
|
"js"
|
|
12
11
|
];
|
|
12
|
+
const DEFAULT_VINEXT_RESOLVE_EXTENSIONS = [
|
|
13
|
+
".tsx",
|
|
14
|
+
".ts",
|
|
15
|
+
".jsx",
|
|
16
|
+
".js",
|
|
17
|
+
".mjs",
|
|
18
|
+
".mts",
|
|
19
|
+
".json"
|
|
20
|
+
];
|
|
13
21
|
function normalizePageExtensions(pageExtensions) {
|
|
14
22
|
if (!Array.isArray(pageExtensions) || pageExtensions.length === 0) return [...DEFAULT_PAGE_EXTENSIONS];
|
|
15
23
|
const filtered = pageExtensions.filter((ext) => typeof ext === "string").map((ext) => ext.trim().replace(/^\.+/, "")).filter((ext) => ext.length > 0);
|
|
@@ -19,6 +27,10 @@ function buildExtensionGlob(stem, extensions) {
|
|
|
19
27
|
if (extensions.length === 1) return `${stem}.${extensions[0]}`;
|
|
20
28
|
return `${stem}.{${extensions.join(",")}}`;
|
|
21
29
|
}
|
|
30
|
+
function includeDotDirectoryMatches(pattern) {
|
|
31
|
+
if (!pattern.startsWith("**/")) return pattern;
|
|
32
|
+
return `{**,**/.*/**}/${pattern.slice(3)}`;
|
|
33
|
+
}
|
|
22
34
|
/**
|
|
23
35
|
* Ported in spirit from Next.js createValidFileMatcher:
|
|
24
36
|
* packages/next/src/server/lib/find-page-file.ts
|
|
@@ -67,58 +79,34 @@ function findFileWithExtensions(basePath, matcher) {
|
|
|
67
79
|
/**
|
|
68
80
|
* Find a file by basename and configured page extension in a directory.
|
|
69
81
|
* Returns the first matching absolute path, or null if not found.
|
|
70
|
-
*
|
|
71
|
-
* `dir` must be forward-slash. The returned path is built with `path.posix.join`,
|
|
72
|
-
* so it is forward-slash too.
|
|
73
82
|
*/
|
|
74
83
|
function findFileWithExts(dir, name, matcher) {
|
|
75
84
|
for (const ext of matcher.dottedExtensions) {
|
|
76
|
-
const filePath = path.
|
|
85
|
+
const filePath = path.join(dir, name + ext);
|
|
77
86
|
if (existsSync(filePath)) return filePath;
|
|
78
87
|
}
|
|
79
88
|
return null;
|
|
80
89
|
}
|
|
81
90
|
/**
|
|
82
|
-
*
|
|
83
|
-
* `.mjs/.mts`). When the user configures `pageExtensions` with values Vite
|
|
84
|
-
* does not know about — e.g. `["platform.tsx", "tsx", "mdx"]` from the
|
|
85
|
-
* Next.js `resolve-extensions` fixture — extensionless imports of those
|
|
86
|
-
* files fail to resolve, and the build crashes with "Custom deploy script
|
|
87
|
-
* failed: undefined (1)".
|
|
88
|
-
*
|
|
89
|
-
* Build the merged extension list that Vite should use:
|
|
91
|
+
* Add the config extensions produced by `vinext init` to vinext's resolver.
|
|
90
92
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* user's pageExtensions include them, but `vinext init` renames CJS config
|
|
96
|
-
* files (e.g. `tailwind.config.js` → `tailwind.config.cjs`) when it adds
|
|
97
|
-
* `"type": "module"`, and app code imports those extensionlessly
|
|
98
|
-
* (`import cfg from "../tailwind.config"`). Without these, the bundle fails
|
|
99
|
-
* with "[UNRESOLVED_IMPORT] Could not resolve '../tailwind.config'".
|
|
93
|
+
* `pageExtensions` is intentionally not part of module resolution. Next.js
|
|
94
|
+
* uses it to discover route files; custom module extensions are configured
|
|
95
|
+
* separately through `turbopack.resolveExtensions` or webpack
|
|
96
|
+
* `resolve.extensions`.
|
|
100
97
|
*
|
|
101
|
-
* The
|
|
102
|
-
* Next.js
|
|
98
|
+
* The default order preserves vinext's existing module-resolution behavior
|
|
99
|
+
* and matches Next.js Turbopack for overlapping JavaScript and TypeScript
|
|
100
|
+
* extensions.
|
|
103
101
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
102
|
+
* `.cjs`/`.cts` go last because `vinext init` renames CJS config files when it
|
|
103
|
+
* adds `"type": "module"`, and app code may import those files extensionlessly.
|
|
106
104
|
*/
|
|
107
|
-
function buildViteResolveExtensions(
|
|
108
|
-
".mjs",
|
|
109
|
-
".js",
|
|
110
|
-
".mts",
|
|
111
|
-
".ts",
|
|
112
|
-
".jsx",
|
|
113
|
-
".tsx",
|
|
114
|
-
".json"
|
|
115
|
-
]) {
|
|
116
|
-
const dotted = normalizePageExtensions(pageExtensions).map((ext) => `.${ext}`);
|
|
105
|
+
function buildViteResolveExtensions(viteExtensions = DEFAULT_VINEXT_RESOLVE_EXTENSIONS) {
|
|
117
106
|
const seen = /* @__PURE__ */ new Set();
|
|
118
107
|
const result = [];
|
|
119
108
|
for (const ext of [
|
|
120
|
-
...
|
|
121
|
-
...viteDefaults,
|
|
109
|
+
...viteExtensions,
|
|
122
110
|
".cjs",
|
|
123
111
|
".cts"
|
|
124
112
|
]) {
|
|
@@ -153,16 +141,15 @@ function normalizeViteResolveExtensions(extensions) {
|
|
|
153
141
|
* Use function-form exclude for Node < 22.14 compatibility.
|
|
154
142
|
*
|
|
155
143
|
* Yields forward-slash relative paths: node's glob emits native (backslash)
|
|
156
|
-
* separators on Windows, so each match
|
|
157
|
-
*
|
|
158
|
-
* forward-slash ids.
|
|
144
|
+
* separators on Windows, so each match goes through `toSlash` — this is the
|
|
145
|
+
* boundary where external fs output enters the canonical forward-slash space.
|
|
159
146
|
*/
|
|
160
147
|
async function* scanWithExtensions(stem, cwd, extensions, exclude) {
|
|
161
|
-
const pattern = buildExtensionGlob(stem, extensions);
|
|
148
|
+
const pattern = includeDotDirectoryMatches(buildExtensionGlob(stem, extensions));
|
|
162
149
|
for await (const file of glob(pattern, {
|
|
163
150
|
cwd,
|
|
164
151
|
...exclude ? { exclude } : {}
|
|
165
|
-
})) yield
|
|
152
|
+
})) yield toSlash(file);
|
|
166
153
|
}
|
|
167
154
|
//#endregion
|
|
168
155
|
export { buildViteResolveExtensions, createValidFileMatcher, findFileWithExtensions, findFileWithExts, normalizePageExtensions, normalizeViteResolveExtensions, scanWithExtensions };
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { decodeRouteSegment, sortRoutes } from "./utils.js";
|
|
2
3
|
import { createValidFileMatcher, scanWithExtensions } from "./file-matcher.js";
|
|
3
4
|
import { patternToNextFormat, validateRoutePatterns } from "./route-validation.js";
|
|
4
|
-
import { createRouteTrieCache,
|
|
5
|
-
import path from "node:path";
|
|
5
|
+
import { createRouteTrieCache, matchRouteWithTrieRawPathname } from "./route-matching.js";
|
|
6
6
|
//#region src/routing/pages-router.ts
|
|
7
7
|
/** Next.js special pages that should not produce routes. */
|
|
8
|
-
const RESERVED_PAGE_NAMES = new Set([
|
|
8
|
+
const RESERVED_PAGE_NAMES = /* @__PURE__ */ new Set([
|
|
9
9
|
"_app",
|
|
10
10
|
"_document",
|
|
11
11
|
"_error"
|
|
12
12
|
]);
|
|
13
13
|
const routeCache = /* @__PURE__ */ new Map();
|
|
14
|
+
let routeCacheGeneration = 0;
|
|
14
15
|
/**
|
|
15
16
|
* Invalidate cached routes for a given pages directory.
|
|
16
17
|
* Called by the file watcher when pages are added/removed.
|
|
17
18
|
*/
|
|
18
19
|
function invalidateRouteCache(pagesDir) {
|
|
20
|
+
routeCacheGeneration++;
|
|
19
21
|
for (const key of routeCache.keys()) if (key.startsWith(`pages:${pagesDir}:`) || key.startsWith(`api:${pagesDir}:`)) routeCache.delete(key);
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
@@ -32,20 +34,7 @@ function invalidateRouteCache(pagesDir) {
|
|
|
32
34
|
*/
|
|
33
35
|
async function pagesRouter(pagesDir, pageExtensions, matcher) {
|
|
34
36
|
matcher ??= createValidFileMatcher(pageExtensions);
|
|
35
|
-
|
|
36
|
-
const cached = routeCache.get(cacheKey);
|
|
37
|
-
if (cached) return cached.promise;
|
|
38
|
-
const promise = scanPageRoutes(pagesDir, matcher);
|
|
39
|
-
routeCache.set(cacheKey, {
|
|
40
|
-
routes: [],
|
|
41
|
-
promise
|
|
42
|
-
});
|
|
43
|
-
const routes = await promise;
|
|
44
|
-
routeCache.set(cacheKey, {
|
|
45
|
-
routes,
|
|
46
|
-
promise
|
|
47
|
-
});
|
|
48
|
-
return routes;
|
|
37
|
+
return getCachedRoutes(`pages:${pagesDir}:${JSON.stringify(matcher.extensions)}`, () => scanPageRoutes(pagesDir, matcher));
|
|
49
38
|
}
|
|
50
39
|
async function scanPageRoutes(pagesDir, matcher) {
|
|
51
40
|
const routes = [];
|
|
@@ -114,7 +103,7 @@ const trieCache = createRouteTrieCache();
|
|
|
114
103
|
* Returns the matched params or null if no match.
|
|
115
104
|
*/
|
|
116
105
|
function matchRoute(url, routes) {
|
|
117
|
-
return
|
|
106
|
+
return matchRouteWithTrieRawPathname(url, routes, trieCache);
|
|
118
107
|
}
|
|
119
108
|
/**
|
|
120
109
|
* Scan the pages/api/ directory and return API routes.
|
|
@@ -126,20 +115,25 @@ function matchRoute(url, routes) {
|
|
|
126
115
|
*/
|
|
127
116
|
async function apiRouter(pagesDir, pageExtensions, matcher) {
|
|
128
117
|
matcher ??= createValidFileMatcher(pageExtensions);
|
|
129
|
-
|
|
118
|
+
return getCachedRoutes(`api:${pagesDir}:${JSON.stringify(matcher.extensions)}`, () => scanApiRoutes(pagesDir, matcher));
|
|
119
|
+
}
|
|
120
|
+
async function getCachedRoutes(cacheKey, scan) {
|
|
130
121
|
const cached = routeCache.get(cacheKey);
|
|
131
|
-
if (cached) return cached
|
|
132
|
-
const promise =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
122
|
+
if (cached) return cached;
|
|
123
|
+
const promise = (async () => {
|
|
124
|
+
while (true) {
|
|
125
|
+
const scanGeneration = routeCacheGeneration;
|
|
126
|
+
const routes = await scan();
|
|
127
|
+
if (scanGeneration === routeCacheGeneration) return routes;
|
|
128
|
+
}
|
|
129
|
+
})();
|
|
130
|
+
routeCache.set(cacheKey, promise);
|
|
131
|
+
try {
|
|
132
|
+
return await promise;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (routeCache.get(cacheKey) === promise) routeCache.delete(cacheKey);
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
143
137
|
}
|
|
144
138
|
async function scanApiRoutes(pagesDir, matcher) {
|
|
145
139
|
const apiDir = path.join(pagesDir, "api");
|
|
@@ -152,7 +146,7 @@ async function scanApiRoutes(pagesDir, matcher) {
|
|
|
152
146
|
}
|
|
153
147
|
const routes = [];
|
|
154
148
|
for (const file of files) {
|
|
155
|
-
const route = fileToRoute(path.
|
|
149
|
+
const route = fileToRoute(path.join("api", file), pagesDir, matcher);
|
|
156
150
|
if (route) routes.push(route);
|
|
157
151
|
}
|
|
158
152
|
validateRoutePatterns(routes.map((route) => route.pattern));
|
|
@@ -23,5 +23,18 @@ declare function matchRouteWithTrie<R extends {
|
|
|
23
23
|
route: R;
|
|
24
24
|
params: Record<string, string | string[]>;
|
|
25
25
|
} | null;
|
|
26
|
+
/**
|
|
27
|
+
* Match a filesystem route against the request's raw encoded pathname.
|
|
28
|
+
*
|
|
29
|
+
* Next.js compares static route identity before decoding, so `/%61bout` does
|
|
30
|
+
* not select the filesystem route `/about`. Dynamic captures are still decoded
|
|
31
|
+
* exactly once by `trieMatch`, matching `getRouteMatcher` upstream.
|
|
32
|
+
*/
|
|
33
|
+
declare function matchRouteWithTrieRawPathname<R extends {
|
|
34
|
+
patternParts: string[];
|
|
35
|
+
}>(url: string, routes: R[], cache: RouteTrieCache<R>): {
|
|
36
|
+
route: R;
|
|
37
|
+
params: Record<string, string | string[]>;
|
|
38
|
+
} | null;
|
|
26
39
|
//#endregion
|
|
27
|
-
export { createRouteTrieCache, matchRouteWithTrie };
|
|
40
|
+
export { createRouteTrieCache, matchRouteWithTrie, matchRouteWithTrieRawPathname };
|
|
@@ -38,5 +38,17 @@ function matchRouteWithTrie(url, routes, cache) {
|
|
|
38
38
|
const urlParts = normalizedUrl.split("/").filter(Boolean);
|
|
39
39
|
return trieMatch(getOrBuildTrie(cache, routes), urlParts);
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Match a filesystem route against the request's raw encoded pathname.
|
|
43
|
+
*
|
|
44
|
+
* Next.js compares static route identity before decoding, so `/%61bout` does
|
|
45
|
+
* not select the filesystem route `/about`. Dynamic captures are still decoded
|
|
46
|
+
* exactly once by `trieMatch`, matching `getRouteMatcher` upstream.
|
|
47
|
+
*/
|
|
48
|
+
function matchRouteWithTrieRawPathname(url, routes, cache) {
|
|
49
|
+
const pathname = url.split("?")[0];
|
|
50
|
+
const urlParts = (pathname === "/" ? "/" : pathname.replace(/\/$/, "")).split("/").filter(Boolean);
|
|
51
|
+
return trieMatch(getOrBuildTrie(cache, routes), urlParts);
|
|
52
|
+
}
|
|
41
53
|
//#endregion
|
|
42
|
-
export { createRouteTrieCache, matchRouteWithTrie };
|
|
54
|
+
export { createRouteTrieCache, matchRouteWithTrie, matchRouteWithTrieRawPathname };
|
|
@@ -4,6 +4,7 @@ declare function routePatternParts(pathname: string): string[];
|
|
|
4
4
|
declare function routePattern(pathname: string): string;
|
|
5
5
|
declare function fillRoutePatternSegments(pathname: string, params: RoutePatternParams): string | null;
|
|
6
6
|
declare function matchRoutePattern(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
|
|
7
|
+
declare function matchRoutePatternRaw(urlParts: readonly string[], patternParts: readonly string[]): RoutePatternParams | null;
|
|
7
8
|
declare function matchRoutePatternPrefix(pathParts: readonly string[], patternParts: readonly string[]): boolean;
|
|
8
9
|
declare function matchRoutePatternWithOptionalDynamicSegments(pathParts: readonly string[], patternParts: readonly string[]): boolean;
|
|
9
10
|
/**
|
|
@@ -61,4 +62,4 @@ declare function normalizeStaticPathname(pathname: string): string;
|
|
|
61
62
|
*/
|
|
62
63
|
declare function normalizeStaticPathsEntry(entry: StaticPathsEntry, routePattern: string): NormalizedStaticPathsEntry;
|
|
63
64
|
//#endregion
|
|
64
|
-
export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
65
|
+
export { RoutePatternParams, StaticPathsEntry, fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
@@ -56,6 +56,11 @@ function fillRoutePatternSegments(pathname, params) {
|
|
|
56
56
|
return resolvedSegments.length > 0 ? `/${resolvedSegments.join("/")}` : "/";
|
|
57
57
|
}
|
|
58
58
|
function matchRoutePattern(urlParts, patternParts) {
|
|
59
|
+
const params = matchRoutePatternRaw(urlParts, patternParts);
|
|
60
|
+
if (params) decodeMatchedParams(params);
|
|
61
|
+
return params;
|
|
62
|
+
}
|
|
63
|
+
function matchRoutePatternRaw(urlParts, patternParts) {
|
|
59
64
|
const params = Object.create(null);
|
|
60
65
|
function matchFrom(urlIndex, patternIndex) {
|
|
61
66
|
if (patternIndex === patternParts.length) return urlIndex === urlParts.length;
|
|
@@ -83,9 +88,7 @@ function matchRoutePattern(urlParts, patternParts) {
|
|
|
83
88
|
if (urlIndex >= urlParts.length || urlParts[urlIndex] !== patternPart) return false;
|
|
84
89
|
return matchFrom(urlIndex + 1, patternIndex + 1);
|
|
85
90
|
}
|
|
86
|
-
|
|
87
|
-
decodeMatchedParams(params);
|
|
88
|
-
return params;
|
|
91
|
+
return matchFrom(0, 0) ? params : null;
|
|
89
92
|
}
|
|
90
93
|
function matchRoutePatternPrefix(pathParts, patternParts) {
|
|
91
94
|
let pathIndex = 0;
|
|
@@ -162,4 +165,4 @@ function normalizeStaticPathsEntry(entry, routePattern) {
|
|
|
162
165
|
return { params };
|
|
163
166
|
}
|
|
164
167
|
//#endregion
|
|
165
|
-
export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
168
|
+
export { fillRoutePatternSegments, matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternRaw, matchRoutePatternWithOptionalDynamicSegments, normalizeStaticPathname, normalizeStaticPathsEntry, routePattern, routePatternParts };
|
|
@@ -63,5 +63,9 @@ declare function trieMatch<R>(root: TrieNode<R>, urlParts: string[]): {
|
|
|
63
63
|
route: R;
|
|
64
64
|
params: Record<string, string | string[]>;
|
|
65
65
|
} | null;
|
|
66
|
+
declare function trieMatchRaw<R>(root: TrieNode<R>, urlParts: string[]): {
|
|
67
|
+
route: R;
|
|
68
|
+
params: Record<string, string | string[]>;
|
|
69
|
+
} | null;
|
|
66
70
|
//#endregion
|
|
67
|
-
export { TrieNode, buildRouteTrie, trieMatch };
|
|
71
|
+
export { TrieNode, buildRouteTrie, trieMatch, trieMatchRaw };
|
|
@@ -92,10 +92,13 @@ function buildRouteTrie(routes) {
|
|
|
92
92
|
* @returns Match result with route and extracted params, or null
|
|
93
93
|
*/
|
|
94
94
|
function trieMatch(root, urlParts) {
|
|
95
|
-
const result =
|
|
95
|
+
const result = trieMatchRaw(root, urlParts);
|
|
96
96
|
if (result) decodeMatchedParams(result.params);
|
|
97
97
|
return result;
|
|
98
98
|
}
|
|
99
|
+
function trieMatchRaw(root, urlParts) {
|
|
100
|
+
return match(root, urlParts, 0, []);
|
|
101
|
+
}
|
|
99
102
|
function match(node, urlParts, index, entries) {
|
|
100
103
|
if (index === urlParts.length) {
|
|
101
104
|
if (node.route !== null) return {
|
|
@@ -140,4 +143,4 @@ function match(node, urlParts, index, entries) {
|
|
|
140
143
|
return null;
|
|
141
144
|
}
|
|
142
145
|
//#endregion
|
|
143
|
-
export { buildRouteTrie, trieMatch };
|
|
146
|
+
export { buildRouteTrie, trieMatch, trieMatchRaw };
|
|
@@ -8,7 +8,7 @@ import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, resolveBodyParserConfig } from "./pa
|
|
|
8
8
|
import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
|
|
9
9
|
import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
|
|
10
10
|
import { performOnDemandRevalidate } from "./pages-revalidate.js";
|
|
11
|
-
import { attachPagesRequestCookies } from "./pages-node-compat.js";
|
|
11
|
+
import { attachPagesPreviewApi, attachPagesRequestCookies } from "./pages-node-compat.js";
|
|
12
12
|
import { isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
13
13
|
import { decode } from "node:querystring";
|
|
14
14
|
import { Buffer } from "node:buffer";
|
|
@@ -166,41 +166,49 @@ function enhanceApiObjects(req, res, query, body) {
|
|
|
166
166
|
query
|
|
167
167
|
});
|
|
168
168
|
attachPagesRequestCookies(apiReq);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
const apiRes = Object.assign(res, {
|
|
170
|
+
status(code) {
|
|
171
|
+
this.statusCode = code;
|
|
172
|
+
return this;
|
|
173
|
+
},
|
|
174
|
+
json(data) {
|
|
175
|
+
this.setHeader("Content-Type", "application/json");
|
|
176
|
+
this.end(JSON.stringify(data));
|
|
177
|
+
},
|
|
178
|
+
send(data) {
|
|
179
|
+
if (Buffer.isBuffer(data)) {
|
|
180
|
+
if (!this.getHeader("Content-Type")) this.setHeader("Content-Type", "application/octet-stream");
|
|
181
|
+
this.setHeader("Content-Length", String(data.length));
|
|
182
|
+
this.end(data);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (typeof data === "object" && data !== null) {
|
|
177
186
|
this.setHeader("Content-Type", "application/json");
|
|
178
187
|
this.end(JSON.stringify(data));
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
this.setHeader("Content-Type", "application/json");
|
|
189
|
-
this.end(JSON.stringify(data));
|
|
190
|
-
} else {
|
|
191
|
-
if (!this.getHeader("Content-Type")) this.setHeader("Content-Type", "text/plain");
|
|
192
|
-
this.end(String(data));
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
redirect(statusOrUrl, url) {
|
|
196
|
-
if (typeof statusOrUrl === "string") this.writeHead(307, { Location: statusOrUrl });
|
|
197
|
-
else this.writeHead(statusOrUrl, { Location: url ?? "" });
|
|
198
|
-
this.end();
|
|
199
|
-
},
|
|
200
|
-
async revalidate(urlPath, opts) {
|
|
201
|
-
await performOnDemandRevalidate(req, urlPath, opts);
|
|
188
|
+
} else {
|
|
189
|
+
if (!this.getHeader("Content-Type")) this.setHeader("Content-Type", "text/plain");
|
|
190
|
+
this.end(String(data));
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
redirect(statusOrUrl, url) {
|
|
194
|
+
if (typeof statusOrUrl === "string") {
|
|
195
|
+
url = statusOrUrl;
|
|
196
|
+
statusOrUrl = 307;
|
|
202
197
|
}
|
|
203
|
-
|
|
198
|
+
if (typeof statusOrUrl !== "number" || typeof url !== "string") throw new Error("Invalid redirect arguments. Please use a single argument URL, e.g. res.redirect('/destination') or use a status code and URL, e.g. res.redirect(307, '/destination').");
|
|
199
|
+
this.writeHead(statusOrUrl, { Location: url });
|
|
200
|
+
this.write(url);
|
|
201
|
+
this.end();
|
|
202
|
+
return this;
|
|
203
|
+
},
|
|
204
|
+
async revalidate(urlPath, opts) {
|
|
205
|
+
await performOnDemandRevalidate(req, urlPath, opts);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
attachPagesPreviewApi(apiReq, apiRes);
|
|
209
|
+
return {
|
|
210
|
+
apiReq,
|
|
211
|
+
apiRes
|
|
204
212
|
};
|
|
205
213
|
}
|
|
206
214
|
/**
|