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.
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 +1548 -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 +852 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +861 -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 +1213 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1678 -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 +41595 -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 +55 -0
  213. package/lib/runtime/next-modules.js +124 -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 +41588 -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
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lambda_event_1 = require("./lambda-event");
4
+ /** Only the fields `toRuntimeRequest` reads; the rest of the shape is noise. */
5
+ function functionUrlEvent(fields = {}) {
6
+ return {
7
+ rawPath: "/",
8
+ rawQueryString: "",
9
+ headers: { host: "abc.lambda-url.us-east-1.on.aws" },
10
+ isBase64Encoded: false,
11
+ requestContext: {
12
+ http: { method: "GET", sourceIp: "203.0.113.7" },
13
+ // CloudFront's Origin Access Control signature, as Lambda reports it.
14
+ authorizer: { iam: { callerId: "cloudfront" } },
15
+ },
16
+ ...fields,
17
+ };
18
+ }
19
+ function restEvent(fields = {}) {
20
+ return {
21
+ httpMethod: "GET",
22
+ path: "/",
23
+ headers: {},
24
+ multiValueHeaders: {},
25
+ queryStringParameters: null,
26
+ multiValueQueryStringParameters: null,
27
+ body: null,
28
+ isBase64Encoded: false,
29
+ requestContext: { path: "/prod/", identity: { sourceIp: "203.0.113.8" } },
30
+ ...fields,
31
+ };
32
+ }
33
+ describe("toRuntimeRequest, for a Function URL event", () => {
34
+ it("rebuilds the target from rawPath and rawQueryString, still encoded", () => {
35
+ const request = (0, lambda_event_1.toRuntimeRequest)(functionUrlEvent({ rawPath: "/a%20b", rawQueryString: "q=a%20b&x=1" }), "");
36
+ expect(request).toMatchObject({
37
+ method: "GET",
38
+ url: "/a%20b?q=a%20b&x=1",
39
+ remoteAddress: "203.0.113.7",
40
+ });
41
+ });
42
+ it("puts the cookies payload v2 lifted out back into one cookie header", () => {
43
+ // Joined with "; ", the separator the Cookie grammar uses. ", " would parse
44
+ // as the single cookie `a = "1, b=2"`, losing draft mode's cookies.
45
+ const request = (0, lambda_event_1.toRuntimeRequest)(functionUrlEvent({
46
+ cookies: ["a=1", "__prerender_bypass=x", "__next_preview_data=y"],
47
+ }), "");
48
+ expect(request.headers.cookie).toBe("a=1; __prerender_bypass=x; __next_preview_data=y");
49
+ });
50
+ it("lowercases header names", () => {
51
+ const request = (0, lambda_event_1.toRuntimeRequest)(functionUrlEvent({ headers: { "X-Forwarded-Host": "shop.test" } }), "");
52
+ expect(request.headers["x-forwarded-host"]).toBe("shop.test");
53
+ });
54
+ // Any IAM-authorized invoker: in practice CloudFront, which overwrites the
55
+ // header.
56
+ it("trusts x-forwarded-host on a request Lambda authenticated", () => {
57
+ expect((0, lambda_event_1.toRuntimeRequest)(functionUrlEvent(), "").trustForwardedHost).toBe(true);
58
+ });
59
+ // A URL overridden to `authType: NONE` takes the header from anyone.
60
+ it("does not trust x-forwarded-host on a request Lambda did not authenticate", () => {
61
+ const request = (0, lambda_event_1.toRuntimeRequest)(functionUrlEvent({
62
+ requestContext: {
63
+ http: { method: "GET", sourceIp: "203.0.113.7" },
64
+ },
65
+ }), "");
66
+ expect(request.trustForwardedHost).toBe(false);
67
+ });
68
+ it("decodes a base64 body, and leaves an absent one absent", () => {
69
+ const encoded = (0, lambda_event_1.toRuntimeRequest)(functionUrlEvent({
70
+ body: Buffer.from("héllo").toString("base64"),
71
+ isBase64Encoded: true,
72
+ }), "");
73
+ expect(encoded.body.toString("utf-8")).toBe("héllo");
74
+ expect((0, lambda_event_1.toRuntimeRequest)(functionUrlEvent(), "").body).toBeUndefined();
75
+ });
76
+ });
77
+ describe("toRuntimeRequest, for an API Gateway REST event", () => {
78
+ // API Gateway sets `Host` to its own domain; the header is the client's.
79
+ it("does not trust x-forwarded-host", () => {
80
+ expect((0, lambda_event_1.toRuntimeRequest)(restEvent({}), "").trustForwardedHost).toBeUndefined();
81
+ });
82
+ it("rejoins repeated Cookie fields with '; ', not ', '", () => {
83
+ const request = (0, lambda_event_1.toRuntimeRequest)(restEvent({
84
+ multiValueHeaders: {
85
+ Cookie: ["a=1", "__prerender_bypass=x"],
86
+ Accept: ["text/html", "application/json"],
87
+ },
88
+ }), "");
89
+ expect(request.headers.cookie).toBe("a=1; __prerender_bypass=x");
90
+ // Every other repeated header is a comma-separated list.
91
+ expect(request.headers.accept).toBe("text/html, application/json");
92
+ });
93
+ // API Gateway sends every header in both maps; the single-valued one keeps
94
+ // only the last value of a repeated header.
95
+ it("reads multiValueHeaders, not the single-valued map", () => {
96
+ const request = (0, lambda_event_1.toRuntimeRequest)(restEvent({
97
+ headers: { Host: "api.test", Cookie: "b=2" },
98
+ multiValueHeaders: { Host: ["api.test"], Cookie: ["a=1", "b=2"] },
99
+ }), "");
100
+ expect(request.headers).toEqual({ cookie: "a=1; b=2", host: "api.test" });
101
+ });
102
+ it("re-encodes the query API Gateway decoded, keeping repeated keys", () => {
103
+ const request = (0, lambda_event_1.toRuntimeRequest)(restEvent({
104
+ path: "/search",
105
+ requestContext: { path: "/prod/search" },
106
+ multiValueQueryStringParameters: { q: ["a b"], tag: ["x", "y"] },
107
+ queryStringParameters: { q: "a b", tag: "y" },
108
+ }), "");
109
+ expect(request.url).toBe("/search?q=a+b&tag=x&tag=y");
110
+ });
111
+ it("puts the stage back for an app whose basePath is the stage", () => {
112
+ const request = (0, lambda_event_1.toRuntimeRequest)(restEvent({
113
+ path: "/blog",
114
+ requestContext: { path: "/prod/blog" },
115
+ }), "/prod");
116
+ expect(request.url).toBe("/prod/blog");
117
+ });
118
+ });
119
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFtYmRhLWV2ZW50LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9sYW1iZGEtZXZlbnQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLGlEQUFrRDtBQUVsRCxnRkFBZ0Y7QUFDaEYsU0FBUyxnQkFBZ0IsQ0FDdkIsU0FBMEMsRUFBRTtJQUU1QyxPQUFPO1FBQ0wsT0FBTyxFQUFFLEdBQUc7UUFDWixjQUFjLEVBQUUsRUFBRTtRQUNsQixPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsaUNBQWlDLEVBQUU7UUFDcEQsZUFBZSxFQUFFLEtBQUs7UUFDdEIsY0FBYyxFQUFFO1lBQ2QsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO1lBQ2hELHNFQUFzRTtZQUN0RSxVQUFVLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLEVBQUU7U0FDaEQ7UUFDRCxHQUFHLE1BQU07S0FDMkIsQ0FBQztBQUN6QyxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQ2hCLFNBQXdDLEVBQUU7SUFFMUMsT0FBTztRQUNMLFVBQVUsRUFBRSxLQUFLO1FBQ2pCLElBQUksRUFBRSxHQUFHO1FBQ1QsT0FBTyxFQUFFLEVBQUU7UUFDWCxpQkFBaUIsRUFBRSxFQUFFO1FBQ3JCLHFCQUFxQixFQUFFLElBQUk7UUFDM0IsK0JBQStCLEVBQUUsSUFBSTtRQUNyQyxJQUFJLEVBQUUsSUFBSTtRQUNWLGVBQWUsRUFBRSxLQUFLO1FBQ3RCLGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxFQUFFO1FBQ3pFLEdBQUcsTUFBTTtLQUN5QixDQUFDO0FBQ3ZDLENBQUM7QUFFRCxRQUFRLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO0lBQzFELEVBQUUsQ0FBQyxvRUFBb0UsRUFB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QUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUVBQWlFLEVBQUUsR0FBRyxFQUFFO1FBQ3pFLE1BQU0sT0FBTyxHQUFHLElBQUEsK0JBQWdCLEVBQzlCLFNBQVMsQ0FBQztZQUNSLElBQUksRUFBRSxTQUFTO1lBQ2YsY0FBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBVztZQUNqRCwrQkFBK0IsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNoRSxxQkFBcUIsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtTQUM5QyxDQUFDLEVBQ0YsRUFBRSxDQUNILENBQUM7UUFDRixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0lBQ3hELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDREQUE0RCxFQUFFLEdBQUcsRUFBRTtRQUNwRSxNQUFNLE9BQU8sR0FBRyxJQUFBLCtCQUFnQixFQUM5QixTQUFTLENBQUM7WUFDUixJQUFJLEVBQUUsT0FBTztZQUNiLGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQVc7U0FDaEQsQ0FBQyxFQUNGLE9BQU8sQ0FDUixDQUFDO1FBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDekMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHR5cGUgeyBBUElHYXRld2F5UHJveHlFdmVudCwgTGFtYmRhRnVuY3Rpb25VUkxFdmVudCB9IGZyb20gXCJhd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyB0b1J1bnRpbWVSZXF1ZXN0IH0gZnJvbSBcIi4vbGFtYmRhLWV2ZW50XCI7XG5cbi8qKiBPbmx5IHRoZSBmaWVsZHMgYHRvUnVudGltZVJlcXVlc3RgIHJlYWRzOyB0aGUgcmVzdCBvZiB0aGUgc2hhcGUgaXMgbm9pc2UuICovXG5mdW5jdGlvbiBmdW5jdGlvblVybEV2ZW50KFxuICBmaWVsZHM6IFBhcnRpYWw8TGFtYmRhRnVuY3Rpb25VUkxFdmVudD4gPSB7fSxcbik6IExhbWJkYUZ1bmN0aW9uVVJMRXZlbnQge1xuICByZXR1cm4ge1xuICAgIHJhd1BhdGg6IFwiL1wiLFxuICAgIHJhd1F1ZXJ5U3RyaW5nOiBcIlwiLFxuICAgIGhlYWRlcnM6IHsgaG9zdDogXCJhYmMubGFtYmRhLXVybC51cy1lYXN0LTEub24uYXdzXCIgfSxcbiAgICBpc0Jhc2U2NEVuY29kZWQ6IGZhbHNlLFxuICAgIHJlcXVlc3RDb250ZXh0OiB7XG4gICAgICBodHRwOiB7IG1ldGhvZDogXCJHRVRcIiwgc291cmNlSXA6IFwiMjAzLjAuMTEzLjdcIiB9LFxuICAgICAgLy8gQ2xvdWRGcm9udCdzIE9yaWdpbiBBY2Nlc3MgQ29udHJvbCBzaWduYXR1cmUsIGFzIExhbWJkYSByZXBvcnRzIGl0LlxuICAgICAgYXV0aG9yaXplcjogeyBpYW06IHsgY2FsbGVySWQ6IFwiY2xvdWRmcm9udFwiIH0gfSxcbiAgICB9LFxuICAgIC4uLmZpZWxkcyxcbiAgfSBhcyB1bmtub3duIGFzIExhbWJkYUZ1bmN0aW9uVVJMRXZlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlc3RFdmVudChcbiAgZmllbGRzOiBQYXJ0aWFsPEFQSUdhdGV3YXlQcm94eUV2ZW50PiA9IHt9LFxuKTogQVBJR2F0ZXdheVByb3h5RXZlbnQge1xuICByZXR1cm4ge1xuICAgIGh0dHBNZXRob2Q6IFwiR0VUXCIsXG4gICAgcGF0aDogXCIvXCIsXG4gICAgaGVhZGVyczoge30sXG4gICAgbXVsdGlWYWx1ZUhlYWRlcnM6IHt9LFxuICAgIHF1ZXJ5U3RyaW5nUGFyYW1ldGVyczogbnVsbCxcbiAgICBtdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiBudWxsLFxuICAgIGJvZHk6IG51bGwsXG4gICAgaXNCYXNlNjRFbmNvZGVkOiBmYWxzZSxcbiAgICByZXF1ZXN0Q29udGV4dDogeyBwYXRoOiBcIi9wcm9kL1wiLCBpZGVudGl0eTogeyBzb3VyY2VJcDogXCIyMDMuMC4xMTMuOFwiIH0gfSxcbiAgICAuLi5maWVsZHMsXG4gIH0gYXMgdW5rbm93biBhcyBBUElHYXRld2F5UHJveHlFdmVudDtcbn1cblxuZGVzY3JpYmUoXCJ0b1J1bnRpbWVSZXF1ZXN0LCBmb3IgYSBGdW5jdGlvbiBVUkwgZXZlbnRcIiwgKCkgPT4ge1xuICBpdChcInJlYnVpbGRzIHRoZSB0YXJnZXQgZnJvbSByYXdQYXRoIGFuZCByYXdRdWVyeVN0cmluZywgc3RpbGwgZW5jb2RlZFwiLCAoKSA9PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IHRvUnVudGltZVJlcXVlc3QoXG4gICAgICBmdW5jdGlvblVybEV2ZW50KHsgcmF3UGF0aDogXCIvYSUyMGJcIiwgcmF3UXVlcnlTdHJpbmc6IFwicT1hJTIwYiZ4PTFcIiB9KSxcbiAgICAgIFwiXCIsXG4gICAgKTtcbiAgICBleHBlY3QocmVxdWVzdCkudG9NYXRjaE9iamVjdCh7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICB1cmw6IFwiL2ElMjBiP3E9YSUyMGImeD0xXCIsXG4gICAgICByZW1vdGVBZGRyZXNzOiBcIjIwMy4wLjExMy43XCIsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwicHV0cyB0aGUgY29va2llcyBwYXlsb2FkIHYyIGxpZnRlZCBvdXQgYmFjayBpbnRvIG9uZSBjb29raWUgaGVhZGVyXCIsICgpID0+IHtcbiAgICAvLyBKb2luZWQgd2l0aCBcIjsgXCIsIHRoZSBzZXBhcmF0b3IgdGhlIENvb2tpZSBncmFtbWFyIHVzZXMuIFwiLCBcIiB3b3VsZCBwYXJzZVxuICAgIC8vIGFzIHRoZSBzaW5nbGUgY29va2llIGBhID0gXCIxLCBiPTJcImAsIGxvc2luZyBkcmFmdCBtb2RlJ3MgY29va2llcy5cbiAgICBjb25zdCByZXF1ZXN0ID0gdG9SdW50aW1lUmVxdWVzdChcbiAgICAgIGZ1bmN0aW9uVXJsRXZlbnQoe1xuICAgICAgICBjb29raWVzOiBbXCJhPTFcIiwgXCJfX3ByZXJlbmRlcl9ieXBhc3M9eFwiLCBcIl9fbmV4dF9wcmV2aWV3X2RhdGE9eVwiXSxcbiAgICAgIH0pLFxuICAgICAgXCJcIixcbiAgICApO1xuICAgIGV4cGVjdChyZXF1ZXN0LmhlYWRlcnMuY29va2llKS50b0JlKFxuICAgICAgXCJhPTE7IF9fcHJlcmVuZGVyX2J5cGFzcz14OyBfX25leHRfcHJldmlld19kYXRhPXlcIixcbiAgICApO1xuICB9KTtcblxuICBpdChcImxvd2VyY2FzZXMgaGVhZGVyIG5hbWVzXCIsICgpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gdG9SdW50aW1lUmVxdWVzdChcbiAgICAgIGZ1bmN0aW9uVXJsRXZlbnQoeyBoZWFkZXJzOiB7IFwiWC1Gb3J3YXJkZWQtSG9zdFwiOiBcInNob3AudGVzdFwiIH0gfSksXG4gICAgICBcIlwiLFxuICAgICk7XG4gICAgZXhwZWN0KHJlcXVlc3QuaGVhZGVyc1tcIngtZm9yd2FyZGVkLWhvc3RcIl0pLnRvQmUoXCJzaG9wLnRlc3RcIik7XG4gIH0pO1xuXG4gIC8vIEFueSBJQU0tYXV0aG9yaXplZCBpbnZva2VyOiBpbiBwcmFjdGljZSBDbG91ZEZyb250LCB3aGljaCBvdmVyd3JpdGVzIHRoZVxuICAvLyBoZWFkZXIuXG4gIGl0KFwidHJ1c3RzIHgtZm9yd2FyZGVkLWhvc3Qgb24gYSByZXF1ZXN0IExhbWJkYSBhdXRoZW50aWNhdGVkXCIsICgpID0+IHtcbiAgICBleHBlY3QodG9SdW50aW1lUmVxdWVzdChmdW5jdGlvblVybEV2ZW50KCksIFwiXCIpLnRydXN0Rm9yd2FyZGVkSG9zdCkudG9CZShcbiAgICAgIHRydWUsXG4gICAgKTtcbiAgfSk7XG5cbiAgLy8gQSBVUkwgb3ZlcnJpZGRlbiB0byBgYXV0aFR5cGU6IE5PTkVgIHRha2VzIHRoZSBoZWFkZXIgZnJvbSBhbnlvbmUuXG4gIGl0KFwiZG9lcyBub3QgdHJ1c3QgeC1mb3J3YXJkZWQtaG9zdCBvbiBhIHJlcXVlc3QgTGFtYmRhIGRpZCBub3QgYXV0aGVudGljYXRlXCIsICgpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gdG9SdW50aW1lUmVxdWVzdChcbiAgICAgIGZ1bmN0aW9uVXJsRXZlbnQoe1xuICAgICAgICByZXF1ZXN0Q29udGV4dDoge1xuICAgICAgICAgIGh0dHA6IHsgbWV0aG9kOiBcIkdFVFwiLCBzb3VyY2VJcDogXCIyMDMuMC4xMTMuN1wiIH0sXG4gICAgICAgIH0gYXMgTGFtYmRhRnVuY3Rpb25VUkxFdmVudFtcInJlcXVlc3RDb250ZXh0XCJdLFxuICAgICAgfSksXG4gICAgICBcIlwiLFxuICAgICk7XG4gICAgZXhwZWN0KHJlcXVlc3QudHJ1c3RGb3J3YXJkZWRIb3N0KS50b0JlKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoXCJkZWNvZGVzIGEgYmFzZTY0IGJvZHksIGFuZCBsZWF2ZXMgYW4gYWJzZW50IG9uZSBhYnNlbnRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGVuY29kZWQgPSB0b1J1bnRpbWVSZXF1ZXN0KFxuICAgICAgZnVuY3Rpb25VcmxFdmVudCh7XG4gICAgICAgIGJvZHk6IEJ1ZmZlci5mcm9tKFwiaMOpbGxvXCIpLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgICBpc0Jhc2U2NEVuY29kZWQ6IHRydWUsXG4gICAgICB9KSxcbiAgICAgIFwiXCIsXG4gICAgKTtcbiAgICBleHBlY3QoKGVuY29kZWQuYm9keSBhcyBCdWZmZXIpLnRvU3RyaW5nKFwidXRmLThcIikpLnRvQmUoXCJow6lsbG9cIik7XG4gICAgZXhwZWN0KHRvUnVudGltZVJlcXVlc3QoZnVuY3Rpb25VcmxFdmVudCgpLCBcIlwiKS5ib2R5KS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwidG9SdW50aW1lUmVxdWVzdCwgZm9yIGFuIEFQSSBHYXRld2F5IFJFU1QgZXZlbnRcIiwgKCkgPT4ge1xuICAvLyBBUEkgR2F0ZXdheSBzZXRzIGBIb3N0YCB0byBpdHMgb3duIGRvbWFpbjsgdGhlIGhlYWRlciBpcyB0aGUgY2xpZW50J3MuXG4gIGl0KFwiZG9lcyBub3QgdHJ1c3QgeC1mb3J3YXJkZWQtaG9zdFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KFxuICAgICAgdG9SdW50aW1lUmVxdWVzdChyZXN0RXZlbnQoe30pLCBcIlwiKS50cnVzdEZvcndhcmRlZEhvc3QsXG4gICAgKS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xuXG4gIGl0KFwicmVqb2lucyByZXBlYXRlZCBDb29raWUgZmllbGRzIHdpdGggJzsgJywgbm90ICcsICdcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSB0b1J1bnRpbWVSZXF1ZXN0KFxuICAgICAgcmVzdEV2ZW50KHtcbiAgICAgICAgbXVsdGlWYWx1ZUhlYWRlcnM6IHtcbiAgICAgICAgICBDb29raWU6IFtcImE9MVwiLCBcIl9fcHJlcmVuZGVyX2J5cGFzcz14XCJdLFxuICAgICAgICAgIEFjY2VwdDogW1widGV4dC9odG1sXCIsIFwiYXBwbGljYXRpb24vanNvblwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgXCJcIixcbiAgICApO1xuICAgIGV4cGVjdChyZXF1ZXN0LmhlYWRlcnMuY29va2llKS50b0JlKFwiYT0xOyBfX3ByZXJlbmRlcl9ieXBhc3M9eFwiKTtcbiAgICAvLyBFdmVyeSBvdGhlciByZXBlYXRlZCBoZWFkZXIgaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdC5cbiAgICBleHBlY3QocmVxdWVzdC5oZWFkZXJzLmFjY2VwdCkudG9CZShcInRleHQvaHRtbCwgYXBwbGljYXRpb24vanNvblwiKTtcbiAgfSk7XG5cbiAgLy8gQVBJIEdhdGV3YXkgc2VuZHMgZXZlcnkgaGVhZGVyIGluIGJvdGggbWFwczsgdGhlIHNpbmdsZS12YWx1ZWQgb25lIGtlZXBzXG4gIC8vIG9ubHkgdGhlIGxhc3QgdmFsdWUgb2YgYSByZXBlYXRlZCBoZWFkZXIuXG4gIGl0KFwicmVhZHMgbXVsdGlWYWx1ZUhlYWRlcnMsIG5vdCB0aGUgc2luZ2xlLXZhbHVlZCBtYXBcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSB0b1J1bnRpbWVSZXF1ZXN0KFxuICAgICAgcmVzdEV2ZW50KHtcbiAgICAgICAgaGVhZGVyczogeyBIb3N0OiBcImFwaS50ZXN0XCIsIENvb2tpZTogXCJiPTJcIiB9LFxuICAgICAgICBtdWx0aVZhbHVlSGVhZGVyczogeyBIb3N0OiBbXCJhcGkudGVzdFwiXSwgQ29va2llOiBbXCJhPTFcIiwgXCJiPTJcIl0gfSxcbiAgICAgIH0pLFxuICAgICAgXCJcIixcbiAgICApO1xuICAgIGV4cGVjdChyZXF1ZXN0LmhlYWRlcnMpLnRvRXF1YWwoeyBjb29raWU6IFwiYT0xOyBiPTJcIiwgaG9zdDogXCJhcGkudGVzdFwiIH0pO1xuICB9KTtcblxuICBpdChcInJlLWVuY29kZXMgdGhlIHF1ZXJ5IEFQSSBHYXRld2F5IGRlY29kZWQsIGtlZXBpbmcgcmVwZWF0ZWQga2V5c1wiLCAoKSA9PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IHRvUnVudGltZVJlcXVlc3QoXG4gICAgICByZXN0RXZlbnQoe1xuICAgICAgICBwYXRoOiBcIi9zZWFyY2hcIixcbiAgICAgICAgcmVxdWVzdENvbnRleHQ6IHsgcGF0aDogXCIvcHJvZC9zZWFyY2hcIiB9IGFzIG5ldmVyLFxuICAgICAgICBtdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiB7IHE6IFtcImEgYlwiXSwgdGFnOiBbXCJ4XCIsIFwieVwiXSB9LFxuICAgICAgICBxdWVyeVN0cmluZ1BhcmFtZXRlcnM6IHsgcTogXCJhIGJcIiwgdGFnOiBcInlcIiB9LFxuICAgICAgfSksXG4gICAgICBcIlwiLFxuICAgICk7XG4gICAgZXhwZWN0KHJlcXVlc3QudXJsKS50b0JlKFwiL3NlYXJjaD9xPWErYiZ0YWc9eCZ0YWc9eVwiKTtcbiAgfSk7XG5cbiAgaXQoXCJwdXRzIHRoZSBzdGFnZSBiYWNrIGZvciBhbiBhcHAgd2hvc2UgYmFzZVBhdGggaXMgdGhlIHN0YWdlXCIsICgpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gdG9SdW50aW1lUmVxdWVzdChcbiAgICAgIHJlc3RFdmVudCh7XG4gICAgICAgIHBhdGg6IFwiL2Jsb2dcIixcbiAgICAgICAgcmVxdWVzdENvbnRleHQ6IHsgcGF0aDogXCIvcHJvZC9ibG9nXCIgfSBhcyBuZXZlcixcbiAgICAgIH0pLFxuICAgICAgXCIvcHJvZFwiLFxuICAgICk7XG4gICAgZXhwZWN0KHJlcXVlc3QudXJsKS50b0JlKFwiL3Byb2QvYmxvZ1wiKTtcbiAgfSk7XG59KTtcbiJdfQ==