@opennextjs/aws 3.2.2 → 3.3.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.
- package/README.md +6 -1
- package/dist/adapters/cache.d.ts +1 -2
- package/dist/adapters/cache.js +2 -12
- package/dist/adapters/config/index.d.ts +2 -0
- package/dist/adapters/config/index.js +4 -3
- package/dist/adapters/config/util.d.ts +2 -0
- package/dist/adapters/config/util.js +12 -2
- package/dist/adapters/image-optimization-adapter.d.ts +1 -2
- package/dist/adapters/logger.js +32 -11
- package/dist/adapters/middleware.js +13 -2
- package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +1 -0
- package/dist/adapters/plugins/image-optimization/image-optimization.js +0 -1
- package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +1 -0
- package/dist/adapters/util.js +5 -1
- package/dist/build/bundleNextServer.d.ts +2 -2
- package/dist/build/bundleNextServer.js +2 -2
- package/dist/build/copyTracedFiles.js +1 -1
- package/dist/build/createAssets.js +23 -24
- package/dist/build/createMiddleware.js +1 -1
- package/dist/build/createServerBundle.js +3 -3
- package/dist/build/edge/createEdgeBundle.d.ts +5 -4
- package/dist/build/edge/createEdgeBundle.js +35 -33
- package/dist/build/helper.d.ts +6 -1
- package/dist/build/helper.js +20 -5
- package/dist/build/validateConfig.js +3 -1
- package/dist/core/requestHandler.d.ts +1 -2
- package/dist/core/requestHandler.js +31 -20
- package/dist/core/routing/matcher.js +1 -1
- package/dist/core/routing/middleware.d.ts +3 -3
- package/dist/core/routing/middleware.js +3 -4
- package/dist/core/routing/routeMatcher.d.ts +10 -0
- package/dist/core/routing/routeMatcher.js +45 -0
- package/dist/core/routing/util.d.ts +3 -3
- package/dist/core/routing/util.js +7 -5
- package/dist/core/routingHandler.d.ts +5 -8
- package/dist/core/routingHandler.js +38 -37
- package/dist/helpers/withCloudflare.d.ts +1 -1
- package/dist/helpers/withCloudflare.js +2 -2
- package/dist/http/openNextResponse.d.ts +2 -10
- package/dist/http/openNextResponse.js +5 -3
- package/dist/overrides/converters/aws-apigw-v2.js +2 -1
- package/dist/overrides/converters/aws-cloudfront.js +1 -1
- package/dist/overrides/converters/edge.d.ts +2 -5
- package/dist/overrides/converters/edge.js +5 -4
- package/dist/overrides/incrementalCache/dummy.js +4 -3
- package/dist/overrides/proxyExternalRequest/dummy.js +2 -1
- package/dist/overrides/proxyExternalRequest/node.js +2 -2
- package/dist/overrides/queue/dummy.js +2 -1
- package/dist/overrides/warmer/dummy.js +2 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +1 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.js +0 -4
- package/dist/overrides/wrappers/aws-lambda.js +0 -3
- package/dist/overrides/wrappers/cloudflare-edge.d.ts +9 -0
- package/dist/overrides/wrappers/{cloudflare.js → cloudflare-edge.js} +3 -3
- package/dist/overrides/wrappers/cloudflare-node.d.ts +8 -0
- package/dist/overrides/wrappers/cloudflare-node.js +50 -0
- package/dist/overrides/wrappers/dummy.d.ts +2 -2
- package/dist/overrides/wrappers/dummy.js +1 -1
- package/dist/overrides/wrappers/node.d.ts +1 -1
- package/dist/overrides/wrappers/node.js +0 -3
- package/dist/plugins/edge.js +6 -1
- package/dist/plugins/resolve.js +5 -1
- package/dist/types/open-next.d.ts +26 -1
- package/dist/types/overrides.d.ts +4 -5
- package/dist/{adapters → utils}/binary.js +1 -0
- package/dist/utils/error.d.ts +1 -0
- package/dist/utils/error.js +8 -0
- package/package.json +3 -3
- package/dist/overrides/wrappers/cloudflare.d.ts +0 -12
- /package/dist/{adapters → utils}/binary.d.ts +0 -0
package/README.md
CHANGED
|
@@ -77,18 +77,23 @@ To run `OpenNext` locally:
|
|
|
77
77
|
|
|
78
78
|
1. Clone this repository.
|
|
79
79
|
1. Build `open-next`:
|
|
80
|
+
|
|
80
81
|
```bash
|
|
81
82
|
cd packages/open-next
|
|
82
83
|
pnpm build
|
|
83
84
|
```
|
|
85
|
+
|
|
84
86
|
1. Run `open-next` in watch mode:
|
|
87
|
+
|
|
85
88
|
```bash
|
|
86
89
|
pnpm dev
|
|
87
90
|
```
|
|
91
|
+
|
|
88
92
|
1. Now, you can make changes in `open-next` and build your Next.js app to test the changes.
|
|
93
|
+
|
|
89
94
|
```bash
|
|
90
95
|
cd path/to/my/nextjs/app
|
|
91
|
-
path/to/
|
|
96
|
+
path/to/opennextjs-aws/packages/open-next/dist/index.js build
|
|
92
97
|
```
|
|
93
98
|
|
|
94
99
|
### Coldstart
|
package/dist/adapters/cache.d.ts
CHANGED
|
@@ -58,8 +58,7 @@ interface CacheHandlerValue {
|
|
|
58
58
|
cacheState?: string;
|
|
59
59
|
value: IncrementalCacheValue | null;
|
|
60
60
|
}
|
|
61
|
-
export
|
|
62
|
-
export default class S3Cache {
|
|
61
|
+
export default class Cache {
|
|
63
62
|
get(key: string, options?: boolean | {
|
|
64
63
|
fetchCache?: boolean;
|
|
65
64
|
kindHint?: "app" | "pages" | "fetch";
|
package/dist/adapters/cache.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { isBinaryContentType } from "
|
|
1
|
+
import { isBinaryContentType } from "../utils/binary";
|
|
2
2
|
import { debug, error, warn } from "./logger";
|
|
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
3
|
function isFetchCache(options) {
|
|
9
4
|
if (typeof options === "boolean") {
|
|
10
5
|
return options;
|
|
@@ -17,7 +12,7 @@ function isFetchCache(options) {
|
|
|
17
12
|
return false;
|
|
18
13
|
}
|
|
19
14
|
// 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
|
|
20
|
-
export default class
|
|
15
|
+
export default class Cache {
|
|
21
16
|
async get(key,
|
|
22
17
|
// fetchCache is for next 13.5 and above, kindHint is for next 14 and above and boolean is for earlier versions
|
|
23
18
|
options) {
|
|
@@ -34,7 +29,6 @@ export default class S3Cache {
|
|
|
34
29
|
debug("get fetch cache", { key, softTags, tags });
|
|
35
30
|
try {
|
|
36
31
|
const { value, lastModified } = await globalThis.incrementalCache.get(key, true);
|
|
37
|
-
// const { Body, LastModified } = await this.getS3Object(key, "fetch");
|
|
38
32
|
const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
|
|
39
33
|
if (_lastModified === -1) {
|
|
40
34
|
// If some tags are stale we need to force revalidation
|
|
@@ -71,10 +65,6 @@ export default class S3Cache {
|
|
|
71
65
|
async getIncrementalCache(key) {
|
|
72
66
|
try {
|
|
73
67
|
const { value: cacheData, lastModified } = await globalThis.incrementalCache.get(key, false);
|
|
74
|
-
// const { Body, LastModified } = await this.getS3Object(key, "cache");
|
|
75
|
-
// const cacheData = JSON.parse(
|
|
76
|
-
// (await Body?.transformToString()) ?? "{}",
|
|
77
|
-
// ) as S3CachedFile;
|
|
78
68
|
const meta = cacheData?.meta;
|
|
79
69
|
const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
|
|
80
70
|
if (_lastModified === -1) {
|
|
@@ -25,3 +25,5 @@ export declare const ConfigHeaders: import("../../types/next-types").Header[] |
|
|
|
25
25
|
export declare const PrerenderManifest: import("../../types/next-types").PrerenderManifest;
|
|
26
26
|
export declare const AppPathsManifestKeys: string[];
|
|
27
27
|
export declare const MiddlewareManifest: import("../../types/next-types").MiddlewareManifest;
|
|
28
|
+
export declare const AppPathsManifest: Record<string, string>;
|
|
29
|
+
export declare const AppPathRoutesManifest: Record<string, string>;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { debug } from "../logger";
|
|
3
|
-
import { loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest,
|
|
4
|
-
// loadPublicAssets,
|
|
5
|
-
loadRoutesManifest, } from "./util.js";
|
|
3
|
+
import { loadAppPathRoutesManifest, loadAppPathsManifest, loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest, loadRoutesManifest, } from "./util.js";
|
|
6
4
|
export const NEXT_DIR = path.join(__dirname, ".next");
|
|
7
5
|
export const OPEN_NEXT_DIR = path.join(__dirname, ".open-next");
|
|
8
6
|
debug({ NEXT_DIR, OPEN_NEXT_DIR });
|
|
@@ -19,3 +17,6 @@ export const AppPathsManifestKeys =
|
|
|
19
17
|
/* @__PURE__ */ loadAppPathsManifestKeys(NEXT_DIR);
|
|
20
18
|
export const MiddlewareManifest =
|
|
21
19
|
/* @__PURE__ */ loadMiddlewareManifest(NEXT_DIR);
|
|
20
|
+
export const AppPathsManifest = /* @__PURE__ */ loadAppPathsManifest(NEXT_DIR);
|
|
21
|
+
export const AppPathRoutesManifest =
|
|
22
|
+
/* @__PURE__ */ loadAppPathRoutesManifest(NEXT_DIR);
|
|
@@ -24,5 +24,7 @@ export declare function loadRoutesManifest(nextDir: string): {
|
|
|
24
24
|
};
|
|
25
25
|
export declare function loadConfigHeaders(nextDir: string): import("../../types/next-types").Header[] | undefined;
|
|
26
26
|
export declare function loadPrerenderManifest(nextDir: string): PrerenderManifest;
|
|
27
|
+
export declare function loadAppPathsManifest(nextDir: string): Record<string, string>;
|
|
28
|
+
export declare function loadAppPathRoutesManifest(nextDir: string): Record<string, string>;
|
|
27
29
|
export declare function loadAppPathsManifestKeys(nextDir: string): string[];
|
|
28
30
|
export declare function loadMiddlewareManifest(nextDir: string): MiddlewareManifest;
|
|
@@ -60,12 +60,22 @@ export function loadPrerenderManifest(nextDir) {
|
|
|
60
60
|
const json = fs.readFileSync(filePath, "utf-8");
|
|
61
61
|
return JSON.parse(json);
|
|
62
62
|
}
|
|
63
|
-
export function
|
|
63
|
+
export function loadAppPathsManifest(nextDir) {
|
|
64
64
|
const appPathsManifestPath = path.join(nextDir, "server", "app-paths-manifest.json");
|
|
65
65
|
const appPathsManifestJson = fs.existsSync(appPathsManifestPath)
|
|
66
66
|
? fs.readFileSync(appPathsManifestPath, "utf-8")
|
|
67
67
|
: "{}";
|
|
68
|
-
|
|
68
|
+
return JSON.parse(appPathsManifestJson);
|
|
69
|
+
}
|
|
70
|
+
export function loadAppPathRoutesManifest(nextDir) {
|
|
71
|
+
const appPathRoutesManifestPath = path.join(nextDir, "app-path-routes-manifest.json");
|
|
72
|
+
if (fs.existsSync(appPathRoutesManifestPath)) {
|
|
73
|
+
return JSON.parse(fs.readFileSync(appPathRoutesManifestPath, "utf-8"));
|
|
74
|
+
}
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
export function loadAppPathsManifestKeys(nextDir) {
|
|
78
|
+
const appPathsManifest = loadAppPathsManifest(nextDir);
|
|
69
79
|
return Object.keys(appPathsManifest).map((key) => {
|
|
70
80
|
// Remove parallel route
|
|
71
81
|
let cleanedKey = key.replace(/\/@[^\/]+/g, "");
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { StreamCreator } from "../
|
|
2
|
-
import type { InternalEvent, InternalResult } from "../types/open-next.js";
|
|
1
|
+
import type { InternalEvent, InternalResult, StreamCreator } from "../types/open-next.js";
|
|
3
2
|
export declare const handler: (...args: any[]) => any;
|
|
4
3
|
export declare function defaultHandler(event: InternalEvent, streamCreator?: StreamCreator): Promise<InternalResult>;
|
package/dist/adapters/logger.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isOpenNextError } from "../utils/error";
|
|
1
2
|
export function debug(...args) {
|
|
2
3
|
if (globalThis.openNextDebug) {
|
|
3
4
|
console.log(...args);
|
|
@@ -22,23 +23,24 @@ export function error(...args) {
|
|
|
22
23
|
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
|
23
24
|
debug(...args);
|
|
24
25
|
}
|
|
25
|
-
else if (args.some((arg) => arg
|
|
26
|
+
else if (args.some((arg) => isOpenNextError(arg))) {
|
|
26
27
|
// In case of an internal error, we log it with the appropriate log level
|
|
27
|
-
const error = args.find((arg) => arg
|
|
28
|
-
if (error.logLevel
|
|
29
|
-
debug(...args);
|
|
28
|
+
const error = args.find((arg) => isOpenNextError(arg));
|
|
29
|
+
if (error.logLevel < getOpenNextErrorLogLevel()) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
+
if (error.logLevel === 0) {
|
|
33
|
+
// Display the name and the message instead of full Open Next errors.
|
|
34
|
+
// console.log is used so that logging does not depend on openNextDebug.
|
|
35
|
+
return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
|
36
|
+
}
|
|
32
37
|
if (error.logLevel === 1) {
|
|
33
|
-
|
|
34
|
-
return;
|
|
38
|
+
// Display the name and the message instead of full Open Next errors.
|
|
39
|
+
return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
|
|
35
40
|
}
|
|
36
|
-
console.error(...args);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
console.error(...args);
|
|
41
|
+
return console.error(...args);
|
|
41
42
|
}
|
|
43
|
+
console.error(...args);
|
|
42
44
|
}
|
|
43
45
|
export const awsLogger = {
|
|
44
46
|
trace: () => { },
|
|
@@ -47,3 +49,22 @@ export const awsLogger = {
|
|
|
47
49
|
warn,
|
|
48
50
|
error,
|
|
49
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the log level for internal errors from the
|
|
54
|
+
* OPEN_NEXT_ERROR_LOG_LEVEL environment variable.
|
|
55
|
+
*
|
|
56
|
+
* @returns The numerical log level 0 (debug), 1 (warn), or 2 (error)
|
|
57
|
+
*/
|
|
58
|
+
function getOpenNextErrorLogLevel() {
|
|
59
|
+
const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
|
|
60
|
+
switch (strLevel.toLowerCase()) {
|
|
61
|
+
case "debug":
|
|
62
|
+
case "0":
|
|
63
|
+
return 0;
|
|
64
|
+
case "error":
|
|
65
|
+
case "2":
|
|
66
|
+
return 2;
|
|
67
|
+
default:
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -2,7 +2,7 @@ import { runWithOpenNextRequestContext } from "../utils/promise";
|
|
|
2
2
|
import { debug, error } from "../adapters/logger";
|
|
3
3
|
import { createGenericHandler } from "../core/createGenericHandler";
|
|
4
4
|
import { resolveIncrementalCache, resolveOriginResolver, resolveProxyRequest, resolveQueue, resolveTagCache, } from "../core/resolve";
|
|
5
|
-
import routingHandler from "../core/routingHandler";
|
|
5
|
+
import routingHandler, { INTERNAL_HEADER_INITIAL_PATH, INTERNAL_HEADER_RESOLVED_ROUTES, } from "../core/routingHandler";
|
|
6
6
|
globalThis.internalFetch = fetch;
|
|
7
7
|
globalThis.__openNextAls = new AsyncLocalStorage();
|
|
8
8
|
const defaultHandler = async (internalEvent) => {
|
|
@@ -22,10 +22,19 @@ const defaultHandler = async (internalEvent) => {
|
|
|
22
22
|
const origin = await originResolver.resolve(result.internalEvent.rawPath);
|
|
23
23
|
return {
|
|
24
24
|
type: "middleware",
|
|
25
|
-
internalEvent:
|
|
25
|
+
internalEvent: {
|
|
26
|
+
...result.internalEvent,
|
|
27
|
+
headers: {
|
|
28
|
+
...result.internalEvent.headers,
|
|
29
|
+
[INTERNAL_HEADER_INITIAL_PATH]: internalEvent.rawPath,
|
|
30
|
+
[INTERNAL_HEADER_RESOLVED_ROUTES]: JSON.stringify(result.resolvedRoutes) ?? "[]",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
26
33
|
isExternalRewrite: result.isExternalRewrite,
|
|
27
34
|
origin,
|
|
28
35
|
isISR: result.isISR,
|
|
36
|
+
initialPath: result.initialPath,
|
|
37
|
+
resolvedRoutes: result.resolvedRoutes,
|
|
29
38
|
};
|
|
30
39
|
}
|
|
31
40
|
try {
|
|
@@ -45,6 +54,8 @@ const defaultHandler = async (internalEvent) => {
|
|
|
45
54
|
isExternalRewrite: false,
|
|
46
55
|
origin: false,
|
|
47
56
|
isISR: result.isISR,
|
|
57
|
+
initialPath: result.internalEvent.rawPath,
|
|
58
|
+
resolvedRoutes: [{ route: "/500", type: "page" }],
|
|
48
59
|
};
|
|
49
60
|
}
|
|
50
61
|
}
|
|
@@ -5,7 +5,6 @@ import { debug } from "../../logger.js";
|
|
|
5
5
|
export async function optimizeImage(headers, imageParams, nextConfig, handleRequest) {
|
|
6
6
|
const result = await imageOptimizer({ headers }, {}, // res object is not necessary as it's not actually used.
|
|
7
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.
|
|
9
8
|
handleRequest);
|
|
10
9
|
debug("optimized result", result);
|
|
11
10
|
return result;
|
package/dist/adapters/util.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
//TODO: We should probably move all the utils to a separate location
|
|
2
2
|
export function setNodeEnv() {
|
|
3
|
-
|
|
3
|
+
// Note: we create a `processEnv` variable instead of just using `process.env` directly
|
|
4
|
+
// because build tools can substitute `process.env.NODE_ENV` on build making
|
|
5
|
+
// assignments such as `process.env.NODE_ENV = ...` problematic
|
|
6
|
+
const processEnv = process.env;
|
|
7
|
+
processEnv.NODE_ENV = process.env.NODE_ENV ?? "production";
|
|
4
8
|
}
|
|
5
9
|
export function generateUniqueId() {
|
|
6
10
|
return Math.random().toString(36).slice(2, 8);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare function bundleNextServer(outputDir: string, appPath: string, {
|
|
2
|
-
|
|
1
|
+
export declare function bundleNextServer(outputDir: string, appPath: string, { minify }: {
|
|
2
|
+
minify?: boolean | undefined;
|
|
3
3
|
}): Promise<void>;
|
|
@@ -35,7 +35,7 @@ const externals = [
|
|
|
35
35
|
// Adding it cause to add a lot of unnecessary deps
|
|
36
36
|
"next/dist/compiled/next-server",
|
|
37
37
|
];
|
|
38
|
-
export async function bundleNextServer(outputDir, appPath, {
|
|
38
|
+
export async function bundleNextServer(outputDir, appPath, { minify = true }) {
|
|
39
39
|
const require = createRequire(`${appPath}/package.json`);
|
|
40
40
|
const entrypoint = require.resolve("next/dist/esm/server/next-server.js");
|
|
41
41
|
await build({
|
|
@@ -46,7 +46,7 @@ export async function bundleNextServer(outputDir, appPath, { debug = false }) {
|
|
|
46
46
|
// packages: "external",
|
|
47
47
|
format: "cjs",
|
|
48
48
|
external: externals,
|
|
49
|
-
minify
|
|
49
|
+
minify,
|
|
50
50
|
outfile: path.join(outputDir, "next-server.runtime.prod.js"),
|
|
51
51
|
sourcemap: false,
|
|
52
52
|
plugins: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { isBinaryContentType } from "../adapters/binary.js";
|
|
4
3
|
import logger from "../logger.js";
|
|
4
|
+
import { isBinaryContentType } from "../utils/binary.js";
|
|
5
5
|
import * as buildHelper from "./helper.js";
|
|
6
6
|
export function createStaticAssets(options) {
|
|
7
7
|
logger.info("Bundling static assets...");
|
|
@@ -109,10 +109,29 @@ export function createCacheAssets(options) {
|
|
|
109
109
|
};
|
|
110
110
|
fs.writeFileSync(cacheFilePath, JSON.stringify(cacheFileContent));
|
|
111
111
|
});
|
|
112
|
+
// We need to traverse the cache to find every .meta file
|
|
113
|
+
const metaFiles = [];
|
|
114
|
+
// Copy fetch-cache to cache folder
|
|
115
|
+
const fetchCachePath = path.join(appBuildOutputPath, ".next/cache/fetch-cache");
|
|
116
|
+
if (fs.existsSync(fetchCachePath)) {
|
|
117
|
+
const fetchOutputPath = path.join(outputDir, "cache", "__fetch", buildId);
|
|
118
|
+
fs.mkdirSync(fetchOutputPath, { recursive: true });
|
|
119
|
+
fs.cpSync(fetchCachePath, fetchOutputPath, { recursive: true });
|
|
120
|
+
buildHelper.traverseFiles(fetchCachePath, () => true, ({ absolutePath, relativePath }) => {
|
|
121
|
+
const fileContent = fs.readFileSync(absolutePath, "utf8");
|
|
122
|
+
const fileData = JSON.parse(fileContent);
|
|
123
|
+
fileData?.tags?.forEach((tag) => {
|
|
124
|
+
metaFiles.push({
|
|
125
|
+
tag: { S: path.posix.join(buildId, tag) },
|
|
126
|
+
path: {
|
|
127
|
+
S: path.posix.join(buildId, relativePath),
|
|
128
|
+
},
|
|
129
|
+
revalidatedAt: { N: "1" },
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
112
134
|
if (!options.config.dangerous?.disableTagCache) {
|
|
113
|
-
// Generate dynamodb data
|
|
114
|
-
// We need to traverse the cache to find every .meta file
|
|
115
|
-
const metaFiles = [];
|
|
116
135
|
// Compute dynamodb cache data
|
|
117
136
|
// Traverse files inside cache to find all meta files and cache tags associated with them
|
|
118
137
|
buildHelper.traverseFiles(outputPath, ({ absolutePath }) => absolutePath.endsWith(".meta"), ({ absolutePath, relativePath }) => {
|
|
@@ -134,26 +153,6 @@ export function createCacheAssets(options) {
|
|
|
134
153
|
});
|
|
135
154
|
}
|
|
136
155
|
});
|
|
137
|
-
// Copy fetch-cache to cache folder
|
|
138
|
-
const fetchCachePath = path.join(appBuildOutputPath, ".next/cache/fetch-cache");
|
|
139
|
-
if (fs.existsSync(fetchCachePath)) {
|
|
140
|
-
const fetchOutputPath = path.join(outputDir, "cache", "__fetch", buildId);
|
|
141
|
-
fs.mkdirSync(fetchOutputPath, { recursive: true });
|
|
142
|
-
fs.cpSync(fetchCachePath, fetchOutputPath, { recursive: true });
|
|
143
|
-
buildHelper.traverseFiles(fetchCachePath, () => true, ({ absolutePath, relativePath }) => {
|
|
144
|
-
const fileContent = fs.readFileSync(absolutePath, "utf8");
|
|
145
|
-
const fileData = JSON.parse(fileContent);
|
|
146
|
-
fileData?.tags?.forEach((tag) => {
|
|
147
|
-
metaFiles.push({
|
|
148
|
-
tag: { S: path.posix.join(buildId, tag) },
|
|
149
|
-
path: {
|
|
150
|
-
S: path.posix.join(buildId, relativePath),
|
|
151
|
-
},
|
|
152
|
-
revalidatedAt: { N: "1" },
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
156
|
if (metaFiles.length > 0) {
|
|
158
157
|
useTagCache = true;
|
|
159
158
|
const providerPath = path.join(outputDir, "dynamodb-provider");
|
|
@@ -20,7 +20,7 @@ export async function createMiddleware(options, { forceOnlyBuildOnce = false } =
|
|
|
20
20
|
const outputPath = path.join(outputDir, "middleware");
|
|
21
21
|
fs.mkdirSync(outputPath, { recursive: true });
|
|
22
22
|
// Copy open-next.config.mjs
|
|
23
|
-
buildHelper.copyOpenNextConfig(options.buildDir, outputPath, config.middleware.override
|
|
23
|
+
buildHelper.copyOpenNextConfig(options.buildDir, outputPath, await buildHelper.isEdgeRuntime(config.middleware.override));
|
|
24
24
|
// Bundle middleware
|
|
25
25
|
await buildEdgeBundle({
|
|
26
26
|
entrypoint: path.join(options.openNextDistDir, "adapters", "middleware.js"),
|
|
@@ -77,7 +77,6 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
77
77
|
// `node_modules` inside `.next/standalone`, and others inside
|
|
78
78
|
// `.next/standalone/package/path` (ie. `.next`, `server.js`).
|
|
79
79
|
// We need to output the handler file inside the package path.
|
|
80
|
-
const isMonorepo = monorepoRoot !== appPath;
|
|
81
80
|
const packagePath = path.relative(monorepoRoot, appBuildOutputPath);
|
|
82
81
|
fs.mkdirSync(path.join(outputPath, packagePath), { recursive: true });
|
|
83
82
|
const ext = fnOptions.runtime === "deno" ? "mjs" : "cjs";
|
|
@@ -89,7 +88,7 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
89
88
|
const isBundled = fnOptions.experimentalBundledNextServer ?? false;
|
|
90
89
|
if (isBundled) {
|
|
91
90
|
await bundleNextServer(path.join(outputPath, packagePath), appPath, {
|
|
92
|
-
|
|
91
|
+
minify: options.minify,
|
|
93
92
|
});
|
|
94
93
|
}
|
|
95
94
|
// Copy middleware
|
|
@@ -166,6 +165,7 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
166
165
|
: {}),
|
|
167
166
|
},
|
|
168
167
|
}, options);
|
|
168
|
+
const isMonorepo = monorepoRoot !== appPath;
|
|
169
169
|
if (isMonorepo) {
|
|
170
170
|
addMonorepoEntrypoint(outputPath, packagePath);
|
|
171
171
|
}
|
|
@@ -208,7 +208,7 @@ function addMonorepoEntrypoint(outputPath, packagePath) {
|
|
|
208
208
|
// that re-exports the real handler.
|
|
209
209
|
// Always use posix path for import path
|
|
210
210
|
const packagePosixPath = packagePath.split(path.sep).join(path.posix.sep);
|
|
211
|
-
fs.writeFileSync(path.join(outputPath, "index.mjs"),
|
|
211
|
+
fs.writeFileSync(path.join(outputPath, "index.mjs"), `export * from "./${packagePosixPath}/index.mjs";`);
|
|
212
212
|
}
|
|
213
213
|
async function minifyServerBundle(outputDir) {
|
|
214
214
|
logger.info("Minimizing server function...");
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { MiddlewareInfo } from "../../types/next-types";
|
|
2
2
|
import type { IncludedConverter, IncludedOriginResolver, LazyLoadedOverride, OverrideOptions, SplittedFunctionOptions } from "../../types/open-next";
|
|
3
3
|
import type { OriginResolver } from "../../types/overrides.js";
|
|
4
|
-
import type
|
|
4
|
+
import { type BuildOptions } from "../helper.js";
|
|
5
|
+
type Override = OverrideOptions & {
|
|
6
|
+
originResolver?: LazyLoadedOverride<OriginResolver> | IncludedOriginResolver;
|
|
7
|
+
};
|
|
5
8
|
interface BuildEdgeBundleOptions {
|
|
6
9
|
middlewareInfo?: MiddlewareInfo;
|
|
7
10
|
entrypoint: string;
|
|
8
11
|
outfile: string;
|
|
9
12
|
options: BuildOptions;
|
|
10
|
-
overrides?:
|
|
11
|
-
originResolver?: LazyLoadedOverride<OriginResolver> | IncludedOriginResolver;
|
|
12
|
-
};
|
|
13
|
+
overrides?: Override;
|
|
13
14
|
defaultConverter?: IncludedConverter;
|
|
14
15
|
additionalInject?: string;
|
|
15
16
|
includeCache?: boolean;
|
|
@@ -6,11 +6,15 @@ import logger from "../../logger.js";
|
|
|
6
6
|
import { openNextEdgePlugins } from "../../plugins/edge.js";
|
|
7
7
|
import { openNextReplacementPlugin } from "../../plugins/replacement.js";
|
|
8
8
|
import { openNextResolvePlugin } from "../../plugins/resolve.js";
|
|
9
|
+
import { isEdgeRuntime } from "../helper.js";
|
|
9
10
|
import { copyOpenNextConfig, esbuildAsync } from "../helper.js";
|
|
10
11
|
export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }) {
|
|
11
|
-
const isInCloudfare =
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const isInCloudfare = await isEdgeRuntime(overrides);
|
|
13
|
+
function override(target) {
|
|
14
|
+
return typeof overrides?.[target] === "string"
|
|
15
|
+
? overrides[target]
|
|
16
|
+
: undefined;
|
|
17
|
+
}
|
|
14
18
|
await esbuildAsync({
|
|
15
19
|
entryPoints: [entrypoint],
|
|
16
20
|
bundle: true,
|
|
@@ -21,31 +25,17 @@ export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, opt
|
|
|
21
25
|
plugins: [
|
|
22
26
|
openNextResolvePlugin({
|
|
23
27
|
overrides: {
|
|
24
|
-
wrapper:
|
|
25
|
-
|
|
26
|
-
: "aws-lambda",
|
|
27
|
-
converter: typeof overrides?.converter === "string"
|
|
28
|
-
? overrides.converter
|
|
29
|
-
: defaultConverter,
|
|
28
|
+
wrapper: override("wrapper") ?? "aws-lambda",
|
|
29
|
+
converter: override("converter") ?? defaultConverter,
|
|
30
30
|
...(includeCache
|
|
31
31
|
? {
|
|
32
|
-
tagCache:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
incrementalCache: typeof overrides?.incrementalCache === "string"
|
|
36
|
-
? overrides.incrementalCache
|
|
37
|
-
: "s3-lite",
|
|
38
|
-
queue: typeof overrides?.queue === "string"
|
|
39
|
-
? overrides.queue
|
|
40
|
-
: "sqs-lite",
|
|
32
|
+
tagCache: override("tagCache") ?? "dynamodb-lite",
|
|
33
|
+
incrementalCache: override("incrementalCache") ?? "s3-lite",
|
|
34
|
+
queue: override("queue") ?? "sqs-lite",
|
|
41
35
|
}
|
|
42
36
|
: {}),
|
|
43
|
-
originResolver:
|
|
44
|
-
|
|
45
|
-
: "pattern-env",
|
|
46
|
-
proxyExternalRequest: typeof overrides?.proxyExternalRequest === "string"
|
|
47
|
-
? overrides.proxyExternalRequest
|
|
48
|
-
: "node",
|
|
37
|
+
originResolver: override("originResolver") ?? "pattern-env",
|
|
38
|
+
proxyExternalRequest: override("proxyExternalRequest") ?? "node",
|
|
49
39
|
},
|
|
50
40
|
fnName: name,
|
|
51
41
|
}),
|
|
@@ -76,20 +66,32 @@ globalThis.Buffer = Buffer;
|
|
|
76
66
|
|
|
77
67
|
import {AsyncLocalStorage} from "node:async_hooks";
|
|
78
68
|
globalThis.AsyncLocalStorage = AsyncLocalStorage;
|
|
69
|
+
|
|
70
|
+
${""
|
|
71
|
+
/**
|
|
72
|
+
* Next.js sets this `__import_unsupported` on `globalThis` (with `configurable: false`):
|
|
73
|
+
* https://github.com/vercel/next.js/blob/5b7833e3/packages/next/src/server/web/globals.ts#L94-L98
|
|
74
|
+
*
|
|
75
|
+
* It does so in both the middleware and the main server, so if the middleware runs in the same place
|
|
76
|
+
* as the main handler this code gets run twice triggering a runtime error.
|
|
77
|
+
*
|
|
78
|
+
* For this reason we need to patch `Object.defineProperty` to avoid this issue.
|
|
79
|
+
*/
|
|
80
|
+
}
|
|
81
|
+
const defaultDefineProperty = Object.defineProperty;
|
|
82
|
+
Object.defineProperty = function(o, p, a) {
|
|
83
|
+
if(p=== '__import_unsupported' && Boolean(globalThis.__import_unsupported)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
return defaultDefineProperty(o, p, a);
|
|
87
|
+
};
|
|
88
|
+
|
|
79
89
|
${isInCloudfare
|
|
80
90
|
? ""
|
|
81
91
|
: `
|
|
82
92
|
const require = (await import("node:module")).createRequire(import.meta.url);
|
|
83
93
|
const __filename = (await import("node:url")).fileURLToPath(import.meta.url);
|
|
84
94
|
const __dirname = (await import("node:path")).dirname(__filename);
|
|
85
|
-
|
|
86
|
-
const defaultDefineProperty = Object.defineProperty;
|
|
87
|
-
Object.defineProperty = function(o, p, a) {
|
|
88
|
-
if(p=== '__import_unsupported' && Boolean(globalThis.__import_unsupported)) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
return defaultDefineProperty(o, p, a);
|
|
92
|
-
};
|
|
93
95
|
`}
|
|
94
96
|
${additionalInject ?? ""}
|
|
95
97
|
`,
|
|
@@ -101,7 +103,7 @@ globalThis.AsyncLocalStorage = AsyncLocalStorage;
|
|
|
101
103
|
outfile,
|
|
102
104
|
allowOverwrite: true,
|
|
103
105
|
bundle: true,
|
|
104
|
-
minify:
|
|
106
|
+
minify: options.minify,
|
|
105
107
|
platform: "node",
|
|
106
108
|
format: "esm",
|
|
107
109
|
conditions: ["workerd", "worker", "browser"],
|
package/dist/build/helper.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BuildOptions as ESBuildOptions } from "esbuild";
|
|
2
|
-
import type { OpenNextConfig } from "../types/open-next.js";
|
|
2
|
+
import type { DefaultOverrideOptions, OpenNextConfig } from "../types/open-next.js";
|
|
3
3
|
export type BuildOptions = ReturnType<typeof normalizeOptions>;
|
|
4
4
|
export declare function normalizeOptions(config: OpenNextConfig, distDir: string, tempBuildDir: string): {
|
|
5
5
|
appBuildOutputPath: string;
|
|
@@ -9,6 +9,7 @@ export declare function normalizeOptions(config: OpenNextConfig, distDir: string
|
|
|
9
9
|
buildDir: string;
|
|
10
10
|
config: OpenNextConfig;
|
|
11
11
|
debug: boolean;
|
|
12
|
+
minify: boolean;
|
|
12
13
|
monorepoRoot: string;
|
|
13
14
|
nextVersion: string;
|
|
14
15
|
openNextVersion: string;
|
|
@@ -68,3 +69,7 @@ export declare function printOpenNextVersion(options: BuildOptions): void;
|
|
|
68
69
|
* the app directory, but the compiled config is in the root of the monorepo.
|
|
69
70
|
*/
|
|
70
71
|
export declare function initOutputDir(options: BuildOptions): void;
|
|
72
|
+
/**
|
|
73
|
+
* @returns Whether the edge runtime is used
|
|
74
|
+
*/
|
|
75
|
+
export declare function isEdgeRuntime(overrides: DefaultOverrideOptions | undefined): Promise<boolean | undefined>;
|
package/dist/build/helper.js
CHANGED
|
@@ -21,6 +21,7 @@ export function normalizeOptions(config, distDir, tempBuildDir) {
|
|
|
21
21
|
else {
|
|
22
22
|
appPackageJsonPath = findNextPackageJsonPath(appPath, monorepoRoot);
|
|
23
23
|
}
|
|
24
|
+
const debug = Boolean(process.env.OPEN_NEXT_DEBUG) ?? false;
|
|
24
25
|
return {
|
|
25
26
|
appBuildOutputPath: buildOutputPath,
|
|
26
27
|
appPackageJsonPath,
|
|
@@ -28,7 +29,9 @@ export function normalizeOptions(config, distDir, tempBuildDir) {
|
|
|
28
29
|
appPublicPath: path.join(appPath, "public"),
|
|
29
30
|
buildDir: path.join(outputDir, ".build"),
|
|
30
31
|
config,
|
|
31
|
-
debug
|
|
32
|
+
debug,
|
|
33
|
+
// Whether ESBuild should minify the code
|
|
34
|
+
minify: !debug,
|
|
32
35
|
monorepoRoot,
|
|
33
36
|
nextVersion: getNextVersion(appPath),
|
|
34
37
|
openNextVersion: getOpenNextVersion(),
|
|
@@ -68,13 +71,13 @@ function findNextPackageJsonPath(appPath, root) {
|
|
|
68
71
|
: path.join(root, "./package.json");
|
|
69
72
|
}
|
|
70
73
|
export function esbuildSync(esbuildOptions, options) {
|
|
71
|
-
const { openNextVersion, debug } = options;
|
|
74
|
+
const { openNextVersion, debug, minify } = options;
|
|
72
75
|
const result = buildSync({
|
|
73
76
|
target: "esnext",
|
|
74
77
|
format: "esm",
|
|
75
78
|
platform: "node",
|
|
76
79
|
bundle: true,
|
|
77
|
-
minify
|
|
80
|
+
minify,
|
|
78
81
|
mainFields: ["module", "main"],
|
|
79
82
|
sourcemap: debug ? "inline" : false,
|
|
80
83
|
sourcesContent: false,
|
|
@@ -95,13 +98,13 @@ export function esbuildSync(esbuildOptions, options) {
|
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
export async function esbuildAsync(esbuildOptions, options) {
|
|
98
|
-
const { openNextVersion, debug } = options;
|
|
101
|
+
const { openNextVersion, debug, minify } = options;
|
|
99
102
|
const result = await buildAsync({
|
|
100
103
|
target: "esnext",
|
|
101
104
|
format: "esm",
|
|
102
105
|
platform: "node",
|
|
103
106
|
bundle: true,
|
|
104
|
-
minify
|
|
107
|
+
minify,
|
|
105
108
|
mainFields: ["module", "main"],
|
|
106
109
|
sourcemap: debug ? "inline" : false,
|
|
107
110
|
sourcesContent: false,
|
|
@@ -261,3 +264,15 @@ export function initOutputDir(options) {
|
|
|
261
264
|
fs.mkdirSync(buildDir, { recursive: true });
|
|
262
265
|
fs.cpSync(options.tempBuildDir, buildDir, { recursive: true });
|
|
263
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* @returns Whether the edge runtime is used
|
|
269
|
+
*/
|
|
270
|
+
export async function isEdgeRuntime(overrides) {
|
|
271
|
+
if (!overrides?.wrapper) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
if (typeof overrides.wrapper === "string") {
|
|
275
|
+
return ["cloudflare-edge", "cloudflare"].includes(overrides.wrapper);
|
|
276
|
+
}
|
|
277
|
+
return (await overrides?.wrapper?.())?.edgeRuntime;
|
|
278
|
+
}
|