cdk-nextjs 0.6.2 → 0.7.0
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/.jsii +2404 -2723
- package/.jsii.tabl.json +1 -1
- package/API.md +1681 -1930
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +667 -4
- package/docs/caching-guide.md +156 -112
- package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
- package/docs/development-guide.md +1 -1
- package/docs/harness-coverage.md +598 -0
- package/docs/init-cache-deployment.md +32 -1
- package/docs/next-build-output-guide.md +30 -20
- package/examples/README.md +5 -1
- package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
- package/lib/adapter/__fixtures__/app-playground.json +4917 -0
- package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
- package/lib/adapter/adapter.mjs +1548 -185
- package/lib/adapter/adapter.test.js +106 -0
- package/lib/adapter/aws-cache-store.d.ts +489 -0
- package/lib/adapter/aws-cache-store.js +1004 -0
- package/lib/adapter/aws-cache-store.test.d.ts +1 -0
- package/lib/adapter/aws-cache-store.test.js +361 -0
- package/lib/adapter/build-outputs.d.ts +80 -0
- package/lib/adapter/build-outputs.js +852 -0
- package/lib/adapter/build-outputs.test.d.ts +1 -0
- package/lib/adapter/build-outputs.test.js +861 -0
- package/lib/adapter/cache-handler.d.ts +9 -2
- package/lib/adapter/cache-handler.js +72 -96
- package/lib/adapter/cache-handler.mjs +18956 -17774
- package/lib/adapter/cache-handler.test.js +263 -31
- package/lib/adapter/cache-kinds.d.ts +32 -0
- package/lib/adapter/cache-kinds.js +35 -0
- package/lib/adapter/cache-kinds.test.d.ts +1 -0
- package/lib/adapter/cache-kinds.test.js +69 -0
- package/lib/adapter/cache-utils.d.ts +90 -0
- package/lib/adapter/cache-utils.js +199 -4
- package/lib/adapter/cache-utils.test.d.ts +1 -0
- package/lib/adapter/cache-utils.test.js +179 -0
- package/lib/adapter/function-groups.d.ts +215 -0
- package/lib/adapter/function-groups.js +1099 -0
- package/lib/adapter/function-groups.test.d.ts +1 -0
- package/lib/adapter/function-groups.test.js +743 -0
- package/lib/adapter/init-cache.d.ts +6 -0
- package/lib/adapter/init-cache.js +245 -0
- package/lib/adapter/init-cache.test.d.ts +1 -0
- package/lib/adapter/init-cache.test.js +137 -0
- package/lib/adapter/local-file-cache-handler.d.ts +23 -0
- package/lib/adapter/local-file-cache-handler.js +52 -1
- package/lib/adapter/memory-cache-handler.d.ts +26 -17
- package/lib/adapter/memory-cache-handler.js +32 -50
- package/lib/adapter/memory-cache-handler.test.js +105 -85
- package/lib/adapter/s3-cache-handler.d.ts +179 -40
- package/lib/adapter/s3-cache-handler.js +807 -277
- package/lib/adapter/s3-cache-handler.test.js +1186 -31
- package/lib/adapter/use-cache-common.d.ts +90 -0
- package/lib/adapter/use-cache-common.js +250 -0
- package/lib/adapter/use-cache-common.test.d.ts +1 -0
- package/lib/adapter/use-cache-common.test.js +646 -0
- package/lib/adapter/use-cache-default-handler.d.ts +24 -0
- package/lib/adapter/use-cache-default-handler.js +90 -0
- package/lib/adapter/use-cache-default-handler.mjs +38645 -0
- package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
- package/lib/adapter/use-cache-handlers.test.js +349 -0
- package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
- package/lib/adapter/use-cache-remote-handler.js +186 -0
- package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
- package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
- package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
- package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
- package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
- package/lib/index.d.ts +6 -7
- package/lib/index.js +2 -4
- package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
- package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
- package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
- package/lib/lambdas/post-deploy/prune-s3.js +41 -12
- package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
- package/lib/nextjs-api.d.ts +102 -18
- package/lib/nextjs-api.js +338 -38
- package/lib/nextjs-api.test.js +537 -1
- package/lib/nextjs-build/global-containers.Dockerfile +15 -10
- package/lib/nextjs-build/nextjs-build.d.ts +339 -63
- package/lib/nextjs-build/nextjs-build.js +684 -327
- package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
- package/lib/nextjs-build/nextjs-build.test.js +412 -0
- package/lib/nextjs-build/patch-fetch.js +1 -1
- package/lib/nextjs-build/patch-fetch.test.js +166 -11
- package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
- package/lib/nextjs-cache.d.ts +82 -4
- package/lib/nextjs-cache.js +186 -10
- package/lib/nextjs-cache.test.js +176 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
- package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
- package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
- package/lib/nextjs-compute/nextjs-containers.js +57 -20
- package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
- package/lib/nextjs-compute/nextjs-functions.js +113 -67
- package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
- package/lib/nextjs-distribution.d.ts +194 -23
- package/lib/nextjs-distribution.js +535 -62
- package/lib/nextjs-distribution.test.d.ts +1 -0
- package/lib/nextjs-distribution.test.js +697 -0
- package/lib/nextjs-post-deploy.d.ts +13 -5
- package/lib/nextjs-post-deploy.js +13 -10
- package/lib/nextjs-post-deploy.test.d.ts +1 -0
- package/lib/nextjs-post-deploy.test.js +34 -0
- package/lib/nextjs-static-assets.d.ts +17 -4
- package/lib/nextjs-static-assets.js +22 -5
- package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
- package/lib/root-constructs/nextjs-base-construct.js +139 -47
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -71
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -70
- package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
- package/lib/root-constructs/nextjs-regional-containers.js +8 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -26
- package/lib/runtime/api-gateway-path.d.ts +34 -0
- package/lib/runtime/api-gateway-path.js +71 -0
- package/lib/runtime/api-gateway-path.test.d.ts +1 -0
- package/lib/runtime/api-gateway-path.test.js +65 -0
- package/lib/runtime/case-redirect.d.ts +22 -0
- package/lib/runtime/case-redirect.js +63 -0
- package/lib/runtime/case-redirect.test.d.ts +1 -0
- package/lib/runtime/case-redirect.test.js +32 -0
- package/lib/runtime/core.d.ts +234 -0
- package/lib/runtime/core.js +1213 -0
- package/lib/runtime/core.test.d.ts +1 -0
- package/lib/runtime/core.test.js +1678 -0
- package/lib/runtime/deployment-root.d.ts +13 -0
- package/lib/runtime/deployment-root.js +29 -0
- package/lib/runtime/dispatch.d.ts +331 -0
- package/lib/runtime/dispatch.js +751 -0
- package/lib/runtime/dispatch.test.d.ts +1 -0
- package/lib/runtime/dispatch.test.js +853 -0
- package/lib/runtime/entrypoints.d.ts +57 -0
- package/lib/runtime/entrypoints.js +115 -0
- package/lib/runtime/http/abort-signal.d.ts +6 -0
- package/lib/runtime/http/abort-signal.js +19 -0
- package/lib/runtime/http/abort-signal.test.d.ts +1 -0
- package/lib/runtime/http/abort-signal.test.js +49 -0
- package/lib/runtime/http/node-server.d.ts +38 -0
- package/lib/runtime/http/node-server.js +99 -0
- package/lib/runtime/http/node-server.test.d.ts +1 -0
- package/lib/runtime/http/node-server.test.js +96 -0
- package/lib/runtime/http/node-sink.d.ts +16 -0
- package/lib/runtime/http/node-sink.js +48 -0
- package/lib/runtime/http/node-sink.test.d.ts +1 -0
- package/lib/runtime/http/node-sink.test.js +66 -0
- package/lib/runtime/http/request.d.ts +62 -0
- package/lib/runtime/http/request.js +134 -0
- package/lib/runtime/http/request.test.d.ts +1 -0
- package/lib/runtime/http/request.test.js +103 -0
- package/lib/runtime/http/response.d.ts +77 -0
- package/lib/runtime/http/response.js +229 -0
- package/lib/runtime/http/response.test.d.ts +1 -0
- package/lib/runtime/http/response.test.js +178 -0
- package/lib/runtime/http/sink.d.ts +73 -0
- package/lib/runtime/http/sink.js +188 -0
- package/lib/runtime/http/sink.test.d.ts +1 -0
- package/lib/runtime/http/sink.test.js +257 -0
- package/lib/runtime/image-utils.d.ts +78 -0
- package/lib/runtime/image-utils.js +129 -0
- package/lib/runtime/image-utils.test.d.ts +1 -0
- package/lib/runtime/image-utils.test.js +237 -0
- package/lib/runtime/image.d.ts +76 -0
- package/lib/runtime/image.js +296 -0
- package/lib/runtime/image.test.d.ts +1 -0
- package/lib/runtime/image.test.js +405 -0
- package/lib/runtime/lambda-event.d.ts +4 -0
- package/lib/runtime/lambda-event.js +113 -0
- package/lib/runtime/lambda-event.test.d.ts +1 -0
- package/lib/runtime/lambda-event.test.js +119 -0
- package/lib/runtime/lambda.mjs +41595 -0
- package/lib/runtime/load-module.d.ts +8 -0
- package/lib/runtime/load-module.js +35 -0
- package/lib/runtime/manifest.d.ts +215 -0
- package/lib/runtime/manifest.js +118 -0
- package/lib/runtime/middleware.d.ts +43 -0
- package/lib/runtime/middleware.js +113 -0
- package/lib/runtime/middleware.test.d.ts +1 -0
- package/lib/runtime/middleware.test.js +259 -0
- package/lib/runtime/next-modules.d.ts +55 -0
- package/lib/runtime/next-modules.js +124 -0
- package/lib/runtime/next-modules.test.d.ts +1 -0
- package/lib/runtime/next-modules.test.js +34 -0
- package/lib/runtime/public-files.d.ts +32 -0
- package/lib/runtime/public-files.js +117 -0
- package/lib/runtime/public-files.test.d.ts +1 -0
- package/lib/runtime/public-files.test.js +97 -0
- package/lib/runtime/server.mjs +41588 -0
- package/lib/runtime/static-files.d.ts +50 -0
- package/lib/runtime/static-files.js +266 -0
- package/lib/runtime/static-files.test.d.ts +1 -0
- package/lib/runtime/static-files.test.js +118 -0
- package/lib/runtime/util.d.ts +28 -0
- package/lib/runtime/util.js +79 -0
- package/lib/utils/base-path.d.ts +106 -13
- package/lib/utils/base-path.js +254 -41
- package/lib/utils/base-path.test.js +219 -51
- package/lib/utils/get-architecture.d.ts +7 -8
- package/lib/utils/get-architecture.js +12 -13
- package/lib/utils/zip-directory.d.ts +14 -0
- package/lib/utils/zip-directory.js +121 -0
- package/lib/utils/zip-directory.test.d.ts +1 -0
- package/lib/utils/zip-directory.test.js +99 -0
- package/package.json +22 -3
- package/scripts/capture-adapter-fixture.mjs +325 -0
- package/scripts/e2e-deploy.sh +398 -0
- package/scripts/e2e-harness/README.md +707 -0
- package/scripts/e2e-harness/app.js +370 -0
- package/scripts/e2e-harness/common.sh +249 -0
- package/scripts/e2e-harness/screen.mjs +302 -0
- package/scripts/e2e-harness/stage-proxy.mjs +145 -0
- package/scripts/e2e-harness/type-filters.mjs +47 -0
- package/scripts/e2e-logs.sh +75 -0
- package/scripts/e2e-offline.sh +91 -0
- package/scripts/e2e-sweep.sh +370 -0
- package/scripts/e2e-warm.sh +114 -0
- package/scripts/zero-config-build.mjs +418 -0
- package/docs/1k-concurrent-users-executions.png +0 -0
- package/docs/plans/adapter-runtime-release.md +0 -362
- package/docs/plans/phase-0-image-function-opt-in.md +0 -295
- package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
- package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
- package/lib/image-optimization/handler-utils.d.ts +0 -34
- package/lib/image-optimization/handler-utils.js +0 -83
- package/lib/image-optimization/handler-utils.test.js +0 -178
- package/lib/nextjs-build/functions.Dockerfile +0 -31
- package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
- package/lib/nextjs-compute/nextjs-image-function.js +0 -59
- package/lib/utils/experimental-flags.d.ts +0 -24
- package/lib/utils/experimental-flags.js +0 -30
- /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deployment root, derived from where the running shell sits.
|
|
3
|
+
*
|
|
4
|
+
* Synth copies the bundled shells and `manifest.json` into
|
|
5
|
+
* `<deploymentRoot>/${RUNTIME_DIR_NAME}/`, so the root is this file's parent's
|
|
6
|
+
* parent. Derived rather than read from `LAMBDA_TASK_ROOT` or the image
|
|
7
|
+
* `WORKDIR`, so that both shells agree and a consumer overriding `WORKDIR` in
|
|
8
|
+
* their own Dockerfile cannot break path resolution.
|
|
9
|
+
*
|
|
10
|
+
* @param shellDir the directory the calling shell was loaded from
|
|
11
|
+
* (`dirname(fileURLToPath(import.meta.url))`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function deploymentRootOf(shellDir: string): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deploymentRootOf = deploymentRootOf;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const manifest_1 = require("./manifest");
|
|
6
|
+
/**
|
|
7
|
+
* The deployment root, derived from where the running shell sits.
|
|
8
|
+
*
|
|
9
|
+
* Synth copies the bundled shells and `manifest.json` into
|
|
10
|
+
* `<deploymentRoot>/${RUNTIME_DIR_NAME}/`, so the root is this file's parent's
|
|
11
|
+
* parent. Derived rather than read from `LAMBDA_TASK_ROOT` or the image
|
|
12
|
+
* `WORKDIR`, so that both shells agree and a consumer overriding `WORKDIR` in
|
|
13
|
+
* their own Dockerfile cannot break path resolution.
|
|
14
|
+
*
|
|
15
|
+
* @param shellDir the directory the calling shell was loaded from
|
|
16
|
+
* (`dirname(fileURLToPath(import.meta.url))`).
|
|
17
|
+
*/
|
|
18
|
+
function deploymentRootOf(shellDir) {
|
|
19
|
+
if ((0, node_path_1.basename)(shellDir) !== manifest_1.RUNTIME_DIR_NAME) {
|
|
20
|
+
// A synth-side packaging mistake. Caught here because the alternative
|
|
21
|
+
// symptom is "manifest.json not found" one directory away from the truth.
|
|
22
|
+
throw new Error(`The cdk-nextjs runtime expected to be deployed at ` +
|
|
23
|
+
`<deploymentRoot>/${manifest_1.RUNTIME_DIR_NAME}/ but is running from ` +
|
|
24
|
+
`"${shellDir}". Every manifest path resolves against the deployment ` +
|
|
25
|
+
`root, so it cannot be inferred from anywhere else.`);
|
|
26
|
+
}
|
|
27
|
+
return (0, node_path_1.dirname)(shellDir);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudC1yb290LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvZGVwbG95bWVudC1yb290LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBZUEsNENBWUM7QUEzQkQseUNBQThDO0FBQzlDLHlDQUE4QztBQUU5Qzs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLGdCQUFnQixDQUFDLFFBQWdCO0lBQy9DLElBQUksSUFBQSxvQkFBUSxFQUFDLFFBQVEsQ0FBQyxLQUFLLDJCQUFnQixFQUFFLENBQUM7UUFDNUMsc0VBQXNFO1FBQ3RFLDBFQUEwRTtRQUMxRSxNQUFNLElBQUksS0FBSyxDQUNiLG9EQUFvRDtZQUNsRCxvQkFBb0IsMkJBQWdCLHdCQUF3QjtZQUM1RCxJQUFJLFFBQVEseURBQXlEO1lBQ3JFLG9EQUFvRCxDQUN2RCxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sSUFBQSxtQkFBTyxFQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBiYXNlbmFtZSwgZGlybmFtZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFJVTlRJTUVfRElSX05BTUUgfSBmcm9tIFwiLi9tYW5pZmVzdFwiO1xuXG4vKipcbiAqIFRoZSBkZXBsb3ltZW50IHJvb3QsIGRlcml2ZWQgZnJvbSB3aGVyZSB0aGUgcnVubmluZyBzaGVsbCBzaXRzLlxuICpcbiAqIFN5bnRoIGNvcGllcyB0aGUgYnVuZGxlZCBzaGVsbHMgYW5kIGBtYW5pZmVzdC5qc29uYCBpbnRvXG4gKiBgPGRlcGxveW1lbnRSb290Pi8ke1JVTlRJTUVfRElSX05BTUV9L2AsIHNvIHRoZSByb290IGlzIHRoaXMgZmlsZSdzIHBhcmVudCdzXG4gKiBwYXJlbnQuIERlcml2ZWQgcmF0aGVyIHRoYW4gcmVhZCBmcm9tIGBMQU1CREFfVEFTS19ST09UYCBvciB0aGUgaW1hZ2VcbiAqIGBXT1JLRElSYCwgc28gdGhhdCBib3RoIHNoZWxscyBhZ3JlZSBhbmQgYSBjb25zdW1lciBvdmVycmlkaW5nIGBXT1JLRElSYCBpblxuICogdGhlaXIgb3duIERvY2tlcmZpbGUgY2Fubm90IGJyZWFrIHBhdGggcmVzb2x1dGlvbi5cbiAqXG4gKiBAcGFyYW0gc2hlbGxEaXIgdGhlIGRpcmVjdG9yeSB0aGUgY2FsbGluZyBzaGVsbCB3YXMgbG9hZGVkIGZyb21cbiAqIChgZGlybmFtZShmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybCkpYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXBsb3ltZW50Um9vdE9mKHNoZWxsRGlyOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoYmFzZW5hbWUoc2hlbGxEaXIpICE9PSBSVU5USU1FX0RJUl9OQU1FKSB7XG4gICAgLy8gQSBzeW50aC1zaWRlIHBhY2thZ2luZyBtaXN0YWtlLiBDYXVnaHQgaGVyZSBiZWNhdXNlIHRoZSBhbHRlcm5hdGl2ZVxuICAgIC8vIHN5bXB0b20gaXMgXCJtYW5pZmVzdC5qc29uIG5vdCBmb3VuZFwiIG9uZSBkaXJlY3RvcnkgYXdheSBmcm9tIHRoZSB0cnV0aC5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVGhlIGNkay1uZXh0anMgcnVudGltZSBleHBlY3RlZCB0byBiZSBkZXBsb3llZCBhdCBgICtcbiAgICAgICAgYDxkZXBsb3ltZW50Um9vdD4vJHtSVU5USU1FX0RJUl9OQU1FfS8gYnV0IGlzIHJ1bm5pbmcgZnJvbSBgICtcbiAgICAgICAgYFwiJHtzaGVsbERpcn1cIi4gRXZlcnkgbWFuaWZlc3QgcGF0aCByZXNvbHZlcyBhZ2FpbnN0IHRoZSBkZXBsb3ltZW50IGAgK1xuICAgICAgICBgcm9vdCwgc28gaXQgY2Fubm90IGJlIGluZmVycmVkIGZyb20gYW55d2hlcmUgZWxzZS5gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGRpcm5hbWUoc2hlbGxEaXIpO1xufVxuIl19
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request dispatch: URL in, routing decision out.
|
|
3
|
+
*
|
|
4
|
+
* All route matching is delegated to `@next/routing`'s `resolveRoutes`, the
|
|
5
|
+
* first-party package `next start` was refactored to expose. Reimplementing
|
|
6
|
+
* redirects/rewrites/i18n/dynamic-route matching is what previous versions of
|
|
7
|
+
* this construct did, and it is the thing this rewrite exists to delete.
|
|
8
|
+
*
|
|
9
|
+
* This module is pure decision-making: it never touches the filesystem, never
|
|
10
|
+
* requires an entrypoint, and never builds a `Response`. It returns a
|
|
11
|
+
* {@link DispatchResult} and the caller (the runtime core, step 4) acts on it.
|
|
12
|
+
* That split is what makes it unit-testable against the committed
|
|
13
|
+
* `onBuildComplete` fixtures with no AWS and no Next.js server.
|
|
14
|
+
*/
|
|
15
|
+
import { MiddlewareContext, MiddlewareResult, ResolveRoutesQuery, ResolveRoutesResult, RouteInvocationTarget } from "@next/routing";
|
|
16
|
+
import { AdapterEntrypoint, AdapterManifest } from "./manifest";
|
|
17
|
+
/**
|
|
18
|
+
* Runs the app's middleware for one request. Supplied by `MiddlewareRunner` in
|
|
19
|
+
* `./middleware`.
|
|
20
|
+
*
|
|
21
|
+
* `MiddlewareContext` carries no method — `resolveRoutes` never needs one — but
|
|
22
|
+
* middleware very much does (`if (request.method === "POST")`), so dispatch adds
|
|
23
|
+
* it from the request it was given. The `Response` middleware returned comes
|
|
24
|
+
* back beside the result, because `resolveRoutes` reports `middlewareResponded`
|
|
25
|
+
* without it.
|
|
26
|
+
*/
|
|
27
|
+
export type MiddlewareInvoker = (ctx: MiddlewareContext & {
|
|
28
|
+
readonly method: string;
|
|
29
|
+
}) => Promise<MiddlewareResult & {
|
|
30
|
+
readonly response: Response;
|
|
31
|
+
}>;
|
|
32
|
+
export interface DispatcherOptions {
|
|
33
|
+
readonly manifest: AdapterManifest;
|
|
34
|
+
/**
|
|
35
|
+
* The files under `public/`, from `readPublicFiles`: unencoded paths relative
|
|
36
|
+
* to it. Served ahead of every route, as `next start` serves them.
|
|
37
|
+
* @default - no `public/` files
|
|
38
|
+
*/
|
|
39
|
+
readonly publicFiles?: readonly string[];
|
|
40
|
+
}
|
|
41
|
+
export interface DispatchRequest {
|
|
42
|
+
readonly method: string;
|
|
43
|
+
readonly url: URL;
|
|
44
|
+
readonly headers: Headers;
|
|
45
|
+
/**
|
|
46
|
+
* Always a stream — `resolveRoutes` requires one because middleware may read
|
|
47
|
+
* the body. Use an already-closed stream for GET/HEAD.
|
|
48
|
+
*/
|
|
49
|
+
readonly body: ReadableStream;
|
|
50
|
+
/**
|
|
51
|
+
* Required whenever `manifest.middleware` is non-null. `resolveRoutes` decides
|
|
52
|
+
* *whether* to call it from `routing.middlewareMatchers`; we only supply the
|
|
53
|
+
* how.
|
|
54
|
+
*/
|
|
55
|
+
readonly invokeMiddleware?: MiddlewareInvoker;
|
|
56
|
+
}
|
|
57
|
+
interface DispatchResultBase {
|
|
58
|
+
/**
|
|
59
|
+
* Headers to merge into the response: `headers()` rules, the immutable
|
|
60
|
+
* `cache-control` for `_next/static`, and anything middleware set via
|
|
61
|
+
* `NextResponse.next({ headers })`. Never request headers.
|
|
62
|
+
*/
|
|
63
|
+
readonly responseHeaders: Headers;
|
|
64
|
+
/** Status forced by a matched route, if any. */
|
|
65
|
+
readonly status?: number;
|
|
66
|
+
}
|
|
67
|
+
/** A route we must invoke. */
|
|
68
|
+
export interface DispatchEntrypointResult extends DispatchResultBase {
|
|
69
|
+
readonly kind: "entrypoint";
|
|
70
|
+
readonly entrypoint: AdapterEntrypoint;
|
|
71
|
+
/** The matched template, i.e. the `manifest.entrypoints` key. */
|
|
72
|
+
readonly resolvedPathname: string;
|
|
73
|
+
/** The *concrete* pathname + query to invoke the route with. */
|
|
74
|
+
readonly invocationTarget: RouteInvocationTarget;
|
|
75
|
+
/** Request headers as middleware left them. */
|
|
76
|
+
readonly requestHeaders: Headers;
|
|
77
|
+
}
|
|
78
|
+
/** A file in `manifest.staticFiles` or `public/`: read off disk, not invoked. */
|
|
79
|
+
export interface DispatchStaticFileResult extends DispatchResultBase {
|
|
80
|
+
readonly kind: "static-file";
|
|
81
|
+
readonly pathname: string;
|
|
82
|
+
/** Repo-root-relative key inside the deployment root. */
|
|
83
|
+
readonly filePath: string;
|
|
84
|
+
readonly source: StaticFileSource;
|
|
85
|
+
/**
|
|
86
|
+
* Request headers as middleware left them, for the 404 the runtime renders
|
|
87
|
+
* when the file is not in the package after all.
|
|
88
|
+
*/
|
|
89
|
+
readonly requestHeaders: Headers;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Where a static file came from, which decides what else it is allowed to do.
|
|
93
|
+
*
|
|
94
|
+
* - `public` — a file in `public/`.
|
|
95
|
+
* - `next-static` — `<distDir>/static`, the client bundles.
|
|
96
|
+
* - `server` — a build output under `<distDir>/server`: prerendered HTML, a
|
|
97
|
+
* static metadata route's `.body`.
|
|
98
|
+
*
|
|
99
|
+
* The first two are what `next start` serves as plain files, with `send`, and
|
|
100
|
+
* only to GET and HEAD (`router-server.js`, the `fsPath` branch); the third it
|
|
101
|
+
* serves by invoking the route it came from.
|
|
102
|
+
*/
|
|
103
|
+
export type StaticFileSource = "public" | "next-static" | "server";
|
|
104
|
+
/** `/_next/image`: our own optimizer, deliberately reached after middleware. */
|
|
105
|
+
export interface DispatchImageOptimizationResult extends DispatchResultBase {
|
|
106
|
+
readonly kind: "image-optimization";
|
|
107
|
+
readonly url: URL;
|
|
108
|
+
readonly requestHeaders: Headers;
|
|
109
|
+
}
|
|
110
|
+
export interface DispatchRedirectResult extends DispatchResultBase {
|
|
111
|
+
readonly kind: "redirect";
|
|
112
|
+
readonly location: string;
|
|
113
|
+
readonly status: number;
|
|
114
|
+
}
|
|
115
|
+
/** A rewrite to another origin: proxy the request through. */
|
|
116
|
+
export interface DispatchExternalRewriteResult extends DispatchResultBase {
|
|
117
|
+
readonly kind: "external-rewrite";
|
|
118
|
+
readonly url: URL;
|
|
119
|
+
readonly requestHeaders: Headers;
|
|
120
|
+
}
|
|
121
|
+
/** Middleware returned its own response: send it. */
|
|
122
|
+
export interface DispatchMiddlewareRespondedResult extends DispatchResultBase {
|
|
123
|
+
readonly kind: "middleware-responded";
|
|
124
|
+
readonly response: Response;
|
|
125
|
+
}
|
|
126
|
+
/** A matched route forced a status with nothing to invoke. */
|
|
127
|
+
export interface DispatchDirectResponseResult extends DispatchResultBase {
|
|
128
|
+
readonly kind: "response";
|
|
129
|
+
readonly status: number;
|
|
130
|
+
}
|
|
131
|
+
export interface DispatchNotFoundResult extends DispatchResultBase {
|
|
132
|
+
readonly kind: "not-found";
|
|
133
|
+
/** What failed to resolve. For logging. */
|
|
134
|
+
readonly pathname: string;
|
|
135
|
+
readonly requestHeaders: Headers;
|
|
136
|
+
}
|
|
137
|
+
export type DispatchResult = DispatchEntrypointResult | DispatchStaticFileResult | DispatchImageOptimizationResult | DispatchRedirectResult | DispatchExternalRewriteResult | DispatchMiddlewareRespondedResult | DispatchDirectResponseResult | DispatchNotFoundResult;
|
|
138
|
+
/**
|
|
139
|
+
* How to produce a 404 or 500 body. Resolved once per locale from the manifest
|
|
140
|
+
* (see {@link statusTargets}); honoring `notFound()` from a route is the
|
|
141
|
+
* runtime core's job, not dispatch's.
|
|
142
|
+
*/
|
|
143
|
+
export type StatusTarget = {
|
|
144
|
+
readonly kind: "entrypoint";
|
|
145
|
+
readonly pathname: string;
|
|
146
|
+
readonly entrypoint: AdapterEntrypoint;
|
|
147
|
+
} | {
|
|
148
|
+
readonly kind: "static-file";
|
|
149
|
+
readonly pathname: string;
|
|
150
|
+
readonly filePath: string;
|
|
151
|
+
} | {
|
|
152
|
+
readonly kind: "none";
|
|
153
|
+
};
|
|
154
|
+
export declare class Dispatcher {
|
|
155
|
+
private readonly options;
|
|
156
|
+
/** The 404 to render for a request to a URL; see {@link statusTargets}. */
|
|
157
|
+
readonly notFoundFor: (url: URL) => StatusTarget;
|
|
158
|
+
private readonly routes;
|
|
159
|
+
private readonly i18n;
|
|
160
|
+
private readonly table;
|
|
161
|
+
private readonly imagePathname;
|
|
162
|
+
private readonly trailingSlash;
|
|
163
|
+
constructor(options: DispatcherOptions);
|
|
164
|
+
get manifest(): AdapterManifest;
|
|
165
|
+
/**
|
|
166
|
+
* Drop the `trailingSlash` slash a resolved pathname may carry, so it can be
|
|
167
|
+
* looked up in `entrypoints`/`staticFiles` and rendered under the same cache
|
|
168
|
+
* key as its prerender. A no-op unless the app sets `trailingSlash`.
|
|
169
|
+
*/
|
|
170
|
+
private normalizePathname;
|
|
171
|
+
/** The request path with `basePath` removed, which is what i18n applies to. */
|
|
172
|
+
private withoutBasePath;
|
|
173
|
+
/**
|
|
174
|
+
* Put the locale in front of a request for the app's root *here*, when the
|
|
175
|
+
* locale is the one the request is already in.
|
|
176
|
+
*
|
|
177
|
+
* `resolveRoutes` prefixes the locale itself, as `${basePath}/${locale}${pathname}`
|
|
178
|
+
* — which for the root turns `/` into `/en-US/`. The slash-stripping 308 that
|
|
179
|
+
* `next build` always compiles into `routing.beforeMiddleware` then matches it,
|
|
180
|
+
* so `GET /` came back as a redirect no `next start` sends: measured against
|
|
181
|
+
* `test/e2e/i18n-support-catchall`, where `/` answers 200. Next.js's own router
|
|
182
|
+
* special-cases exactly this (`resolve-routes.ts`: `pathname === '/' ?
|
|
183
|
+
* `/${defaultLocale}` : …`).
|
|
184
|
+
*
|
|
185
|
+
* With `trailingSlash`, the prefixed root keeps its slash (`/en-US/`): the
|
|
186
|
+
* slash-*adding* 308 that build compiles instead matches `/en-US` the same
|
|
187
|
+
* way, and `/en-US/` is the canonical URL `next start` serves with a 200.
|
|
188
|
+
*
|
|
189
|
+
* Only the root, and only when no redirect is owed: a request whose detected
|
|
190
|
+
* locale is *not* the default has to reach `resolveRoutes`, which answers it
|
|
191
|
+
* with the 307 Next.js sends — after middleware has had the request, which is
|
|
192
|
+
* the ordering that matters and the reason this does not redirect itself.
|
|
193
|
+
*/
|
|
194
|
+
private withRootLocale;
|
|
195
|
+
/**
|
|
196
|
+
* Repair the two things `resolveRoutes` gets wrong about a redirect it built
|
|
197
|
+
* from the locale-prefixed root — the same `${basePath}/${locale}${pathname}`
|
|
198
|
+
* concatenation as in {@link withRootLocale}, this time reported as a location:
|
|
199
|
+
*
|
|
200
|
+
* - the stray trailing slash (`/nl/`, where Next.js sends `/nl`), which
|
|
201
|
+
* otherwise costs a second round trip to the 308 that strips it, and
|
|
202
|
+
* - the absolute URL, where Next.js sends a path. Both are legal, but a test
|
|
203
|
+
* asserting `headers.location` sees the difference, and so does any client
|
|
204
|
+
* comparing it to a link.
|
|
205
|
+
*/
|
|
206
|
+
private normalizeRedirectLocation;
|
|
207
|
+
/**
|
|
208
|
+
* The `headers()` rules a request matched, for a response middleware wrote
|
|
209
|
+
* itself.
|
|
210
|
+
*
|
|
211
|
+
* They compile into `routing.beforeMiddleware`, and `resolveRoutes` applies
|
|
212
|
+
* them there, but when middleware answers it returns `{ middlewareResponded:
|
|
213
|
+
* true }` and nothing else, so they were lost: a middleware 401 went out
|
|
214
|
+
* without the app's HSTS and CSP. `next start` sends them with it (its
|
|
215
|
+
* `resolve-routes.js` sets them on the response before middleware runs). So
|
|
216
|
+
* that one phase is run again on its own — no middleware, no files, nothing
|
|
217
|
+
* after it — which leaves exactly the headers it set.
|
|
218
|
+
*/
|
|
219
|
+
private beforeMiddlewareHeaders;
|
|
220
|
+
/**
|
|
221
|
+
* The URL to optimize, once `/_next/image` has resolved: as middleware
|
|
222
|
+
* rewrote it, or as received — or, when a `next.config` rewrite is what put
|
|
223
|
+
* the request on the image path, rebuilt from the query `resolveRoutes`
|
|
224
|
+
* resolved, which is the only place that rewrite's destination query is.
|
|
225
|
+
*/
|
|
226
|
+
private imageUrl;
|
|
227
|
+
dispatch(request: DispatchRequest): Promise<DispatchResult>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Normalize the two shapes `resolveRoutes` reports a redirect in.
|
|
231
|
+
*
|
|
232
|
+
* `ResolveRoutesResult.redirect` is documented, and an i18n locale-detection 307
|
|
233
|
+
* arrives that way, but the rest — the slash-stripping 308, a middleware
|
|
234
|
+
* `NextResponse.redirect()` — arrive instead as a bare `status` with `location`
|
|
235
|
+
* in `resolvedHeaders`. `next.config` `redirects()` too: they compile to routes
|
|
236
|
+
* carrying `headers: { Location }` plus `status`. Both shapes are handled, and
|
|
237
|
+
* {@link Dispatcher.normalizeRedirectLocation} then puts the location itself in
|
|
238
|
+
* the form Next.js sends.
|
|
239
|
+
*/
|
|
240
|
+
export declare function toRedirect(result: ResolveRoutesResult, responseHeaders: Headers): {
|
|
241
|
+
location: string;
|
|
242
|
+
status: number;
|
|
243
|
+
} | undefined;
|
|
244
|
+
/**
|
|
245
|
+
* Correct the `nxtP` route params in a resolved query from `routeMatches`.
|
|
246
|
+
*
|
|
247
|
+
* `@next/routing` expands a dynamic route's destination
|
|
248
|
+
* (`/[id]/[id2]?nxtPid=$nxtPid&nxtPid2=$nxtPid2`) by looping over the source
|
|
249
|
+
* regex's named groups and doing one global string replace per group name. Group
|
|
250
|
+
* names are substituted in insertion order, so `$nxtPid` — a *prefix* of
|
|
251
|
+
* `$nxtPid2` — is replaced first and leaves the trailing `2` behind as a
|
|
252
|
+
* literal: `/a/b` resolves with `nxtPid2=a2` instead of `nxtPid2=b`. Next.js
|
|
253
|
+
* recovers `params` from exactly these query values (`RouteModule.prepare`), so
|
|
254
|
+
* the page renders `id2: "a2"` — measured against
|
|
255
|
+
* `test/e2e/app-dir/use-params`, whose fixture is `app/[id]/[id2]/page.tsx`.
|
|
256
|
+
*
|
|
257
|
+
* `routeMatches` is the raw capture map, before any destination expansion, so it
|
|
258
|
+
* is the authority for every param it names. Only keys the expansion already
|
|
259
|
+
* produced are overwritten: adding others would invent params for a rewrite that
|
|
260
|
+
* deliberately dropped them.
|
|
261
|
+
*
|
|
262
|
+
* The same prefix collision reaches positional placeholders (`$1` inside `$10`,
|
|
263
|
+
* so a route with ten or more captures), and `next.config` `rewrites()`
|
|
264
|
+
* destinations that interpolate their own query values. Those are not route
|
|
265
|
+
* params and are left alone — there is no second source of truth to repair them
|
|
266
|
+
* from.
|
|
267
|
+
*
|
|
268
|
+
* The second correction is the opposite shape: a param the route *has* but the
|
|
269
|
+
* request did not fill. An optional catchall's group is the only one a match can
|
|
270
|
+
* leave unset — `^/optional\-catchall(?:/(?<nxtPparams>.+?))?(?:/)?$` against
|
|
271
|
+
* `/optional-catchall` — and both `routeMatches` and the expanded query keep the
|
|
272
|
+
* key with no value: `{ nxtPparams: undefined }`, which the `@next/routing` types
|
|
273
|
+
* do not admit. The key is what matters, not the value. `RouteModule.prepare`
|
|
274
|
+
* recovers a param for every `nxtP` key it finds, so a layout reading `params`
|
|
275
|
+
* renders a segment that was never requested — as `["undefined"]`, because
|
|
276
|
+
* `URLSearchParams.append` stringifies — where `next start` gives it no `params`
|
|
277
|
+
* key at all. Measured against `test/e2e/app-dir/layout-params`, whose fixture is
|
|
278
|
+
* `app/optional-catchall/[[...params]]`. No other param shape can be legitimately
|
|
279
|
+
* unfilled — a required segment captures `[^/]+?` and a required catchall `.+?` —
|
|
280
|
+
* so an unfilled value `routeMatches` does not vouch for is always this.
|
|
281
|
+
*/
|
|
282
|
+
export declare function repairRouteParamQuery(query: ResolveRoutesQuery, routeMatches: Record<string, string | undefined>): ResolveRoutesQuery;
|
|
283
|
+
/**
|
|
284
|
+
* Route params to hand Next.js out-of-band, for the one request shape the `nxtP`
|
|
285
|
+
* query contract cannot carry: a capture containing an encoded `/`. `undefined`
|
|
286
|
+
* — the common case — means the contract is lossless and nothing special is
|
|
287
|
+
* needed.
|
|
288
|
+
*
|
|
289
|
+
* The contract normally is lossless, which is why {@link NextjsRuntime} passes
|
|
290
|
+
* route params as query values everywhere else. But `RouteModule.prepare`
|
|
291
|
+
* recovers them by running `normalizeQueryParams` — which calls
|
|
292
|
+
* `decodeQueryPathParameter`, a **second** `decodeURIComponent`, on every
|
|
293
|
+
* de-prefixed value because "when deployed to Vercel the value may be encoded" —
|
|
294
|
+
* and then `normalizeDynamicRouteParams`, which splits a string repeat param on
|
|
295
|
+
* `/` because "query values from the proxy aren't already split into arrays".
|
|
296
|
+
* Two decodes and a split: `nxtPrest=..%252F..%252Fserver-reference-manifest`
|
|
297
|
+
* (what the contract asks for, and what we send) arrives as the three params
|
|
298
|
+
* `['..', '..', 'server-reference-manifest']` rather than the one the client
|
|
299
|
+
* requested. The resolved pathname built back out of those is
|
|
300
|
+
* `/pages-cache/../../server-reference-manifest`, and `normalizePagePath` throws
|
|
301
|
+
* `Requested and resolved page mismatch` on it when the cache asks for a key —
|
|
302
|
+
* so a `_next/data` request for a catch-all whose segment contains `%2F` 500s.
|
|
303
|
+
* Measured against `test/e2e/incremental-cache-path-traversal`. No encoding can
|
|
304
|
+
* fix it from this side: whatever survives two decodes still gets split.
|
|
305
|
+
*
|
|
306
|
+
* `next start` never hits it because its `router-server` sets
|
|
307
|
+
* `requestMeta.params` instead, which `prepare` takes as-is
|
|
308
|
+
* (`route-module.ts`: `getRequestMeta(req, 'params')`) with no decode and no
|
|
309
|
+
* split. That is what this reproduces — narrowly, only for the affected
|
|
310
|
+
* requests, so that the documented query contract stays the path for everything
|
|
311
|
+
* else.
|
|
312
|
+
*
|
|
313
|
+
* The `nxtP` values have to leave the query as well as arrive in `params`.
|
|
314
|
+
* `prepare` prefers the query over `params` when both parse and are the same
|
|
315
|
+
* size, so leaving them in would just restore the split. Dropping them also
|
|
316
|
+
* matches `next start`, which has no `nxtP` query at all.
|
|
317
|
+
*/
|
|
318
|
+
export declare function outOfBandRouteParams(query: ResolveRoutesQuery, resolvedPathname: string): {
|
|
319
|
+
params: Record<string, string | string[]>;
|
|
320
|
+
query: ResolveRoutesQuery;
|
|
321
|
+
} | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* {@link statusTarget} for every locale, resolved once, and a lookup of the
|
|
324
|
+
* request's: in an i18n app, the prerender of the locale the URL is in
|
|
325
|
+
* (`/fr/nope` gets `/fr/404`), and otherwise of the domain's default locale —
|
|
326
|
+
* which is how `next start` picks the locale it renders a status page in. A
|
|
327
|
+
* request whose URL could not be parsed, `undefined`, gets the default
|
|
328
|
+
* locale's.
|
|
329
|
+
*/
|
|
330
|
+
export declare function statusTargets(manifest: AdapterManifest, status: 404 | 500): (url: URL | undefined) => StatusTarget;
|
|
331
|
+
export {};
|