@opennextjs/aws 3.1.6 → 3.2.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 (152) hide show
  1. package/README.md +27 -22
  2. package/dist/adapters/binary.js +2 -0
  3. package/dist/adapters/cache.d.ts +4 -2
  4. package/dist/adapters/cache.js +14 -8
  5. package/dist/adapters/config/util.d.ts +2 -2
  6. package/dist/adapters/image-optimization-adapter.d.ts +2 -2
  7. package/dist/adapters/middleware.js +5 -52
  8. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +7 -4
  9. package/dist/adapters/plugins/image-optimization/image-optimization.js +2 -3
  10. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +3 -0
  11. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.js +4 -7
  12. package/dist/adapters/warmer-function.js +2 -67
  13. package/dist/build/buildNextApp.d.ts +3 -0
  14. package/dist/build/buildNextApp.js +19 -0
  15. package/dist/build/bundleNextServer.js +2 -2
  16. package/dist/build/compileCache.d.ts +9 -0
  17. package/dist/build/compileCache.js +30 -0
  18. package/dist/build/compileConfig.d.ts +17 -3
  19. package/dist/build/compileConfig.js +56 -34
  20. package/dist/build/compileTagCacheProvider.d.ts +2 -0
  21. package/dist/build/compileTagCacheProvider.js +26 -0
  22. package/dist/build/copyTracedFiles.js +2 -2
  23. package/dist/build/createAssets.d.ts +11 -0
  24. package/dist/build/createAssets.js +161 -0
  25. package/dist/build/createImageOptimizationBundle.d.ts +2 -0
  26. package/dist/build/createImageOptimizationBundle.js +82 -0
  27. package/dist/build/createMiddleware.d.ts +10 -0
  28. package/dist/build/createMiddleware.js +47 -0
  29. package/dist/build/createRevalidationBundle.d.ts +2 -0
  30. package/dist/build/createRevalidationBundle.js +35 -0
  31. package/dist/build/createServerBundle.d.ts +2 -2
  32. package/dist/build/createServerBundle.js +35 -39
  33. package/dist/build/createWarmerBundle.d.ts +2 -0
  34. package/dist/build/createWarmerBundle.js +44 -0
  35. package/dist/build/edge/createEdgeBundle.d.ts +6 -8
  36. package/dist/build/edge/createEdgeBundle.js +11 -15
  37. package/dist/build/helper.d.ts +22 -5
  38. package/dist/build/helper.js +42 -11
  39. package/dist/build/installDeps.d.ts +2 -0
  40. package/dist/build/installDeps.js +46 -0
  41. package/dist/build/utils.d.ts +5 -0
  42. package/dist/build/utils.js +22 -0
  43. package/dist/build/validateConfig.d.ts +1 -1
  44. package/dist/build.d.ts +0 -4
  45. package/dist/build.js +26 -486
  46. package/dist/core/createGenericHandler.js +5 -5
  47. package/dist/core/createMainHandler.d.ts +3 -3
  48. package/dist/core/createMainHandler.js +5 -5
  49. package/dist/core/requestHandler.d.ts +2 -2
  50. package/dist/core/requestHandler.js +2 -2
  51. package/dist/core/resolve.d.ts +13 -4
  52. package/dist/core/resolve.js +30 -5
  53. package/dist/core/routing/cacheInterceptor.d.ts +1 -1
  54. package/dist/core/routing/i18n/index.d.ts +1 -1
  55. package/dist/core/routing/i18n/index.js +3 -0
  56. package/dist/core/routing/matcher.d.ts +2 -1
  57. package/dist/core/routing/matcher.js +13 -6
  58. package/dist/core/routing/middleware.d.ts +6 -2
  59. package/dist/core/routing/middleware.js +13 -7
  60. package/dist/core/routing/util.d.ts +3 -2
  61. package/dist/core/routing/util.js +16 -7
  62. package/dist/core/routingHandler.d.ts +1 -1
  63. package/dist/core/routingHandler.js +1 -1
  64. package/dist/helpers/withCloudflare.d.ts +1 -1
  65. package/dist/helpers/withSST.d.ts +1 -1
  66. package/dist/http/openNextResponse.d.ts +10 -2
  67. package/dist/http/openNextResponse.js +27 -0
  68. package/dist/http/request.d.ts +1 -0
  69. package/dist/http/util.d.ts +1 -1
  70. package/dist/{converters → overrides/converters}/aws-apigw-v1.d.ts +1 -1
  71. package/dist/{converters → overrides/converters}/aws-apigw-v1.js +2 -2
  72. package/dist/{converters → overrides/converters}/aws-apigw-v2.d.ts +1 -1
  73. package/dist/{converters → overrides/converters}/aws-apigw-v2.js +4 -4
  74. package/dist/{converters → overrides/converters}/aws-cloudfront.d.ts +1 -1
  75. package/dist/{converters → overrides/converters}/aws-cloudfront.js +6 -7
  76. package/dist/{converters → overrides/converters}/dummy.d.ts +1 -1
  77. package/dist/overrides/converters/edge.d.ts +9 -0
  78. package/dist/{converters → overrides/converters}/edge.js +6 -3
  79. package/dist/{converters → overrides/converters}/node.d.ts +1 -1
  80. package/dist/{converters → overrides/converters}/node.js +1 -1
  81. package/dist/overrides/converters/sqs-revalidate.d.ts +4 -0
  82. package/dist/overrides/imageLoader/dummy.d.ts +3 -0
  83. package/dist/overrides/imageLoader/dummy.js +8 -0
  84. package/dist/overrides/imageLoader/host.d.ts +1 -1
  85. package/dist/overrides/imageLoader/s3.d.ts +1 -1
  86. package/dist/overrides/incrementalCache/dummy.d.ts +3 -0
  87. package/dist/overrides/incrementalCache/dummy.js +13 -0
  88. package/dist/{cache/incremental → overrides/incrementalCache}/s3-lite.d.ts +1 -1
  89. package/dist/{cache/incremental → overrides/incrementalCache}/s3.d.ts +1 -1
  90. package/dist/{cache/incremental → overrides/incrementalCache}/types.d.ts +1 -1
  91. package/dist/overrides/originResolver/dummy.d.ts +3 -0
  92. package/dist/overrides/originResolver/dummy.js +7 -0
  93. package/dist/overrides/originResolver/pattern-env.d.ts +3 -0
  94. package/dist/overrides/originResolver/pattern-env.js +39 -0
  95. package/dist/overrides/queue/dummy.d.ts +3 -0
  96. package/dist/overrides/queue/dummy.js +7 -0
  97. package/dist/{queue → overrides/queue}/sqs-lite.d.ts +1 -1
  98. package/dist/{queue → overrides/queue}/sqs-lite.js +3 -3
  99. package/dist/{queue → overrides/queue}/sqs.d.ts +1 -1
  100. package/dist/{queue → overrides/queue}/sqs.js +1 -1
  101. package/dist/overrides/tagCache/dummy.d.ts +3 -0
  102. package/dist/overrides/tagCache/dummy.js +17 -0
  103. package/dist/{cache/tag → overrides/tagCache}/dynamodb-lite.d.ts +1 -1
  104. package/dist/{cache/tag → overrides/tagCache}/dynamodb-lite.js +1 -1
  105. package/dist/{cache/tag → overrides/tagCache}/dynamodb.d.ts +1 -1
  106. package/dist/{cache/tag → overrides/tagCache}/dynamodb.js +1 -1
  107. package/dist/overrides/warmer/aws-lambda.d.ts +3 -0
  108. package/dist/overrides/warmer/aws-lambda.js +59 -0
  109. package/dist/overrides/warmer/dummy.d.ts +3 -0
  110. package/dist/overrides/warmer/dummy.js +7 -0
  111. package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +7 -0
  112. package/dist/{wrappers → overrides/wrappers}/aws-lambda-streaming.js +1 -1
  113. package/dist/overrides/wrappers/aws-lambda.d.ts +7 -0
  114. package/dist/{wrappers → overrides/wrappers}/cloudflare.d.ts +2 -2
  115. package/dist/{wrappers → overrides/wrappers}/cloudflare.js +1 -1
  116. package/dist/overrides/wrappers/dummy.d.ts +7 -0
  117. package/dist/overrides/wrappers/dummy.js +6 -0
  118. package/dist/overrides/wrappers/node.d.ts +7 -0
  119. package/dist/{wrappers → overrides/wrappers}/node.js +1 -1
  120. package/dist/plugins/edge.d.ts +5 -4
  121. package/dist/plugins/edge.js +27 -29
  122. package/dist/plugins/replacement.d.ts +2 -2
  123. package/dist/plugins/replacement.js +4 -5
  124. package/dist/plugins/resolve.d.ts +4 -2
  125. package/dist/plugins/resolve.js +32 -20
  126. package/dist/types/aws-lambda.d.ts +3 -2
  127. package/dist/{cache/next-types.d.ts → types/cache.d.ts} +1 -0
  128. package/dist/types/next-types.d.ts +3 -1
  129. package/dist/types/open-next.d.ts +44 -13
  130. package/package.json +2 -2
  131. package/dist/adapters/plugins/without-routing/requestHandler.d.ts +0 -2
  132. package/dist/adapters/plugins/without-routing/requestHandler.js +0 -10
  133. package/dist/converters/edge.d.ts +0 -6
  134. package/dist/converters/sqs-revalidate.d.ts +0 -4
  135. package/dist/wrappers/aws-lambda-streaming.d.ts +0 -7
  136. package/dist/wrappers/aws-lambda.d.ts +0 -7
  137. package/dist/wrappers/node.d.ts +0 -7
  138. /package/dist/{converters → overrides/converters}/dummy.js +0 -0
  139. /package/dist/{converters → overrides/converters}/sqs-revalidate.js +0 -0
  140. /package/dist/{converters → overrides/converters}/utils.d.ts +0 -0
  141. /package/dist/{converters → overrides/converters}/utils.js +0 -0
  142. /package/dist/{cache/incremental → overrides/incrementalCache}/s3-lite.js +0 -0
  143. /package/dist/{cache/incremental → overrides/incrementalCache}/s3.js +0 -0
  144. /package/dist/{cache/incremental → overrides/incrementalCache}/types.js +0 -0
  145. /package/dist/{queue → overrides/queue}/types.d.ts +0 -0
  146. /package/dist/{cache/tag → overrides/queue}/types.js +0 -0
  147. /package/dist/{cache/tag → overrides/tagCache}/constants.d.ts +0 -0
  148. /package/dist/{cache/tag → overrides/tagCache}/constants.js +0 -0
  149. /package/dist/{cache/tag → overrides/tagCache}/types.d.ts +0 -0
  150. /package/dist/{queue → overrides/tagCache}/types.js +0 -0
  151. /package/dist/{wrappers → overrides/wrappers}/aws-lambda.js +0 -0
  152. /package/dist/{cache/next-types.js → types/cache.js} +0 -0
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="https://open-next.js.org">
2
+ <a href="https://opennext.js.org">
3
3
  <picture>
