cdk-nextjs 0.6.2 → 0.7.1

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.
Files changed (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +667 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1551 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +857 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +863 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1216 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1686 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41600 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +71 -0
  213. package/lib/runtime/next-modules.js +144 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41593 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -8,7 +8,7 @@ import { Construct } from "constructs";
8
8
  import { NextjsType } from "./constants";
9
9
  import { OptionalDistributionProps } from "./generated-structs/OptionalDistributionProps";
10
10
  import { OptionalS3OriginBucketWithOACProps } from "./generated-structs/OptionalS3OriginBucketWithOACProps";
11
- import { PublicDirEntry } from "./nextjs-build/nextjs-build";
11
+ import { NextjsFunctionGroupBehavior, PublicDirEntry } from "./nextjs-build/nextjs-build";
12
12
  export interface NextjsDistributionOverrides {
13
13
  readonly distributionProps?: OptionalDistributionProps;
14
14
  readonly imageBehaviorOptions?: AddBehaviorOptions;
@@ -19,7 +19,6 @@ export interface NextjsDistributionOverrides {
19
19
  readonly dynamicResponseHeadersPolicyProps?: ResponseHeadersPolicyProps;
20
20
  readonly dynamicFunctionUrlOriginWithOACProps?: FunctionUrlOriginWithOACProps;
21
21
  readonly dynamicVpcOriginWithEndpointProps?: VpcOriginWithEndpointProps;
22
- readonly imageFunctionUrlOriginWithOACProps?: FunctionUrlOriginWithOACProps;
23
22
  readonly staticBehaviorOptions?: AddBehaviorOptions;
24
23
  readonly staticResponseHeadersPolicyProps?: ResponseHeadersPolicyProps;
25
24
  readonly s3BucketOriginProps?: OptionalS3OriginBucketWithOACProps;
@@ -30,6 +29,25 @@ export interface NextjsDistributionProps {
30
29
  * Must be provided if you want to serve static files.
31
30
  */
32
31
  readonly assetsBucket: IBucket;
32
+ /**
33
+ * The app's own `assetPrefix`. Next.js emits `<assetPrefix>/_next/static/...`
34
+ * for every bundle while the objects stay at `<basePath>/_next/static/...` in
35
+ * S3, so the prefix's path gets a cache behavior of its own that rewrites it
36
+ * away.
37
+ *
38
+ * Either form is accepted: a path ("/cdn"), or an absolute URL, in which case
39
+ * only its path counts ("https://cdn.example.com/cdn" behaves as "/cdn", and
40
+ * "https://cdn.example.com" needs no behavior at all). An absolute prefix's path
41
+ * matters because `next build` compiles a `/cdn/_next/:path+` rewrite of its
42
+ * own, so `next start` serves every bundle under it — a CDN fronting this
43
+ * distribution there has to be answered too.
44
+ *
45
+ * Applied on top of `basePath`, not under it, because that is how Next.js
46
+ * builds the URL.
47
+ *
48
+ * @default - none; pass `NextjsBuild.nextConfigAssetPrefixPath`
49
+ */
50
+ readonly assetPrefix?: string;
33
51
  /**
34
52
  * URI path prefix the app is served at. Surrounding slashes are normalized
35
53
  * away, so "/base", "base" and "/base/" all produce the same cache behaviors.
@@ -44,14 +62,6 @@ export interface NextjsDistributionProps {
44
62
  * Required if `NextjsType.GLOBAL_FUNCTIONS`
45
63
  */
46
64
  readonly functionUrl?: IFunctionUrl;
47
- /**
48
- * Function URL of the dedicated image optimization Lambda. Only applicable
49
- * to `NextjsType.GLOBAL_FUNCTIONS`, and only when the dedicated image
50
- * function is enabled. When omitted, the `_next/image*` behavior points at
51
- * the dynamic origin, which serves image optimization from the Next.js
52
- * server itself.
53
- */
54
- readonly imageFunctionUrl?: IFunctionUrl;
55
65
  /**
56
66
  * Required if `NextjsType.GLOBAL_CONTAINERS` or `NextjsType.REGIONAL_CONTAINERS`
57
67
  */
@@ -66,6 +76,37 @@ export interface NextjsDistributionProps {
66
76
  * add static behaviors to distribution.
67
77
  */
68
78
  readonly publicDirEntries: PublicDirEntry[];
79
+ /**
80
+ * The non-`default` function groups, the origins
81
+ * {@link functionGroupBehaviors} route to.
82
+ * @default - no splitting; the default behavior serves every dynamic route
83
+ */
84
+ readonly functionGroups?: NextjsDistributionFunctionGroup[];
85
+ /**
86
+ * `NextjsBuild.functionGroupBehaviors`: one cache behavior each, added in
87
+ * order, so the routes each group was packaged with reach it rather than the
88
+ * default function.
89
+ * @default - none
90
+ */
91
+ readonly functionGroupBehaviors?: NextjsFunctionGroupBehavior[];
92
+ /**
93
+ * The most cache behaviors the distribution may have, the default one
94
+ * included. cdk-nextjs counts what it adds against this at synth, so running
95
+ * out is a synth error naming what used them rather than a failed deploy.
96
+ *
97
+ * Raise it after raising the "Cache behaviors per distribution" quota for
98
+ * your account. Lower it by the behaviors a supplied {@link distribution}
99
+ * (or `overrides.distributionProps`) already has, which are not counted.
100
+ * @default 75 - CloudFront's default quota
101
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html#limits-web-distributions
102
+ */
103
+ readonly maxCacheBehaviors?: number;
104
+ }
105
+ /** A non-default function group and the origin its routes must reach. */
106
+ export interface NextjsDistributionFunctionGroup {
107
+ readonly name: string;
108
+ /** The group's Lambda Function URL. */
109
+ readonly functionUrl: IFunctionUrl;
69
110
  }
70
111
  export declare class NextjsDistribution extends Construct {
71
112
  distribution: Distribution;
@@ -77,6 +118,13 @@ export declare class NextjsDistribution extends Construct {
77
118
  * relying on the caller having passed one.
78
119
  */
79
120
  private basePath;
121
+ /**
122
+ * `props.assetPrefix` normalized to a leading-slash path, `""` when the app
123
+ * sets none or sets one that already equals the `basePath` prefix — in which
124
+ * case the ordinary `_next/static*` behavior already covers it and a second one
125
+ * would be a duplicate pattern CloudFront rejects.
126
+ */
127
+ private assetPrefix;
80
128
  /**
81
129
  * Common security headers applied by default to all origins
82
130
  * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html#managed-response-headers-policies-security
@@ -84,7 +132,6 @@ export declare class NextjsDistribution extends Construct {
84
132
  private commonSecurityHeadersBehavior;
85
133
  private staticOrigin;
86
134
  private dynamicOrigin;
87
- private imageOrigin;
88
135
  private dynamicOriginResponsePolicy;
89
136
  private dynamicCloudFrontFunctionAssociations;
90
137
  private isFunctionCompute;
@@ -102,22 +149,17 @@ export declare class NextjsDistribution extends Construct {
102
149
  private getComment;
103
150
  private createStaticOrigin;
104
151
  private createDynamicOrigin;
105
- /**
106
- * A dedicated image optimization Lambda is only wired up when
107
- * {@link NextjsDistributionProps.imageFunctionUrl} is supplied, which today
108
- * only `NextjsType.GLOBAL_FUNCTIONS` does. Otherwise `_next/image*` keeps
109
- * going to the dynamic origin, where the Next.js server optimizes images
110
- * itself.
111
- *
112
- * The `_next/image*` behavior is kept either way: its cache policy
113
- * (`queryStringBehavior: all()`, `accept` in the cache key) is the right one
114
- * for image requests regardless of which origin answers them.
115
- */
116
- private createImageOrigin;
117
152
  /**
118
153
  * Lambda Function URLs "expect the `Host` header to contain the origin domain
119
154
  * name, not the domain name of the CloudFront distribution."
155
+ *
156
+ * A container origin also gets CloudFront's own headers, for
157
+ * `CloudFront-Forwarded-Proto`: without a certificate CloudFront reaches the
158
+ * ALB over plain HTTP, so the ALB's `X-Forwarded-Proto` is `http`, and the
159
+ * runtime would build every absolute URL (`request.url`, the origin a server
160
+ * action is forwarded to) as `http://` behind a viewer on HTTPS.
120
161
  * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-except-host-header
162
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront
121
163
  */
122
164
  private createDynamicOriginRequestPolicy;
123
165
  /**
@@ -128,15 +170,144 @@ export declare class NextjsDistribution extends Construct {
128
170
  private createDynamicCloudFrontFunctionAssociations;
129
171
  private createStaticBehaviorOptions;
130
172
  private createDynamicBehaviorOptions;
173
+ /**
174
+ * The behavior's function associations: an override's, plus the viewer-request
175
+ * function Global Functions depends on.
176
+ *
177
+ * Spreading the override's `functionAssociations` over ours would silently
178
+ * drop that function, and with it the only thing standing between a viewer's
179
+ * own `X-Forwarded-Host` and the runtime, which trusts that header on Function
180
+ * URL events (`lambda-event.ts`): host injection into redirects and absolute
181
+ * URLs, cached for other viewers because the header is not in the cache key.
182
+ * So ours is kept, and an override claiming VIEWER_REQUEST — which CloudFront
183
+ * allows only one of per behavior — is an error rather than a replacement.
184
+ */
185
+ private withDynamicFunctionAssociations;
186
+ /**
187
+ * `_next/image*` goes to the same origin as everything else — the Next.js
188
+ * server optimizes images in-process — but keeps its own behavior for the
189
+ * cache policy: `queryStringBehavior: all()` plus `accept` in the cache key is
190
+ * right for image requests and wrong for the rest.
191
+ */
131
192
  private createImageBehaviorOptions;
132
193
  /**
133
194
  * Creates or uses user specified CloudFront Distribution
134
195
  */
135
196
  private getDistribution;
136
197
  private addDynamicBehaviors;
198
+ /**
199
+ * Before any behavior is computed: the budget and the `public/` checks both
200
+ * generate the group patterns, and would otherwise fail first with a less
201
+ * useful message.
202
+ */
203
+ private validateFunctionGroupProps;
204
+ /**
205
+ * Every group behavior, final path pattern included, in the order
206
+ * {@link addFunctionGroupBehaviors} adds them.
207
+ */
208
+ private functionGroupBehaviors;
209
+ /**
210
+ * One behavior per group pattern, most specific first.
211
+ *
212
+ * The order is the whole mechanism. CloudFront evaluates behaviors in order
213
+ * and stops at the first whose path pattern matches, and `addBehavior`
214
+ * appends — so `api/*` added before `api/reports/*` would swallow every
215
+ * report request and send it to a function whose package has no report
216
+ * entrypoint. The adapter sorted the list when it checked it against how
217
+ * `assignRoutesToGroups` packaged the same routes, so it is added as it is.
218
+ */
219
+ private addFunctionGroupBehaviors;
220
+ /**
221
+ * `lambda:InvokeFunction` for CloudFront, which a Function URL behind OAC
222
+ * needs besides the `lambda:InvokeFunctionUrl` `FunctionUrlOrigin` grants,
223
+ * and scoped the same way: to this distribution, and to calls that come
224
+ * through the Function URL.
225
+ */
226
+ private grantInvoke;
227
+ /**
228
+ * The `assetPrefix` path that needs a behavior of its own, or `""` for none.
229
+ *
230
+ * An absolute prefix contributes its *path*: "https://cdn.example.com" needs no
231
+ * behavior, but "https://cdn.example.com/cdn" does, because `next build`
232
+ * compiles a `/cdn/_next/:path+` rewrite of its own and `next start` serves
233
+ * every bundle under that path — so a CDN fronting this distribution there has
234
+ * to be answered. A prefix equal to the `basePath` prefix is dropped — that is
235
+ * the Next.js default when `basePath` is set, and `_next/static*` already
236
+ * resolves under it, so adding a second identical pattern would make CloudFront
237
+ * reject the distribution.
238
+ */
239
+ private resolveAssetPrefix;
240
+ /**
241
+ * Serves `<assetPrefix>/_next/static/*` from the same S3 objects as
242
+ * `_next/static/*`.
243
+ *
244
+ * Needed because Next.js puts `assetPrefix` in front of every bundle URL it
245
+ * emits while the objects keep their `<basePath>/_next/static/...` keys, and
246
+ * `assetPrefix` sits on top of `basePath` rather than under it, so
247
+ * `getPathPattern` is deliberately not used here. Without this behavior the
248
+ * request falls through to the default one, reaches the compute origin, and
249
+ * 404s: the deployment package carries no `.next/static` directory at all.
250
+ *
251
+ * A viewer-request function does the rewrite because an S3 origin keys on the
252
+ * request URI and `originPath` can only prepend. The prefix is a synth-time
253
+ * literal, so the function is a fixed-length string operation rather than a
254
+ * parse.
255
+ */
256
+ private addAssetPrefixBehavior;
137
257
  private addStaticBehaviors;
258
+ /**
259
+ * The behavior path pattern for each top-level `public/` entry, final form:
260
+ * `/*` for a directory and the basePath prefix both applied.
261
+ *
262
+ * An entry whose name has no character CloudFront can spell is left out, with
263
+ * a warning, rather than given a pattern of nothing but wildcards. `фото/` is
264
+ * `????????/*` — any 8-byte first segment — and public/ behaviors are added
265
+ * ahead of every compute behavior, so it would send `/products/42` and
266
+ * `/settings/*` to S3, which answers 403. Leaving the entry out costs its own
267
+ * files instead: those requests reach the compute, which does not have them,
268
+ * and 404. One literal character is enough to keep a pattern narrow —
269
+ * `????????.jpg` only matches `.jpg` requests — so only the all-wildcard ones
270
+ * go.
271
+ *
272
+ * The length limit is checked here, on the final pattern, rather than in
273
+ * {@link toPathPattern}: the `/*` and the basePath count against it too, and a
274
+ * pattern that passed without them failed at deploy instead.
275
+ */
276
+ private publicPathPatterns;
277
+ /**
278
+ * Refuse a group behavior that a `public/` behavior would make unreachable.
279
+ *
280
+ * `public/` behaviors are added first, and CloudFront stops at the first match,
281
+ * so two cases send a group's route to S3 instead of its function — which is
282
+ * why this is checked at synth, where both sides are known:
283
+ * - the same pattern twice: `public/docs/` and `/docs/**` both deploy as
284
+ * `docs/*`. The synth succeeded and CloudFront rejected the deploy.
285
+ * - a group pattern under a public directory: `/docs/guide/**` behind
286
+ * `docs/*` deploys and never matches.
287
+ */
288
+ private assertNoPublicCollisions;
289
+ /**
290
+ * CloudFront has a per-distribution cache behavior quota, counting the default
291
+ * one — 75 unless raised, and `maxCacheBehaviors` says which — and there are
292
+ * three things competing for it: `public/` entries, function groups, and
293
+ * cdk-nextjs's own fixed set.
294
+ * Checked in one place so the error can say which to cut.
295
+ *
296
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html#limits-web-distributions
297
+ */
298
+ private assertBehaviorBudget;
138
299
  /**
139
300
  * Optionally prepends base path to given path pattern.
301
+ *
302
+ * A trailing slash on `pathPattern` is load-bearing and survives, which is why
303
+ * this concatenates rather than going through `joinPath`. The build's
304
+ * `functionGroupBehaviors` hold both "pricing" and "pricing/" for a
305
+ * `trailingSlash` app, and normalizing the second one collapsed it onto the
306
+ * first: `addBehavior` was
307
+ * then called twice with `/base/pricing`, which CloudFront rejects at deploy
308
+ * ("more than one cache behavior has the same path pattern"), and the
309
+ * canonical `/base/pricing/` was left to the `/base/*` catch-all — the misroute
310
+ * the second pattern exists to prevent.
140
311
  */
141
312
  private getPathPattern;
142
313
  }