@opennextjs/aws 3.1.4

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 (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/dist/adapters/binary.d.ts +1 -0
  4. package/dist/adapters/binary.js +63 -0
  5. package/dist/adapters/cache.d.ts +96 -0
  6. package/dist/adapters/cache.js +278 -0
  7. package/dist/adapters/config/index.d.ts +27 -0
  8. package/dist/adapters/config/index.js +21 -0
  9. package/dist/adapters/config/util.d.ts +28 -0
  10. package/dist/adapters/config/util.js +84 -0
  11. package/dist/adapters/dynamo-provider.d.ts +8 -0
  12. package/dist/adapters/dynamo-provider.js +42 -0
  13. package/dist/adapters/edge-adapter.d.ts +8 -0
  14. package/dist/adapters/edge-adapter.js +54 -0
  15. package/dist/adapters/image-optimization-adapter.d.ts +4 -0
  16. package/dist/adapters/image-optimization-adapter.js +193 -0
  17. package/dist/adapters/logger.d.ts +13 -0
  18. package/dist/adapters/logger.js +51 -0
  19. package/dist/adapters/middleware.d.ts +5 -0
  20. package/dist/adapters/middleware.js +84 -0
  21. package/dist/adapters/plugins/14.1/util.d.ts +1 -0
  22. package/dist/adapters/plugins/14.1/util.js +29 -0
  23. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +11 -0
  24. package/dist/adapters/plugins/image-optimization/image-optimization.js +14 -0
  25. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +11 -0
  26. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.js +22 -0
  27. package/dist/adapters/plugins/without-routing/requestHandler.d.ts +2 -0
  28. package/dist/adapters/plugins/without-routing/requestHandler.js +10 -0
  29. package/dist/adapters/revalidate.d.ts +9 -0
  30. package/dist/adapters/revalidate.js +71 -0
  31. package/dist/adapters/server-adapter.d.ts +4 -0
  32. package/dist/adapters/server-adapter.js +27 -0
  33. package/dist/adapters/util.d.ts +10 -0
  34. package/dist/adapters/util.js +28 -0
  35. package/dist/adapters/warmer-function.d.ts +12 -0
  36. package/dist/adapters/warmer-function.js +80 -0
  37. package/dist/build/bundleNextServer.d.ts +1 -0
  38. package/dist/build/bundleNextServer.js +87 -0
  39. package/dist/build/compileConfig.d.ts +3 -0
  40. package/dist/build/compileConfig.js +64 -0
  41. package/dist/build/copyTracedFiles.d.ts +1 -0
  42. package/dist/build/copyTracedFiles.js +207 -0
  43. package/dist/build/createServerBundle.d.ts +3 -0
  44. package/dist/build/createServerBundle.js +228 -0
  45. package/dist/build/edge/createEdgeBundle.d.ts +20 -0
  46. package/dist/build/edge/createEdgeBundle.js +149 -0
  47. package/dist/build/generateOutput.d.ts +2 -0
  48. package/dist/build/generateOutput.js +239 -0
  49. package/dist/build/helper.d.ts +33 -0
  50. package/dist/build/helper.js +193 -0
  51. package/dist/build/patch/patchedAsyncStorage.d.ts +5 -0
  52. package/dist/build/patch/patchedAsyncStorage.js +16 -0
  53. package/dist/build/validateConfig.d.ts +2 -0
  54. package/dist/build/validateConfig.js +76 -0
  55. package/dist/build.d.ts +7 -0
  56. package/dist/build.js +533 -0
  57. package/dist/cache/incremental/s3-lite.d.ts +3 -0
  58. package/dist/cache/incremental/s3-lite.js +72 -0
  59. package/dist/cache/incremental/s3.d.ts +3 -0
  60. package/dist/cache/incremental/s3.js +44 -0
  61. package/dist/cache/incremental/types.d.ts +34 -0
  62. package/dist/cache/incremental/types.js +1 -0
  63. package/dist/cache/next-types.d.ts +62 -0
  64. package/dist/cache/next-types.js +1 -0
  65. package/dist/cache/tag/constants.d.ts +2 -0
  66. package/dist/cache/tag/constants.js +17 -0
  67. package/dist/cache/tag/dynamodb-lite.d.ts +3 -0
  68. package/dist/cache/tag/dynamodb-lite.js +174 -0
  69. package/dist/cache/tag/dynamodb.d.ts +3 -0
  70. package/dist/cache/tag/dynamodb.js +129 -0
  71. package/dist/cache/tag/types.d.ts +11 -0
  72. package/dist/cache/tag/types.js +1 -0
  73. package/dist/converters/aws-apigw-v1.d.ts +3 -0
  74. package/dist/converters/aws-apigw-v1.js +89 -0
  75. package/dist/converters/aws-apigw-v2.d.ts +3 -0
  76. package/dist/converters/aws-apigw-v2.js +99 -0
  77. package/dist/converters/aws-cloudfront.d.ts +3 -0
  78. package/dist/converters/aws-cloudfront.js +170 -0
  79. package/dist/converters/dummy.d.ts +7 -0
  80. package/dist/converters/dummy.js +16 -0
  81. package/dist/converters/edge.d.ts +6 -0
  82. package/dist/converters/edge.js +88 -0
  83. package/dist/converters/node.d.ts +3 -0
  84. package/dist/converters/node.js +45 -0
  85. package/dist/converters/sqs-revalidate.d.ts +4 -0
  86. package/dist/converters/sqs-revalidate.js +22 -0
  87. package/dist/converters/utils.d.ts +1 -0
  88. package/dist/converters/utils.js +9 -0
  89. package/dist/core/createGenericHandler.d.ts +11 -0
  90. package/dist/core/createGenericHandler.js +16 -0
  91. package/dist/core/createMainHandler.d.ts +18 -0
  92. package/dist/core/createMainHandler.js +24 -0
  93. package/dist/core/edgeFunctionHandler.d.ts +54 -0
  94. package/dist/core/edgeFunctionHandler.js +21 -0
  95. package/dist/core/patchAsyncStorage.d.ts +1 -0
  96. package/dist/core/patchAsyncStorage.js +16 -0
  97. package/dist/core/requestHandler.d.ts +3 -0
  98. package/dist/core/requestHandler.js +162 -0
  99. package/dist/core/require-hooks.d.ts +3 -0
  100. package/dist/core/require-hooks.js +102 -0
  101. package/dist/core/resolve.d.ts +31 -0
  102. package/dist/core/resolve.js +81 -0
  103. package/dist/core/routing/cacheInterceptor.d.ts +2 -0
  104. package/dist/core/routing/cacheInterceptor.js +162 -0
  105. package/dist/core/routing/i18n/accept-header.d.ts +1 -0
  106. package/dist/core/routing/i18n/accept-header.js +101 -0
  107. package/dist/core/routing/i18n/index.d.ts +2 -0
  108. package/dist/core/routing/i18n/index.js +36 -0
  109. package/dist/core/routing/matcher.d.ts +25 -0
  110. package/dist/core/routing/matcher.js +294 -0
  111. package/dist/core/routing/middleware.d.ts +7 -0
  112. package/dist/core/routing/middleware.js +167 -0
  113. package/dist/core/routing/util.d.ts +105 -0
  114. package/dist/core/routing/util.js +415 -0
  115. package/dist/core/routingHandler.d.ts +8 -0
  116. package/dist/core/routingHandler.js +127 -0
  117. package/dist/core/util.d.ts +5 -0
  118. package/dist/core/util.js +84 -0
  119. package/dist/helpers/withCloudflare.d.ts +65 -0
  120. package/dist/helpers/withCloudflare.js +58 -0
  121. package/dist/helpers/withSST.d.ts +54 -0
  122. package/dist/helpers/withSST.js +28 -0
  123. package/dist/http/index.d.ts +2 -0
  124. package/dist/http/index.js +4 -0
  125. package/dist/http/openNextResponse.d.ts +78 -0
  126. package/dist/http/openNextResponse.js +281 -0
  127. package/dist/http/request.d.ts +12 -0
  128. package/dist/http/request.js +35 -0
  129. package/dist/http/util.d.ts +4 -0
  130. package/dist/http/util.js +34 -0
  131. package/dist/index.d.ts +2 -0
  132. package/dist/index.js +37 -0
  133. package/dist/logger.d.ts +12 -0
  134. package/dist/logger.js +13 -0
  135. package/dist/minimize-js.d.ts +1 -0
  136. package/dist/minimize-js.js +101 -0
  137. package/dist/overrides/imageLoader/host.d.ts +3 -0
  138. package/dist/overrides/imageLoader/host.js +29 -0
  139. package/dist/overrides/imageLoader/s3.d.ts +3 -0
  140. package/dist/overrides/imageLoader/s3.js +33 -0
  141. package/dist/plugins/edge.d.ts +15 -0
  142. package/dist/plugins/edge.js +157 -0
  143. package/dist/plugins/replacement.d.ts +42 -0
  144. package/dist/plugins/replacement.js +74 -0
  145. package/dist/plugins/resolve.d.ts +18 -0
  146. package/dist/plugins/resolve.js +45 -0
  147. package/dist/queue/sqs-lite.d.ts +3 -0
  148. package/dist/queue/sqs-lite.js +52 -0
  149. package/dist/queue/sqs.d.ts +3 -0
  150. package/dist/queue/sqs.js +20 -0
  151. package/dist/queue/types.d.ts +12 -0
  152. package/dist/queue/types.js +1 -0
  153. package/dist/types/aws-lambda.d.ts +22 -0
  154. package/dist/types/aws-lambda.js +1 -0
  155. package/dist/types/next-types.d.ts +155 -0
  156. package/dist/types/next-types.js +2 -0
  157. package/dist/types/open-next.d.ts +303 -0
  158. package/dist/types/open-next.js +1 -0
  159. package/dist/utils/error.d.ts +23 -0
  160. package/dist/utils/error.js +32 -0
  161. package/dist/utils/fetch.d.ts +2 -0
  162. package/dist/utils/fetch.js +23 -0
  163. package/dist/utils/promise.d.ts +18 -0
  164. package/dist/utils/promise.js +48 -0
  165. package/dist/utils/stream.d.ts +5 -0
  166. package/dist/utils/stream.js +30 -0
  167. package/dist/wrappers/aws-lambda-streaming.d.ts +7 -0
  168. package/dist/wrappers/aws-lambda-streaming.js +88 -0
  169. package/dist/wrappers/aws-lambda.d.ts +7 -0
  170. package/dist/wrappers/aws-lambda.js +39 -0
  171. package/dist/wrappers/cloudflare.d.ts +11 -0
  172. package/dist/wrappers/cloudflare.js +20 -0
  173. package/dist/wrappers/node.d.ts +7 -0
  174. package/dist/wrappers/node.js +57 -0
  175. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 SST
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ <p align="center">
2
+ <a href="https://open-next.js.org">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs/public/logo-dark.svg">
5
+ <img alt="OpenNext" src="docs/public/logo-light.svg" width="300" />
6
+ </picture>
7
+ </a>
8
+ </p>
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>
12
+ </p>
13
+
14
+ ---
15
+
16
+ <p align="center">
17
+ <a href="https://open-next.js.org/">Docs</a> |
18
+ <a href="#example">Example</a>
19
+ </p>
20
+
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
+
23
+ ## Features
24
+
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
+
27
+ - [x] App & Pages Router
28
+ - [x] API routes
29
+ - [x] Dynamic routes
30
+ - [x] Static site generation (SSG)
31
+ - [x] Server-side rendering (SSR)
32
+ - [x] Incremental static regeneration (ISR)
33
+ - [x] Middleware
34
+ - [x] Image optimization
35
+ - [x] [NextAuth.js](https://next-auth.js.org)
36
+ - [x] Running at edge
37
+ - [x] No cold start
38
+
39
+ ## Who is using OpenNext?
40
+
41
+ [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
+
43
+
44
+
45
+ ## Example
46
+
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).
48
+
49
+ AWS link: https://d1gwt3w78t4dm3.cloudfront.net
50
+
51
+ Vercel link: https://open-next.vercel.app
52
+
53
+ ## Configuration
54
+
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
+
61
+ ## Contribute
62
+
63
+ To run `OpenNext` locally:
64
+
65
+ 1. Clone this repository.
66
+ 1. Build `open-next`:
67
+ ```bash
68
+ cd open-next
69
+ pnpm build
70
+ ```
71
+ 1. Run `open-next` in watch mode:
72
+ ```bash
73
+ pnpm dev
74
+ ```
75
+ 1. Now, you can make changes in `open-next` and build your Next.js app to test the changes.
76
+ ```bash
77
+ cd path/to/my/nextjs/app
78
+ path/to/open-next/packages/open-next/dist/index.js build
79
+ ```
80
+
81
+ ## Acknowledgements
82
+
83
+ We are grateful for the projects that inspired OpenNext and the amazing tools and libraries developed by the community:
84
+
85
+ - [nextjs-lambda](https://github.com/sladg/nextjs-lambda) by [Jan](https://github.com/sladg) for serving as inspiration for packaging Next.js's standalone output to Lambda.
86
+ - [CDK NextJS](https://github.com/jetbridge/cdk-nextjs/) by [JetBridge](https://github.com/jetbridge) for its contribution to the deployment architecture of a Next.js application on AWS.
87
+ - [serverless-http](https://github.com/dougmoscrop/serverless-http) by [Doug Moscrop](https://github.com/dougmoscrop) for developing an excellent library for transforming AWS Lambda events and responses.
88
+ - [serverless-nextjs](https://github.com/serverless-nextjs/serverless-next.js) by [Serverless Framework](https://github.com/serverless) for paving the way for serverless Next.js applications on AWS.
89
+
90
+ Special shoutout to [@khuezy](https://github.com/khuezy) and [@conico974](https://github.com/conico974) for their outstanding contributions to the project.
91
+
92
+ ---
93
+
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)
@@ -0,0 +1 @@
1
+ export declare function isBinaryContentType(contentType?: string | null): boolean;
@@ -0,0 +1,63 @@
1
+ const commonBinaryMimeTypes = new Set([
2
+ "application/octet-stream",
3
+ // Docs
4
+ "application/epub+zip",
5
+ "application/msword",
6
+ "application/pdf",
7
+ "application/rtf",
8
+ "application/vnd.amazon.ebook",
9
+ "application/vnd.ms-excel",
10
+ "application/vnd.ms-powerpoint",
11
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
12
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
13
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
14
+ // Fonts
15
+ "font/otf",
16
+ "font/woff",
17
+ "font/woff2",
18
+ // Images
19
+ "image/bmp",
20
+ "image/gif",
21
+ "image/jpeg",
22
+ "image/png",
23
+ "image/tiff",
24
+ "image/vnd.microsoft.icon",
25
+ "image/webp",
26
+ // Audio
27
+ "audio/3gpp",
28
+ "audio/aac",
29
+ "audio/basic",
30
+ "audio/mpeg",
31
+ "audio/ogg",
32
+ "audio/wavaudio/webm",
33
+ "audio/x-aiff",
34
+ "audio/x-midi",
35
+ "audio/x-wav",
36
+ // Video
37
+ "video/3gpp",
38
+ "video/mp2t",
39
+ "video/mpeg",
40
+ "video/ogg",
41
+ "video/quicktime",
42
+ "video/webm",
43
+ "video/x-msvideo",
44
+ // Archives
45
+ "application/java-archive",
46
+ "application/vnd.apple.installer+xml",
47
+ "application/x-7z-compressed",
48
+ "application/x-apple-diskimage",
49
+ "application/x-bzip",
50
+ "application/x-bzip2",
51
+ "application/x-gzip",
52
+ "application/x-java-archive",
53
+ "application/x-rar-compressed",
54
+ "application/x-tar",
55
+ "application/x-zip",
56
+ "application/zip",
57
+ ]);
58
+ export function isBinaryContentType(contentType) {
59
+ if (!contentType)
60
+ return false;
61
+ const value = contentType?.split(";")[0] ?? "";
62
+ return commonBinaryMimeTypes.has(value);
63
+ }
@@ -0,0 +1,96 @@
1
+ /// <reference types="node" />
2
+ import { IncrementalCache } from "../cache/incremental/types.js";
3
+ import { TagCache } from "../cache/tag/types.js";
4
+ interface CachedFetchValue {
5
+ kind: "FETCH";
6
+ data: {
7
+ headers: {
8
+ [k: string]: string;
9
+ };
10
+ body: string;
11
+ url: string;
12
+ status?: number;
13
+ tags?: string[];
14
+ };
15
+ revalidate: number;
16
+ }
17
+ interface CachedRedirectValue {
18
+ kind: "REDIRECT";
19
+ props: Object;
20
+ }
21
+ interface CachedRouteValue {
22
+ kind: "ROUTE" | "APP_ROUTE";
23
+ body: Buffer;
24
+ status: number;
25
+ headers: Record<string, undefined | string | string[]>;
26
+ }
27
+ interface CachedImageValue {
28
+ kind: "IMAGE";
29
+ etag: string;
30
+ buffer: Buffer;
31
+ extension: string;
32
+ isMiss?: boolean;
33
+ isStale?: boolean;
34
+ }
35
+ interface IncrementalCachedPageValue {
36
+ kind: "PAGE" | "PAGES";
37
+ html: string;
38
+ pageData: Object;
39
+ status?: number;
40
+ headers?: Record<string, undefined | string>;
41
+ }
42
+ interface IncrementalCachedAppPageValue {
43
+ kind: "APP_PAGE";
44
+ html: string;
45
+ rscData: Buffer;
46
+ headers?: Record<string, undefined | string | string[]>;
47
+ postponed?: string;
48
+ status?: number;
49
+ }
50
+ type IncrementalCacheValue = CachedRedirectValue | IncrementalCachedPageValue | IncrementalCachedAppPageValue | CachedImageValue | CachedFetchValue | CachedRouteValue;
51
+ type IncrementalCacheContext = {
52
+ revalidate?: number | false | undefined;
53
+ fetchCache?: boolean | undefined;
54
+ fetchUrl?: string | undefined;
55
+ fetchIdx?: number | undefined;
56
+ tags?: string[] | undefined;
57
+ };
58
+ interface CacheHandlerContext {
59
+ fs?: never;
60
+ dev?: boolean;
61
+ flushToDisk?: boolean;
62
+ serverDistDir?: string;
63
+ maxMemoryCacheSize?: number;
64
+ _appDir: boolean;
65
+ _requestHeaders: never;
66
+ fetchCacheKeyPrefix?: string;
67
+ }
68
+ interface CacheHandlerValue {
69
+ lastModified?: number;
70
+ age?: number;
71
+ cacheState?: string;
72
+ value: IncrementalCacheValue | null;
73
+ }
74
+ export declare function hasCacheExtension(key: string): boolean;
75
+ declare global {
76
+ var incrementalCache: IncrementalCache;
77
+ var tagCache: TagCache;
78
+ var disableDynamoDBCache: boolean;
79
+ var disableIncrementalCache: boolean;
80
+ var lastModified: Record<string, number>;
81
+ var isNextAfter15: boolean;
82
+ }
83
+ export default class S3Cache {
84
+ constructor(_ctx: CacheHandlerContext);
85
+ get(key: string, options?: boolean | {
86
+ fetchCache?: boolean;
87
+ kindHint?: "app" | "pages" | "fetch";
88
+ tags?: string[];
89
+ softTags?: string[];
90
+ }): Promise<CacheHandlerValue | null>;
91
+ getFetchCache(key: string, softTags?: string[], tags?: string[]): Promise<CacheHandlerValue | null>;
92
+ getIncrementalCache(key: string): Promise<CacheHandlerValue | null>;
93
+ set(key: string, data?: IncrementalCacheValue, ctx?: IncrementalCacheContext): Promise<void>;
94
+ revalidateTag(tags: string | string[]): Promise<void>;
95
+ }
96
+ export {};
@@ -0,0 +1,278 @@
1
+ import { isBinaryContentType } from "./binary.js";
2
+ import { debug, error, warn } from "./logger.js";
3
+ /** Beginning single backslash is intentional, to look for the dot + the extension. Do not escape it again. */
4
+ const CACHE_EXTENSION_REGEX = /\.(cache|fetch)$/;
5
+ export function hasCacheExtension(key) {
6
+ return CACHE_EXTENSION_REGEX.test(key);
7
+ }
8
+ // 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
+ export default class S3Cache {
10
+ constructor(_ctx) { }
11
+ async get(key,
12
+ // fetchCache is for next 13.5 and above, kindHint is for next 14 and above and boolean is for earlier versions
13
+ options) {
14
+ if (globalThis.disableIncrementalCache) {
15
+ return null;
16
+ }
17
+ const isFetchCache = typeof options === "object"
18
+ ? options.kindHint
19
+ ? options.kindHint === "fetch"
20
+ : options.fetchCache
21
+ : options;
22
+ const softTags = typeof options === "object" ? options.softTags : [];
23
+ const tags = typeof options === "object" ? options.tags : [];
24
+ return isFetchCache
25
+ ? this.getFetchCache(key, softTags, tags)
26
+ : this.getIncrementalCache(key);
27
+ }
28
+ async getFetchCache(key, softTags, tags) {
29
+ debug("get fetch cache", { key, softTags, tags });
30
+ try {
31
+ const { value, lastModified } = await globalThis.incrementalCache.get(key, true);
32
+ // const { Body, LastModified } = await this.getS3Object(key, "fetch");
33
+ const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
34
+ if (_lastModified === -1) {
35
+ // If some tags are stale we need to force revalidation
36
+ return null;
37
+ }
38
+ if (value === undefined)
39
+ return null;
40
+ // For cases where we don't have tags, we need to ensure that the soft tags are not being revalidated
41
+ // We only need to check for the path as it should already contain all the tags
42
+ if ((tags ?? []).length === 0) {
43
+ // Then we need to find the path for the given key
44
+ const path = softTags?.find((tag) => tag.startsWith("_N_T_/") &&
45
+ !tag.endsWith("layout") &&
46
+ !tag.endsWith("page"));
47
+ if (path) {
48
+ const pathLastModified = await globalThis.tagCache.getLastModified(path.replace("_N_T_/", ""), lastModified);
49
+ if (pathLastModified === -1) {
50
+ // In case the path has been revalidated, we don't want to use the fetch cache
51
+ return null;
52
+ }
53
+ }
54
+ }
55
+ return {
56
+ lastModified: _lastModified,
57
+ value: value,
58
+ };
59
+ }
60
+ catch (e) {
61
+ // We can usually ignore errors here as they are usually due to cache not being found
62
+ debug("Failed to get fetch cache", e);
63
+ return null;
64
+ }
65
+ }
66
+ async getIncrementalCache(key) {
67
+ try {
68
+ const { value: cacheData, lastModified } = await globalThis.incrementalCache.get(key, false);
69
+ // const { Body, LastModified } = await this.getS3Object(key, "cache");
70
+ // const cacheData = JSON.parse(
71
+ // (await Body?.transformToString()) ?? "{}",
72
+ // ) as S3CachedFile;
73
+ const meta = cacheData?.meta;
74
+ const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
75
+ if (_lastModified === -1) {
76
+ // If some tags are stale we need to force revalidation
77
+ return null;
78
+ }
79
+ const requestId = globalThis.__als.getStore()?.requestId ?? "";
80
+ globalThis.lastModified[requestId] = _lastModified;
81
+ if (cacheData?.type === "route") {
82
+ return {
83
+ lastModified: _lastModified,
84
+ value: {
85
+ kind: globalThis.isNextAfter15 ? "APP_ROUTE" : "ROUTE",
86
+ body: Buffer.from(cacheData.body ?? Buffer.alloc(0), isBinaryContentType(String(meta?.headers?.["content-type"]))
87
+ ? "base64"
88
+ : "utf8"),
89
+ status: meta?.status,
90
+ headers: meta?.headers,
91
+ },
92
+ };
93
+ }
94
+ else if (cacheData?.type === "page" || cacheData?.type === "app") {
95
+ if (globalThis.isNextAfter15 && cacheData?.type === "app") {
96
+ return {
97
+ lastModified: _lastModified,
98
+ value: {
99
+ kind: "APP_PAGE",
100
+ html: cacheData.html,
101
+ rscData: Buffer.from(cacheData.rsc),
102
+ status: meta?.status,
103
+ headers: meta?.headers,
104
+ },
105
+ };
106
+ }
107
+ return {
108
+ lastModified: _lastModified,
109
+ value: {
110
+ kind: globalThis.isNextAfter15 ? "PAGES" : "PAGE",
111
+ html: cacheData.html,
112
+ pageData: cacheData.type === "page" ? cacheData.json : cacheData.rsc,
113
+ status: meta?.status,
114
+ headers: meta?.headers,
115
+ },
116
+ };
117
+ }
118
+ else if (cacheData?.type === "redirect") {
119
+ return {
120
+ lastModified: _lastModified,
121
+ value: {
122
+ kind: "REDIRECT",
123
+ props: cacheData.props,
124
+ },
125
+ };
126
+ }
127
+ else {
128
+ warn("Unknown cache type", cacheData);
129
+ return null;
130
+ }
131
+ }
132
+ catch (e) {
133
+ // We can usually ignore errors here as they are usually due to cache not being found
134
+ debug("Failed to get body cache", e);
135
+ return null;
136
+ }
137
+ }
138
+ async set(key, data, ctx) {
139
+ if (globalThis.disableIncrementalCache) {
140
+ return;
141
+ }
142
+ // This one might not even be necessary anymore
143
+ // Better be safe than sorry
144
+ const detachedPromise = globalThis.__als
145
+ .getStore()
146
+ ?.pendingPromiseRunner.withResolvers();
147
+ try {
148
+ if (data?.kind === "ROUTE" || data?.kind === "APP_ROUTE") {
149
+ const { body, status, headers } = data;
150
+ await globalThis.incrementalCache.set(key, {
151
+ type: "route",
152
+ body: body.toString(isBinaryContentType(String(headers["content-type"]))
153
+ ? "base64"
154
+ : "utf8"),
155
+ meta: {
156
+ status,
157
+ headers,
158
+ },
159
+ }, false);
160
+ }
161
+ else if (data?.kind === "PAGE" || data?.kind === "PAGES") {
162
+ const { html, pageData, status, headers } = data;
163
+ const isAppPath = typeof pageData === "string";
164
+ if (isAppPath) {
165
+ await globalThis.incrementalCache.set(key, {
166
+ type: "app",
167
+ html,
168
+ rsc: pageData,
169
+ meta: {
170
+ status,
171
+ headers,
172
+ },
173
+ }, false);
174
+ }
175
+ else {
176
+ await globalThis.incrementalCache.set(key, {
177
+ type: "page",
178
+ html,
179
+ json: pageData,
180
+ }, false);
181
+ }
182
+ }
183
+ else if (data?.kind === "APP_PAGE") {
184
+ const { html, rscData, headers, status } = data;
185
+ await globalThis.incrementalCache.set(key, {
186
+ type: "app",
187
+ html,
188
+ rsc: rscData.toString("utf8"),
189
+ meta: {
190
+ status,
191
+ headers,
192
+ },
193
+ }, false);
194
+ }
195
+ else if (data?.kind === "FETCH") {
196
+ await globalThis.incrementalCache.set(key, data, true);
197
+ }
198
+ else if (data?.kind === "REDIRECT") {
199
+ await globalThis.incrementalCache.set(key, {
200
+ type: "redirect",
201
+ props: data.props,
202
+ }, false);
203
+ }
204
+ else if (data === null || data === undefined) {
205
+ await globalThis.incrementalCache.delete(key);
206
+ }
207
+ // Write derivedTags to dynamodb
208
+ // If we use an in house version of getDerivedTags in build we should use it here instead of next's one
209
+ const derivedTags = data?.kind === "FETCH"
210
+ ? ctx?.tags ?? data?.data?.tags ?? [] // before version 14 next.js used data?.data?.tags so we keep it for backward compatibility
211
+ : data?.kind === "PAGE"
212
+ ? data.headers?.["x-next-cache-tags"]?.split(",") ?? []
213
+ : [];
214
+ debug("derivedTags", derivedTags);
215
+ // Get all tags stored in dynamodb for the given key
216
+ // If any of the derived tags are not stored in dynamodb for the given key, write them
217
+ const storedTags = await globalThis.tagCache.getByPath(key);
218
+ const tagsToWrite = derivedTags.filter((tag) => !storedTags.includes(tag));
219
+ if (tagsToWrite.length > 0) {
220
+ await globalThis.tagCache.writeTags(tagsToWrite.map((tag) => ({
221
+ path: key,
222
+ tag: tag,
223
+ // In case the tags are not there we just need to create them
224
+ // but we don't want them to return from `getLastModified` as they are not stale
225
+ revalidatedAt: 1,
226
+ })));
227
+ }
228
+ debug("Finished setting cache");
229
+ }
230
+ catch (e) {
231
+ error("Failed to set cache", e);
232
+ }
233
+ finally {
234
+ // We need to resolve the promise even if there was an error
235
+ detachedPromise?.resolve();
236
+ }
237
+ }
238
+ async revalidateTag(tags) {
239
+ if (globalThis.disableDynamoDBCache || globalThis.disableIncrementalCache) {
240
+ return;
241
+ }
242
+ try {
243
+ const _tags = Array.isArray(tags) ? tags : [tags];
244
+ for (const tag of _tags) {
245
+ debug("revalidateTag", tag);
246
+ // Find all keys with the given tag
247
+ const paths = await globalThis.tagCache.getByTag(tag);
248
+ debug("Items", paths);
249
+ const toInsert = paths.map((path) => ({
250
+ path,
251
+ tag,
252
+ }));
253
+ // If the tag is a soft tag, we should also revalidate the hard tags
254
+ if (tag.startsWith("_N_T_/")) {
255
+ for (const path of paths) {
256
+ // We need to find all hard tags for a given path
257
+ const _tags = await globalThis.tagCache.getByPath(path);
258
+ const hardTags = _tags.filter((t) => !t.startsWith("_N_T_/"));
259
+ // For every hard tag, we need to find all paths and revalidate them
260
+ for (const hardTag of hardTags) {
261
+ const _paths = await globalThis.tagCache.getByTag(hardTag);
262
+ debug({ hardTag, _paths });
263
+ toInsert.push(..._paths.map((path) => ({
264
+ path,
265
+ tag: hardTag,
266
+ })));
267
+ }
268
+ }
269
+ }
270
+ // Update all keys with the given tag with revalidatedAt set to now
271
+ await globalThis.tagCache.writeTags(toInsert);
272
+ }
273
+ }
274
+ catch (e) {
275
+ error("Failed to revalidate tag", e);
276
+ }
277
+ }
278
+ }
@@ -0,0 +1,27 @@
1
+ export declare const NEXT_DIR: string;
2
+ export declare const OPEN_NEXT_DIR: string;
3
+ export declare const NextConfig: import("../../types/next-types").NextConfig;
4
+ export declare const BuildId: string;
5
+ export declare const HtmlPages: string[];
6
+ export declare const RoutesManifest: {
7
+ basePath: string | undefined;
8
+ rewrites: {
9
+ beforeFiles: import("../../types/next-types").RewriteDefinition[];
10
+ afterFiles: import("../../types/next-types").RewriteDefinition[];
11
+ fallback: import("../../types/next-types").RewriteDefinition[];
12
+ };
13
+ redirects: import("../../types/next-types").RedirectDefinition[];
14
+ routes: {
15
+ static: import("../../types/next-types").RouteDefinition[];
16
+ dynamic: import("../../types/next-types").RouteDefinition[];
17
+ data: {
18
+ static: import("../../types/next-types").DataRouteDefinition[];
19
+ dynamic: import("../../types/next-types").DataRouteDefinition[];
20
+ };
21
+ };
22
+ locales: string[];
23
+ };
24
+ export declare const ConfigHeaders: import("../../types/next-types").Header[] | undefined;
25
+ export declare const PrerenderManifest: import("../../types/next-types").PrerenderManifest;
26
+ export declare const AppPathsManifestKeys: string[];
27
+ export declare const MiddlewareManifest: import("../../types/next-types").MiddlewareManifest;
@@ -0,0 +1,21 @@
1
+ import path from "path";
2
+ import { debug } from "../logger";
3
+ import { loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest,
4
+ // loadPublicAssets,
5
+ loadRoutesManifest, } from "./util.js";
6
+ export const NEXT_DIR = path.join(__dirname, ".next");
7
+ export const OPEN_NEXT_DIR = path.join(__dirname, ".open-next");
8
+ debug({ NEXT_DIR, OPEN_NEXT_DIR });
9
+ //TODO: inject these values at build time
10
+ export const NextConfig = /* @__PURE__ */ loadConfig(NEXT_DIR);
11
+ export const BuildId = /* @__PURE__ */ loadBuildId(NEXT_DIR);
12
+ export const HtmlPages = /* @__PURE__ */ loadHtmlPages(NEXT_DIR);
13
+ // export const PublicAssets = loadPublicAssets(OPEN_NEXT_DIR);
14
+ export const RoutesManifest = /* @__PURE__ */ loadRoutesManifest(NEXT_DIR);
15
+ export const ConfigHeaders = /* @__PURE__ */ loadConfigHeaders(NEXT_DIR);
16
+ export const PrerenderManifest =
17
+ /* @__PURE__ */ loadPrerenderManifest(NEXT_DIR);
18
+ export const AppPathsManifestKeys =
19
+ /* @__PURE__ */ loadAppPathsManifestKeys(NEXT_DIR);
20
+ export const MiddlewareManifest =
21
+ /* @__PURE__ */ loadMiddlewareManifest(NEXT_DIR);
@@ -0,0 +1,28 @@
1
+ import { MiddlewareManifest, NextConfig, PrerenderManifest } from "../../types/next-types";
2
+ import { PublicFiles } from "../../build";
3
+ export declare function loadConfig(nextDir: string): NextConfig;
4
+ export declare function loadBuildId(nextDir: string): string;
5
+ export declare function loadHtmlPages(nextDir: string): string[];
6
+ export declare function loadPublicAssets(openNextDir: string): PublicFiles;
7
+ export declare function loadRoutesManifest(nextDir: string): {
8
+ basePath: string | undefined;
9
+ rewrites: {
10
+ beforeFiles: import("../../types/next-types").RewriteDefinition[];
11
+ afterFiles: import("../../types/next-types").RewriteDefinition[];
12
+ fallback: import("../../types/next-types").RewriteDefinition[];
13
+ };
14
+ redirects: import("../../types/next-types").RedirectDefinition[];
15
+ routes: {
16
+ static: import("../../types/next-types").RouteDefinition[];
17
+ dynamic: import("../../types/next-types").RouteDefinition[];
18
+ data: {
19
+ static: import("../../types/next-types").DataRouteDefinition[];
20
+ dynamic: import("../../types/next-types").DataRouteDefinition[];
21
+ };
22
+ };
23
+ locales: string[];
24
+ };
25
+ export declare function loadConfigHeaders(nextDir: string): import("../../types/next-types").Header[] | undefined;
26
+ export declare function loadPrerenderManifest(nextDir: string): PrerenderManifest;
27
+ export declare function loadAppPathsManifestKeys(nextDir: string): string[];
28
+ export declare function loadMiddlewareManifest(nextDir: string): MiddlewareManifest;