4
4
  <source media="(prefers-color-scheme: dark)" srcset="docs/public/logo-dark.svg">
5
5
  <img alt="OpenNext" src="docs/public/logo-light.svg" width="300" />
@@ -7,22 +7,23 @@
7
7
  </a>
8
8
  </p>
9
9
  <p align="center">
10
- <a href="https://sst.dev/discord"><img alt="Discord" src="https://img.shields.io/discord/983865673656705025?style=flat-square" /></a>
11
- <a href="https://www.npmjs.com/package/open-next"><img alt="npm" src="https://img.shields.io/npm/v/open-next.svg?style=flat-square" /></a>
10
+ <a href="https://discord.gg/opennextjs"><img alt="Discord" src="https://img.shields.io/discord/1283128968140161065?style=flat-square" /></a>
11
+ <a href="https://www.npmjs.com/package/@opennextjs/aws"><img alt="npm" src="https://img.shields.io/npm/v/@opennextjs/aws.svg?style=flat-square" /></a>
12
12
  </p>
13
13
 
14
14
  ---
15
15
 
16
- <p align="center">
17
- <a href="https://open-next.js.org/">Docs</a> |
18
- <a href="#example">Example</a>
19
- </p>
16
+ <h1 align="center">
17
+ <a href="https://opennext.js.org/aws">Docs</a>
18
+ </h1>
19
+
20
+ ## Description
20
21
 
