@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/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ import { build } from "./build.js";
3
+ const command = process.argv[2];
4
+ if (command !== "build")
5
+ printHelp();
6
+ const args = parseArgs();
7
+ if (Object.keys(args).includes("--help"))
8
+ printHelp();
9
+ await build(args["--config-path"], args["--node-externals"]);
10
+ function parseArgs() {
11
+ return process.argv.slice(2).reduce((acc, key, ind, self) => {
12
+ if (key.startsWith("--")) {
13
+ if (self[ind + 1] && self[ind + 1].startsWith("-")) {
14
+ acc[key] = undefined;
15
+ }
16
+ else if (self[ind + 1]) {
17
+ acc[key] = self[ind + 1];
18
+ }
19
+ else if (!self[ind + 1]) {
20
+ acc[key] = undefined;
21
+ }
22
+ }
23
+ return acc;
24
+ }, {});
25
+ }
26
+ function printHelp() {
27
+ console.log("Unknown command");
28
+ console.log("");
29
+ console.log("Usage:");
30
+ console.log(" npx open-next build");
31
+ console.log("You can use a custom config path here");
32
+ console.log(" npx open-next build --config-path ./path/to/open-next.config.ts");
33
+ console.log("You can configure externals for the esbuild compilation of the open-next.config.ts file");
34
+ console.log(" npx open-next build --node-externals aws-sdk,sharp,sqlite3");
35
+ console.log("");
36
+ process.exit(1);
37
+ }
@@ -0,0 +1,12 @@
1
+ type LEVEL = "info" | "debug";
2
+ declare const _default: {
3
+ setLevel: (level: LEVEL) => LEVEL;
4
+ debug: (...args: any[]) => void;
5
+ info: {
6
+ (...data: any[]): void;
7
+ (message?: any, ...optionalParams: any[]): void;
8
+ };
9
+ warn: (...args: any[]) => void;
10
+ error: (...args: any[]) => void;
11
+ };
12
+ export default _default;
package/dist/logger.js ADDED
@@ -0,0 +1,13 @@
1
+ import chalk from "chalk";
2
+ let logLevel = "info";
3
+ export default {
4
+ setLevel: (level) => (logLevel = level),
5
+ debug: (...args) => {
6
+ if (logLevel !== "debug")
7
+ return;
8
+ console.log(chalk.magenta("DEBUG"), ...args);
9
+ },
10
+ info: console.log,
11
+ warn: (...args) => console.warn(chalk.yellow("WARN"), ...args),
12
+ error: (...args) => console.error(chalk.red("ERROR"), ...args),
13
+ };
@@ -0,0 +1 @@
1
+ export declare function minifyAll(dir: any, opts: any): Promise<void>;
@@ -0,0 +1,101 @@
1
+ // Copied and modified from node-minify-all-js by Adones Pitogo
2
+ // https://github.com/adonespitogo/node-minify-all-js/blob/master/index.js
3
+ // @ts-nocheck
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import minify from "@node-minify/core";
7
+ import terser from "@node-minify/terser";
8
+ var failed_files = [];
9
+ var total_files = 0;
10
+ var options = {};
11
+ const promiseSeries = async (tasks, initial) => {
12
+ if (!Array.isArray(tasks)) {
13
+ return Promise.reject(new TypeError("promise.series only accepts an array of functions"));
14
+ }
15
+ return tasks.reduce((current, next) => {
16
+ return current.then(next);
17
+ }, Promise.resolve(initial));
18
+ };
19
+ const minifyJS = async (file) => {
20
+ total_files++;
21
+ try {
22
+ await minify({
23
+ compressor: terser,
24
+ input: file,
25
+ output: file,
26
+ options: {
27
+ module: options.module,
28
+ mangle: options.mangle,
29
+ compress: { reduce_vars: false },
30
+ },
31
+ });
32
+ }
33
+ catch (e) {
34
+ failed_files.push(file);
35
+ }
36
+ //process.stdout.write(".");
37
+ };
38
+ const minifyJSON = async (file) => {
39
+ try {
40
+ if (options.compress_json || options.packagejson) {
41
+ total_files++;
42
+ var is_package_json = file.indexOf("package.json") > -1;
43
+ var data = await fs.readFile(file, "utf8");
44
+ var json = JSON.parse(data);
45
+ var new_json = {};
46
+ if (options.packagejson && is_package_json) {
47
+ var { name, version, bin, main, binary, engines } = json;
48
+ new_json = { name, version };
49
+ if (bin)
50
+ new_json.bin = bin;
51
+ if (binary)
52
+ new_json.binary = binary;
53
+ if (main)
54
+ new_json.main = main;
55
+ if (engines)
56
+ new_json.engines = engines;
57
+ }
58
+ else {
59
+ new_json = json;
60
+ }
61
+ await fs.writeFile(file, JSON.stringify(new_json));
62
+ }
63
+ }
64
+ catch (e) { }
65
+ //process.stdout.write(".");
66
+ };
67
+ const walk = async (currentDirPath) => {
68
+ var js_files = [];
69
+ var json_files = [];
70
+ var dirs = [];
71
+ var current_dirs = await fs.readdir(currentDirPath);
72
+ for (const name of current_dirs) {
73
+ var filePath = path.join(currentDirPath, name);
74
+ var stat = await fs.stat(filePath);
75
+ var is_bin = /\.bin$/;
76
+ if (stat.isFile()) {
77
+ if (filePath.substr(-5) === ".json")
78
+ json_files.push(filePath);
79
+ else if (filePath.substr(-3) === ".js" || options.all_js)
80
+ js_files.push(filePath);
81
+ }
82
+ else if (stat.isDirectory() && !is_bin.test(filePath)) {
83
+ dirs.push(filePath);
84
+ }
85
+ }
86
+ var js_promise = Promise.all(js_files.map((f) => minifyJS(f)));
87
+ var json_promise = Promise.all(json_files.map((f) => minifyJSON(f)));
88
+ await Promise.all([js_promise, json_promise]);
89
+ await promiseSeries(dirs.map((dir) => () => walk(dir)));
90
+ };
91
+ export async function minifyAll(dir, opts) {
92
+ Object.assign(options, opts || {});
93
+ //console.log("minify-all-js options:\n", JSON.stringify(options, null, 2));
94
+ await walk(dir);
95
+ //process.stdout.write(".\n");
96
+ //console.log("Total found files: " + total_files);
97
+ if (failed_files.length) {
98
+ console.log(`\n\nFailed to minify files:`);
99
+ failed_files.forEach((f) => console.log("\t" + f));
100
+ }
101
+ }
@@ -0,0 +1,3 @@
1
+ import { ImageLoader } from "../../types/open-next";
2
+ declare const hostLoader: ImageLoader;
3
+ export default hostLoader;
@@ -0,0 +1,29 @@
1
+ import { Readable } from "node:stream";
2
+ import { FatalError } from "../../utils/error";
3
+ const hostLoader = {
4
+ name: "host",
5
+ load: async (key) => {
6
+ const host = process.env.HOST;
7
+ if (!host) {
8
+ throw new FatalError("Host must be defined!");
9
+ }
10
+ const url = `https://${host}${key}`;
11
+ const response = await fetch(url);
12
+ if (!response.ok) {
13
+ throw new FatalError(`Failed to fetch image from ${url}`);
14
+ }
15
+ if (!response.body) {
16
+ throw new FatalError("No body in response");
17
+ }
18
+ const body = Readable.fromWeb(response.body);
19
+ const contentType = response.headers.get("content-type") ?? "image/jpeg";
20
+ const cacheControl = response.headers.get("cache-control") ??
21
+ "private, max-age=0, must-revalidate";
22
+ return {
23
+ body,
24
+ contentType,
25
+ cacheControl,
26
+ };
27
+ },
28
+ };
29
+ export default hostLoader;
@@ -0,0 +1,3 @@
1
+ import { ImageLoader } from "../../types/open-next";
2
+ declare const s3Loader: ImageLoader;
3
+ export default s3Loader;
@@ -0,0 +1,33 @@
1
+ import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
2
+ import { FatalError } from "../../utils/error";
3
+ import { awsLogger } from "../../adapters/logger";
4
+ const { BUCKET_NAME, BUCKET_KEY_PREFIX } = process.env;
5
+ function ensureBucketExists() {
6
+ if (!BUCKET_NAME) {
7
+ throw new Error("Bucket name must be defined!");
8
+ }
9
+ }
10
+ const s3Loader = {
11
+ name: "s3",
12
+ load: async (key) => {
13
+ const s3Client = new S3Client({ logger: awsLogger });
14
+ ensureBucketExists();
15
+ const keyPrefix = BUCKET_KEY_PREFIX?.replace(/^\/|\/$/g, "");
16
+ const response = await s3Client.send(new GetObjectCommand({
17
+ Bucket: BUCKET_NAME,
18
+ Key: keyPrefix
19
+ ? keyPrefix + "/" + key.replace(/^\//, "")
20
+ : key.replace(/^\//, ""),
21
+ }));
22
+ const body = response.Body;
23
+ if (!body) {
24
+ throw new FatalError("No body in S3 response");
25
+ }
26
+ return {
27
+ body: body,
28
+ contentType: response.ContentType,
29
+ cacheControl: response.CacheControl,
30
+ };
31
+ },
32
+ };
33
+ export default s3Loader;
@@ -0,0 +1,15 @@
1
+ import { Plugin } from "esbuild";
2
+ import { MiddlewareInfo } from "../types/next-types.js";
3
+ export interface IPluginSettings {
4
+ nextDir: string;
5
+ edgeFunctionHandlerPath?: string;
6
+ middlewareInfo: MiddlewareInfo;
7
+ isInCloudfare?: boolean;
8
+ }
9
+ /**
10
+ * @param opts.nextDir - The path to the .next directory
11
+ * @param opts.edgeFunctionHandlerPath - The path to the edgeFunctionHandler.js file that we'll use to bundle the routing
12
+ * @param opts.entryFiles - The entry files that we'll inject into the edgeFunctionHandler.js file
13
+ * @returns
14
+ */
15
+ export declare function openNextEdgePlugins({ nextDir, edgeFunctionHandlerPath, middlewareInfo, isInCloudfare, }: IPluginSettings): Plugin;
@@ -0,0 +1,157 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest, loadRoutesManifest, } from "../adapters/config/util.js";
4
+ /**
5
+ * @param opts.nextDir - The path to the .next directory
6
+ * @param opts.edgeFunctionHandlerPath - The path to the edgeFunctionHandler.js file that we'll use to bundle the routing
7
+ * @param opts.entryFiles - The entry files that we'll inject into the edgeFunctionHandler.js file
8
+ * @returns
9
+ */
10
+ export function openNextEdgePlugins({ nextDir, edgeFunctionHandlerPath, middlewareInfo, isInCloudfare, }) {
11
+ const entryFiles = middlewareInfo.files.map((file) => path.join(nextDir, file));
12
+ const routes = [
13
+ {
14
+ name: middlewareInfo.name || "/",
15
+ page: middlewareInfo.page,
16
+ regex: middlewareInfo.matchers.map((m) => m.regexp),
17
+ },
18
+ ];
19
+ const wasmFiles = middlewareInfo.wasm ?? [];
20
+ return {
21
+ name: "opennext-edge",
22
+ setup(build) {
23
+ if (edgeFunctionHandlerPath) {
24
+ // If we bundle the routing, we need to resolve the middleware
25
+ build.onResolve({ filter: /\.\/middleware.mjs/g }, () => {
26
+ return {
27
+ path: edgeFunctionHandlerPath,
28
+ };
29
+ });
30
+ }
31
+ build.onResolve({ filter: /\.(mjs|wasm)$/g }, (args) => {
32
+ return {
33
+ external: true,
34
+ };
35
+ });
36
+ //Copied from https://github.com/cloudflare/next-on-pages/blob/7a18efb5cab4d86c8e3e222fc94ea88ac05baffd/packages/next-on-pages/src/buildApplication/processVercelFunctions/build.ts#L86-L112
37
+ build.onResolve({ filter: /^node:/ }, ({ kind, path }) => {
38
+ // this plugin converts `require("node:*")` calls, those are the only ones that
39
+ // need updating (esm imports to "node:*" are totally valid), so here we tag with the
40
+ // node-buffer namespace only imports that are require calls
41
+ return kind === "require-call"
42
+ ? { path, namespace: "node-built-in-modules" }
43
+ : undefined;
44
+ });
45
+ // we convert the imports we tagged with the node-built-in-modules namespace so that instead of `require("node:*")`
46
+ // they import from `export * from "node:*";`
47
+ build.onLoad({ filter: /.*/, namespace: "node-built-in-modules" }, ({ path }) => {
48
+ return {
49
+ contents: `export * from '${path}'`,
50
+ loader: "js",
51
+ };
52
+ });
53
+ // We inject the entry files into the edgeFunctionHandler
54
+ build.onLoad({ filter: /\/edgeFunctionHandler.js/g }, async (args) => {
55
+ let contents = readFileSync(args.path, "utf-8");
56
+ contents = `
57
+ globalThis._ENTRIES = {};
58
+ globalThis.self = globalThis;
59
+ globalThis._ROUTES = ${JSON.stringify(routes)};
60
+
61
+ ${isInCloudfare
62
+ ? ``
63
+ : `
64
+ import {readFileSync} from "node:fs";
65
+ import path from "node:path";
66
+ function addDuplexToInit(init) {
67
+ return typeof init === 'undefined' ||
68
+ (typeof init === 'object' && init.duplex === undefined)
69
+ ? { duplex: 'half', ...init }
70
+ : init
71
+ }
72
+ // We need to override Request to add duplex to the init, it seems Next expects it to work like this
73
+ class OverrideRequest extends Request {
74
+ constructor(input, init) {
75
+ super(input, addDuplexToInit(init))
76
+ }
77
+ }
78
+ globalThis.Request = OverrideRequest;
79
+
80
+ // If we're not in cloudflare, we polyfill crypto
81
+ // https://github.com/vercel/edge-runtime/blob/main/packages/primitives/src/primitives/crypto.js
82
+ import { webcrypto } from 'node:crypto'
83
+ if(!globalThis.crypto){
84
+ globalThis.crypto = new webcrypto.Crypto()
85
+ }
86
+ if(!globalThis.CryptoKey){
87
+ globalThis.CryptoKey = webcrypto.CryptoKey
88
+ }
89
+ function SubtleCrypto() {
90
+ if (!(this instanceof SubtleCrypto)) return new SubtleCrypto()
91
+ throw TypeError('Illegal constructor')
92
+ }
93
+ if(!globalThis.SubtleCrypto) {
94
+ globalThis.SubtleCrypto = SubtleCrypto
95
+ }
96
+ if(!globalThis.Crypto) {
97
+ globalThis.Crypto = webcrypto.Crypto
98
+ }
99
+ // We also need to polyfill URLPattern
100
+ if (!globalThis.URLPattern) {
101
+ await import("urlpattern-polyfill");
102
+ }
103
+ `}
104
+ ${wasmFiles
105
+ .map((file) => isInCloudfare
106
+ ? `import ${file.name} from './wasm/${file.name}.wasm';`
107
+ : `const ${file.name} = readFileSync(path.join(__dirname,'/wasm/${file.name}.wasm'));`)
108
+ .join("\n")}
109
+ ${entryFiles?.map((file) => `require("${file}");`).join("\n")}
110
+ ${contents}
111
+ `;
112
+ return {
113
+ contents,
114
+ };
115
+ });
116
+ build.onLoad({ filter: /adapters\/config\/index/g }, async () => {
117
+ const NextConfig = loadConfig(nextDir);
118
+ const BuildId = loadBuildId(nextDir);
119
+ const HtmlPages = loadHtmlPages(nextDir);
120
+ const RoutesManifest = loadRoutesManifest(nextDir);
121
+ const ConfigHeaders = loadConfigHeaders(nextDir);
122
+ const PrerenderManifest = loadPrerenderManifest(nextDir);
123
+ const AppPathsManifestKeys = loadAppPathsManifestKeys(nextDir);
124
+ const MiddlewareManifest = loadMiddlewareManifest(nextDir);
125
+ const contents = `
126
+ import path from "path";
127
+
128
+ import { debug } from "../logger";
129
+
130
+ if(!globalThis.__dirname) {
131
+ globalThis.__dirname = ""
132
+ }
133
+
134
+ export const NEXT_DIR = path.join(__dirname, ".next");
135
+ export const OPEN_NEXT_DIR = path.join(__dirname, ".open-next");
136
+
137
+ debug({ NEXT_DIR, OPEN_NEXT_DIR });
138
+
139
+ export const NextConfig = ${JSON.stringify(NextConfig)};
140
+ export const BuildId = ${JSON.stringify(BuildId)};
141
+ export const HtmlPages = ${JSON.stringify(HtmlPages)};
142
+ export const RoutesManifest = ${JSON.stringify(RoutesManifest)};
143
+ export const ConfigHeaders = ${JSON.stringify(ConfigHeaders)};
144
+ export const PrerenderManifest = ${JSON.stringify(PrerenderManifest)};
145
+ export const AppPathsManifestKeys = ${JSON.stringify(AppPathsManifestKeys)};
146
+ export const MiddlewareManifest = ${JSON.stringify(MiddlewareManifest)};
147
+
148
+ process.env.NEXT_BUILD_ID = BuildId;
149
+
150
+ `;
151
+ return {
152
+ contents,
153
+ };
154
+ });
155
+ },
156
+ };
157
+ }
@@ -0,0 +1,42 @@
1
+ import { Plugin } from "esbuild";
2
+ export interface IPluginSettings {
3
+ target: RegExp;
4
+ replacements?: string[];
5
+ deletes?: string[];
6
+ name?: string;
7
+ }
8
+ /**
9
+ *
10
+ * openNextPlugin({
11
+ * target: /plugins\/default\.js/g,
12
+ * replacements: [require.resolve("./plugins/default.js")],
13
+ * deletes: ["id1"],
14
+ * })
15
+ *
16
+ * To inject arbritary code by using (import at top of file):
17
+ *
18
+ * //#import
19
+ *
20
+ * import data from 'data'
21
+ * const datum = data.datum
22
+ *
23
+ * //#endImport
24
+ *
25
+ * To replace code:
26
+ *
27
+ * //#override id1
28
+ *
29
+ * export function overrideMe() {
30
+ * // I will replace the "id1" block in the target file
31
+ * }
32
+ *
33
+ * //#endOverride
34
+ *
35
+ *
36
+ * @param opts.target - the target file to replace
37
+ * @param opts.replacements - list of files used to replace the imports/overrides in the target
38
+ * - the path is absolute
39
+ * @param opts.deletes - list of ids to delete from the target
40
+ * @returns
41
+ */
42
+ export declare function openNextReplacementPlugin({ target, replacements, deletes, name, }: IPluginSettings): Plugin;
@@ -0,0 +1,74 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import chalk from "chalk";
3
+ import logger from "../logger.js";
4
+ const overridePattern = /\/\/#override (\w+)\n([\s\S]*?)\n\/\/#endOverride/gm;
5
+ const importPattern = /\/\/#import([\s\S]*?)\n\/\/#endImport/gm;
6
+ /**
7
+ *
8
+ * openNextPlugin({
9
+ * target: /plugins\/default\.js/g,
10
+ * replacements: [require.resolve("./plugins/default.js")],
11
+ * deletes: ["id1"],
12
+ * })
13
+ *
14
+ * To inject arbritary code by using (import at top of file):
15
+ *
16
+ * //#import
17
+ *
18
+ * import data from 'data'
19
+ * const datum = data.datum
20
+ *
21
+ * //#endImport
22
+ *
23
+ * To replace code:
24
+ *
25
+ * //#override id1
26
+ *
27
+ * export function overrideMe() {
28
+ * // I will replace the "id1" block in the target file
29
+ * }
30
+ *
31
+ * //#endOverride
32
+ *
33
+ *
34
+ * @param opts.target - the target file to replace
35
+ * @param opts.replacements - list of files used to replace the imports/overrides in the target
36
+ * - the path is absolute
37
+ * @param opts.deletes - list of ids to delete from the target
38
+ * @returns
39
+ */
40
+ export function openNextReplacementPlugin({ target, replacements, deletes, name, }) {
41
+ return {
42
+ name: name ?? "opennext",
43
+ setup(build) {
44
+ build.onLoad({ filter: target }, async (args) => {
45
+ let contents = await readFile(args.path, "utf-8");
46
+ await Promise.all([
47
+ ...(deletes ?? []).map(async (id) => {
48
+ const pattern = new RegExp(`\/\/#override (${id})\n([\\s\\S]*?)\/\/#endOverride`);
49
+ logger.debug(chalk.blue(`Open-next replacement plugin ${name}`), ` -- Deleting override for ${id}`);
50
+ contents = contents.replace(pattern, "");
51
+ }),
52
+ ...(replacements ?? []).map(async (fp) => {
53
+ const p = fp;
54
+ const replacementFile = await readFile(p, "utf-8");
55
+ const matches = replacementFile.matchAll(overridePattern);
56
+ const importMatch = replacementFile.match(importPattern);
57
+ const addedImport = importMatch ? importMatch[0] : "";
58
+ contents = `${addedImport}\n${contents}`;
59
+ for (const match of matches) {
60
+ const replacement = match[2];
61
+ const id = match[1];
62
+ const pattern = new RegExp(`\/\/#override (${id})\n([\\s\\S]*?)\/\/#endOverride`, "g");
63
+ logger.debug(chalk.blue(`Open-next replacement plugin ${name}`), `-- Applying override for ${id} from ${fp}`);
64
+ contents = contents.replace(pattern, replacement);
65
+ }
66
+ }),
67
+ ]);
68
+ return {
69
+ contents,
70
+ };
71
+ });
72
+ },
73
+ };
74
+ }
@@ -0,0 +1,18 @@
1
+ import { Plugin } from "esbuild";
2
+ import type { DefaultOverrideOptions, ImageLoader, IncludedImageLoader, LazyLoadedOverride, OverrideOptions } from "../types/open-next";
3
+ export interface IPluginSettings {
4
+ overrides?: {
5
+ wrapper?: DefaultOverrideOptions<any, any>["wrapper"];
6
+ converter?: DefaultOverrideOptions<any, any>["converter"];
7
+ tagCache?: OverrideOptions["tagCache"];
8
+ queue?: OverrideOptions["queue"];
9
+ incrementalCache?: OverrideOptions["incrementalCache"];
10
+ imageLoader?: LazyLoadedOverride<ImageLoader> | IncludedImageLoader;
11
+ };
12
+ fnName?: string;
13
+ }
14
+ /**
15
+ * @param opts.overrides - The name of the overrides to use
16
+ * @returns
17
+ */
18
+ export declare function openNextResolvePlugin({ overrides, fnName, }: IPluginSettings): Plugin;
@@ -0,0 +1,45 @@
1
+ import { readFileSync } from "node:fs";
2
+ import logger from "../logger.js";
3
+ function getOverrideOrDefault(override, defaultOverride) {
4
+ if (typeof override === "string") {
5
+ return override;
6
+ }
7
+ return defaultOverride;
8
+ }
9
+ /**
10
+ * @param opts.overrides - The name of the overrides to use
11
+ * @returns
12
+ */
13
+ export function openNextResolvePlugin({ overrides, fnName, }) {
14
+ return {
15
+ name: "opennext-resolve",
16
+ setup(build) {
17
+ logger.debug(`OpenNext Resolve plugin for ${fnName}`);
18
+ build.onLoad({ filter: /core(\/|\\)resolve\.js/g }, async (args) => {
19
+ let contents = readFileSync(args.path, "utf-8");
20
+ //TODO: refactor this. Every override should be at the same place so we can generate this dynamically
21
+ if (overrides?.wrapper) {
22
+ contents = contents.replace("../wrappers/aws-lambda.js", `../wrappers/${getOverrideOrDefault(overrides.wrapper, "aws-lambda")}.js`);
23
+ }
24
+ if (overrides?.converter) {
25
+ contents = contents.replace("../converters/aws-apigw-v2.js", `../converters/${getOverrideOrDefault(overrides.converter, "dummy")}.js`);
26
+ }
27
+ if (overrides?.tagCache) {
28
+ contents = contents.replace("../cache/tag/dynamodb.js", `../cache/tag/${getOverrideOrDefault(overrides.tagCache, "dynamodb-lite")}.js`);
29
+ }
30
+ if (overrides?.queue) {
31
+ contents = contents.replace("../queue/sqs.js", `../queue/${getOverrideOrDefault(overrides.queue, "sqs-lite")}.js`);
32
+ }
33
+ if (overrides?.incrementalCache) {
34
+ contents = contents.replace("../cache/incremental/s3.js", `../cache/incremental/${getOverrideOrDefault(overrides.incrementalCache, "s3-lite")}.js`);
35
+ }
36
+ if (overrides?.imageLoader) {
37
+ contents = contents.replace("../overrides/imageLoader/s3.js", `../overrides/imageLoader/${getOverrideOrDefault(overrides.imageLoader, "s3")}.js`);
38
+ }
39
+ return {
40
+ contents,
41
+ };
42
+ });
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,3 @@
1
+ import { Queue } from "./types";
2
+ declare const queue: Queue;
3
+ export default queue;
@@ -0,0 +1,52 @@
1
+ import { AwsClient } from "aws4fetch";
2
+ import { RecoverableError } from "../utils/error";
3
+ import { customFetchClient } from "../utils/fetch";
4
+ import { error } from "../adapters/logger";
5
+ let awsClient = null;
6
+ const getAwsClient = () => {
7
+ if (awsClient) {
8
+ return awsClient;
9
+ }
10
+ else {
11
+ awsClient = new AwsClient({
12
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
13
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
14
+ sessionToken: process.env.AWS_SESSION_TOKEN,
15
+ region: process.env.REVALIDATION_QUEUE_REGION,
16
+ });
17
+ return awsClient;
18
+ }
19
+ };
20
+ const awsFetch = (body) => {
21
+ const { REVALIDATION_QUEUE_REGION } = process.env;
22
+ const client = getAwsClient();
23
+ return customFetchClient(client)(`https://sqs.${REVALIDATION_QUEUE_REGION ?? "us-east-1"}.amazonaws.com`, {
24
+ method: "POST",
25
+ headers: {
26
+ "Content-Type": "application/x-amz-json-1.0",
27
+ "X-Amz-Target": "AmazonSQS.SendMessage",
28
+ },
29
+ body,
30
+ });
31
+ };
32
+ const queue = {
33
+ send: async ({ MessageBody, MessageDeduplicationId, MessageGroupId }) => {
34
+ try {
35
+ const { REVALIDATION_QUEUE_URL } = process.env;
36
+ const result = await awsFetch(JSON.stringify({
37
+ QueueUrl: REVALIDATION_QUEUE_URL,
38
+ MessageBody: JSON.stringify(MessageBody),
39
+ MessageDeduplicationId,
40
+ MessageGroupId,
41
+ }));
42
+ if (result.status !== 200) {
43
+ throw new RecoverableError(`Failed to send message: ${result.status}`);
44
+ }
45
+ }
46
+ catch (e) {
47
+ error(e);
48
+ }
49
+ },
50
+ name: "sqs",
51
+ };
52
+ export default queue;
@@ -0,0 +1,3 @@
1
+ import { Queue } from "./types";
2
+ declare const queue: Queue;
3
+ export default queue;