cdk-nextjs 0.6.1 → 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 +2467 -2714
- package/.jsii.tabl.json +1 -1
- package/API.md +1725 -1909
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +687 -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 +13 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
- 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/post-deploy.lambda.js +3 -2
- 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 +19 -3
- package/lib/lambdas/post-deploy/prune-s3.js +54 -15
- package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
- 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 +107 -18
- package/lib/nextjs-api.js +349 -39
- package/lib/nextjs-api.test.js +582 -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 +23 -3
- package/lib/nextjs-post-deploy.js +14 -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 +23 -4
- package/lib/nextjs-static-assets.js +29 -6
- package/lib/nextjs-static-assets.test.js +20 -1
- package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
- package/lib/root-constructs/nextjs-base-construct.js +144 -34
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -70
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -69
- package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
- package/lib/root-constructs/nextjs-regional-containers.js +17 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -25
- 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 +123 -11
- package/lib/utils/base-path.js +276 -39
- package/lib/utils/base-path.test.js +275 -50
- 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,325 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Capture a real `onBuildComplete` context from an example app and write it to
|
|
4
|
+
* `src/adapter/__fixtures__/<name>.json`, for the unit tests in
|
|
5
|
+
* `src/adapter/build-outputs.test.ts`.
|
|
6
|
+
*
|
|
7
|
+
* Regenerate the fixtures whenever `next` is upgraded: the shape of
|
|
8
|
+
* `ctx.routing` / `ctx.outputs` is Next.js's, not ours, and it changes between
|
|
9
|
+
* minors (`routing.middlewareMatchers`, for one, did not exist in 16.2).
|
|
10
|
+
*
|
|
11
|
+
* pnpm bundle
|
|
12
|
+
* node scripts/capture-adapter-fixture.mjs app-playground
|
|
13
|
+
* NEXTJS_BASE_PATH=/prod node scripts/capture-adapter-fixture.mjs \
|
|
14
|
+
* app-playground --name app-playground-base-path
|
|
15
|
+
*
|
|
16
|
+
* Pass `--reuse-capture` to re-trim the previous run's dump without rebuilding.
|
|
17
|
+
*
|
|
18
|
+
* How it captures: `examples/<app>`'s `sync-cdk-nextjs` script copies this
|
|
19
|
+
* repo's bundled adapter into its own `node_modules/cdk-nextjs`, and
|
|
20
|
+
* `next.config.ts` resolves `adapterPath` to that copy. The copy is untracked build output, so we
|
|
21
|
+
* append a wrapper to it that dumps `ctx` before delegating to the real hook,
|
|
22
|
+
* then run `next build`. Nothing tracked is modified.
|
|
23
|
+
*
|
|
24
|
+
* How it trims: a raw capture of app-playground is ~9 MB, almost all of it
|
|
25
|
+
* repeated `node_modules` paths in per-output `assets`/`assetsHashes` maps. The
|
|
26
|
+
* fixture keeps a curated subset of outputs, and within each output keeps every
|
|
27
|
+
* non-`node_modules` asset key plus a deterministic sample of the
|
|
28
|
+
* `node_modules` ones. Absolute paths are rewritten to a `/repo` placeholder so
|
|
29
|
+
* the fixture is machine-independent. The trim is recorded in `_meta`.
|
|
30
|
+
*/
|
|
31
|
+
import { execFileSync } from "node:child_process";
|
|
32
|
+
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
33
|
+
import { dirname, join, resolve } from "node:path";
|
|
34
|
+
import { fileURLToPath } from "node:url";
|
|
35
|
+
|
|
36
|
+
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
37
|
+
const PLACEHOLDER_ROOT = "/repo";
|
|
38
|
+
/** Per kept output, how many `node_modules/` asset keys to retain. */
|
|
39
|
+
const NODE_MODULES_ASSET_SAMPLE = 8;
|
|
40
|
+
/**
|
|
41
|
+
* Cap on *concrete* prerenders, per route template. Per template rather than
|
|
42
|
+
* overall, so that adding a route to `KEEP_PATHNAMES` cannot push another
|
|
43
|
+
* route's concrete pages (`/isr/1` and its `.rsc`/segment variants) out of the
|
|
44
|
+
* fixture. Dynamic templates are always kept in full.
|
|
45
|
+
*/
|
|
46
|
+
const MAX_PRERENDERS_PER_ROUTE = 12;
|
|
47
|
+
const MAX_STATIC_FILES = 8;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Which route templates to keep per example app. Chosen to cover: the root
|
|
51
|
+
* page, a dynamic ISR route, a multi-segment dynamic route whose param names
|
|
52
|
+
* prefix one another, optional catch-all and encoded params, the synthetic
|
|
53
|
+
* `_not-found` page, and both a static and a mutating route handler. Each
|
|
54
|
+
* app-router page also has a sibling `.rsc` output, kept automatically.
|
|
55
|
+
*/
|
|
56
|
+
const KEEP_PATHNAMES = {
|
|
57
|
+
"app-playground": [
|
|
58
|
+
"/",
|
|
59
|
+
"/_not-found",
|
|
60
|
+
"/isr/[id]",
|
|
61
|
+
"/api/health",
|
|
62
|
+
"/api/revalidate",
|
|
63
|
+
"/api/echo",
|
|
64
|
+
// The destination of `next.config.ts`'s one `beforeFiles` rewrite.
|
|
65
|
+
"/e2e/rewrite/echo",
|
|
66
|
+
// `[id]` is a prefix of `[id2]`, which is what `@next/routing`'s param
|
|
67
|
+
// expansion gets wrong (see `dispatch.test.ts`).
|
|
68
|
+
"/params/prefix/[id]/[id2]",
|
|
69
|
+
"/params/optional/[[...rest]]",
|
|
70
|
+
"/params/encoded/[slug]",
|
|
71
|
+
],
|
|
72
|
+
// Small enough to keep whole; `keep` being empty means "keep everything".
|
|
73
|
+
"pages-i18n": [],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function main() {
|
|
77
|
+
const args = process.argv.slice(2);
|
|
78
|
+
const app = args[0];
|
|
79
|
+
if (!app) {
|
|
80
|
+
console.error(
|
|
81
|
+
"usage: node scripts/capture-adapter-fixture.mjs <example-app> [--name <fixture-name>]",
|
|
82
|
+
);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const nameFlag = args.indexOf("--name");
|
|
86
|
+
const name = nameFlag === -1 ? app : args[nameFlag + 1];
|
|
87
|
+
// Re-trim the dump a previous run left behind instead of rebuilding. For when
|
|
88
|
+
// the trim rules change but `next` has not; skips a ~2 minute `next build`.
|
|
89
|
+
const reuse = args.includes("--reuse-capture");
|
|
90
|
+
|
|
91
|
+
const appDir = join(repoRoot, "examples", app);
|
|
92
|
+
const dumpPath = join(appDir, ".next", `adapter-ctx-capture.json`);
|
|
93
|
+
const fixturePath = join(
|
|
94
|
+
repoRoot,
|
|
95
|
+
"src",
|
|
96
|
+
"adapter",
|
|
97
|
+
"__fixtures__",
|
|
98
|
+
`${name}.json`,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (!reuse) {
|
|
102
|
+
// The example app's sync script copies this repo's *bundled* adapter, so a
|
|
103
|
+
// stale bundle would silently capture the previous implementation.
|
|
104
|
+
run("pnpm", ["bundle"], repoRoot);
|
|
105
|
+
run("pnpm", ["run", "sync-cdk-nextjs"], appDir);
|
|
106
|
+
patchAdapterCopy(appDir);
|
|
107
|
+
rmSync(dumpPath, { force: true });
|
|
108
|
+
run("npx", ["next", "build"], appDir, {
|
|
109
|
+
CDK_NEXTJS_DUMP_CTX: dumpPath,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const raw = JSON.parse(readFileSync(dumpPath, "utf8"));
|
|
114
|
+
const fixture = trim(raw, { app, name });
|
|
115
|
+
mkdirSync(dirname(fixturePath), { recursive: true });
|
|
116
|
+
writeFileSync(fixturePath, `${JSON.stringify(fixture, null, 2)}\n`);
|
|
117
|
+
console.log(
|
|
118
|
+
`wrote ${fixturePath} (${(readFileSync(fixturePath).length / 1024).toFixed(0)} KB)`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function run(cmd, args, cwd, env = {}) {
|
|
123
|
+
console.error(`$ ${cmd} ${args.join(" ")} (in ${cwd})`);
|
|
124
|
+
execFileSync(cmd, args, {
|
|
125
|
+
cwd,
|
|
126
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
127
|
+
env: { ...process.env, ...env },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Append a `ctx`-dumping wrapper to the untracked copy of the bundled adapter
|
|
133
|
+
* that the sync script just made.
|
|
134
|
+
*/
|
|
135
|
+
function patchAdapterCopy(appDir) {
|
|
136
|
+
const copy = join(
|
|
137
|
+
appDir,
|
|
138
|
+
"node_modules",
|
|
139
|
+
"cdk-nextjs",
|
|
140
|
+
"lib",
|
|
141
|
+
"adapter",
|
|
142
|
+
"adapter.mjs",
|
|
143
|
+
);
|
|
144
|
+
const needle = "export {\n adapter_default as default\n};";
|
|
145
|
+
const source = readFileSync(copy, "utf8");
|
|
146
|
+
if (!source.includes(needle)) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`Could not find the default export in ${copy}. The esbuild output shape changed; update this script.`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
writeFileSync(
|
|
152
|
+
copy,
|
|
153
|
+
source.replace(
|
|
154
|
+
needle,
|
|
155
|
+
`
|
|
156
|
+
const __captureAdapter = {
|
|
157
|
+
...adapter_default,
|
|
158
|
+
async onBuildComplete(ctx) {
|
|
159
|
+
const { writeFile } = await import("node:fs/promises");
|
|
160
|
+
const { routing, outputs, projectDir, repoRoot, distDir, nextVersion, buildId, config } = ctx;
|
|
161
|
+
await writeFile(
|
|
162
|
+
process.env.CDK_NEXTJS_DUMP_CTX,
|
|
163
|
+
JSON.stringify({
|
|
164
|
+
routing,
|
|
165
|
+
outputs,
|
|
166
|
+
projectDir,
|
|
167
|
+
repoRoot,
|
|
168
|
+
distDir,
|
|
169
|
+
nextVersion,
|
|
170
|
+
buildId,
|
|
171
|
+
config: {
|
|
172
|
+
basePath: config.basePath,
|
|
173
|
+
trailingSlash: config.trailingSlash,
|
|
174
|
+
assetPrefix: config.assetPrefix,
|
|
175
|
+
i18n: config.i18n,
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
);
|
|
179
|
+
return adapter_default.onBuildComplete(ctx);
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
export { __captureAdapter as default };`,
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function trim(raw, { app, name }) {
|
|
188
|
+
const realRoot = raw.repoRoot;
|
|
189
|
+
const rewrite = (value) =>
|
|
190
|
+
typeof value === "string" && value.startsWith(realRoot)
|
|
191
|
+
? PLACEHOLDER_ROOT + value.slice(realRoot.length)
|
|
192
|
+
: value;
|
|
193
|
+
|
|
194
|
+
// Output `pathname`s carry `basePath` (`/prod/api/health`) while `id`,
|
|
195
|
+
// `sourcePage` and `prerenders[].route` do not, so the allowlist matches on
|
|
196
|
+
// the basePath-stripped pathname and `keptTemplates` holds stripped names.
|
|
197
|
+
const basePath = raw.config.basePath || "";
|
|
198
|
+
const normalize = (pathname) => {
|
|
199
|
+
let p = pathname;
|
|
200
|
+
if (basePath && (p === basePath || p.startsWith(`${basePath}/`))) {
|
|
201
|
+
p = p.slice(basePath.length);
|
|
202
|
+
}
|
|
203
|
+
p = p.replace(/\.rsc$/, "");
|
|
204
|
+
return p === "" || p === "/index" ? "/" : p;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const keep = new Set(KEEP_PATHNAMES[app] ?? []);
|
|
208
|
+
const keptTemplates = new Set();
|
|
209
|
+
const keepOutput = (output) => {
|
|
210
|
+
const base = normalize(output.pathname);
|
|
211
|
+
if (keep.size === 0 || keep.has(base)) {
|
|
212
|
+
keptTemplates.add(base);
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const trimOutput = (output) => {
|
|
219
|
+
const assetKeys = Object.keys(output.assets).sort();
|
|
220
|
+
const local = assetKeys.filter((k) => !k.startsWith("node_modules/"));
|
|
221
|
+
const vendored = assetKeys
|
|
222
|
+
.filter((k) => k.startsWith("node_modules/"))
|
|
223
|
+
.slice(0, NODE_MODULES_ASSET_SAMPLE);
|
|
224
|
+
const kept = [...local, ...vendored];
|
|
225
|
+
|
|
226
|
+
const assets = {};
|
|
227
|
+
const assetsHashes = {};
|
|
228
|
+
for (const key of kept) {
|
|
229
|
+
assets[key] = rewrite(output.assets[key]);
|
|
230
|
+
if (output.assetsHashes[key] !== undefined) {
|
|
231
|
+
assetsHashes[key] = output.assetsHashes[key];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// The entrypoint's own hash is keyed in `assetsHashes` but deliberately
|
|
235
|
+
// absent from `assets`; keeping it is what lets the tests assert the
|
|
236
|
+
// entrypoint gets staged from its hash-derived key.
|
|
237
|
+
for (const [key, hash] of Object.entries(output.assetsHashes)) {
|
|
238
|
+
if (!(key in output.assets)) {
|
|
239
|
+
assetsHashes[key] = hash;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
...output,
|
|
244
|
+
filePath: rewrite(output.filePath),
|
|
245
|
+
assets,
|
|
246
|
+
assetsHashes,
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const outputs = {
|
|
251
|
+
pages: raw.outputs.pages.filter(keepOutput).map(trimOutput),
|
|
252
|
+
pagesApi: raw.outputs.pagesApi.filter(keepOutput).map(trimOutput),
|
|
253
|
+
appPages: raw.outputs.appPages.filter(keepOutput).map(trimOutput),
|
|
254
|
+
appRoutes: raw.outputs.appRoutes.filter(keepOutput).map(trimOutput),
|
|
255
|
+
prerenders: [
|
|
256
|
+
// Dynamic templates are never dropped: they are what
|
|
257
|
+
// `buildAdapterManifest` turns into extra `entrypoints`/`pathnames`
|
|
258
|
+
// entries (Pages Router `/_next/data/…/[slug].json` in particular), so a
|
|
259
|
+
// fixture without them would not exercise that path at all.
|
|
260
|
+
...raw.outputs.prerenders.filter(
|
|
261
|
+
(p) => keptTemplates.has(p.route) && p.pathname.includes("["),
|
|
262
|
+
),
|
|
263
|
+
...capPerRoute(
|
|
264
|
+
raw.outputs.prerenders.filter(
|
|
265
|
+
(p) => keptTemplates.has(p.route) && !p.pathname.includes("["),
|
|
266
|
+
),
|
|
267
|
+
MAX_PRERENDERS_PER_ROUTE,
|
|
268
|
+
),
|
|
269
|
+
].map((p) => ({
|
|
270
|
+
...p,
|
|
271
|
+
fallback: p.fallback
|
|
272
|
+
? { ...p.fallback, filePath: rewrite(p.fallback.filePath) }
|
|
273
|
+
: p.fallback,
|
|
274
|
+
})),
|
|
275
|
+
staticFiles: [
|
|
276
|
+
...raw.outputs.staticFiles.filter(
|
|
277
|
+
(f) => !normalize(f.pathname).startsWith("/_next/static"),
|
|
278
|
+
),
|
|
279
|
+
...raw.outputs.staticFiles.filter((f) =>
|
|
280
|
+
normalize(f.pathname).startsWith("/_next/static"),
|
|
281
|
+
),
|
|
282
|
+
]
|
|
283
|
+
.slice(0, MAX_STATIC_FILES)
|
|
284
|
+
.map((f) => ({ ...f, filePath: rewrite(f.filePath) })),
|
|
285
|
+
middleware: raw.outputs.middleware
|
|
286
|
+
? trimOutput(raw.outputs.middleware)
|
|
287
|
+
: undefined,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
_meta: {
|
|
292
|
+
fixture: name,
|
|
293
|
+
capturedFrom: `examples/${app}`,
|
|
294
|
+
nextVersion: raw.nextVersion,
|
|
295
|
+
generatedBy: "scripts/capture-adapter-fixture.mjs",
|
|
296
|
+
trimmed: {
|
|
297
|
+
repoRootRewrittenTo: PLACEHOLDER_ROOT,
|
|
298
|
+
keptRouteTemplates: [...keptTemplates].sort(),
|
|
299
|
+
nodeModulesAssetsPerOutput: NODE_MODULES_ASSET_SAMPLE,
|
|
300
|
+
maxConcretePrerendersPerRoute: MAX_PRERENDERS_PER_ROUTE,
|
|
301
|
+
maxStaticFiles: MAX_STATIC_FILES,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
routing: raw.routing,
|
|
305
|
+
outputs,
|
|
306
|
+
projectDir: rewrite(raw.projectDir),
|
|
307
|
+
repoRoot: PLACEHOLDER_ROOT,
|
|
308
|
+
distDir: rewrite(raw.distDir),
|
|
309
|
+
nextVersion: raw.nextVersion,
|
|
310
|
+
buildId: raw.buildId,
|
|
311
|
+
config: raw.config,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** The first `max` of `prerenders` for each `route`, in their original order. */
|
|
316
|
+
function capPerRoute(prerenders, max) {
|
|
317
|
+
const seen = new Map();
|
|
318
|
+
return prerenders.filter((p) => {
|
|
319
|
+
const count = seen.get(p.route) ?? 0;
|
|
320
|
+
seen.set(p.route, count + 1);
|
|
321
|
+
return count < max;
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
main();
|