21
- OpenNext takes the Next.js build output and converts it into a package that can be deployed to any functions as a service platform.
22
+ OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments. Natively OpenNext has support for AWS Lambda, and classic Node.js Server.
22
23
 
23
24
  ## Features
24
25
 
25
- OpenNext aims to support all Next.js 14 features. Some features are work in progress. Please open a [new issue](/issues/new) to let us know!
26
+ OpenNext aims to support all Next.js 14 features. Some features are work in progress. If you are running into any problems make sure to check the [docs](https://opennext.js.org/aws) first before you open a [new issue](/issues/new) or visit our [Discord](https://discord.gg/opennextjs) to let us know!
26
27
 
27
28
  - [x] App & Pages Router
28
29
  - [x] API routes
@@ -31,32 +32,30 @@ OpenNext aims to support all Next.js 14 features. Some features are work in prog
31
32
  - [x] Server-side rendering (SSR)
32
33
  - [x] Incremental static regeneration (ISR)
33
34
  - [x] Middleware
35
+ - [x] Server actions
34
36
  - [x] Image optimization
35
37
  - [x] [NextAuth.js](https://next-auth.js.org)
36
38
  - [x] Running at edge
37
- - [x] No cold start
39
+ - [x] [Almost no coldstart (*)](#coldstart)
38
40
 
39
41
  ## Who is using OpenNext?
40
42
 
41
43
  [Gymshark UK](https://uk.gymshark.com), [Udacity](https://engineering.udacity.com/deploying-next-js-on-the-edge-with-sst-is-sst-the-game-changer-its-claimed-to-be-1f05a0abc27c), [TUDN](https://www.tudn.com), [NHS England](https://github.com/nhs-england-tools/terraform-aws-opennext)
42
44
 
45
+ ## Configuration
43
46
 
47
+ ### Configuration file
44
48
 
45
- ## Example
49
+ For personalisation you need to create a file `open-next.config.ts` at the same place as your `next.config.js`, and export a default object that satisfies the `OpenNextConfig` interface. It is possible to not have an open-next.config.ts file, the default configuration will then be applied automatically.
46
50
 
47
- In the `example` folder, you can find a Next.js benchmark app. It contains a variety of pages that each test a single Next.js feature. The app is deployed to both Vercel and AWS using [SST](https://docs.sst.dev/start/nextjs).
51
+ ### Debug mode
48
52
 
49
- AWS link: https://d1gwt3w78t4dm3.cloudfront.net
53
+ OpenNext can be executed in debug mode by setting the environment variable `OPEN_NEXT_DEBUG=true` before your build.
50
54
 
51
- Vercel link: https://open-next.vercel.app
55
+ This will output A LOT of additional logs to the console. This also disable minifying in esbuild, and add source maps to the output. This can result in code that might be up to 2-3X larger than the production build. Do **not** enable this in production.
52
56
 
53
- ## Configuration
57
+ You can read more about the configuration in the [docs](https://opennext.js.org/aws/config)
54
58
 
55
- ### Environment variables
56
-
57
- - AWS_SDK_DYNAMODB_MAX_ATTEMPTS: The maximum number of times requests that encounter retryable failures should be attempted for DynamoDB. Defaults to 3.
58
- - AWS_SDK_S3_MAX_ATTEMPTS: The maximum number of times requests that encounter retryable failures should be attempted for S3. Defaults to 3.
59
- - DYNAMO_BATCH_WRITE_COMMAND_CONCURRENCY: The number of concurrent batch write commands to DynamoDB. Defaults to 4 in an effort to leave plenty of DynamoDB write request capacity for the production load.
60
59
 
61
60
  ## Contribute
62
61
 
@@ -65,7 +64,7 @@ To run `OpenNext` locally:
65
64
  1. Clone this repository.
66
65
  1. Build `open-next`:
67
66
  ```bash
68
- cd open-next
67
+ cd packages/open-next
69
68
  pnpm build
70
69
  ```
71
70
  1. Run `open-next` in watch mode:
@@ -78,6 +77,12 @@ To run `OpenNext` locally:
78
77
  path/to/open-next/packages/open-next/dist/index.js build
79
78
  ```
80
79
 
80
+ ### Coldstart
81
+
82
+ OpenNext provide you with a warmer function that can be used to reduce cold start.
83
+
84
+ On Lambda, there are multiple scenarios where a lambda will trigger a cold start even if you have some warmed instance. For example if you have more requests than warm instances you'll get a cold start. Also NextJs lazy load the routes, so even if you hit a warm instance, this specific route might not have been loaded yet.
85
+
81
86
  ## Acknowledgements
82
87
 
83
88
  We are grateful for the projects that inspired OpenNext and the amazing tools and libraries developed by the community:
@@ -91,4 +96,4 @@ Special shoutout to [@khuezy](https://github.com/khuezy) and [@conico974](https:
91
96
 
92
97
  ---
93
98
 
94
- Maintained by [SST](https://sst.dev). Join our community: [Discord](https://sst.dev/discord) | [YouTube](https://www.youtube.com/c/sst-dev) | [Twitter](https://twitter.com/SST_dev)
99
+ Maintained by [SST](https://sst.dev). Join our community: [Discord](https://discord.gg/opennextjs) | [YouTube](https://www.youtube.com/c/sst-dev) | [Twitter](https://twitter.com/SST_dev)
@@ -54,6 +54,8 @@ const commonBinaryMimeTypes = new Set([
54
54
  "application/x-tar",
55
55
  "application/x-zip",
56
56
  "application/zip",
57
+ // Serialized data
58
+ "application/x-protobuf",
57
59
  ]);
58
60
  export function isBinaryContentType(contentType) {
59
61
  if (!contentType)
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
- import { IncrementalCache } from "../cache/incremental/types.js";
3
- import { TagCache } from "../cache/tag/types.js";
2
+ /// <reference types="node" />
3
+ import type { IncrementalCache } from "../overrides/incrementalCache/types.js";
4
+ import type { TagCache } from "../overrides/tagCache/types.js";
4
5
  interface CachedFetchValue {
5
6
  kind: "FETCH";
6
7
  data: {
@@ -87,6 +88,7 @@ export default class S3Cache {
87
88
  kindHint?: "app" | "pages" | "fetch";
88
89
  tags?: string[];
89
90
  softTags?: string[];
91
+ kind?: "FETCH";
90
92
  }): Promise<CacheHandlerValue | null>;
91
93
  getFetchCache(key: string, softTags?: string[], tags?: string[]): Promise<CacheHandlerValue | null>;
92
94
  getIncrementalCache(key: string): Promise<CacheHandlerValue | null>;
@@ -5,6 +5,17 @@ const CACHE_EXTENSION_REGEX = /\.(cache|fetch)$/;
5
5
  export function hasCacheExtension(key) {
6
6
  return CACHE_EXTENSION_REGEX.test(key);
7
7
  }
8
+ function isFetchCache(options) {
9
+ if (typeof options === "boolean") {
10
+ return options;
11
+ }
12
+ if (typeof options === "object") {
13
+ return (options.kindHint === "fetch" ||
14
+ options.fetchCache ||
15
+ options.kind === "FETCH");
16
+ }
17
+ return false;
18
+ }
8
19
  // We need to use globalThis client here as this class can be defined at load time in next 12 but client is not available at load time
9
20
  export default class S3Cache {
10
21
  constructor(_ctx) { }
@@ -14,14 +25,9 @@ export default class S3Cache {
14
25
  if (globalThis.disableIncrementalCache) {
15
26
  return null;
16
27
  }
17
- const isFetchCache = typeof options === "object"
18
- ? options.kindHint
19
- ? options.kindHint === "fetch"
20
- : options.fetchCache
21
- : options;
22
28
  const softTags = typeof options === "object" ? options.softTags : [];
23
29
  const tags = typeof options === "object" ? options.tags : [];
24
- return isFetchCache
30
+ return isFetchCache(options)
25
31
  ? this.getFetchCache(key, softTags, tags)
26
32
  : this.getIncrementalCache(key);
27
33
  }
@@ -219,9 +225,9 @@ export default class S3Cache {
219
225
  // Write derivedTags to dynamodb
220
226
  // If we use an in house version of getDerivedTags in build we should use it here instead of next's one
221
227
  const derivedTags = data?.kind === "FETCH"
222
- ? ctx?.tags ?? data?.data?.tags ?? [] // before version 14 next.js used data?.data?.tags so we keep it for backward compatibility
228
+ ? (ctx?.tags ?? data?.data?.tags ?? []) // before version 14 next.js used data?.data?.tags so we keep it for backward compatibility
223
229
  : data?.kind === "PAGE"
224
- ? data.headers?.["x-next-cache-tags"]?.split(",") ?? []
230
+ ? (data.headers?.["x-next-cache-tags"]?.split(",") ?? [])
225
231
  : [];
226
232
  debug("derivedTags", derivedTags);
227
233
  // Get all tags stored in dynamodb for the given key
@@ -1,5 +1,5 @@
1
- import { MiddlewareManifest, NextConfig, PrerenderManifest } from "../../types/next-types";
2
- import { PublicFiles } from "../../build";
1
+ import type { MiddlewareManifest, NextConfig, PrerenderManifest } from "../../types/next-types";
2
+ import type { PublicFiles } from "../../build";
3
3
  export declare function loadConfig(nextDir: string): NextConfig;
4
4
  export declare function loadBuildId(nextDir: string): string;
5
5
  export declare function loadHtmlPages(nextDir: string): string[];
@@ -1,4 +1,4 @@
1
- import { StreamCreator } from "../http/openNextResponse.js";
2
- import { InternalEvent, InternalResult } from "../types/open-next.js";
1
+ import type { StreamCreator } from "../http/openNextResponse.js";
2
+ import type { InternalEvent, InternalResult } from "../types/open-next.js";
3
3
  export declare const handler: (...args: any[]) => any;
4
4
  export declare function defaultHandler(event: InternalEvent, streamCreator?: StreamCreator): Promise<InternalResult>;
@@ -1,55 +1,10 @@
1
- import { debug, error } from "../adapters/logger";
1
+ import { debug } from "../adapters/logger";
2
2
  import { createGenericHandler } from "../core/createGenericHandler";
3
- import { resolveIncrementalCache, resolveQueue, resolveTagCache, } from "../core/resolve";
3
+ import { resolveIncrementalCache, resolveOriginResolver, resolveQueue, resolveTagCache, } from "../core/resolve";
4
4
  import routingHandler from "../core/routingHandler";
5
- const resolveOriginResolver = () => {
6
- const openNextParams = globalThis.openNextConfig.middleware;
7
- if (typeof openNextParams?.originResolver === "function") {
8
- return openNextParams.originResolver();
9
- }
10
- else {
11
- return Promise.resolve({
12
- name: "env",
13
- resolve: async (_path) => {
14
- try {
15
- const origin = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}");
16
- for (const [key, value] of Object.entries(globalThis.openNextConfig.functions ?? {}).filter(([key]) => key !== "default")) {
17
- if (value.patterns.some((pattern) => {
18
- // Convert cloudfront pattern to regex
19
- return new RegExp(
20
- // transform glob pattern to regex
21
- "/" +
22
- pattern
23
- .replace(/\*\*/g, "(.*)")
24
- .replace(/\*/g, "([^/]*)")
25
- .replace(/\//g, "\\/")
26
- .replace(/\?/g, ".")).test(_path);
27
- })) {
28
- debug("Using origin", key, value.patterns);
29
- return origin[key];
30
- }
31
- }
32
- if (_path.startsWith("/_next/image") && origin["imageOptimizer"]) {
33
- debug("Using origin", "imageOptimizer", _path);
34
- return origin["imageOptimizer"];
35
- }
36
- if (origin["default"]) {
37
- debug("Using default origin", origin["default"], _path);
38
- return origin["default"];
39
- }
40
- return false;
41
- }
42
- catch (e) {
43
- error("Error while resolving origin", e);
44
- return false;
45
- }
46
- },
47
- });
48
- }
49
- };
50
5
  globalThis.internalFetch = fetch;
51
6
  const defaultHandler = async (internalEvent) => {
52
- const originResolver = await resolveOriginResolver();
7
+ const originResolver = await resolveOriginResolver(globalThis.openNextConfig.middleware?.originResolver);
53
8
  //#override includeCacheInMiddleware
54
9
  globalThis.tagCache = await resolveTagCache(globalThis.openNextConfig.middleware?.override?.tagCache);
55
10
  globalThis.queue = await resolveQueue(globalThis.openNextConfig.middleware?.override?.queue);
@@ -70,10 +25,8 @@ const defaultHandler = async (internalEvent) => {
70
25
  isISR: result.isISR,
71
26
  };
72
27
  }
73
- else {
74
- debug("Middleware response", result);
75
- return result;
76
- }
28
+ debug("Middleware response", result);
29
+ return result;
77
30
  };
78
31
  export const handler = await createGenericHandler({
79
32
  handler: defaultHandler,
@@ -1,11 +1,14 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { IncomingMessage, ServerResponse } from "node:http";
4
- import { APIGatewayProxyEventHeaders } from "aws-lambda";
5
- import { NextConfig } from "next/dist/server/config-shared";
6
- import { NextUrlWithParsedQuery } from "next/dist/server/request-meta";
3
+ /// <reference types="node" />
4
+ import type { IncomingMessage, ServerResponse } from "node:http";
5
+ import type { APIGatewayProxyEventHeaders } from "aws-lambda";
6
+ import type { NextConfig } from "next/dist/server/config-shared";
7
+ import type { NextUrlWithParsedQuery } from "next/dist/server/request-meta";
7
8
  export declare function optimizeImage(headers: APIGatewayProxyEventHeaders, imageParams: any, nextConfig: NextConfig, handleRequest: (newReq: IncomingMessage, newRes: ServerResponse, newParsedUrl: NextUrlWithParsedQuery) => Promise<void>): Promise<{
8
9
  buffer: Buffer;
9
10
  contentType: string;
10
11
  maxAge: number;
12
+ etag: string;
13
+ upstreamEtag: string;
11
14
  }>;
@@ -3,10 +3,9 @@ import { imageOptimizer } from "next/dist/server/image-optimizer";
3
3
  import { debug } from "../../logger.js";
4
4
  //#override optimizeImage
5
5
  export async function optimizeImage(headers, imageParams, nextConfig, handleRequest) {
6
- const result = await imageOptimizer(
7
- // @ts-ignore
8
- { headers }, {}, // res object is not necessary as it's not actually used.
6
+ const result = await imageOptimizer({ headers }, {}, // res object is not necessary as it's not actually used.
9
7
  imageParams, nextConfig, false, // not in dev mode
8
+ // @ts-expect-error - This file is used only for Next 14.1 and below. Typing is correct for these versions.
10
9
  handleRequest);
11
10
  debug("optimized result", result);
12
11
  return result;
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
+ /// <reference types="node" />
3
4
  import type { IncomingMessage, ServerResponse } from "node:http";
4
5
  import type { APIGatewayProxyEventHeaders } from "aws-lambda";
5
6
  import type { NextConfig } from "next/dist/server/config-shared";
@@ -8,4 +9,6 @@ export declare function optimizeImage(headers: APIGatewayProxyEventHeaders, imag
8
9
  buffer: Buffer;
9
10
  contentType: string;
10
11
  maxAge: number;
12
+ etag: string;
13
+ upstreamEtag: string;
11
14
  }>;
@@ -1,9 +1,5 @@
1
1
  //#override imports
2
- import {
3
- // @ts-ignore
4
- fetchExternalImage,
5
- // @ts-ignore
6
- fetchInternalImage, imageOptimizer, } from "next/dist/server/image-optimizer";
2
+ import { fetchExternalImage, fetchInternalImage, imageOptimizer, } from "next/dist/server/image-optimizer";
7
3
  import { debug } from "../../logger.js";
8
4
  //#override optimizeImage
9
5
  export async function optimizeImage(headers, imageParams, nextConfig, handleRequest) {
@@ -11,11 +7,12 @@ export async function optimizeImage(headers, imageParams, nextConfig, handleRequ
11
7
  const imageUpstream = isAbsolute
12
8
  ? await fetchExternalImage(href)
13
9
  : await fetchInternalImage(href,
14
- // @ts-ignore
10
+ // @ts-expect-error - It is supposed to be an IncomingMessage object, but only the headers are used.
15
11
  { headers }, {}, // res object is not necessary as it's not actually used.
16
12
  handleRequest);
13
+ const result = await imageOptimizer(imageUpstream, imageParams,
17
14
  // @ts-ignore
18
- const result = await imageOptimizer(imageUpstream, imageParams, nextConfig, false);
15
+ nextConfig, false);
19
16
  debug("optimized result", result);
20
17
  return result;
21
18
  }
@@ -1,78 +1,13 @@
1
1
  import { createGenericHandler } from "../core/createGenericHandler.js";
2
- import { debug, error } from "./logger.js";
2
+ import { resolveWarmerInvoke } from "../core/resolve.js";
3
3
  import { generateUniqueId } from "./util.js";
4
- const resolveWarmerInvoke = async () => {
5
- const openNextParams = globalThis.openNextConfig.warmer;
6
- if (typeof openNextParams?.invokeFunction === "function") {
7
- return await openNextParams.invokeFunction();
8
- }
9
- else {
10
- return Promise.resolve({
11
- name: "aws-invoke",
12
- invoke: async (warmerId) => {
13
- const { InvokeCommand, LambdaClient } = await import("@aws-sdk/client-lambda");
14
- const lambda = new LambdaClient({});
15
- const warmParams = JSON.parse(process.env.WARM_PARAMS);
16
- for (const warmParam of warmParams) {
17
- const { concurrency: CONCURRENCY, function: FUNCTION_NAME } = warmParam;
18
- debug({
19
- event: "warmer invoked",
20
- functionName: FUNCTION_NAME,
21
- concurrency: CONCURRENCY,
22
- warmerId,
23
- });
24
- const ret = await Promise.all(Array.from({ length: CONCURRENCY }, (_v, i) => i).map((i) => {
25
- try {
26
- return lambda.send(new InvokeCommand({
27
- FunctionName: FUNCTION_NAME,
28
- InvocationType: "RequestResponse",
29
- Payload: Buffer.from(JSON.stringify({
30
- type: "warmer",
31
- warmerId,
32
- index: i,
33
- concurrency: CONCURRENCY,
34
- delay: 75,
35
- })),
36
- }));
37
- }
38
- catch (e) {
39
- error(`failed to warm up #${i}`, e);
40
- // ignore error
41
- }
42
- }));
43
- // Print status
44
- const warmedServerIds = ret
45
- .map((r, i) => {
46
- if (r?.StatusCode !== 200 || !r?.Payload) {
47
- error(`failed to warm up #${i}:`, r?.Payload?.toString());
48
- return;
49
- }
50
- const payload = JSON.parse(Buffer.from(r.Payload).toString());
51
- return {
52
- statusCode: r.StatusCode,
53
- payload,
54
- type: "warmer",
55
- };
56
- })
57
- .filter((r) => !!r);
58
- debug({
59
- event: "warmer result",
60
- sent: CONCURRENCY,
61
- success: warmedServerIds.length,
62
- uniqueServersWarmed: [...new Set(warmedServerIds)].length,
63
- });
64
- }
65
- },
66
- });
67
- }
68
- };
69
4
  export const handler = await createGenericHandler({
70
5
  handler: defaultHandler,
71
6
  type: "warmer",
72
7
  });
