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
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
//#region src/server/middleware-path-to-regexp.ts
|
|
2
|
+
function lexer(value) {
|
|
3
|
+
const tokens = [];
|
|
4
|
+
let index = 0;
|
|
5
|
+
while (index < value.length) {
|
|
6
|
+
const character = value[index];
|
|
7
|
+
if (character === "*" || character === "+" || character === "?") {
|
|
8
|
+
tokens.push({
|
|
9
|
+
type: "MODIFIER",
|
|
10
|
+
index,
|
|
11
|
+
value: value[index++]
|
|
12
|
+
});
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (character === "\\") {
|
|
16
|
+
tokens.push({
|
|
17
|
+
type: "ESCAPED_CHAR",
|
|
18
|
+
index: index++,
|
|
19
|
+
value: value[index++]
|
|
20
|
+
});
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (character === "{") {
|
|
24
|
+
tokens.push({
|
|
25
|
+
type: "OPEN",
|
|
26
|
+
index,
|
|
27
|
+
value: value[index++]
|
|
28
|
+
});
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (character === "}") {
|
|
32
|
+
tokens.push({
|
|
33
|
+
type: "CLOSE",
|
|
34
|
+
index,
|
|
35
|
+
value: value[index++]
|
|
36
|
+
});
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (character === ":") {
|
|
40
|
+
let name = "";
|
|
41
|
+
let nameEnd = index + 1;
|
|
42
|
+
while (nameEnd < value.length) {
|
|
43
|
+
const code = value.charCodeAt(nameEnd);
|
|
44
|
+
if (code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 95) {
|
|
45
|
+
name += value[nameEnd++];
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (!name) throw new TypeError(`Missing parameter name at ${index}`);
|
|
51
|
+
tokens.push({
|
|
52
|
+
type: "NAME",
|
|
53
|
+
index,
|
|
54
|
+
value: name
|
|
55
|
+
});
|
|
56
|
+
index = nameEnd;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (character === "(") {
|
|
60
|
+
let depth = 1;
|
|
61
|
+
let pattern = "";
|
|
62
|
+
let patternEnd = index + 1;
|
|
63
|
+
if (value[patternEnd] === "?") throw new TypeError(`Pattern cannot start with "?" at ${patternEnd}`);
|
|
64
|
+
while (patternEnd < value.length) {
|
|
65
|
+
if (value[patternEnd] === "\\") {
|
|
66
|
+
pattern += value[patternEnd++] + value[patternEnd++];
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (value[patternEnd] === ")") {
|
|
70
|
+
depth--;
|
|
71
|
+
if (depth === 0) {
|
|
72
|
+
patternEnd++;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
} else if (value[patternEnd] === "(") {
|
|
76
|
+
depth++;
|
|
77
|
+
if (value[patternEnd + 1] !== "?") throw new TypeError(`Capturing groups are not allowed at ${patternEnd}`);
|
|
78
|
+
}
|
|
79
|
+
pattern += value[patternEnd++];
|
|
80
|
+
}
|
|
81
|
+
if (depth) throw new TypeError(`Unbalanced pattern at ${index}`);
|
|
82
|
+
if (!pattern) throw new TypeError(`Missing pattern at ${index}`);
|
|
83
|
+
tokens.push({
|
|
84
|
+
type: "PATTERN",
|
|
85
|
+
index,
|
|
86
|
+
value: pattern
|
|
87
|
+
});
|
|
88
|
+
index = patternEnd;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
tokens.push({
|
|
92
|
+
type: "CHAR",
|
|
93
|
+
index,
|
|
94
|
+
value: value[index++]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
tokens.push({
|
|
98
|
+
type: "END",
|
|
99
|
+
index,
|
|
100
|
+
value: ""
|
|
101
|
+
});
|
|
102
|
+
return tokens;
|
|
103
|
+
}
|
|
104
|
+
function parseMiddlewarePath(value) {
|
|
105
|
+
const tokens = lexer(value);
|
|
106
|
+
const result = [];
|
|
107
|
+
const prefixes = "./";
|
|
108
|
+
const delimiter = "/#?";
|
|
109
|
+
let key = 0;
|
|
110
|
+
let index = 0;
|
|
111
|
+
let path = "";
|
|
112
|
+
const tryConsume = (type) => {
|
|
113
|
+
if (index < tokens.length && tokens[index].type === type) return tokens[index++].value;
|
|
114
|
+
};
|
|
115
|
+
const mustConsume = (type) => {
|
|
116
|
+
const consumed = tryConsume(type);
|
|
117
|
+
if (consumed !== void 0) return consumed;
|
|
118
|
+
const next = tokens[index];
|
|
119
|
+
throw new TypeError(`Unexpected ${next.type} at ${next.index}, expected ${type}`);
|
|
120
|
+
};
|
|
121
|
+
const consumeText = () => {
|
|
122
|
+
let text = "";
|
|
123
|
+
let consumed;
|
|
124
|
+
while ((consumed = tryConsume("CHAR") ?? tryConsume("ESCAPED_CHAR")) !== void 0) text += consumed;
|
|
125
|
+
return text;
|
|
126
|
+
};
|
|
127
|
+
const containsDelimiter = (text) => {
|
|
128
|
+
for (const character of delimiter) if (text.includes(character)) return true;
|
|
129
|
+
return false;
|
|
130
|
+
};
|
|
131
|
+
const defaultPattern = (prefix) => {
|
|
132
|
+
const previous = result[result.length - 1];
|
|
133
|
+
const previousText = prefix || (typeof previous === "string" ? previous : "");
|
|
134
|
+
if (previous && !previousText) {
|
|
135
|
+
const name = typeof previous === "string" ? previous : previous.name;
|
|
136
|
+
throw new TypeError(`Must have text between two parameters, missing text after "${name}"`);
|
|
137
|
+
}
|
|
138
|
+
if (!previousText || containsDelimiter(previousText)) return "[^\\/#\\?]+?";
|
|
139
|
+
return `(?:(?!${escapeRegex(previousText)})[^\\/#\\?])+?`;
|
|
140
|
+
};
|
|
141
|
+
while (index < tokens.length) {
|
|
142
|
+
const character = tryConsume("CHAR");
|
|
143
|
+
const name = tryConsume("NAME");
|
|
144
|
+
const pattern = tryConsume("PATTERN");
|
|
145
|
+
if (name !== void 0 || pattern !== void 0) {
|
|
146
|
+
let prefix = character ?? "";
|
|
147
|
+
if (!prefixes.includes(prefix)) {
|
|
148
|
+
path += prefix;
|
|
149
|
+
prefix = "";
|
|
150
|
+
}
|
|
151
|
+
if (path) {
|
|
152
|
+
result.push(path);
|
|
153
|
+
path = "";
|
|
154
|
+
}
|
|
155
|
+
result.push({
|
|
156
|
+
name: name ?? key++,
|
|
157
|
+
prefix,
|
|
158
|
+
suffix: "",
|
|
159
|
+
pattern: pattern ?? defaultPattern(prefix),
|
|
160
|
+
modifier: tryConsume("MODIFIER") ?? ""
|
|
161
|
+
});
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const text = character ?? tryConsume("ESCAPED_CHAR");
|
|
165
|
+
if (text !== void 0) {
|
|
166
|
+
path += text;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (path) {
|
|
170
|
+
result.push(path);
|
|
171
|
+
path = "";
|
|
172
|
+
}
|
|
173
|
+
if (tryConsume("OPEN") !== void 0) {
|
|
174
|
+
const prefix = consumeText();
|
|
175
|
+
const groupName = tryConsume("NAME") ?? "";
|
|
176
|
+
const groupPattern = tryConsume("PATTERN") ?? "";
|
|
177
|
+
const suffix = consumeText();
|
|
178
|
+
mustConsume("CLOSE");
|
|
179
|
+
result.push({
|
|
180
|
+
name: groupName || (groupPattern ? key++ : ""),
|
|
181
|
+
pattern: groupName && !groupPattern ? defaultPattern(prefix) : groupPattern,
|
|
182
|
+
prefix,
|
|
183
|
+
suffix,
|
|
184
|
+
modifier: tryConsume("MODIFIER") ?? ""
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
mustConsume("END");
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
function escapeRegex(value) {
|
|
193
|
+
return value.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
|
194
|
+
}
|
|
195
|
+
function normalizeMiddlewarePathTokens(tokens) {
|
|
196
|
+
return tokens.map((token) => {
|
|
197
|
+
if (typeof token === "object" && (token.modifier === "*" || token.modifier === "+") && token.prefix === "" && token.suffix === "") return {
|
|
198
|
+
...token,
|
|
199
|
+
prefix: "/"
|
|
200
|
+
};
|
|
201
|
+
return token;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function middlewarePathTokensToRegExp(tokens) {
|
|
205
|
+
const delimiterRegex = `[${escapeRegex("/#?")}]`;
|
|
206
|
+
let route = "^";
|
|
207
|
+
for (const token of tokens) {
|
|
208
|
+
if (typeof token === "string") {
|
|
209
|
+
route += escapeRegex(token);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const prefix = escapeRegex(token.prefix);
|
|
213
|
+
const suffix = escapeRegex(token.suffix);
|
|
214
|
+
if (token.pattern) if (prefix || suffix) if (token.modifier === "+" || token.modifier === "*") {
|
|
215
|
+
const optional = token.modifier === "*" ? "?" : "";
|
|
216
|
+
route += `(?:${prefix}((?:${token.pattern})(?:${suffix}${prefix}(?:${token.pattern}))*)${suffix})${optional}`;
|
|
217
|
+
} else route += `(?:${prefix}(${token.pattern})${suffix})${token.modifier}`;
|
|
218
|
+
else {
|
|
219
|
+
if (token.modifier === "+" || token.modifier === "*") throw new TypeError(`Can not repeat "${token.name}" without a prefix and suffix`);
|
|
220
|
+
route += `(${token.pattern})${token.modifier}`;
|
|
221
|
+
}
|
|
222
|
+
else route += `(?:${prefix}${suffix})${token.modifier}`;
|
|
223
|
+
}
|
|
224
|
+
route += `${delimiterRegex}?$`;
|
|
225
|
+
return new RegExp(route, "i");
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
export { middlewarePathTokensToRegExp, normalizeMiddlewarePathTokens, parseMiddlewarePath };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/server/middleware-response-headers.ts
|
|
2
|
-
const ADDITIVE_RESPONSE_HEADER_NAMES = new Set(["set-cookie", "vary"]);
|
|
2
|
+
const ADDITIVE_RESPONSE_HEADER_NAMES = /* @__PURE__ */ new Set(["set-cookie", "vary"]);
|
|
3
3
|
function mergeVaryHeader(target, value) {
|
|
4
4
|
const existing = target.get("Vary");
|
|
5
5
|
const tokens = (existing ? `${existing}, ${value}` : value).split(",").map((token) => token.trim()).filter((token) => token.length > 0);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
2
3
|
import { addBasePathToPathname, hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
3
4
|
import "./server-globals.js";
|
|
@@ -10,7 +11,6 @@ import { normalizePath } from "./normalize-path.js";
|
|
|
10
11
|
import { matchesMiddleware } from "./middleware-matcher.js";
|
|
11
12
|
import { badRequestResponse, internalServerErrorResponse } from "./http-error-responses.js";
|
|
12
13
|
import { processMiddlewareHeaders } from "./request-pipeline.js";
|
|
13
|
-
import path from "node:path";
|
|
14
14
|
//#region src/server/middleware-runtime.ts
|
|
15
15
|
function isMiddlewareHandler(value) {
|
|
16
16
|
return typeof value === "function";
|
|
@@ -112,10 +112,11 @@ function resolveMiddlewarePathname(request) {
|
|
|
112
112
|
return badRequestResponse();
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
function createNextRequest(request,
|
|
115
|
+
function createNextRequest(request, i18nConfig, basePath, trailingSlash, hadBasePath) {
|
|
116
116
|
const url = new URL(request.url);
|
|
117
117
|
let mwRequest = request.body && !request.bodyUsed ? request.clone() : request;
|
|
118
|
-
const
|
|
118
|
+
const requestPathname = url.pathname;
|
|
119
|
+
const mwPathname = basePath && hadBasePath && !hasBasePath(requestPathname, basePath) ? addBasePathToPathname(requestPathname, basePath) : requestPathname;
|
|
119
120
|
if (mwPathname !== url.pathname) {
|
|
120
121
|
const mwUrl = new URL(url);
|
|
121
122
|
mwUrl.pathname = mwPathname;
|
|
@@ -141,7 +142,7 @@ async function executeMiddleware(options) {
|
|
|
141
142
|
const hadBasePath = options.hadBasePath ?? (!options.basePath || hasBasePath(new URL(options.request.url).pathname, options.basePath));
|
|
142
143
|
const matchPathname = options.basePath ? stripBasePath(normalizedPathname, options.basePath) : normalizedPathname;
|
|
143
144
|
if (!matchesMiddleware(matchPathname, middlewareMatcher(options.module), options.request, options.i18nConfig)) return { continue: true };
|
|
144
|
-
const nextRequest = createNextRequest(options.request,
|
|
145
|
+
const nextRequest = createNextRequest(options.request, options.i18nConfig, options.basePath, options.trailingSlash, hadBasePath);
|
|
145
146
|
if (options.isDataRequest) Object.defineProperty(nextRequest, "__isData", {
|
|
146
147
|
enumerable: false,
|
|
147
148
|
value: true
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextI18nConfig } from "../config/next-config.js";
|
|
2
2
|
import { ValidFileMatcher } from "../routing/file-matcher.js";
|
|
3
|
+
import { NextFetchEvent, NextRequest } from "../shims/server.js";
|
|
3
4
|
import { MiddlewareModule, MiddlewareResult } from "./middleware-runtime.js";
|
|
4
5
|
import { matchPattern, matchesMiddleware } from "./middleware-matcher.js";
|
|
5
6
|
import { ModuleRunner } from "vite/module-runner";
|
|
@@ -57,6 +58,6 @@ declare function findMiddlewareFile(root: string, fileMatcher: ValidFileMatcher,
|
|
|
57
58
|
* @param request - The incoming Request object
|
|
58
59
|
* @returns Middleware result describing what action to take
|
|
59
60
|
*/
|
|
60
|
-
declare function runMiddleware(runner: ModuleRunner, middlewarePath: string, request: Request, i18nConfig?: NextI18nConfig | null, basePath?: string, trailingSlash?: boolean, isDataRequest?: boolean): Promise<MiddlewareResult>;
|
|
61
|
+
declare function runMiddleware(runner: ModuleRunner, middlewarePath: string, request: Request, i18nConfig?: NextI18nConfig | null, basePath?: string, trailingSlash?: boolean, isDataRequest?: boolean, normalizedPathname?: string): Promise<MiddlewareResult>;
|
|
61
62
|
//#endregion
|
|
62
63
|
export { findMiddlewareFile, isProxyFile, matchPattern, matchesMiddleware, resolveMiddlewareHandler, runMiddleware };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { matchPattern, matchesMiddleware } from "./middleware-matcher.js";
|
|
2
3
|
import { resolveMiddlewareModuleHandler, runGeneratedMiddleware } from "./middleware-runtime.js";
|
|
3
4
|
import fs from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
5
|
//#region src/server/middleware.ts
|
|
6
6
|
/**
|
|
7
7
|
* Determine whether a middleware/proxy file path refers to a proxy file.
|
|
@@ -94,7 +94,7 @@ function isMiddlewareModule(value) {
|
|
|
94
94
|
* @param request - The incoming Request object
|
|
95
95
|
* @returns Middleware result describing what action to take
|
|
96
96
|
*/
|
|
97
|
-
async function runMiddleware(runner, middlewarePath, request, i18nConfig, basePath, trailingSlash, isDataRequest) {
|
|
97
|
+
async function runMiddleware(runner, middlewarePath, request, i18nConfig, basePath, trailingSlash, isDataRequest, normalizedPathname) {
|
|
98
98
|
const mod = await runner.import(middlewarePath);
|
|
99
99
|
if (!isMiddlewareModule(mod)) throw new Error(`Middleware module "${middlewarePath}" did not evaluate to an object.`);
|
|
100
100
|
return runGeneratedMiddleware({
|
|
@@ -106,6 +106,7 @@ async function runMiddleware(runner, middlewarePath, request, i18nConfig, basePa
|
|
|
106
106
|
isDataRequest,
|
|
107
107
|
isProxy: isProxyFile(middlewarePath),
|
|
108
108
|
module: mod,
|
|
109
|
+
normalizedPathname,
|
|
109
110
|
request,
|
|
110
111
|
trailingSlash
|
|
111
112
|
});
|
|
@@ -121,6 +121,7 @@ type RscFetchResultFacts = {
|
|
|
121
121
|
compatibilityIdHeader: string | null;
|
|
122
122
|
responseUrl: string | null;
|
|
123
123
|
streamedRedirectTarget: string | null;
|
|
124
|
+
streamedRedirectType?: "push" | "replace" | null;
|
|
124
125
|
};
|
|
125
126
|
type RscRedirectFollow = {
|
|
126
127
|
href: string;
|
|
@@ -142,6 +143,7 @@ type RscFetchResultDecision = {
|
|
|
142
143
|
kind: "hardNavigate";
|
|
143
144
|
discardBody: boolean;
|
|
144
145
|
url: string;
|
|
146
|
+
hardNavigationMode?: "assign" | "replace";
|
|
145
147
|
reason: RscFetchResultHardNavReason;
|
|
146
148
|
trace: NavigationTrace;
|
|
147
149
|
};
|
|
@@ -8,6 +8,9 @@ import { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop
|
|
|
8
8
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
9
9
|
import { verifyOperationTokenForCacheReuse } from "./operation-token.js";
|
|
10
10
|
//#region src/server/navigation-planner.ts
|
|
11
|
+
function mergeRscRedirectHistoryMode(navigationMode, redirectType) {
|
|
12
|
+
return navigationMode === "push" || redirectType === "push" ? "push" : "replace";
|
|
13
|
+
}
|
|
11
14
|
const ROUTE_INTERCEPTION_CONTEXT_SEPARATOR = "\0";
|
|
12
15
|
const CACHE_ENTRY_PROOF_MISSING_CODE = "CP_CACHE_ENTRY_PROOF_MISSING";
|
|
13
16
|
function createRequestWorkDecision(options) {
|
|
@@ -41,6 +44,7 @@ function createRscFetchResultHardNavigationDecision(options) {
|
|
|
41
44
|
return {
|
|
42
45
|
discardBody: options.discardBody,
|
|
43
46
|
kind: "hardNavigate",
|
|
47
|
+
...options.hardNavigationMode !== void 0 ? { hardNavigationMode: options.hardNavigationMode } : {},
|
|
44
48
|
reason: options.reason,
|
|
45
49
|
trace: createNavigationTrace(options.reasonCode, createRscFetchResultTraceFields(options.facts, {
|
|
46
50
|
...options.redirectSignal !== void 0 ? { redirectSignal: options.redirectSignal } : {},
|
|
@@ -133,9 +137,10 @@ function classifyRscFetchResult(facts) {
|
|
|
133
137
|
});
|
|
134
138
|
}
|
|
135
139
|
if (facts.streamedRedirectTarget !== null) {
|
|
140
|
+
const streamedHistoryMode = mergeRscRedirectHistoryMode(facts.effectiveHistoryUpdateMode, facts.streamedRedirectType);
|
|
136
141
|
const redirectDecision = resolveStreamedRscRedirectLifecycleHop({
|
|
137
142
|
currentHref: facts.currentHref,
|
|
138
|
-
historyUpdateMode:
|
|
143
|
+
historyUpdateMode: streamedHistoryMode,
|
|
139
144
|
origin: facts.origin,
|
|
140
145
|
redirectDepth: facts.redirectDepth,
|
|
141
146
|
requestPreviousNextUrl: facts.requestPreviousNextUrl,
|
|
@@ -149,6 +154,7 @@ function classifyRscFetchResult(facts) {
|
|
|
149
154
|
reason: terminalReason.hardNavigationReason,
|
|
150
155
|
reasonCode: terminalReason.traceReasonCode,
|
|
151
156
|
redirectSignal: "streamed-header",
|
|
157
|
+
hardNavigationMode: streamedHistoryMode === "push" ? "assign" : "replace",
|
|
152
158
|
url: redirectDecision.href
|
|
153
159
|
});
|
|
154
160
|
}
|
|
@@ -157,7 +163,7 @@ function classifyRscFetchResult(facts) {
|
|
|
157
163
|
facts,
|
|
158
164
|
redirect: {
|
|
159
165
|
href: redirectDecision.href,
|
|
160
|
-
historyUpdateMode:
|
|
166
|
+
historyUpdateMode: streamedHistoryMode,
|
|
161
167
|
previousNextUrl: redirectDecision.previousNextUrl,
|
|
162
168
|
redirectDepth: redirectDecision.redirectDepth
|
|
163
169
|
},
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
+
import { RedirectDigest } from "../utils/redirect-digest.js";
|
|
2
|
+
|
|
1
3
|
//#region src/server/next-error-digest.d.ts
|
|
2
|
-
|
|
3
|
-
* Helpers for parsing Next.js error `digest` strings shared across the App
|
|
4
|
-
* Router execution paths (server actions, page renders, route handlers).
|
|
5
|
-
*
|
|
6
|
-
* Next.js encodes special control flow as thrown errors carrying a `digest`
|
|
7
|
-
* field with one of these formats:
|
|
8
|
-
* - `NEXT_REDIRECT;<type>;<encodedUrl>;<status>` — `redirect()` / `permanentRedirect()`
|
|
9
|
-
* - `NEXT_NOT_FOUND` — `notFound()`
|
|
10
|
-
* - `NEXT_HTTP_ERROR_FALLBACK;<status>` — `forbidden()` / `unauthorized()` / etc.
|
|
11
|
-
*
|
|
12
|
-
* Each call site needs slightly different post-processing (URL resolution
|
|
13
|
-
* against the request, 303-vs-307 status overrides for actions, etc.), so
|
|
14
|
-
* these helpers only handle the parsing — callers shape the result.
|
|
15
|
-
*/
|
|
16
|
-
type NextRedirectDigest = {
|
|
17
|
-
status: number;
|
|
18
|
-
type: string | null;
|
|
19
|
-
url: string;
|
|
20
|
-
};
|
|
4
|
+
type NextRedirectDigest = RedirectDigest;
|
|
21
5
|
type NextHttpErrorDigest = {
|
|
22
6
|
status: number;
|
|
23
7
|
};
|
|
@@ -27,11 +11,12 @@ type NextHttpErrorDigest = {
|
|
|
27
11
|
*/
|
|
28
12
|
declare function getNextErrorDigest(error: unknown): string | null;
|
|
29
13
|
/**
|
|
30
|
-
* Parses
|
|
31
|
-
* when the digest is not a
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
14
|
+
* Parses redirect digests from vinext's encoded three-part form and Next.js's
|
|
15
|
+
* raw, semicolon-terminated form. Returns null when the digest is not a
|
|
16
|
+
* redirect digest. Vinext's encoded URL is decoded with `decodeURIComponent`;
|
|
17
|
+
* Next.js's canonical raw URL is preserved verbatim. The `status` defaults to
|
|
18
|
+
* 307 when omitted; an omitted `type` is left as null so the caller can apply
|
|
19
|
+
* the correct context-sensitive default.
|
|
35
20
|
*/
|
|
36
21
|
declare function parseNextRedirectDigest(digest: string): NextRedirectDigest | null;
|
|
37
22
|
/**
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import { parseRedirectDigest } from "../utils/redirect-digest.js";
|
|
1
2
|
//#region src/server/next-error-digest.ts
|
|
2
3
|
/**
|
|
4
|
+
* Helpers for parsing Next.js error `digest` strings shared across the App
|
|
5
|
+
* Router execution paths (server actions, page renders, route handlers).
|
|
6
|
+
*
|
|
7
|
+
* Special control flow is encoded as thrown errors carrying a `digest` field.
|
|
8
|
+
* Redirect digests may appear as vinext's encoded three-part form or Next.js's
|
|
9
|
+
* raw, semicolon-terminated form:
|
|
10
|
+
* - `NEXT_REDIRECT;<type>;<url>[;<status>[;]]` — `redirect()` / `permanentRedirect()`
|
|
11
|
+
* - `NEXT_NOT_FOUND` — `notFound()`
|
|
12
|
+
* - `NEXT_HTTP_ERROR_FALLBACK;<status>` — `forbidden()` / `unauthorized()` / etc.
|
|
13
|
+
*
|
|
14
|
+
* Each call site needs slightly different post-processing (URL resolution
|
|
15
|
+
* against the request, 303-vs-307 status overrides for actions, etc.), so
|
|
16
|
+
* these helpers only handle the parsing — callers shape the result.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
3
19
|
* Pulls a stringified `digest` off an unknown thrown value, or returns null
|
|
4
20
|
* when the value is not a digest-bearing error.
|
|
5
21
|
*/
|
|
@@ -8,23 +24,15 @@ function getNextErrorDigest(error) {
|
|
|
8
24
|
return String(error.digest);
|
|
9
25
|
}
|
|
10
26
|
/**
|
|
11
|
-
* Parses
|
|
12
|
-
* when the digest is not a
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
27
|
+
* Parses redirect digests from vinext's encoded three-part form and Next.js's
|
|
28
|
+
* raw, semicolon-terminated form. Returns null when the digest is not a
|
|
29
|
+
* redirect digest. Vinext's encoded URL is decoded with `decodeURIComponent`;
|
|
30
|
+
* Next.js's canonical raw URL is preserved verbatim. The `status` defaults to
|
|
31
|
+
* 307 when omitted; an omitted `type` is left as null so the caller can apply
|
|
32
|
+
* the correct context-sensitive default.
|
|
16
33
|
*/
|
|
17
34
|
function parseNextRedirectDigest(digest) {
|
|
18
|
-
|
|
19
|
-
const parts = digest.split(";");
|
|
20
|
-
const encodedUrl = parts[2];
|
|
21
|
-
if (!encodedUrl) return null;
|
|
22
|
-
const type = parts[1];
|
|
23
|
-
return {
|
|
24
|
-
status: parts[3] ? parseInt(parts[3], 10) : 307,
|
|
25
|
-
type: type || null,
|
|
26
|
-
url: decodeURIComponent(encodedUrl)
|
|
27
|
-
};
|
|
35
|
+
return parseRedirectDigest(digest);
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
38
|
* Parses a `NEXT_NOT_FOUND` or `NEXT_HTTP_ERROR_FALLBACK;<status>` digest.
|
|
@@ -41,7 +41,7 @@ function evaluateDimension(dimension, token, authority) {
|
|
|
41
41
|
}
|
|
42
42
|
function verifyOperationToken(token, authority, policy) {
|
|
43
43
|
const required = new Set(policy.require);
|
|
44
|
-
const evaluated = new Set([...policy.check, ...policy.require]);
|
|
44
|
+
const evaluated = /* @__PURE__ */ new Set([...policy.check, ...policy.require]);
|
|
45
45
|
for (const dimension of DIMENSION_ORDER) {
|
|
46
46
|
if (!evaluated.has(dimension)) continue;
|
|
47
47
|
const status = evaluateDimension(dimension, token, authority);
|
|
@@ -49,7 +49,8 @@ function parseSizeLimit(value) {
|
|
|
49
49
|
if (!match) return void 0;
|
|
50
50
|
const amount = Number.parseFloat(match[1]);
|
|
51
51
|
if (!Number.isFinite(amount) || amount < 0) return void 0;
|
|
52
|
-
const
|
|
52
|
+
const unit = match[2] ?? "b";
|
|
53
|
+
const multiplier = SIZE_UNITS[unit];
|
|
53
54
|
if (multiplier === void 0) return void 0;
|
|
54
55
|
return Math.floor(amount * multiplier);
|
|
55
56
|
}
|
|
@@ -34,6 +34,16 @@ type NextDataMatch = {
|
|
|
34
34
|
* even when the buildId is wrong (so we can still return a 404 JSON response).
|
|
35
35
|
*/
|
|
36
36
|
declare function isNextDataPathname(pathname: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* WHATWG URL parsing removes TAB, LF, and CR characters. Reject paths where
|
|
39
|
+
* that normalization would manufacture the internal Pages data namespace.
|
|
40
|
+
*/
|
|
41
|
+
declare function urlParserCreatesPagesDataPath(pathname: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Keep URL-parser-ignored characters encoded until route matching decodes the
|
|
44
|
+
* captured parameter. Passing them literally to `new URL()` would remove them.
|
|
45
|
+
*/
|
|
46
|
+
declare function encodeUrlParserIgnoredCharacters(pathname: string): string;
|
|
37
47
|
/**
|
|
38
48
|
* Parse `/_next/data/<buildId>/<...page>.json` and return the normalized page
|
|
39
49
|
* pathname. Returns `null` if the pathname does not match the pattern or if
|
|
@@ -120,4 +130,4 @@ type NormalizePagesDataRequestResult = {
|
|
|
120
130
|
*/
|
|
121
131
|
declare function normalizePagesDataRequest(request: Request, buildId: string | null, basePath?: string, trailingSlash?: boolean): NormalizePagesDataRequestResult;
|
|
122
132
|
//#endregion
|
|
123
|
-
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
133
|
+
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, urlParserCreatesPagesDataPath };
|
|
@@ -32,6 +32,21 @@ function isNextDataPathname(pathname) {
|
|
|
32
32
|
return pathname.startsWith(NEXT_DATA_PREFIX) && pathname.endsWith(NEXT_DATA_SUFFIX);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
+
* WHATWG URL parsing removes TAB, LF, and CR characters. Reject paths where
|
|
36
|
+
* that normalization would manufacture the internal Pages data namespace.
|
|
37
|
+
*/
|
|
38
|
+
function urlParserCreatesPagesDataPath(pathname) {
|
|
39
|
+
const parsedPathname = pathname.replaceAll(" ", "").replaceAll("\n", "").replaceAll("\r", "");
|
|
40
|
+
return pathname !== parsedPathname && !isNextDataPathname(pathname) && isNextDataPathname(parsedPathname);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Keep URL-parser-ignored characters encoded until route matching decodes the
|
|
44
|
+
* captured parameter. Passing them literally to `new URL()` would remove them.
|
|
45
|
+
*/
|
|
46
|
+
function encodeUrlParserIgnoredCharacters(pathname) {
|
|
47
|
+
return pathname.replaceAll(" ", "%09").replaceAll("\n", "%0A").replaceAll("\r", "%0D");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
35
50
|
* Parse `/_next/data/<buildId>/<...page>.json` and return the normalized page
|
|
36
51
|
* pathname. Returns `null` if the pathname does not match the pattern or if
|
|
37
52
|
* the buildId segment does not match the server's buildId.
|
|
@@ -168,4 +183,4 @@ function normalizePagesDataRequest(request, buildId, basePath = "", trailingSlas
|
|
|
168
183
|
};
|
|
169
184
|
}
|
|
170
185
|
//#endregion
|
|
171
|
-
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
186
|
+
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, urlParserCreatesPagesDataPath };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/server/pages-dev-hydration.d.ts
|
|
2
|
+
type PagesDevHydrationOptions = {
|
|
3
|
+
appModuleSource: string | null;
|
|
4
|
+
forceRouterReady?: boolean;
|
|
5
|
+
normalizePageProps?: boolean;
|
|
6
|
+
pageModuleSource: string;
|
|
7
|
+
reactStrictMode: boolean;
|
|
8
|
+
replaceFallbackRoute?: boolean;
|
|
9
|
+
scriptNonce?: string;
|
|
10
|
+
setPagePatternsFromNextData?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare function createPagesDevHydrationScript(options: PagesDevHydrationOptions): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { PagesDevHydrationOptions, createPagesDevHydrationScript };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createNonceAttribute } from "./html.js";
|
|
2
|
+
//#region src/server/pages-dev-hydration.ts
|
|
3
|
+
function createPagesDevHydrationScript(options) {
|
|
4
|
+
const nonceAttr = createNonceAttribute(options.scriptNonce);
|
|
5
|
+
const initializeRouter = options.forceRouterReady ? "_initializePagesRouterReadyFromNextData(nextData, true);" : "_initializePagesRouterReadyFromNextData(nextData);";
|
|
6
|
+
const pagePatterns = options.setPagePatternsFromNextData ? "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
|
|
7
|
+
const pageProps = options.normalizePageProps === false ? "const pageProps = rawPageProps ?? {};" : "const pageProps = rawPageProps && typeof rawPageProps === \"object\" ? rawPageProps : {};";
|
|
8
|
+
const fallbackReplacement = options.replaceFallbackRoute ? `
|
|
9
|
+
if (nextData.isFallback) {
|
|
10
|
+
await Router.replace(window.location.pathname + window.location.search + window.location.hash, undefined, { _h: 1, scroll: false });
|
|
11
|
+
}` : "";
|
|
12
|
+
const createElement = options.appModuleSource ? `
|
|
13
|
+
const appModule = await import(${JSON.stringify(options.appModuleSource)});
|
|
14
|
+
const AppComponent = appModule.default;
|
|
15
|
+
window.__VINEXT_APP__ = AppComponent;
|
|
16
|
+
const appRouter = ${options.forceRouterReady ? "{ ...Router, isReady: true }" : "Router"};
|
|
17
|
+
element = React.createElement(AppComponent, {
|
|
18
|
+
...props,
|
|
19
|
+
Component: PageComponent,
|
|
20
|
+
pageProps: rawPageProps,
|
|
21
|
+
router: appRouter,
|
|
22
|
+
});
|
|
23
|
+
` : `
|
|
24
|
+
element = React.createElement(PageComponent, pageProps);
|
|
25
|
+
`;
|
|
26
|
+
return `
|
|
27
|
+
<script type="module"${nonceAttr}>
|
|
28
|
+
import "vinext/instrumentation-client";
|
|
29
|
+
import React from "react";
|
|
30
|
+
import { hydrateRoot } from "react-dom/client";
|
|
31
|
+
import Router, { wrapWithRouterContext, _initializePagesRouterReadyFromNextData } from "next/router";
|
|
32
|
+
|
|
33
|
+
const nextDataElement = document.getElementById("__NEXT_DATA__");
|
|
34
|
+
if (nextDataElement?.textContent) {
|
|
35
|
+
window.__NEXT_DATA__ = JSON.parse(nextDataElement.textContent);
|
|
36
|
+
window.__VINEXT_LOCALE__ = window.__NEXT_DATA__.locale;
|
|
37
|
+
window.__VINEXT_LOCALES__ = window.__NEXT_DATA__.locales;
|
|
38
|
+
window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
|
|
39
|
+
}
|
|
40
|
+
const nextData = window.__NEXT_DATA__;
|
|
41
|
+
${initializeRouter}
|
|
42
|
+
const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
|
|
43
|
+
const rawPageProps = props.pageProps;
|
|
44
|
+
${pageProps}
|
|
45
|
+
window.__VINEXT_PAGE_LOADERS__ = { [nextData.page]: () => import(${JSON.stringify(options.pageModuleSource)}) };
|
|
46
|
+
${pagePatterns}
|
|
47
|
+
window.__VINEXT_APP_LOADER__ = ${options.appModuleSource ? `() => import(${JSON.stringify(options.appModuleSource)})` : "undefined"};
|
|
48
|
+
window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(options.reactStrictMode)};
|
|
49
|
+
|
|
50
|
+
async function hydrate() {
|
|
51
|
+
let hydrateRootOptions;
|
|
52
|
+
if (import.meta.env.DEV) {
|
|
53
|
+
const overlay = await import("vinext/dev-error-overlay");
|
|
54
|
+
overlay.installDevErrorOverlay();
|
|
55
|
+
overlay.installViteHmrErrorHandler(import.meta.hot);
|
|
56
|
+
overlay.reportInitialDevServerErrors();
|
|
57
|
+
hydrateRootOptions = {
|
|
58
|
+
onCaughtError: overlay.devOnCaughtError,
|
|
59
|
+
onUncaughtError: overlay.devOnUncaughtError,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const pageModule = await import(${JSON.stringify(options.pageModuleSource)});
|
|
64
|
+
const PageComponent = pageModule.default;
|
|
65
|
+
let element;
|
|
66
|
+
${createElement}
|
|
67
|
+
let resolveHydrationCommit;
|
|
68
|
+
const hydrationCommitted = new Promise((resolve) => { resolveHydrationCommit = resolve; });
|
|
69
|
+
element = wrapWithRouterContext(element, resolveHydrationCommit);
|
|
70
|
+
const root = hydrateRoot(document.getElementById("__next"), element, hydrateRootOptions);
|
|
71
|
+
window.__VINEXT_ROOT__ = root;
|
|
72
|
+
await hydrationCommitted;
|
|
73
|
+
const hydratedAt = performance.now();
|
|
74
|
+
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
75
|
+
window.__NEXT_HYDRATED = true;
|
|
76
|
+
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
77
|
+
window.__NEXT_HYDRATED_CB?.();${fallbackReplacement}
|
|
78
|
+
}
|
|
79
|
+
hydrate();
|
|
80
|
+
<\/script>`;
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { createPagesDevHydrationScript };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import path from "
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
//#region src/server/pages-dev-module-url.ts
|
|
3
3
|
function normalizeBase(base) {
|
|
4
4
|
if (!base || base === "/") return "/";
|
|
@@ -11,7 +11,7 @@ function createPagesDevAssetUrl(assetPath) {
|
|
|
11
11
|
return "/" + encodePagesDevModulePath(assetPath.replace(/^\/+/, ""));
|
|
12
12
|
}
|
|
13
13
|
function createPagesDevModuleUrl(viteRoot, moduleFilePath, viteBase) {
|
|
14
|
-
const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath)
|
|
14
|
+
const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath);
|
|
15
15
|
return normalizeBase(viteBase) + encodePagesDevModulePath(relativePath);
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|