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,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const node_os_1 = require("node:os");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const dispatch_1 = require("./dispatch");
|
|
10
|
+
const middleware_1 = require("./middleware");
|
|
11
|
+
const app_playground_json_1 = __importDefault(require("../adapter/__fixtures__/app-playground.json"));
|
|
12
|
+
const build_outputs_1 = require("../adapter/build-outputs");
|
|
13
|
+
const fixtureContext = structuredClone(app_playground_json_1.default);
|
|
14
|
+
// The fixture's project dir is a synthetic `/repo/…` path, so the build cwd has
|
|
15
|
+
// to be stated; see `assertBuildCwd`.
|
|
16
|
+
const manifest = (0, build_outputs_1.buildAdapterManifest)(fixtureContext, {
|
|
17
|
+
buildCwd: fixtureContext.projectDir,
|
|
18
|
+
}).manifest;
|
|
19
|
+
const ORIGIN = "https://example.test";
|
|
20
|
+
const dispatcher = new dispatch_1.Dispatcher({ manifest });
|
|
21
|
+
function request(url, init = {}) {
|
|
22
|
+
return {
|
|
23
|
+
method: init.method ?? "GET",
|
|
24
|
+
url: new URL(url, ORIGIN),
|
|
25
|
+
headers: new Headers({ host: "example.test", ...init.headers }),
|
|
26
|
+
body: new ReadableStream({
|
|
27
|
+
start(controller) {
|
|
28
|
+
if (init.body !== undefined) {
|
|
29
|
+
controller.enqueue(new TextEncoder().encode(init.body));
|
|
30
|
+
}
|
|
31
|
+
controller.close();
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function runnerFor(handler) {
|
|
37
|
+
return new middleware_1.MiddlewareRunner({
|
|
38
|
+
middleware: manifest.middleware,
|
|
39
|
+
root: "/unused-because-loadHandler-is-set",
|
|
40
|
+
loadHandler: async () => handler,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Dispatch a request through a `Dispatcher` backed by `handler`. */
|
|
44
|
+
function dispatchThrough(handler, dispatchRequest, perRequest) {
|
|
45
|
+
return dispatcher.dispatch({
|
|
46
|
+
...dispatchRequest,
|
|
47
|
+
invokeMiddleware: runnerFor(handler).invokerFor(perRequest),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
describe("MiddlewareRunner request construction", () => {
|
|
51
|
+
it("gives middleware the real method, url and headers", async () => {
|
|
52
|
+
const seen = [];
|
|
53
|
+
await dispatchThrough(async (incoming) => {
|
|
54
|
+
seen.push(incoming);
|
|
55
|
+
return next();
|
|
56
|
+
}, request("/isr/1?q=1", { headers: { "x-caller": "yes" } }));
|
|
57
|
+
expect(seen).toHaveLength(1);
|
|
58
|
+
expect(seen[0].method).toBe("GET");
|
|
59
|
+
expect(seen[0].url).toBe(`${ORIGIN}/isr/1?q=1`);
|
|
60
|
+
expect(seen[0].headers.get("x-caller")).toBe("yes");
|
|
61
|
+
});
|
|
62
|
+
it("attaches the body for methods that can have one", async () => {
|
|
63
|
+
const bodies = [];
|
|
64
|
+
await dispatchThrough(async (incoming) => {
|
|
65
|
+
bodies.push(await incoming.text());
|
|
66
|
+
return next();
|
|
67
|
+
}, request("/api/health", { method: "POST", body: "payload" }));
|
|
68
|
+
expect(bodies).toEqual(["payload"]);
|
|
69
|
+
});
|
|
70
|
+
it("omits the body for GET and HEAD", async () => {
|
|
71
|
+
// `new Request(url, { body })` throws for these, so the runner must not
|
|
72
|
+
// attach the stream at all.
|
|
73
|
+
for (const method of ["GET", "HEAD", "get"]) {
|
|
74
|
+
const seen = [];
|
|
75
|
+
await dispatchThrough(async (incoming) => {
|
|
76
|
+
seen.push(incoming);
|
|
77
|
+
return next();
|
|
78
|
+
}, request("/isr/1", { method }));
|
|
79
|
+
expect(seen[0].body).toBeNull();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
it("passes waitUntil straight through", async () => {
|
|
83
|
+
const waited = [];
|
|
84
|
+
await dispatchThrough(async (_incoming, ctx) => {
|
|
85
|
+
ctx.waitUntil?.(Promise.resolve("logged"));
|
|
86
|
+
return next();
|
|
87
|
+
}, request("/isr/1"), { waitUntil: (promise) => waited.push(promise) });
|
|
88
|
+
expect(waited).toHaveLength(1);
|
|
89
|
+
});
|
|
90
|
+
it("loads the handler at most once across requests", async () => {
|
|
91
|
+
let loads = 0;
|
|
92
|
+
const runner = new middleware_1.MiddlewareRunner({
|
|
93
|
+
middleware: manifest.middleware,
|
|
94
|
+
root: "/unused",
|
|
95
|
+
loadHandler: async () => {
|
|
96
|
+
loads += 1;
|
|
97
|
+
return async () => next();
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const invokeMiddleware = runner.invokerFor();
|
|
101
|
+
await dispatcher.dispatch({ ...request("/isr/1"), invokeMiddleware });
|
|
102
|
+
await dispatcher.dispatch({ ...request("/isr/2"), invokeMiddleware });
|
|
103
|
+
// A fresh invoker for a later request must reuse the loaded handler.
|
|
104
|
+
await dispatcher.dispatch({
|
|
105
|
+
...request("/isr/3"),
|
|
106
|
+
invokeMiddleware: runner.invokerFor(),
|
|
107
|
+
});
|
|
108
|
+
expect(loads).toBe(1);
|
|
109
|
+
});
|
|
110
|
+
it("retries a load that failed instead of caching the rejection", async () => {
|
|
111
|
+
// Middleware runs on every request, so a cached rejection is the whole app
|
|
112
|
+
// answering 500 for the life of the sandbox — over a load failure that may
|
|
113
|
+
// have nothing to do with the module (EMFILE under a cold-start burst, an
|
|
114
|
+
// allocation near the memory limit).
|
|
115
|
+
let loads = 0;
|
|
116
|
+
const runner = new middleware_1.MiddlewareRunner({
|
|
117
|
+
middleware: manifest.middleware,
|
|
118
|
+
root: "/unused",
|
|
119
|
+
loadHandler: async () => {
|
|
120
|
+
loads += 1;
|
|
121
|
+
if (loads === 1) {
|
|
122
|
+
throw new Error("EMFILE");
|
|
123
|
+
}
|
|
124
|
+
return async () => next();
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const dispatch = () => dispatcher.dispatch({
|
|
128
|
+
...request("/isr/1"),
|
|
129
|
+
invokeMiddleware: runner.invokerFor(),
|
|
130
|
+
});
|
|
131
|
+
await expect(dispatch()).rejects.toThrow(/EMFILE/);
|
|
132
|
+
await expect(dispatch()).resolves.toBeDefined();
|
|
133
|
+
expect(loads).toBe(2);
|
|
134
|
+
});
|
|
135
|
+
it("attributes a middleware throw to middleware", async () => {
|
|
136
|
+
await expect(dispatchThrough(async () => {
|
|
137
|
+
throw new Error("boom");
|
|
138
|
+
}, request("/isr/1"))).rejects.toThrow(/Middleware \(.*middleware\.js\) threw while handling GET/);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("MiddlewareRunner response translation", () => {
|
|
142
|
+
it("treats NextResponse.next() as a pass-through", async () => {
|
|
143
|
+
const result = await dispatchThrough(async () => next(), request("/isr/1"));
|
|
144
|
+
expect(result.kind).toBe("entrypoint");
|
|
145
|
+
});
|
|
146
|
+
it("forwards request headers set via the x-middleware-* protocol", async () => {
|
|
147
|
+
// This is the real wire format behind `NextResponse.next({ request: { headers } })`,
|
|
148
|
+
// and the reason dispatch captures `MiddlewareResult.requestHeaders`:
|
|
149
|
+
// `resolveRoutes` itself drops them.
|
|
150
|
+
const result = await dispatchThrough(async () => new Response(null, {
|
|
151
|
+
status: 200,
|
|
152
|
+
headers: {
|
|
153
|
+
"x-middleware-next": "1",
|
|
154
|
+
"x-middleware-override-headers": "host,x-user",
|
|
155
|
+
"x-middleware-request-host": "example.test",
|
|
156
|
+
"x-middleware-request-x-user": "42",
|
|
157
|
+
},
|
|
158
|
+
}), request("/isr/1"));
|
|
159
|
+
expect(result.kind).toBe("entrypoint");
|
|
160
|
+
if (result.kind !== "entrypoint")
|
|
161
|
+
return;
|
|
162
|
+
expect(result.requestHeaders.get("x-user")).toBe("42");
|
|
163
|
+
});
|
|
164
|
+
it("returns response headers middleware set", async () => {
|
|
165
|
+
const result = await dispatchThrough(async () => new Response(null, {
|
|
166
|
+
status: 200,
|
|
167
|
+
headers: { "x-middleware-next": "1", "x-flag": "on" },
|
|
168
|
+
}), request("/isr/1"));
|
|
169
|
+
expect(result.responseHeaders.get("x-flag")).toBe("on");
|
|
170
|
+
});
|
|
171
|
+
it("turns an internal x-middleware-rewrite into the rewritten entrypoint", async () => {
|
|
172
|
+
const result = await dispatchThrough(async () => new Response(null, {
|
|
173
|
+
status: 200,
|
|
174
|
+
headers: { "x-middleware-rewrite": `${ORIGIN}/api/health` },
|
|
175
|
+
}), request("/isr/1"));
|
|
176
|
+
expect(result.kind).toBe("entrypoint");
|
|
177
|
+
if (result.kind !== "entrypoint")
|
|
178
|
+
return;
|
|
179
|
+
expect(result.resolvedPathname).toBe("/api/health");
|
|
180
|
+
});
|
|
181
|
+
it("turns an external x-middleware-rewrite into a proxy target", async () => {
|
|
182
|
+
const result = await dispatchThrough(async () => new Response(null, {
|
|
183
|
+
status: 200,
|
|
184
|
+
headers: { "x-middleware-rewrite": "https://upstream.test/x" },
|
|
185
|
+
}), request("/isr/1"));
|
|
186
|
+
expect(result.kind).toBe("external-rewrite");
|
|
187
|
+
});
|
|
188
|
+
it("turns a location header into a redirect", async () => {
|
|
189
|
+
const result = await dispatchThrough(async () => new Response(null, {
|
|
190
|
+
status: 307,
|
|
191
|
+
headers: { location: `${ORIGIN}/login` },
|
|
192
|
+
}), request("/isr/1"));
|
|
193
|
+
// A same-origin `location` comes back relative: `resolveRoutes` emits the
|
|
194
|
+
// path, not the absolute URL middleware wrote. Matches `next start`.
|
|
195
|
+
expect(result).toMatchObject({
|
|
196
|
+
kind: "redirect",
|
|
197
|
+
status: 307,
|
|
198
|
+
location: "/login",
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
it("treats a middleware-authored response as the response", async () => {
|
|
202
|
+
// No `x-middleware-next` and no rewrite: middleware answered the request.
|
|
203
|
+
const result = await dispatchThrough(async () => new Response("denied", { status: 401 }), request("/isr/1"));
|
|
204
|
+
expect(result.kind).toBe("middleware-responded");
|
|
205
|
+
if (result.kind !== "middleware-responded")
|
|
206
|
+
return;
|
|
207
|
+
expect(result.response.status).toBe(401);
|
|
208
|
+
expect(await result.response.text()).toBe("denied");
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe("MiddlewareRunner module loading", () => {
|
|
212
|
+
/** Writes a CJS middleware module and returns the root to resolve it from. */
|
|
213
|
+
async function writeModule(source) {
|
|
214
|
+
const root = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "cdk-nextjs-middleware-"));
|
|
215
|
+
await (0, promises_1.writeFile)((0, node_path_1.join)(root, "middleware.js"), source);
|
|
216
|
+
return root;
|
|
217
|
+
}
|
|
218
|
+
const invoke = (root) => new middleware_1.MiddlewareRunner({
|
|
219
|
+
middleware: { id: "/_middleware", filePath: "middleware.js" },
|
|
220
|
+
root,
|
|
221
|
+
}).invokerFor()({
|
|
222
|
+
method: "GET",
|
|
223
|
+
url: new URL(`${ORIGIN}/isr/1`),
|
|
224
|
+
headers: new Headers({ host: "example.test" }),
|
|
225
|
+
requestBody: new ReadableStream({
|
|
226
|
+
start(controller) {
|
|
227
|
+
controller.close();
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
230
|
+
});
|
|
231
|
+
it("loads a module that exports handler directly", async () => {
|
|
232
|
+
const root = await writeModule(`exports.handler = async () => new Response(null, { headers: { "x-middleware-next": "1", "x-flag": "sync" } });`);
|
|
233
|
+
const result = await invoke(root);
|
|
234
|
+
expect(result.responseHeaders?.get("x-flag")).toBe("sync");
|
|
235
|
+
});
|
|
236
|
+
it("awaits a module whose exports are a promise", async () => {
|
|
237
|
+
// Turbopack's async-module shape: `module.exports` is a Promise. A real
|
|
238
|
+
// `.next/server/middleware.js` built by Turbopack looks exactly like this.
|
|
239
|
+
const root = await writeModule(`module.exports = Promise.resolve({ handler: async () => new Response(null, { headers: { "x-middleware-next": "1", "x-flag": "async" } }) });`);
|
|
240
|
+
const result = await invoke(root);
|
|
241
|
+
expect(result.responseHeaders?.get("x-flag")).toBe("async");
|
|
242
|
+
});
|
|
243
|
+
it("reports a missing module as an incomplete package", async () => {
|
|
244
|
+
const root = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "cdk-nextjs-middleware-"));
|
|
245
|
+
await expect(invoke(root)).rejects.toThrow(/Could not load middleware from .*middleware\.js.*deployment package is incomplete/s);
|
|
246
|
+
});
|
|
247
|
+
it("reports a module without a handler export", async () => {
|
|
248
|
+
const root = await writeModule(`module.exports = { nope: 1 };`);
|
|
249
|
+
await expect(invoke(root)).rejects.toThrow(/does not export a `handler` function \(got undefined\)/);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
/** The wire form of `NextResponse.next()`. */
|
|
253
|
+
function next() {
|
|
254
|
+
return new Response(null, {
|
|
255
|
+
status: 200,
|
|
256
|
+
headers: { "x-middleware-next": "1" },
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvbWlkZGxld2FyZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0NBQXNEO0FBQ3RELHFDQUFpQztBQUNqQyx5Q0FBaUM7QUFDakMseUNBQXlEO0FBRXpELDZDQUlzQjtBQUN0QixzR0FBd0U7QUFDeEUsNERBR2tDO0FBRWxDLE1BQU0sY0FBYyxHQUFHLGVBQWUsQ0FDcEMsNkJBQWEsQ0FDcUIsQ0FBQztBQUNyQyxnRkFBZ0Y7QUFDaEYsc0NBQXNDO0FBQ3RDLE1BQU0sUUFBUSxHQUFvQixJQUFBLG9DQUFvQixFQUFDLGNBQWMsRUFBRTtJQUNyRSxRQUFRLEVBQUUsY0FBYyxDQUFDLFVBQVU7Q0FDcEMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztBQUVaLE1BQU0sTUFBTSxHQUFHLHNCQUFzQixDQUFDO0FBRXRDLE1BQU0sVUFBVSxHQUFHLElBQUkscUJBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFFaEQsU0FBUyxPQUFPLENBQ2QsR0FBVyxFQUNYLE9BSUksRUFBRTtJQUVOLE9BQU87UUFDTCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxLQUFLO1FBQzVCLEdBQUcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO1FBQ3pCLE9BQU8sRUFBRSxJQUFJLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0QsSUFBSSxFQUFFLElBQUksY0FBYyxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyxVQUFVO2dCQUNkLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDNUIsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxD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bXBvcnQgeyBta2R0ZW1wLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBEaXNwYXRjaGVyLCBEaXNwYXRjaFJlcXVlc3QgfSBmcm9tIFwiLi9kaXNwYXRjaFwiO1xuaW1wb3J0IHsgQWRhcHRlck1hbmlmZXN0IH0gZnJvbSBcIi4vbWFuaWZlc3RcIjtcbmltcG9ydCB7XG4gIE1pZGRsZXdhcmVIYW5kbGVyLFxuICBNaWRkbGV3YXJlUGVyUmVxdWVzdCxcbiAgTWlkZGxld2FyZVJ1bm5lcixcbn0gZnJvbSBcIi4vbWlkZGxld2FyZVwiO1xuaW1wb3J0IGFwcFBsYXlncm91bmQgZnJvbSBcIi4uL2FkYXB0ZXIvX19maXh0dXJlc19fL2FwcC1wbGF5Z3JvdW5kLmpzb25cIjtcbmltcG9ydCB7XG4gIEJ1aWxkQ29tcGxldGVDb250ZXh0LFxuICBidWlsZEFkYXB0ZXJNYW5pZmVzdCxcbn0gZnJvbSBcIi4uL2FkYXB0ZXIvYnVpbGQtb3V0cHV0c1wiO1xuXG5jb25zdCBmaXh0dXJlQ29udGV4dCA9IHN0cnVjdHVyZWRDbG9uZShcbiAgYXBwUGxheWdyb3VuZCxcbikgYXMgdW5rbm93biBhcyBCdWlsZENvbXBsZXRlQ29udGV4dDtcbi8vIFRoZSBmaXh0dXJlJ3MgcHJvamVjdCBkaXIgaXMgYSBzeW50aGV0aWMgYC9yZXBvL+KApmAgcGF0aCwgc28gdGhlIGJ1aWxkIGN3ZCBoYXNcbi8vIHRvIGJlIHN0YXRlZDsgc2VlIGBhc3NlcnRCdWlsZEN3ZGAuXG5jb25zdCBtYW5pZmVzdDogQWRhcHRlck1hbmlmZXN0ID0gYnVpbGRBZGFwdGVyTWFuaWZlc3QoZml4dHVyZUNvbnRleHQsIHtcbiAgYnVpbGRDd2Q6IGZpeHR1cmVDb250ZXh0LnByb2plY3REaXIsXG59KS5tYW5pZmVzdDtcblxuY29uc3QgT1JJR0lOID0gXCJodHRwczovL2V4YW1wbGUudGVzdFwiO1xuXG5jb25zdCBkaXNwYXRjaGVyID0gbmV3IERpc3BhdGNoZXIoeyBtYW5pZmVzdCB9KTtcblxuZnVuY3Rpb24gcmVxdWVzdChcbiAgdXJsOiBzdHJpbmcsXG4gIGluaXQ6IHtcbiAgICBtZXRob2Q/OiBzdHJpbmc7XG4gICAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgYm9keT86IHN0cmluZztcbiAgfSA9IHt9LFxuKTogRGlzcGF0Y2hSZXF1ZXN0IHtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IGluaXQubWV0aG9kID8/IFwiR0VUXCIsXG4gICAgdXJsOiBuZXcgVVJMKHVybCwgT1JJR0lOKSxcbiAgICBoZWFkZXJzOiBuZXcgSGVhZGVycyh7IGhvc3Q6IFwiZXhhbXBsZS50ZXN0XCIsIC4uLmluaXQuaGVhZGVycyB9KSxcbiAgICBib2R5OiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICBpZiAoaW5pdC5ib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGluaXQuYm9keSkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgIH0sXG4gICAgfSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJ1bm5lckZvcihoYW5kbGVyOiBNaWRkbGV3YXJlSGFuZGxlcikge1xuICByZXR1cm4gbmV3IE1pZGRsZXdhcmVSdW5uZXIoe1xuICAgIG1pZGRsZXdhcmU6IG1hbmlmZXN0Lm1pZGRsZXdhcmUhLFxuICAgIHJvb3Q6IFwiL3VudXNlZC1iZWNhdXNlLWxvYWRIYW5kbGVyLWlzLXNldFwiLFxuICAgIGxvYWRIYW5kbGVyOiBhc3luYyAoKSA9PiBoYW5kbGVyLFxuICB9KTtcbn1cblxuLyoqIERpc3BhdGNoIGEgcmVxdWVzdCB0aHJvdWdoIGEgYERpc3BhdGNoZXJgIGJhY2tlZCBieSBgaGFuZGxlcmAuICovXG5mdW5jdGlvbiBkaXNwYXRjaFRocm91Z2goXG4gIGhhbmRsZXI6IE1pZGRsZXdhcmVIYW5kbGVyLFxuICBkaXNwYXRjaFJlcXVlc3Q6IERpc3BhdGNoUmVxdWVzdCxcbiAgcGVyUmVxdWVzdD86IE1pZGRsZXdhcmVQZXJSZXF1ZXN0LFxuKSB7XG4gIHJldHVybiBkaXNwYXRjaGVyLmRpc3BhdGNoKHtcbiAgICAuLi5kaXNwYXRjaFJlcXVlc3QsXG4gICAgaW52b2tlTWlkZGxld2FyZTogcnVubmVyRm9yKGhhbmRsZXIpLmludm9rZXJGb3IocGVyUmVxdWVzdCksXG4gIH0pO1xufVxuXG5kZXNjcmliZShcIk1pZGRsZXdhcmVSdW5uZXIgcmVxdWVzdCBjb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICBpdChcImdpdmVzIG1pZGRsZXdhcmUgdGhlIHJlYWwgbWV0aG9kLCB1cmwgYW5kIGhlYWRlcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHNlZW46IFJlcXVlc3RbXSA9IFtdO1xuICAgIGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jIChpbmNvbWluZykgPT4ge1xuICAgICAgICBzZWVuLnB1c2goaW5jb21pbmcpO1xuICAgICAgICByZXR1cm4gbmV4dCgpO1xuICAgICAgfSxcbiAgICAgIHJlcXVlc3QoXCIvaXNyLzE/cT0xXCIsIHsgaGVhZGVyczogeyBcIngtY2FsbGVyXCI6IFwieWVzXCIgfSB9KSxcbiAgICApO1xuICAgIGV4cGVjdChzZWVuKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgZXhwZWN0KHNlZW5bMF0ubWV0aG9kKS50b0JlKFwiR0VUXCIpO1xuICAgIGV4cGVjdChzZWVuWzBdLnVybCkudG9CZShgJHtPUklHSU59L2lzci8xP3E9MWApO1xuICAgIGV4cGVjdChzZWVuWzBdLmhlYWRlcnMuZ2V0KFwieC1jYWxsZXJcIikpLnRvQmUoXCJ5ZXNcIik7XG4gIH0pO1xuXG4gIGl0KFwiYXR0YWNoZXMgdGhlIGJvZHkgZm9yIG1ldGhvZHMgdGhhdCBjYW4gaGF2ZSBvbmVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGJvZGllczogKHN0cmluZyB8IG51bGwpW10gPSBbXTtcbiAgICBhd2FpdCBkaXNwYXRjaFRocm91Z2goXG4gICAgICBhc3luYyAoaW5jb21pbmcpID0+IHtcbiAgICAgICAgYm9kaWVzLnB1c2goYXdhaXQgaW5jb21pbmcudGV4dCgpKTtcbiAgICAgICAgcmV0dXJuIG5leHQoKTtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0KFwiL2FwaS9oZWFsdGhcIiwgeyBtZXRob2Q6IFwiUE9TVFwiLCBib2R5OiBcInBheWxvYWRcIiB9KSxcbiAgICApO1xuICAgIGV4cGVjdChib2RpZXMpLnRvRXF1YWwoW1wicGF5bG9hZFwiXSk7XG4gIH0pO1xuXG4gIGl0KFwib21pdHMgdGhlIGJvZHkgZm9yIEdFVCBhbmQgSEVBRFwiLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gYG5ldyBSZXF1ZXN0KHVybCwgeyBib2R5IH0pYCB0aHJvd3MgZm9yIHRoZXNlLCBzbyB0aGUgcnVubmVyIG11c3Qgbm90XG4gICAgLy8gYXR0YWNoIHRoZSBzdHJlYW0gYXQgYWxsLlxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIFtcIkdFVFwiLCBcIkhFQURcIiwgXCJnZXRcIl0pIHtcbiAgICAgIGNvbnN0IHNlZW46IFJlcXVlc3RbXSA9IFtdO1xuICAgICAgYXdhaXQgZGlzcGF0Y2hUaHJvdWdoKFxuICAgICAgICBhc3luYyAoaW5jb21pbmcpID0+IHtcbiAgICAgICAgICBzZWVuLnB1c2goaW5jb21pbmcpO1xuICAgICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3QoXCIvaXNyLzFcIiwgeyBtZXRob2QgfSksXG4gICAgICApO1xuICAgICAgZXhwZWN0KHNlZW5bMF0uYm9keSkudG9CZU51bGwoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KFwicGFzc2VzIHdhaXRVbnRpbCBzdHJhaWdodCB0aHJvdWdoXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB3YWl0ZWQ6IFByb21pc2U8dW5rbm93bj5bXSA9IFtdO1xuICAgIGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jIChfaW5jb21pbmcsIGN0eCkgPT4ge1xuICAgICAgICBjdHgud2FpdFVudGlsPy4oUHJvbWlzZS5yZXNvbHZlKFwibG9nZ2VkXCIpKTtcbiAgICAgICAgcmV0dXJuIG5leHQoKTtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0KFwiL2lzci8xXCIpLFxuICAgICAgeyB3YWl0VW50aWw6IChwcm9taXNlKSA9PiB3YWl0ZWQucHVzaChwcm9taXNlKSB9LFxuICAgICk7XG4gICAgZXhwZWN0KHdhaXRlZCkudG9IYXZlTGVuZ3RoKDEpO1xuICB9KTtcblxuICBpdChcImxvYWRzIHRoZSBoYW5kbGVyIGF0IG1vc3Qgb25jZSBhY3Jvc3MgcmVxdWVzdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGxldCBsb2FkcyA9IDA7XG4gICAgY29uc3QgcnVubmVyID0gbmV3IE1pZGRsZXdhcmVSdW5uZXIoe1xuICAgICAgbWlkZGxld2FyZTogbWFuaWZlc3QubWlkZGxld2FyZSEsXG4gICAgICByb290OiBcIi91bnVzZWRcIixcbiAgICAgIGxvYWRIYW5kbGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxvYWRzICs9IDE7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiBuZXh0KCk7XG4gICAgICB9LFxuICAgIH0pO1xuICAgIGNvbnN0IGludm9rZU1pZGRsZXdhcmUgPSBydW5uZXIuaW52b2tlckZvcigpO1xuICAgIGF3YWl0IGRpc3BhdGNoZXIuZGlzcGF0Y2goeyAuLi5yZXF1ZXN0KFwiL2lzci8xXCIpLCBpbnZva2VNaWRkbGV3YXJlIH0pO1xuICAgIGF3YWl0IGRpc3BhdGNoZXIuZGlzcGF0Y2goeyAuLi5yZXF1ZXN0KFwiL2lzci8yXCIpLCBpbnZva2VNaWRkbGV3YXJlIH0pO1xuICAgIC8vIEEgZnJlc2ggaW52b2tlciBmb3IgYSBsYXRlciByZXF1ZXN0IG11c3QgcmV1c2UgdGhlIGxvYWRlZCBoYW5kbGVyLlxuICAgIGF3YWl0IGRpc3BhdGNoZXIuZGlzcGF0Y2goe1xuICAgICAgLi4ucmVxdWVzdChcIi9pc3IvM1wiKSxcbiAgICAgIGludm9rZU1pZGRsZXdhcmU6IHJ1bm5lci5pbnZva2VyRm9yKCksXG4gICAgfSk7XG4gICAgZXhwZWN0KGxvYWRzKS50b0JlKDEpO1xuICB9KTtcblxuICBpdChcInJldHJpZXMgYSBsb2FkIHRoYXQgZmFpbGVkIGluc3RlYWQgb2YgY2FjaGluZyB0aGUgcmVqZWN0aW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICAvLyBNaWRkbGV3YXJlIHJ1bnMgb24gZXZlcnkgcmVxdWVzdCwgc28gYSBjYWNoZWQgcmVqZWN0aW9uIGlzIHRoZSB3aG9sZSBhcHBcbiAgICAvLyBhbnN3ZXJpbmcgNTAwIGZvciB0aGUgbGlmZSBvZiB0aGUgc2FuZGJveCDigJQgb3ZlciBhIGxvYWQgZmFpbHVyZSB0aGF0IG1heVxuICAgIC8vIGhhdmUgbm90aGluZyB0byBkbyB3aXRoIHRoZSBtb2R1bGUgKEVNRklMRSB1bmRlciBhIGNvbGQtc3RhcnQgYnVyc3QsIGFuXG4gICAgLy8gYWxsb2NhdGlvbiBuZWFyIHRoZSBtZW1vcnkgbGltaXQpLlxuICAgIGxldCBsb2FkcyA9IDA7XG4gICAgY29uc3QgcnVubmVyID0gbmV3IE1pZGRsZXdhcmVSdW5uZXIoe1xuICAgICAgbWlkZGxld2FyZTogbWFuaWZlc3QubWlkZGxld2FyZSEsXG4gICAgICByb290OiBcIi91bnVzZWRcIixcbiAgICAgIGxvYWRIYW5kbGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxvYWRzICs9IDE7XG4gICAgICAgIGlmIChsb2FkcyA9PT0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVNRklMRVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXN5bmMgKCkgPT4gbmV4dCgpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCBkaXNwYXRjaCA9ICgpID0+XG4gICAgICBkaXNwYXRjaGVyLmRpc3BhdGNoKHtcbiAgICAgICAgLi4ucmVxdWVzdChcIi9pc3IvMVwiKSxcbiAgICAgICAgaW52b2tlTWlkZGxld2FyZTogcnVubmVyLmludm9rZXJGb3IoKSxcbiAgICAgIH0pO1xuXG4gICAgYXdhaXQgZXhwZWN0KGRpc3BhdGNoKCkpLnJlamVjdHMudG9UaHJvdygvRU1GSUxFLyk7XG4gICAgYXdhaXQgZXhwZWN0KGRpc3BhdGNoKCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gICAgZXhwZWN0KGxvYWRzKS50b0JlKDIpO1xuICB9KTtcblxuICBpdChcImF0dHJpYnV0ZXMgYSBtaWRkbGV3YXJlIHRocm93IHRvIG1pZGRsZXdhcmVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IGV4cGVjdChcbiAgICAgIGRpc3BhdGNoVGhyb3VnaChhc3luYyAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImJvb21cIik7XG4gICAgICB9LCByZXF1ZXN0KFwiL2lzci8xXCIpKSxcbiAgICApLnJlamVjdHMudG9UaHJvdyhcbiAgICAgIC9NaWRkbGV3YXJlIFxcKC4qbWlkZGxld2FyZVxcLmpzXFwpIHRocmV3IHdoaWxlIGhhbmRsaW5nIEdFVC8sXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJNaWRkbGV3YXJlUnVubmVyIHJlc3BvbnNlIHRyYW5zbGF0aW9uXCIsICgpID0+IHtcbiAgaXQoXCJ0cmVhdHMgTmV4dFJlc3BvbnNlLm5leHQoKSBhcyBhIHBhc3MtdGhyb3VnaFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZGlzcGF0Y2hUaHJvdWdoKGFzeW5jICgpID0+IG5leHQoKSwgcmVxdWVzdChcIi9pc3IvMVwiKSk7XG4gICAgZXhwZWN0KHJlc3VsdC5raW5kKS50b0JlKFwiZW50cnlwb2ludFwiKTtcbiAgfSk7XG5cbiAgaXQoXCJmb3J3YXJkcyByZXF1ZXN0IGhlYWRlcnMgc2V0IHZpYSB0aGUgeC1taWRkbGV3YXJlLSogcHJvdG9jb2xcIiwgYXN5bmMgKCkgPT4ge1xuICAgIC8vIFRoaXMgaXMgdGhlIHJlYWwgd2lyZSBmb3JtYXQgYmVoaW5kIGBOZXh0UmVzcG9uc2UubmV4dCh7IHJlcXVlc3Q6IHsgaGVhZGVycyB9IH0pYCxcbiAgICAvLyBhbmQgdGhlIHJlYXNvbiBkaXNwYXRjaCBjYXB0dXJlcyBgTWlkZGxld2FyZVJlc3VsdC5yZXF1ZXN0SGVhZGVyc2A6XG4gICAgLy8gYHJlc29sdmVSb3V0ZXNgIGl0c2VsZiBkcm9wcyB0aGVtLlxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jICgpID0+XG4gICAgICAgIG5ldyBSZXNwb25zZShudWxsLCB7XG4gICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgXCJ4LW1pZGRsZXdhcmUtbmV4dFwiOiBcIjFcIixcbiAgICAgICAgICAgIFwieC1taWRkbGV3YXJlLW92ZXJyaWRlLWhlYWRlcnNcIjogXCJob3N0LHgtdXNlclwiLFxuICAgICAgICAgICAgXCJ4LW1pZGRsZXdhcmUtcmVxdWVzdC1ob3N0XCI6IFwiZXhhbXBsZS50ZXN0XCIsXG4gICAgICAgICAgICBcIngtbWlkZGxld2FyZS1yZXF1ZXN0LXgtdXNlclwiOiBcIjQyXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICByZXF1ZXN0KFwiL2lzci8xXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KHJlc3VsdC5raW5kKS50b0JlKFwiZW50cnlwb2ludFwiKTtcbiAgICBpZiAocmVzdWx0LmtpbmQgIT09IFwiZW50cnlwb2ludFwiKSByZXR1cm47XG4gICAgZXhwZWN0KHJlc3VsdC5yZXF1ZXN0SGVhZGVycy5nZXQoXCJ4LXVzZXJcIikpLnRvQmUoXCI0MlwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZXR1cm5zIHJlc3BvbnNlIGhlYWRlcnMgbWlkZGxld2FyZSBzZXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jICgpID0+XG4gICAgICAgIG5ldyBSZXNwb25zZShudWxsLCB7XG4gICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgaGVhZGVyczogeyBcIngtbWlkZGxld2FyZS1uZXh0XCI6IFwiMVwiLCBcIngtZmxhZ1wiOiBcIm9uXCIgfSxcbiAgICAgICAgfSksXG4gICAgICByZXF1ZXN0KFwiL2lzci8xXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KHJlc3VsdC5yZXNwb25zZUhlYWRlcnMuZ2V0KFwieC1mbGFnXCIpKS50b0JlKFwib25cIik7XG4gIH0pO1xuXG4gIGl0KFwidHVybnMgYW4gaW50ZXJuYWwgeC1taWRkbGV3YXJlLXJld3JpdGUgaW50byB0aGUgcmV3cml0dGVuIGVudHJ5cG9pbnRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jICgpID0+XG4gICAgICAgIG5ldyBSZXNwb25zZShudWxsLCB7XG4gICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgaGVhZGVyczogeyBcIngtbWlkZGxld2FyZS1yZXdyaXRlXCI6IGAke09SSUdJTn0vYXBpL2hlYWx0aGAgfSxcbiAgICAgICAgfSksXG4gICAgICByZXF1ZXN0KFwiL2lzci8xXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KHJlc3VsdC5raW5kKS50b0JlKFwiZW50cnlwb2ludFwiKTtcbiAgICBpZiAocmVzdWx0LmtpbmQgIT09IFwiZW50cnlwb2ludFwiKSByZXR1cm47XG4gICAgZXhwZWN0KHJlc3VsdC5yZXNvbHZlZFBhdGhuYW1lKS50b0JlKFwiL2FwaS9oZWFsdGhcIik7XG4gIH0pO1xuXG4gIGl0KFwidHVybnMgYW4gZXh0ZXJuYWwgeC1taWRkbGV3YXJlLXJld3JpdGUgaW50byBhIHByb3h5IHRhcmdldFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZGlzcGF0Y2hUaHJvdWdoKFxuICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgbmV3IFJlc3BvbnNlKG51bGwsIHtcbiAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7IFwieC1taWRkbGV3YXJlLXJld3JpdGVcIjogXCJodHRwczovL3Vwc3RyZWFtLnRlc3QveFwiIH0sXG4gICAgICAgIH0pLFxuICAgICAgcmVxdWVzdChcIi9pc3IvMVwiKSxcbiAgICApO1xuICAgIGV4cGVjdChyZXN1bHQua2luZCkudG9CZShcImV4dGVybmFsLXJld3JpdGVcIik7XG4gIH0pO1xuXG4gIGl0KFwidHVybnMgYSBsb2NhdGlvbiBoZWFkZXIgaW50byBhIHJlZGlyZWN0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkaXNwYXRjaFRocm91Z2goXG4gICAgICBhc3luYyAoKSA9PlxuICAgICAgICBuZXcgUmVzcG9uc2UobnVsbCwge1xuICAgICAgICAgIHN0YXR1czogMzA3LFxuICAgICAgICAgIGhlYWRlcnM6IHsgbG9jYXRpb246IGAke09SSUdJTn0vbG9naW5gIH0sXG4gICAgICAgIH0pLFxuICAgICAgcmVxdWVzdChcIi9pc3IvMVwiKSxcbiAgICApO1xuICAgIC8vIEEgc2FtZS1vcmlnaW4gYGxvY2F0aW9uYCBjb21lcyBiYWNrIHJlbGF0aXZlOiBgcmVzb2x2ZVJvdXRlc2AgZW1pdHMgdGhlXG4gICAgLy8gcGF0aCwgbm90IHRoZSBhYnNvbHV0ZSBVUkwgbWlkZGxld2FyZSB3cm90ZS4gTWF0Y2hlcyBgbmV4dCBzdGFydGAuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9NYXRjaE9iamVjdCh7XG4gICAgICBraW5kOiBcInJlZGlyZWN0XCIsXG4gICAgICBzdGF0dXM6IDMwNyxcbiAgICAgIGxvY2F0aW9uOiBcIi9sb2dpblwiLFxuICAgIH0pO1xuICB9KTtcblxuICBpdChcInRyZWF0cyBhIG1pZGRsZXdhcmUtYXV0aG9yZWQgcmVzcG9uc2UgYXMgdGhlIHJlc3BvbnNlXCIsIGFzeW5jICgpID0+IHtcbiAgICAvLyBObyBgeC1taWRkbGV3YXJlLW5leHRgIGFuZCBubyByZXdyaXRlOiBtaWRkbGV3YXJlIGFuc3dlcmVkIHRoZSByZXF1ZXN0LlxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRpc3BhdGNoVGhyb3VnaChcbiAgICAgIGFzeW5jICgpID0+IG5ldyBSZXNwb25zZShcImRlbmllZFwiLCB7IHN0YXR1czogNDAxIH0pLFxuICAgICAgcmVxdWVzdChcIi9pc3IvMVwiKSxcbiAgICApO1xuICAgIGV4cGVjdChyZXN1bHQua2luZCkudG9CZShcIm1pZGRsZXdhcmUtcmVzcG9uZGVkXCIpO1xuICAgIGlmIChyZXN1bHQua2luZCAhPT0gXCJtaWRkbGV3YXJlLXJlc3BvbmRlZFwiKSByZXR1cm47XG4gICAgZXhwZWN0KHJlc3VsdC5yZXNwb25zZS5zdGF0dXMpLnRvQmUoNDAxKTtcbiAgICBleHBlY3QoYXdhaXQgcmVzdWx0LnJlc3BvbnNlLnRleHQoKSkudG9CZShcImRlbmllZFwiKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJNaWRkbGV3YXJlUnVubmVyIG1vZHVsZSBsb2FkaW5nXCIsICgpID0+IHtcbiAgLyoqIFdyaXRlcyBhIENKUyBtaWRkbGV3YXJlIG1vZHVsZSBhbmQgcmV0dXJucyB0aGUgcm9vdCB0byByZXNvbHZlIGl0IGZyb20uICovXG4gIGFzeW5jIGZ1bmN0aW9uIHdyaXRlTW9kdWxlKHNvdXJjZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgcm9vdCA9IGF3YWl0IG1rZHRlbXAoam9pbih0bXBkaXIoKSwgXCJjZGstbmV4dGpzLW1pZGRsZXdhcmUtXCIpKTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoam9pbihyb290LCBcIm1pZGRsZXdhcmUuanNcIiksIHNvdXJjZSk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cblxuICBjb25zdCBpbnZva2UgPSAocm9vdDogc3RyaW5nKSA9PlxuICAgIG5ldyBNaWRkbGV3YXJlUnVubmVyKHtcbiAgICAgIG1pZGRsZXdhcmU6IHsgaWQ6IFwiL19taWRkbGV3YXJlXCIsIGZpbGVQYXRoOiBcIm1pZGRsZXdhcmUuanNcIiB9LFxuICAgICAgcm9vdCxcbiAgICB9KS5pbnZva2VyRm9yKCkoe1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgdXJsOiBuZXcgVVJMKGAke09SSUdJTn0vaXNyLzFgKSxcbiAgICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKHsgaG9zdDogXCJleGFtcGxlLnRlc3RcIiB9KSxcbiAgICAgIHJlcXVlc3RCb2R5OiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgICBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgaXQoXCJsb2FkcyBhIG1vZHVsZSB0aGF0IGV4cG9ydHMgaGFuZGxlciBkaXJlY3RseVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IGF3YWl0IHdyaXRlTW9kdWxlKFxuICAgICAgYGV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IG5ldyBSZXNwb25zZShudWxsLCB7IGhlYWRlcnM6IHsgXCJ4LW1pZGRsZXdhcmUtbmV4dFwiOiBcIjFcIiwgXCJ4LWZsYWdcIjogXCJzeW5jXCIgfSB9KTtgLFxuICAgICk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW52b2tlKHJvb3QpO1xuICAgIGV4cGVjdChyZXN1bHQucmVzcG9uc2VIZWFkZXJzPy5nZXQoXCJ4LWZsYWdcIikpLnRvQmUoXCJzeW5jXCIpO1xuICB9KTtcblxuICBpdChcImF3YWl0cyBhIG1vZHVsZSB3aG9zZSBleHBvcnRzIGFyZSBhIHByb21pc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIC8vIFR1cmJvcGFjaydzIGFzeW5jLW1vZHVsZSBzaGFwZTogYG1vZHVsZS5leHBvcnRzYCBpcyBhIFByb21pc2UuIEEgcmVhbFxuICAgIC8vIGAubmV4dC9zZXJ2ZXIvbWlkZGxld2FyZS5qc2AgYnVpbHQgYnkgVHVyYm9wYWNrIGxvb2tzIGV4YWN0bHkgbGlrZSB0aGlzLlxuICAgIGNvbnN0IHJvb3QgPSBhd2FpdCB3cml0ZU1vZHVsZShcbiAgICAgIGBtb2R1bGUuZXhwb3J0cyA9IFByb21pc2UucmVzb2x2ZSh7IGhhbmRsZXI6IGFzeW5jICgpID0+IG5ldyBSZXNwb25zZShudWxsLCB7IGhlYWRlcnM6IHsgXCJ4LW1pZGRsZXdhcmUtbmV4dFwiOiBcIjFcIiwgXCJ4LWZsYWdcIjogXCJhc3luY1wiIH0gfSkgfSk7YCxcbiAgICApO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGludm9rZShyb290KTtcbiAgICBleHBlY3QocmVzdWx0LnJlc3BvbnNlSGVhZGVycz8uZ2V0KFwieC1mbGFnXCIpKS50b0JlKFwiYXN5bmNcIik7XG4gIH0pO1xuXG4gIGl0KFwicmVwb3J0cyBhIG1pc3NpbmcgbW9kdWxlIGFzIGFuIGluY29tcGxldGUgcGFja2FnZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IGF3YWl0IG1rZHRlbXAoam9pbih0bXBkaXIoKSwgXCJjZGstbmV4dGpzLW1pZGRsZXdhcmUtXCIpKTtcbiAgICBhd2FpdCBleHBlY3QoaW52b2tlKHJvb3QpKS5yZWplY3RzLnRvVGhyb3coXG4gICAgICAvQ291bGQgbm90IGxvYWQgbWlkZGxld2FyZSBmcm9tIC4qbWlkZGxld2FyZVxcLmpzLipkZXBsb3ltZW50IHBhY2thZ2UgaXMgaW5jb21wbGV0ZS9zLFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwicmVwb3J0cyBhIG1vZHVsZSB3aXRob3V0IGEgaGFuZGxlciBleHBvcnRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBhd2FpdCB3cml0ZU1vZHVsZShgbW9kdWxlLmV4cG9ydHMgPSB7IG5vcGU6IDEgfTtgKTtcbiAgICBhd2FpdCBleHBlY3QoaW52b2tlKHJvb3QpKS5yZWplY3RzLnRvVGhyb3coXG4gICAgICAvZG9lcyBub3QgZXhwb3J0IGEgYGhhbmRsZXJgIGZ1bmN0aW9uIFxcKGdvdCB1bmRlZmluZWRcXCkvLFxuICAgICk7XG4gIH0pO1xufSk7XG5cbi8qKiBUaGUgd2lyZSBmb3JtIG9mIGBOZXh0UmVzcG9uc2UubmV4dCgpYC4gKi9cbmZ1bmN0aW9uIG5leHQoKTogUmVzcG9uc2Uge1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKG51bGwsIHtcbiAgICBzdGF0dXM6IDIwMCxcbiAgICBoZWFkZXJzOiB7IFwieC1taWRkbGV3YXJlLW5leHRcIjogXCIxXCIgfSxcbiAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Point `next` resolution at the staged Next.js project. Called once by
|
|
3
|
+
* `loadRuntime`, before anything can serve a request.
|
|
4
|
+
*
|
|
5
|
+
* @param projectDir absolute path to the staged project dir
|
|
6
|
+
* (`join(deploymentRoot, manifest.relativeProjectDir)`).
|
|
7
|
+
*/
|
|
8
|
+
export declare function useNextFrom(projectDir: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* The bootstrap Next.js exposes for adapters — "can be used to ensure Node.js
|
|
11
|
+
* APIs are setup as expected without requiring `next-server`", in its own words.
|
|
12
|
+
* It installs the globals, the `react`/`react-dom` require hook, and the
|
|
13
|
+
* `console`/`Error`/`Date`/crypto extensions that `next start` installs before it
|
|
14
|
+
* loads any route.
|
|
15
|
+
*
|
|
16
|
+
* Its most load-bearing effect is `globalThis.AsyncLocalStorage`, which
|
|
17
|
+
* `next/dist/server/app-render/async-local-storage.js` reads *at module scope* —
|
|
18
|
+
* whatever is loaded first wins, permanently.
|
|
19
|
+
*
|
|
20
|
+
* Without this, `next/dist/compiled/next-server/app-page-turbo.runtime.prod.js`
|
|
21
|
+
* requires `work-async-storage.external.js` before its own
|
|
22
|
+
* `route-module.js` gets to the bootstrap, and the app-render storage is created
|
|
23
|
+
* as Next's `FakeAsyncLocalStorage`, which throws "Invariant: AsyncLocalStorage
|
|
24
|
+
* accessed in runtime where it is not available" on the first dynamic render.
|
|
25
|
+
*
|
|
26
|
+
* It is easy to miss, because an app with middleware is accidentally fine:
|
|
27
|
+
* `next/dist/build/templates/middleware.js` requires the same bootstrap, and the
|
|
28
|
+
* runtime runs middleware before it loads a page entrypoint. Only an app with no
|
|
29
|
+
* middleware — and only on a dynamic app-page render — reaches the invariant.
|
|
30
|
+
*
|
|
31
|
+
* `next/dist/build/adapter/setup-node-env.external.js` is side-effect-only and
|
|
32
|
+
* idempotent (`node-environment.js` guards its own re-entry), so calling this
|
|
33
|
+
* more than once is harmless.
|
|
34
|
+
*/
|
|
35
|
+
export declare function setupNodeEnvironment(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Load the staged `.env` / `.env.production` into `process.env`, the way
|
|
38
|
+
* `NextNodeServer` does when `next start` constructs it. Nothing else would:
|
|
39
|
+
* the built entrypoints never call `loadEnvConfig`, and the runtime builds no
|
|
40
|
+
* `NextNodeServer`.
|
|
41
|
+
*
|
|
42
|
+
* Same semantics as `next start` because it is the same function — variables
|
|
43
|
+
* already in `process.env` (the Lambda or task environment) win over the files.
|
|
44
|
+
* `@next/env` is a dependency of `next`, not of the app, so it is resolved from
|
|
45
|
+
* `next`'s own directory; the adapter stages it on that basis
|
|
46
|
+
* (`addRuntimeNextClosure`).
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadEnvFiles(projectDir: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* `require` a `next` submodule from the staged app.
|
|
51
|
+
*
|
|
52
|
+
* Pass the module's own type — `nextModule<typeof import("next/dist/...")>(...)` —
|
|
53
|
+
* so the call is as type-checked as a static import would be.
|
|
54
|
+
*/
|
|
55
|
+
export declare function nextModule<T>(specifier: string): T;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useNextFrom = useNextFrom;
|
|
4
|
+
exports.setupNodeEnvironment = setupNodeEnvironment;
|
|
5
|
+
exports.loadEnvFiles = loadEnvFiles;
|
|
6
|
+
exports.nextModule = nextModule;
|
|
7
|
+
/**
|
|
8
|
+
* Resolving the handful of `next` internals the runtime itself needs, out of the
|
|
9
|
+
* staged app rather than from next to the shell.
|
|
10
|
+
*
|
|
11
|
+
* `next` is deliberately external to both shell bundles: the deployment already
|
|
12
|
+
* carries the traced `next` files every built entrypoint requires, and a second
|
|
13
|
+
* bundled copy would be a different module instance — pinned to *cdk-nextjs's*
|
|
14
|
+
* `next` version rather than the consumer's.
|
|
15
|
+
*
|
|
16
|
+
* Marking it external is not enough on its own. esbuild turns
|
|
17
|
+
* `import { serveStatic } from "next/dist/server/serve-static.js"` into a real,
|
|
18
|
+
* hoisted `import` inside `cdk-nextjs-runtime/lambda.mjs`, which Node resolves by
|
|
19
|
+
* walking `cdk-nextjs-runtime/node_modules` and then `<deploymentRoot>/node_modules`
|
|
20
|
+
* — and under pnpm neither holds `next`. The only `next` in the staged tree is the
|
|
21
|
+
* relative symlink at `<projectDir>/node_modules/next` that the traced entrypoints
|
|
22
|
+
* resolve through, one directory *below* the deployment root. A hoisted npm/yarn
|
|
23
|
+
* monorepo puts it somewhere else again. Since those imports are hoisted, getting
|
|
24
|
+
* this wrong is not a degraded image route: the shell fails to load at all.
|
|
25
|
+
*
|
|
26
|
+
* So every such module is required through a `createRequire` anchored inside the
|
|
27
|
+
* staged project dir, which makes the runtime resolve `next` by the same walk the
|
|
28
|
+
* entrypoints do, for any package manager and any layout. That also means they
|
|
29
|
+
* cannot be imported at module scope; each caller resolves (and memoizes) on
|
|
30
|
+
* first use, after {@link useNextFrom}.
|
|
31
|
+
*/
|
|
32
|
+
const node_module_1 = require("node:module");
|
|
33
|
+
const node_path_1 = require("node:path");
|
|
34
|
+
let nextRequire;
|
|
35
|
+
/**
|
|
36
|
+
* Point `next` resolution at the staged Next.js project. Called once by
|
|
37
|
+
* `loadRuntime`, before anything can serve a request.
|
|
38
|
+
*
|
|
39
|
+
* @param projectDir absolute path to the staged project dir
|
|
40
|
+
* (`join(deploymentRoot, manifest.relativeProjectDir)`).
|
|
41
|
+
*/
|
|
42
|
+
function useNextFrom(projectDir) {
|
|
43
|
+
// Anchored on a path *inside* `projectDir`, because `createRequire` starts its
|
|
44
|
+
// `node_modules` walk at the anchor's directory. The file needn't exist.
|
|
45
|
+
nextRequire = (0, node_module_1.createRequire)((0, node_path_1.join)(projectDir, "cdk-nextjs-next-resolver.cjs"));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The bootstrap Next.js exposes for adapters — "can be used to ensure Node.js
|
|
49
|
+
* APIs are setup as expected without requiring `next-server`", in its own words.
|
|
50
|
+
* It installs the globals, the `react`/`react-dom` require hook, and the
|
|
51
|
+
* `console`/`Error`/`Date`/crypto extensions that `next start` installs before it
|
|
52
|
+
* loads any route.
|
|
53
|
+
*
|
|
54
|
+
* Its most load-bearing effect is `globalThis.AsyncLocalStorage`, which
|
|
55
|
+
* `next/dist/server/app-render/async-local-storage.js` reads *at module scope* —
|
|
56
|
+
* whatever is loaded first wins, permanently.
|
|
57
|
+
*
|
|
58
|
+
* Without this, `next/dist/compiled/next-server/app-page-turbo.runtime.prod.js`
|
|
59
|
+
* requires `work-async-storage.external.js` before its own
|
|
60
|
+
* `route-module.js` gets to the bootstrap, and the app-render storage is created
|
|
61
|
+
* as Next's `FakeAsyncLocalStorage`, which throws "Invariant: AsyncLocalStorage
|
|
62
|
+
* accessed in runtime where it is not available" on the first dynamic render.
|
|
63
|
+
*
|
|
64
|
+
* It is easy to miss, because an app with middleware is accidentally fine:
|
|
65
|
+
* `next/dist/build/templates/middleware.js` requires the same bootstrap, and the
|
|
66
|
+
* runtime runs middleware before it loads a page entrypoint. Only an app with no
|
|
67
|
+
* middleware — and only on a dynamic app-page render — reaches the invariant.
|
|
68
|
+
*
|
|
69
|
+
* `next/dist/build/adapter/setup-node-env.external.js` is side-effect-only and
|
|
70
|
+
* idempotent (`node-environment.js` guards its own re-entry), so calling this
|
|
71
|
+
* more than once is harmless.
|
|
72
|
+
*/
|
|
73
|
+
function setupNodeEnvironment() {
|
|
74
|
+
nextModule("next/dist/build/adapter/setup-node-env.external.js");
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Load the staged `.env` / `.env.production` into `process.env`, the way
|
|
78
|
+
* `NextNodeServer` does when `next start` constructs it. Nothing else would:
|
|
79
|
+
* the built entrypoints never call `loadEnvConfig`, and the runtime builds no
|
|
80
|
+
* `NextNodeServer`.
|
|
81
|
+
*
|
|
82
|
+
* Same semantics as `next start` because it is the same function — variables
|
|
83
|
+
* already in `process.env` (the Lambda or task environment) win over the files.
|
|
84
|
+
* `@next/env` is a dependency of `next`, not of the app, so it is resolved from
|
|
85
|
+
* `next`'s own directory; the adapter stages it on that basis
|
|
86
|
+
* (`addRuntimeNextClosure`).
|
|
87
|
+
*/
|
|
88
|
+
function loadEnvFiles(projectDir) {
|
|
89
|
+
const nextEnvRequire = (0, node_module_1.createRequire)(nextModuleResolve("next/package.json"));
|
|
90
|
+
// Typed locally: `@next/env` is `next`'s dependency, not a resolvable one here.
|
|
91
|
+
const { loadEnvConfig } = nextEnvRequire("@next/env");
|
|
92
|
+
loadEnvConfig(projectDir, false);
|
|
93
|
+
}
|
|
94
|
+
function nextModuleResolve(specifier) {
|
|
95
|
+
return nextRequireOrThrow(specifier).resolve(specifier);
|
|
96
|
+
}
|
|
97
|
+
function nextRequireOrThrow(specifier) {
|
|
98
|
+
if (!nextRequire) {
|
|
99
|
+
throw new Error(`Cannot load "${specifier}": \`next\` resolution has not been pointed at ` +
|
|
100
|
+
`the staged app yet. \`useNextFrom\` runs in \`loadRuntime\`, so this ` +
|
|
101
|
+
`means runtime code loaded a \`next\` module before the runtime was ` +
|
|
102
|
+
`loaded.`);
|
|
103
|
+
}
|
|
104
|
+
return nextRequire;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* `require` a `next` submodule from the staged app.
|
|
108
|
+
*
|
|
109
|
+
* Pass the module's own type — `nextModule<typeof import("next/dist/...")>(...)` —
|
|
110
|
+
* so the call is as type-checked as a static import would be.
|
|
111
|
+
*/
|
|
112
|
+
function nextModule(specifier) {
|
|
113
|
+
const load = nextRequireOrThrow(specifier);
|
|
114
|
+
try {
|
|
115
|
+
return load(specifier);
|
|
116
|
+
}
|
|
117
|
+
catch (cause) {
|
|
118
|
+
throw new Error(`Could not resolve "${specifier}" from the deployed Next.js project. The ` +
|
|
119
|
+
`deployment package is missing part of the \`next\` closure that ` +
|
|
120
|
+
`\`next build\` traced, or \`node_modules/next\` resolves to a symlink ` +
|
|
121
|
+
`target that was not staged.`, { cause });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dC1tb2R1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvbmV4dC1tb2R1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBcUNBLGtDQUlDO0FBNEJELG9EQUVDO0FBY0Qsb0NBT0M7QUEwQkQsZ0NBYUM7QUFuSUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRztBQUNILDZDQUE0QztBQUM1Qyx5Q0FBaUM7QUFFakMsSUFBSSxXQUF5RCxDQUFDO0FBRTlEOzs7Ozs7R0FNRztBQUNILFNBQWdCLFdBQVcsQ0FBQyxVQUFrQjtJQUM1QywrRUFBK0U7SUFDL0UseUVBQXlFO0lBQ3pFLFdBQVcsR0FBRyxJQUFBLDJCQUFhLEVBQUMsSUFBQSxnQkFBSSxFQUFDLFVBQVUsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDLENBQUM7QUFDaEYsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0gsU0FBZ0Isb0JBQW9CO0lBQ2xDLFVBQVUsQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLFlBQVksQ0FBQyxVQUFrQjtJQUM3QyxNQUFNLGNBQWMsR0FBRyxJQUFBLDJCQUFhLEVBQUMsaUJBQWlCLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO0lBQzdFLGdGQUFnRjtJQUNoRixNQUFNLEVBQUUsYUFBYSxFQUFFLEdBQUcsY0FBYyxDQUFDLFdBQVcsQ0FFbkQsQ0FBQztJQUNGLGFBQWEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsU0FBaUI7SUFDMUMsT0FBTyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQ3pCLFNBQWlCO0lBRWpCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixNQUFNLElBQUksS0FBSyxDQUNiLGdCQUFnQixTQUFTLGlEQUFpRDtZQUN4RSx1RUFBdUU7WUFDdkUscUVBQXFFO1lBQ3JFLFNBQVMsQ0FDWixDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLFVBQVUsQ0FBSSxTQUFpQjtJQUM3QyxNQUFNLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMzQyxJQUFJLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQU0sQ0FBQztJQUM5QixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxLQUFLLENBQ2Isc0JBQXNCLFNBQVMsMkNBQTJDO1lBQ3hFLGtFQUFrRTtZQUNsRSx3RUFBd0U7WUFDeEUsNkJBQTZCLEVBQy9CLEVBQUUsS0FBSyxFQUFFLENBQ1YsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZXNvbHZpbmcgdGhlIGhhbmRmdWwgb2YgYG5leHRgIGludGVybmFscyB0aGUgcnVudGltZSBpdHNlbGYgbmVlZHMsIG91dCBvZiB0aGVcbiAqIHN0YWdlZCBhcHAgcmF0aGVyIHRoYW4gZnJvbSBuZXh0IHRvIHRoZSBzaGVsbC5cbiAqXG4gKiBgbmV4dGAgaXMgZGVsaWJlcmF0ZWx5IGV4dGVybmFsIHRvIGJvdGggc2hlbGwgYnVuZGxlczogdGhlIGRlcGxveW1lbnQgYWxyZWFkeVxuICogY2FycmllcyB0aGUgdHJhY2VkIGBuZXh0YCBmaWxlcyBldmVyeSBidWlsdCBlbnRyeXBvaW50IHJlcXVpcmVzLCBhbmQgYSBzZWNvbmRcbiAqIGJ1bmRsZWQgY29weSB3b3VsZCBiZSBhIGRpZmZlcmVudCBtb2R1bGUgaW5zdGFuY2Ug4oCUIHBpbm5lZCB0byAqY2RrLW5leHRqcydzKlxuICogYG5leHRgIHZlcnNpb24gcmF0aGVyIHRoYW4gdGhlIGNvbnN1bWVyJ3MuXG4gKlxuICogTWFya2luZyBpdCBleHRlcm5hbCBpcyBub3QgZW5vdWdoIG9uIGl0cyBvd24uIGVzYnVpbGQgdHVybnNcbiAqIGBpbXBvcnQgeyBzZXJ2ZVN0YXRpYyB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3NlcnZlLXN0YXRpYy5qc1wiYCBpbnRvIGEgcmVhbCxcbiAqIGhvaXN0ZWQgYGltcG9ydGAgaW5zaWRlIGBjZGstbmV4dGpzLXJ1bnRpbWUvbGFtYmRhLm1qc2AsIHdoaWNoIE5vZGUgcmVzb2x2ZXMgYnlcbiAqIHdhbGtpbmcgYGNkay1uZXh0anMtcnVudGltZS9ub2RlX21vZHVsZXNgIGFuZCB0aGVuIGA8ZGVwbG95bWVudFJvb3Q+L25vZGVfbW9kdWxlc2BcbiAqIOKAlCBhbmQgdW5kZXIgcG5wbSBuZWl0aGVyIGhvbGRzIGBuZXh0YC4gVGhlIG9ubHkgYG5leHRgIGluIHRoZSBzdGFnZWQgdHJlZSBpcyB0aGVcbiAqIHJlbGF0aXZlIHN5bWxpbmsgYXQgYDxwcm9qZWN0RGlyPi9ub2RlX21vZHVsZXMvbmV4dGAgdGhhdCB0aGUgdHJhY2VkIGVudHJ5cG9pbnRzXG4gKiByZXNvbHZlIHRocm91Z2gsIG9uZSBkaXJlY3RvcnkgKmJlbG93KiB0aGUgZGVwbG95bWVudCByb290LiBBIGhvaXN0ZWQgbnBtL3lhcm5cbiAqIG1vbm9yZXBvIHB1dHMgaXQgc29tZXdoZXJlIGVsc2UgYWdhaW4uIFNpbmNlIHRob3NlIGltcG9ydHMgYXJlIGhvaXN0ZWQsIGdldHRpbmdcbiAqIHRoaXMgd3JvbmcgaXMgbm90IGEgZGVncmFkZWQgaW1hZ2Ugcm91dGU6IHRoZSBzaGVsbCBmYWlscyB0byBsb2FkIGF0IGFsbC5cbiAqXG4gKiBTbyBldmVyeSBzdWNoIG1vZHVsZSBpcyByZXF1aXJlZCB0aHJvdWdoIGEgYGNyZWF0ZVJlcXVpcmVgIGFuY2hvcmVkIGluc2lkZSB0aGVcbiAqIHN0YWdlZCBwcm9qZWN0IGRpciwgd2hpY2ggbWFrZXMgdGhlIHJ1bnRpbWUgcmVzb2x2ZSBgbmV4dGAgYnkgdGhlIHNhbWUgd2FsayB0aGVcbiAqIGVudHJ5cG9pbnRzIGRvLCBmb3IgYW55IHBhY2thZ2UgbWFuYWdlciBhbmQgYW55IGxheW91dC4gVGhhdCBhbHNvIG1lYW5zIHRoZXlcbiAqIGNhbm5vdCBiZSBpbXBvcnRlZCBhdCBtb2R1bGUgc2NvcGU7IGVhY2ggY2FsbGVyIHJlc29sdmVzIChhbmQgbWVtb2l6ZXMpIG9uXG4gKiBmaXJzdCB1c2UsIGFmdGVyIHtAbGluayB1c2VOZXh0RnJvbX0uXG4gKi9cbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmxldCBuZXh0UmVxdWlyZTogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlUmVxdWlyZT4gfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUG9pbnQgYG5leHRgIHJlc29sdXRpb24gYXQgdGhlIHN0YWdlZCBOZXh0LmpzIHByb2plY3QuIENhbGxlZCBvbmNlIGJ5XG4gKiBgbG9hZFJ1bnRpbWVgLCBiZWZvcmUgYW55dGhpbmcgY2FuIHNlcnZlIGEgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gcHJvamVjdERpciBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBzdGFnZWQgcHJvamVjdCBkaXJcbiAqIChgam9pbihkZXBsb3ltZW50Um9vdCwgbWFuaWZlc3QucmVsYXRpdmVQcm9qZWN0RGlyKWApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlTmV4dEZyb20ocHJvamVjdERpcjogc3RyaW5nKTogdm9pZCB7XG4gIC8vIEFuY2hvcmVkIG9uIGEgcGF0aCAqaW5zaWRlKiBgcHJvamVjdERpcmAsIGJlY2F1c2UgYGNyZWF0ZVJlcXVpcmVgIHN0YXJ0cyBpdHNcbiAgLy8gYG5vZGVfbW9kdWxlc2Agd2FsayBhdCB0aGUgYW5jaG9yJ3MgZGlyZWN0b3J5LiBUaGUgZmlsZSBuZWVkbid0IGV4aXN0LlxuICBuZXh0UmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoam9pbihwcm9qZWN0RGlyLCBcImNkay1uZXh0anMtbmV4dC1yZXNvbHZlci5janNcIikpO1xufVxuXG4vKipcbiAqIFRoZSBib290c3RyYXAgTmV4dC5qcyBleHBvc2VzIGZvciBhZGFwdGVycyDigJQgXCJjYW4gYmUgdXNlZCB0byBlbnN1cmUgTm9kZS5qc1xuICogQVBJcyBhcmUgc2V0dXAgYXMgZXhwZWN0ZWQgd2l0aG91dCByZXF1aXJpbmcgYG5leHQtc2VydmVyYFwiLCBpbiBpdHMgb3duIHdvcmRzLlxuICogSXQgaW5zdGFsbHMgdGhlIGdsb2JhbHMsIHRoZSBgcmVhY3RgL2ByZWFjdC1kb21gIHJlcXVpcmUgaG9vaywgYW5kIHRoZVxuICogYGNvbnNvbGVgL2BFcnJvcmAvYERhdGVgL2NyeXB0byBleHRlbnNpb25zIHRoYXQgYG5leHQgc3RhcnRgIGluc3RhbGxzIGJlZm9yZSBpdFxuICogbG9hZHMgYW55IHJvdXRlLlxuICpcbiAqIEl0cyBtb3N0IGxvYWQtYmVhcmluZyBlZmZlY3QgaXMgYGdsb2JhbFRoaXMuQXN5bmNMb2NhbFN0b3JhZ2VgLCB3aGljaFxuICogYG5leHQvZGlzdC9zZXJ2ZXIvYXBwLXJlbmRlci9hc3luYy1sb2NhbC1zdG9yYWdlLmpzYCByZWFkcyAqYXQgbW9kdWxlIHNjb3BlKiDigJRcbiAqIHdoYXRldmVyIGlzIGxvYWRlZCBmaXJzdCB3aW5zLCBwZXJtYW5lbnRseS5cbiAqXG4gKiBXaXRob3V0IHRoaXMsIGBuZXh0L2Rpc3QvY29tcGlsZWQvbmV4dC1zZXJ2ZXIvYXBwLXBhZ2UtdHVyYm8ucnVudGltZS5wcm9kLmpzYFxuICogcmVxdWlyZXMgYHdvcmstYXN5bmMtc3RvcmFnZS5leHRlcm5hbC5qc2AgYmVmb3JlIGl0cyBvd25cbiAqIGByb3V0ZS1tb2R1bGUuanNgIGdldHMgdG8gdGhlIGJvb3RzdHJhcCwgYW5kIHRoZSBhcHAtcmVuZGVyIHN0b3JhZ2UgaXMgY3JlYXRlZFxuICogYXMgTmV4dCdzIGBGYWtlQXN5bmNMb2NhbFN0b3JhZ2VgLCB3aGljaCB0aHJvd3MgXCJJbnZhcmlhbnQ6IEFzeW5jTG9jYWxTdG9yYWdlXG4gKiBhY2Nlc3NlZCBpbiBydW50aW1lIHdoZXJlIGl0IGlzIG5vdCBhdmFpbGFibGVcIiBvbiB0aGUgZmlyc3QgZHluYW1pYyByZW5kZXIuXG4gKlxuICogSXQgaXMgZWFzeSB0byBtaXNzLCBiZWNhdXNlIGFuIGFwcCB3aXRoIG1pZGRsZXdhcmUgaXMgYWNjaWRlbnRhbGx5IGZpbmU6XG4gKiBgbmV4dC9kaXN0L2J1aWxkL3RlbXBsYXRlcy9taWRkbGV3YXJlLmpzYCByZXF1aXJlcyB0aGUgc2FtZSBib290c3RyYXAsIGFuZCB0aGVcbiAqIHJ1bnRpbWUgcnVucyBtaWRkbGV3YXJlIGJlZm9yZSBpdCBsb2FkcyBhIHBhZ2UgZW50cnlwb2ludC4gT25seSBhbiBhcHAgd2l0aCBub1xuICogbWlkZGxld2FyZSDigJQgYW5kIG9ubHkgb24gYSBkeW5hbWljIGFwcC1wYWdlIHJlbmRlciDigJQgcmVhY2hlcyB0aGUgaW52YXJpYW50LlxuICpcbiAqIGBuZXh0L2Rpc3QvYnVpbGQvYWRhcHRlci9zZXR1cC1ub2RlLWVudi5leHRlcm5hbC5qc2AgaXMgc2lkZS1lZmZlY3Qtb25seSBhbmRcbiAqIGlkZW1wb3RlbnQgKGBub2RlLWVudmlyb25tZW50LmpzYCBndWFyZHMgaXRzIG93biByZS1lbnRyeSksIHNvIGNhbGxpbmcgdGhpc1xuICogbW9yZSB0aGFuIG9uY2UgaXMgaGFybWxlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXR1cE5vZGVFbnZpcm9ubWVudCgpOiB2b2lkIHtcbiAgbmV4dE1vZHVsZShcIm5leHQvZGlzdC9idWlsZC9hZGFwdGVyL3NldHVwLW5vZGUtZW52LmV4dGVybmFsLmpzXCIpO1xufVxuXG4vKipcbiAqIExvYWQgdGhlIHN0YWdlZCBgLmVudmAgLyBgLmVudi5wcm9kdWN0aW9uYCBpbnRvIGBwcm9jZXNzLmVudmAsIHRoZSB3YXlcbiAqIGBOZXh0Tm9kZVNlcnZlcmAgZG9lcyB3aGVuIGBuZXh0IHN0YXJ0YCBjb25zdHJ1Y3RzIGl0LiBOb3RoaW5nIGVsc2Ugd291bGQ6XG4gKiB0aGUgYnVpbHQgZW50cnlwb2ludHMgbmV2ZXIgY2FsbCBgbG9hZEVudkNvbmZpZ2AsIGFuZCB0aGUgcnVudGltZSBidWlsZHMgbm9cbiAqIGBOZXh0Tm9kZVNlcnZlcmAuXG4gKlxuICogU2FtZSBzZW1hbnRpY3MgYXMgYG5leHQgc3RhcnRgIGJlY2F1c2UgaXQgaXMgdGhlIHNhbWUgZnVuY3Rpb24g4oCUIHZhcmlhYmxlc1xuICogYWxyZWFkeSBpbiBgcHJvY2Vzcy5lbnZgICh0aGUgTGFtYmRhIG9yIHRhc2sgZW52aXJvbm1lbnQpIHdpbiBvdmVyIHRoZSBmaWxlcy5cbiAqIGBAbmV4dC9lbnZgIGlzIGEgZGVwZW5kZW5jeSBvZiBgbmV4dGAsIG5vdCBvZiB0aGUgYXBwLCBzbyBpdCBpcyByZXNvbHZlZCBmcm9tXG4gKiBgbmV4dGAncyBvd24gZGlyZWN0b3J5OyB0aGUgYWRhcHRlciBzdGFnZXMgaXQgb24gdGhhdCBiYXNpc1xuICogKGBhZGRSdW50aW1lTmV4dENsb3N1cmVgKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWRFbnZGaWxlcyhwcm9qZWN0RGlyOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgbmV4dEVudlJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKG5leHRNb2R1bGVSZXNvbHZlKFwibmV4dC9wYWNrYWdlLmpzb25cIikpO1xuICAvLyBUeXBlZCBsb2NhbGx5OiBgQG5leHQvZW52YCBpcyBgbmV4dGAncyBkZXBlbmRlbmN5LCBub3QgYSByZXNvbHZhYmxlIG9uZSBoZXJlLlxuICBjb25zdCB7IGxvYWRFbnZDb25maWcgfSA9IG5leHRFbnZSZXF1aXJlKFwiQG5leHQvZW52XCIpIGFzIHtcbiAgICBsb2FkRW52Q29uZmlnOiAoZGlyOiBzdHJpbmcsIGRldj86IGJvb2xlYW4pID0+IHVua25vd247XG4gIH07XG4gIGxvYWRFbnZDb25maWcocHJvamVjdERpciwgZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBuZXh0TW9kdWxlUmVzb2x2ZShzcGVjaWZpZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXh0UmVxdWlyZU9yVGhyb3coc3BlY2lmaWVyKS5yZXNvbHZlKHNwZWNpZmllcik7XG59XG5cbmZ1bmN0aW9uIG5leHRSZXF1aXJlT3JUaHJvdyhcbiAgc3BlY2lmaWVyOiBzdHJpbmcsXG4pOiBSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVSZXF1aXJlPiB7XG4gIGlmICghbmV4dFJlcXVpcmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgQ2Fubm90IGxvYWQgXCIke3NwZWNpZmllcn1cIjogXFxgbmV4dFxcYCByZXNvbHV0aW9uIGhhcyBub3QgYmVlbiBwb2ludGVkIGF0IGAgK1xuICAgICAgICBgdGhlIHN0YWdlZCBhcHAgeWV0LiBcXGB1c2VOZXh0RnJvbVxcYCBydW5zIGluIFxcYGxvYWRSdW50aW1lXFxgLCBzbyB0aGlzIGAgK1xuICAgICAgICBgbWVhbnMgcnVudGltZSBjb2RlIGxvYWRlZCBhIFxcYG5leHRcXGAgbW9kdWxlIGJlZm9yZSB0aGUgcnVudGltZSB3YXMgYCArXG4gICAgICAgIGBsb2FkZWQuYCxcbiAgICApO1xuICB9XG4gIHJldHVybiBuZXh0UmVxdWlyZTtcbn1cblxuLyoqXG4gKiBgcmVxdWlyZWAgYSBgbmV4dGAgc3VibW9kdWxlIGZyb20gdGhlIHN0YWdlZCBhcHAuXG4gKlxuICogUGFzcyB0aGUgbW9kdWxlJ3Mgb3duIHR5cGUg4oCUIGBuZXh0TW9kdWxlPHR5cGVvZiBpbXBvcnQoXCJuZXh0L2Rpc3QvLi4uXCIpPiguLi4pYCDigJRcbiAqIHNvIHRoZSBjYWxsIGlzIGFzIHR5cGUtY2hlY2tlZCBhcyBhIHN0YXRpYyBpbXBvcnQgd291bGQgYmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZXh0TW9kdWxlPFQ+KHNwZWNpZmllcjogc3RyaW5nKTogVCB7XG4gIGNvbnN0IGxvYWQgPSBuZXh0UmVxdWlyZU9yVGhyb3coc3BlY2lmaWVyKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gbG9hZChzcGVjaWZpZXIpIGFzIFQ7XG4gIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYENvdWxkIG5vdCByZXNvbHZlIFwiJHtzcGVjaWZpZXJ9XCIgZnJvbSB0aGUgZGVwbG95ZWQgTmV4dC5qcyBwcm9qZWN0LiBUaGUgYCArXG4gICAgICAgIGBkZXBsb3ltZW50IHBhY2thZ2UgaXMgbWlzc2luZyBwYXJ0IG9mIHRoZSBcXGBuZXh0XFxgIGNsb3N1cmUgdGhhdCBgICtcbiAgICAgICAgYFxcYG5leHQgYnVpbGRcXGAgdHJhY2VkLCBvciBcXGBub2RlX21vZHVsZXMvbmV4dFxcYCByZXNvbHZlcyB0byBhIHN5bWxpbmsgYCArXG4gICAgICAgIGB0YXJnZXQgdGhhdCB3YXMgbm90IHN0YWdlZC5gLFxuICAgICAgeyBjYXVzZSB9LFxuICAgICk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_path_1 = require("node:path");
|
|
4
|
+
const next_modules_1 = require("./next-modules");
|
|
5
|
+
/** This repo's own root, which has a `node_modules/next`, as a stand-in for a staged project dir. */
|
|
6
|
+
const repoRoot = (0, node_path_1.join)(__dirname, "../..");
|
|
7
|
+
describe("nextModule", () => {
|
|
8
|
+
it("resolves a next submodule out of the pointed-at project dir", () => {
|
|
9
|
+
(0, next_modules_1.useNextFrom)(repoRoot);
|
|
10
|
+
const { getExtension } = (0, next_modules_1.nextModule)("next/dist/server/serve-static.js");
|
|
11
|
+
expect(getExtension("image/webp")).toBe("webp");
|
|
12
|
+
});
|
|
13
|
+
it("explains that the deployment package is incomplete when resolution fails", () => {
|
|
14
|
+
(0, next_modules_1.useNextFrom)(repoRoot);
|
|
15
|
+
expect(() => (0, next_modules_1.nextModule)("next/dist/server/not-a-real-module.js")).toThrow(/Could not resolve .* from the deployed Next.js project/);
|
|
16
|
+
});
|
|
17
|
+
it("makes AsyncLocalStorage global, which app-render reads at module scope", () => {
|
|
18
|
+
// The symptom of skipping this is "Invariant: AsyncLocalStorage accessed in
|
|
19
|
+
// runtime where it is not available" on the first dynamic app-page render.
|
|
20
|
+
(0, next_modules_1.useNextFrom)(repoRoot);
|
|
21
|
+
(0, next_modules_1.setupNodeEnvironment)();
|
|
22
|
+
const polyfilled = globalThis;
|
|
23
|
+
expect(typeof polyfilled.AsyncLocalStorage).toBe("function");
|
|
24
|
+
});
|
|
25
|
+
it("explains that the runtime was not loaded when nothing pointed it anywhere", () => {
|
|
26
|
+
// `useNextFrom` is module state, so the uninitialized case needs a fresh copy
|
|
27
|
+
// of the module rather than a reset of this one.
|
|
28
|
+
jest.isolateModules(() => {
|
|
29
|
+
const fresh = jest.requireActual("./next-modules");
|
|
30
|
+
expect(() => fresh.nextModule("next/dist/server/serve-static.js")).toThrow(/resolution has not been pointed at the staged app yet/);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dC1tb2R1bGVzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9uZXh0LW1vZHVsZXMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUFpQztBQUNqQyxpREFBK0U7QUFFL0UscUdBQXFHO0FBQ3JHLE1BQU0sUUFBUSxHQUFHLElBQUEsZ0JBQUksRUFBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFMUMsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7SUFDMUIsRUFBRSxDQUFDLDZEQUE2RCxFQUFFLEdBQUcsRUFBRTtRQUNyRSxJQUFBLDBCQUFXLEVBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEIsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUEseUJBQVUsRUFFakMsa0NBQWtDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBFQUEwRSxFQUFFLEdBQUcsRUFBRTtRQUNsRixJQUFBLDBCQUFXLEVBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEseUJBQVUsRUFBQyx1Q0FBdUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUN2RSx3REFBd0QsQ0FDekQsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdFQUF3RSxFQUFFLEdBQUcsRUFBRTtRQUNoRiw0RUFBNEU7UUFDNUUsMkVBQTJFO1FBQzNFLElBQUEsMEJBQVcsRUFBQyxRQUFRLENBQUMsQ0FBQztRQUN0QixJQUFBLG1DQUFvQixHQUFFLENBQUM7UUFDdkIsTUFBTSxVQUFVLEdBQUcsVUFBNkMsQ0FBQztRQUNqRSxNQUFNLENBQUMsT0FBTyxVQUFVLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0QsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMkVBQTJFLEVBQUUsR0FBRyxFQUFFO1FBQ25GLDhFQUE4RTtRQUM5RSxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUU7WUFDdkIsTUFBTSxLQUFLLEdBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBa0MsZ0JBQWdCLENBQUMsQ0FBQztZQUN4RSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQ1YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUNyRCxDQUFDLE9BQU8sQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQ3JFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBuZXh0TW9kdWxlLCBzZXR1cE5vZGVFbnZpcm9ubWVudCwgdXNlTmV4dEZyb20gfSBmcm9tIFwiLi9uZXh0LW1vZHVsZXNcIjtcblxuLyoqIFRoaXMgcmVwbydzIG93biByb290LCB3aGljaCBoYXMgYSBgbm9kZV9tb2R1bGVzL25leHRgLCBhcyBhIHN0YW5kLWluIGZvciBhIHN0YWdlZCBwcm9qZWN0IGRpci4gKi9cbmNvbnN0IHJlcG9Sb290ID0gam9pbihfX2Rpcm5hbWUsIFwiLi4vLi5cIik7XG5cbmRlc2NyaWJlKFwibmV4dE1vZHVsZVwiLCAoKSA9PiB7XG4gIGl0KFwicmVzb2x2ZXMgYSBuZXh0IHN1Ym1vZHVsZSBvdXQgb2YgdGhlIHBvaW50ZWQtYXQgcHJvamVjdCBkaXJcIiwgKCkgPT4ge1xuICAgIHVzZU5leHRGcm9tKHJlcG9Sb290KTtcbiAgICBjb25zdCB7IGdldEV4dGVuc2lvbiB9ID0gbmV4dE1vZHVsZTxcbiAgICAgIHR5cGVvZiBpbXBvcnQoXCJuZXh0L2Rpc3Qvc2VydmVyL3NlcnZlLXN0YXRpYy5qc1wiKVxuICAgID4oXCJuZXh0L2Rpc3Qvc2VydmVyL3NlcnZlLXN0YXRpYy5qc1wiKTtcbiAgICBleHBlY3QoZ2V0RXh0ZW5zaW9uKFwiaW1hZ2Uvd2VicFwiKSkudG9CZShcIndlYnBcIik7XG4gIH0pO1xuXG4gIGl0KFwiZXhwbGFpbnMgdGhhdCB0aGUgZGVwbG95bWVudCBwYWNrYWdlIGlzIGluY29tcGxldGUgd2hlbiByZXNvbHV0aW9uIGZhaWxzXCIsICgpID0+IHtcbiAgICB1c2VOZXh0RnJvbShyZXBvUm9vdCk7XG4gICAgZXhwZWN0KCgpID0+IG5leHRNb2R1bGUoXCJuZXh0L2Rpc3Qvc2VydmVyL25vdC1hLXJlYWwtbW9kdWxlLmpzXCIpKS50b1Rocm93KFxuICAgICAgL0NvdWxkIG5vdCByZXNvbHZlIC4qIGZyb20gdGhlIGRlcGxveWVkIE5leHQuanMgcHJvamVjdC8sXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoXCJtYWtlcyBBc3luY0xvY2FsU3RvcmFnZSBnbG9iYWwsIHdoaWNoIGFwcC1yZW5kZXIgcmVhZHMgYXQgbW9kdWxlIHNjb3BlXCIsICgpID0+IHtcbiAgICAvLyBUaGUgc3ltcHRvbSBvZiBza2lwcGluZyB0aGlzIGlzIFwiSW52YXJpYW50OiBBc3luY0xvY2FsU3RvcmFnZSBhY2Nlc3NlZCBpblxuICAgIC8vIHJ1bnRpbWUgd2hlcmUgaXQgaXMgbm90IGF2YWlsYWJsZVwiIG9uIHRoZSBmaXJzdCBkeW5hbWljIGFwcC1wYWdlIHJlbmRlci5cbiAgICB1c2VOZXh0RnJvbShyZXBvUm9vdCk7XG4gICAgc2V0dXBOb2RlRW52aXJvbm1lbnQoKTtcbiAgICBjb25zdCBwb2x5ZmlsbGVkID0gZ2xvYmFsVGhpcyBhcyB7IEFzeW5jTG9jYWxTdG9yYWdlPzogdW5rbm93biB9O1xuICAgIGV4cGVjdCh0eXBlb2YgcG9seWZpbGxlZC5Bc3luY0xvY2FsU3RvcmFnZSkudG9CZShcImZ1bmN0aW9uXCIpO1xuICB9KTtcblxuICBpdChcImV4cGxhaW5zIHRoYXQgdGhlIHJ1bnRpbWUgd2FzIG5vdCBsb2FkZWQgd2hlbiBub3RoaW5nIHBvaW50ZWQgaXQgYW55d2hlcmVcIiwgKCkgPT4ge1xuICAgIC8vIGB1c2VOZXh0RnJvbWAgaXMgbW9kdWxlIHN0YXRlLCBzbyB0aGUgdW5pbml0aWFsaXplZCBjYXNlIG5lZWRzIGEgZnJlc2ggY29weVxuICAgIC8vIG9mIHRoZSBtb2R1bGUgcmF0aGVyIHRoYW4gYSByZXNldCBvZiB0aGlzIG9uZS5cbiAgICBqZXN0Lmlzb2xhdGVNb2R1bGVzKCgpID0+IHtcbiAgICAgIGNvbnN0IGZyZXNoID1cbiAgICAgICAgamVzdC5yZXF1aXJlQWN0dWFsPHR5cGVvZiBpbXBvcnQoXCIuL25leHQtbW9kdWxlc1wiKT4oXCIuL25leHQtbW9kdWxlc1wiKTtcbiAgICAgIGV4cGVjdCgoKSA9PlxuICAgICAgICBmcmVzaC5uZXh0TW9kdWxlKFwibmV4dC9kaXN0L3NlcnZlci9zZXJ2ZS1zdGF0aWMuanNcIiksXG4gICAgICApLnRvVGhyb3coL3Jlc29sdXRpb24gaGFzIG5vdCBiZWVuIHBvaW50ZWQgYXQgdGhlIHN0YWdlZCBhcHAgeWV0Lyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AdapterManifest } from "./manifest";
|
|
2
|
+
/** Where `public/` sits in the deployment root, as a POSIX key. */
|
|
3
|
+
export declare function publicDirKey(manifest: AdapterManifest): string;
|
|
4
|
+
/**
|
|
5
|
+
* Every file under `public/`, as `/`-separated paths relative to it, unencoded:
|
|
6
|
+
* `static/hello e2e.png`, `images/logo@2x.png`.
|
|
7
|
+
*
|
|
8
|
+
* Symlinks are followed, files and directories alike, because Next.js's
|
|
9
|
+
* `recursiveReadDir` follows them and so does everything that puts `public/` in
|
|
10
|
+
* front of a user: Docker `COPY` keeps a working link in the image, and CDK's
|
|
11
|
+
* asset staging uploads the target's bytes to S3. `Dirent.isFile()` describes the
|
|
12
|
+
* link, not its target, so filtering on it silently dropped them. A directory
|
|
13
|
+
* is not entered from inside itself, so a link cycle terminates.
|
|
14
|
+
*/
|
|
15
|
+
export declare function readPublicFiles(dir: string): string[];
|
|
16
|
+
/** `public/` as the runtime serves it, and where its bytes are. */
|
|
17
|
+
export interface PublicFiles {
|
|
18
|
+
readonly files: readonly string[];
|
|
19
|
+
/**
|
|
20
|
+
* `true` when `files` came from {@link PUBLIC_FILES_FILE_NAME}: every type
|
|
21
|
+
* but `NextjsRegionalContainers`. Their bytes are in S3.
|
|
22
|
+
*/
|
|
23
|
+
readonly inS3: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The synth-time list when the deployment root has one, which is every type but
|
|
27
|
+
* `NextjsRegionalContainers`, and `public/` off disk otherwise. The list wins
|
|
28
|
+
* even when some of `public/` is on disk: a route that reads a `public/` file
|
|
29
|
+
* through `fs` gets that file traced into a Lambda root, and the rest of
|
|
30
|
+
* `public/` is still only in S3.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolvePublicFiles(deploymentRoot: string, manifest: AdapterManifest): PublicFiles;
|