73
8
  async function defaultHandler() {
74
9
  const warmerId = `warmer-${generateUniqueId()}`;
75
- const invokeFn = await resolveWarmerInvoke();
10
+ const invokeFn = await resolveWarmerInvoke(globalThis.openNextConfig.warmer?.invokeFunction);
76
11
  await invokeFn.invoke(warmerId);
77
12
  return {
78
13
  type: "warmer",
@@ -0,0 +1,3 @@
1
+ import type * as buildHelper from "./helper.js";
2
+ export declare function setStandaloneBuildMode(options: buildHelper.BuildOptions): void;
3
+ export declare function buildNextjsApp(options: buildHelper.BuildOptions): void;
@@ -0,0 +1,19 @@
1
+ import cp from "node:child_process";
2
+ import path from "node:path";
3
+ export function setStandaloneBuildMode(options) {
4
+ // Equivalent to setting `output: "standalone"` in next.config.js
5
+ process.env.NEXT_PRIVATE_STANDALONE = "true";
6
+ // Equivalent to setting `experimental.outputFileTracingRoot` in next.config.js
7
+ process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT = options.monorepoRoot;
8
+ }
9
+ export function buildNextjsApp(options) {
10
+ const { config, packager } = options;
11
+ const command = config.buildCommand ??
12
+ (["bun", "npm"].includes(packager)
13
+ ? `${packager} run build`
14
+ : `${packager} build`);
15
+ cp.execSync(command, {
16
+ stdio: "inherit",
17
+ cwd: path.dirname(options.appPackageJsonPath),
18
+ });
19
+ }
@@ -1,4 +1,4 @@
1
- import { createRequire as topLevelCreateRequire } from "node:module";
1
+ import { createRequire } from "node:module";
2
2
  import { build } from "esbuild";
3
3
  import path from "path";
4
4
  const externals = [
@@ -36,7 +36,7 @@ const externals = [
36
36
  "next/dist/compiled/next-server",
37
37
  ];
38
38
  export async function bundleNextServer(outputDir, appPath) {
39
- const require = topLevelCreateRequire(`${appPath}/package.json`);
39
+ const require = createRequire(`${appPath}/package.json`);
40
40
  const entrypoint = require.resolve("next/dist/esm/server/next-server.js");
41
41
  await build({
42
42
  entryPoints: [entrypoint],
@@ -0,0 +1,9 @@
1
+ import * as buildHelper from "./helper.js";
2
+ /**
3
+ * Compiles the cache adapter.
4
+ *
5
+ * @param options Build options.
6
+ * @param format Output format.
7
+ * @returns The path to the compiled file.
8
+ */
9
+ export declare function compileCache(options: buildHelper.BuildOptions, format?: "cjs" | "esm"): string;
@@ -0,0 +1,30 @@
1
+ import path from "node:path";
2
+ import * as buildHelper from "./helper.js";
3
+ /**
4
+ * Compiles the cache adapter.
5
+ *
6
+ * @param options Build options.
7
+ * @param format Output format.
8
+ * @returns The path to the compiled file.
9
+ */
10
+ export function compileCache(options, format = "cjs") {
11
+ const { config } = options;
12
+ const ext = format === "cjs" ? "cjs" : "mjs";
13
+ const outFile = path.join(options.buildDir, `cache.${ext}`);
14
+ const isAfter15 = buildHelper.compareSemver(options.nextVersion, "15.0.0") >= 0;
15
+ buildHelper.esbuildSync({
16
+ external: ["next", "styled-jsx", "react", "@aws-sdk/*"],
17
+ entryPoints: [path.join(options.openNextDistDir, "adapters", "cache.js")],
18
+ outfile: outFile,
19
+ target: ["node18"],
20
+ format,
21
+ banner: {
22
+ js: [
23
+ `globalThis.disableIncrementalCache = ${config.dangerous?.disableIncrementalCache ?? false};`,
24
+ `globalThis.disableDynamoDBCache = ${config.dangerous?.disableTagCache ?? false};`,
25
+ `globalThis.isNextAfter15 = ${isAfter15};`,
26
+ ].join(""),
27
+ },
28
+ }, options);
29
+ return outFile;
30
+ }
@@ -1,3 +1,17 @@
1
- import { OpenNextConfig } from "../types/open-next.js";
2
- export declare function compileOpenNextConfigNode(tempDir: string, openNextConfigPath?: string, nodeExternals?: string): string;
3
- export declare function compileOpenNextConfigEdge(tempDir: string, config: OpenNextConfig, openNextConfigPath?: string): void;
1
+ import type { OpenNextConfig } from "../types/open-next.js";
2
+ /**
3
+ * Compiles the OpenNext configuration.
4
+ *
5
+ * The configuration is always compiled for Node.js and for the edge only if needed.
6
+ *
7
+ * @param baseDir Directory where to look for the configuration.
8
+ * @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
9
+ * @param nodeExternals Externals for the Node.js compilation.
10
+ * @return The configuration and the build directory.
11
+ */
12
+ export declare function compileOpenNextConfig(baseDir: string, openNextConfigPath?: string, nodeExternals?: string): Promise<{
13
+ config: OpenNextConfig;
14
+ buildDir: string;
15
+ }>;
16
+ export declare function compileOpenNextConfigNode(sourcePath: string, outputDir: string, externals: string[]): string;
17
+ export declare function compileOpenNextConfigEdge(sourcePath: string, outputDir: string, externals: string[]): void;