@opennextjs/aws 3.5.2 → 3.5.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.
- package/dist/adapters/config/util.d.ts +1 -0
- package/dist/adapters/config/util.js +5 -2
- package/dist/adapters/logger.js +1 -1
- package/dist/build/compileCache.js +1 -1
- package/dist/build/compileConfig.d.ts +6 -2
- package/dist/build/compileConfig.js +8 -7
- package/dist/build/constant.d.ts +1 -0
- package/dist/build/constant.js +1 -0
- package/dist/build/copyTracedFiles.d.ts +21 -1
- package/dist/build/copyTracedFiles.js +28 -5
- package/dist/build/createImageOptimizationBundle.js +1 -1
- package/dist/build/createMiddleware.js +1 -0
- package/dist/build/createServerBundle.d.ts +9 -1
- package/dist/build/createServerBundle.js +39 -15
- package/dist/build/edge/createEdgeBundle.d.ts +9 -2
- package/dist/build/edge/createEdgeBundle.js +28 -17
- package/dist/build/helper.d.ts +3 -2
- package/dist/build/helper.js +45 -20
- package/dist/build/patch/astCodePatcher.d.ts +58 -0
- package/dist/build/patch/astCodePatcher.js +76 -0
- package/dist/build/patch/codePatcher.d.ts +46 -0
- package/dist/build/patch/codePatcher.js +119 -0
- package/dist/build/patch/patchFetchCacheISR.d.ts +5 -0
- package/dist/build/patch/patchFetchCacheISR.js +102 -0
- package/dist/build/patch/patchFetchCacheWaitUntil.d.ts +3 -0
- package/dist/build/patch/patchFetchCacheWaitUntil.js +36 -0
- package/dist/build.js +1 -1
- package/dist/core/requestHandler.js +3 -1
- package/dist/core/routing/cacheInterceptor.js +6 -1
- package/dist/core/routing/middleware.js +12 -2
- package/dist/core/routing/queue.d.ts +1 -0
- package/dist/core/routing/queue.js +12 -8
- package/dist/core/routing/util.js +3 -3
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +2 -0
- package/dist/overrides/wrappers/express-dev.js +2 -0
- package/dist/overrides/wrappers/node.js +0 -1
- package/dist/plugins/content-updater.d.ts +48 -0
- package/dist/plugins/content-updater.js +65 -0
- package/dist/plugins/edge.d.ts +3 -3
- package/dist/plugins/edge.js +18 -8
- package/dist/types/next-types.d.ts +3 -0
- package/dist/types/overrides.d.ts +2 -0
- package/package.json +4 -2
|
@@ -2,6 +2,7 @@ import type { FunctionsConfigManifest, MiddlewareManifest, NextConfig, Prerender
|
|
|
2
2
|
import type { PublicFiles } from "../../build";
|
|
3
3
|
export declare function loadConfig(nextDir: string): NextConfig;
|
|
4
4
|
export declare function loadBuildId(nextDir: string): string;
|
|
5
|
+
export declare function loadPagesManifest(nextDir: string): any;
|
|
5
6
|
export declare function loadHtmlPages(nextDir: string): string[];
|
|
6
7
|
export declare function loadPublicAssets(openNextDir: string): PublicFiles;
|
|
7
8
|
export declare function loadRoutesManifest(nextDir: string): {
|
|
@@ -10,10 +10,13 @@ export function loadBuildId(nextDir) {
|
|
|
10
10
|
const filePath = path.join(nextDir, "BUILD_ID");
|
|
11
11
|
return fs.readFileSync(filePath, "utf-8").trim();
|
|
12
12
|
}
|
|
13
|
-
export function
|
|
13
|
+
export function loadPagesManifest(nextDir) {
|
|
14
14
|
const filePath = path.join(nextDir, "server/pages-manifest.json");
|
|
15
15
|
const json = fs.readFileSync(filePath, "utf-8");
|
|
16
|
-
return
|
|
16
|
+
return JSON.parse(json);
|
|
17
|
+
}
|
|
18
|
+
export function loadHtmlPages(nextDir) {
|
|
19
|
+
return Object.entries(loadPagesManifest(nextDir))
|
|
17
20
|
.filter(([_, value]) => value.endsWith(".html"))
|
|
18
21
|
.map(([key]) => key);
|
|
19
22
|
}
|
package/dist/adapters/logger.js
CHANGED
|
@@ -11,7 +11,7 @@ export function compileCache(options, format = "cjs") {
|
|
|
11
11
|
const { config } = options;
|
|
12
12
|
const ext = format === "cjs" ? "cjs" : "mjs";
|
|
13
13
|
const outFile = path.join(options.buildDir, `cache.${ext}`);
|
|
14
|
-
const isAfter15 = buildHelper.compareSemver(options.nextVersion, "15.0.0")
|
|
14
|
+
const isAfter15 = buildHelper.compareSemver(options.nextVersion, ">=", "15.0.0");
|
|
15
15
|
buildHelper.esbuildSync({
|
|
16
16
|
external: ["next", "styled-jsx", "react", "@aws-sdk/*"],
|
|
17
17
|
entryPoints: [path.join(options.openNextDistDir, "adapters", "cache.js")],
|
|
@@ -6,10 +6,14 @@ import type { OpenNextConfig } from "../types/open-next.js";
|
|
|
6
6
|
*
|
|
7
7
|
* @param baseDir Directory where to look for the configuration.
|
|
8
8
|
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
9
|
-
* @param nodeExternals Externals for the Node.js compilation.
|
|
9
|
+
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
10
|
+
* @param compileEdge Force compiling for the edge runtime when true
|
|
10
11
|
* @return The configuration and the build directory.
|
|
11
12
|
*/
|
|
12
|
-
export declare function compileOpenNextConfig(baseDir: string, openNextConfigPath?: string, nodeExternals?:
|
|
13
|
+
export declare function compileOpenNextConfig(baseDir: string, openNextConfigPath?: string, { nodeExternals, compileEdge }?: {
|
|
14
|
+
nodeExternals?: string | undefined;
|
|
15
|
+
compileEdge?: boolean | undefined;
|
|
16
|
+
}): Promise<{
|
|
13
17
|
config: OpenNextConfig;
|
|
14
18
|
buildDir: string;
|
|
15
19
|
}>;
|
|
@@ -11,13 +11,14 @@ import { validateConfig } from "./validateConfig.js";
|
|
|
11
11
|
*
|
|
12
12
|
* @param baseDir Directory where to look for the configuration.
|
|
13
13
|
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
14
|
-
* @param nodeExternals Externals for the Node.js compilation.
|
|
14
|
+
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
15
|
+
* @param compileEdge Force compiling for the edge runtime when true
|
|
15
16
|
* @return The configuration and the build directory.
|
|
16
17
|
*/
|
|
17
|
-
export async function compileOpenNextConfig(baseDir, openNextConfigPath, nodeExternals) {
|
|
18
|
+
export async function compileOpenNextConfig(baseDir, openNextConfigPath, { nodeExternals = "", compileEdge = false } = {}) {
|
|
18
19
|
const sourcePath = path.join(baseDir, openNextConfigPath ?? "open-next.config.ts");
|
|
19
20
|
const buildDir = fs.mkdtempSync(path.join(os.tmpdir(), "open-next-tmp"));
|
|
20
|
-
let configPath = compileOpenNextConfigNode(sourcePath, buildDir, nodeExternals
|
|
21
|
+
let configPath = compileOpenNextConfigNode(sourcePath, buildDir, nodeExternals.split(","));
|
|
21
22
|
// On Windows, we need to use file:// protocol to load the config file using import()
|
|
22
23
|
if (process.platform === "win32")
|
|
23
24
|
configPath = `file://${configPath}`;
|
|
@@ -31,12 +32,12 @@ export async function compileOpenNextConfig(baseDir, openNextConfigPath, nodeExt
|
|
|
31
32
|
// If it does, we need to compile it with the edge runtime
|
|
32
33
|
const usesEdgeRuntime = (config.middleware?.external && config.middleware.runtime !== "node") ||
|
|
33
34
|
Object.values(config.functions || {}).some((fn) => fn.runtime === "edge");
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
//Nothing to do here
|
|
35
|
+
if (usesEdgeRuntime || compileEdge) {
|
|
36
|
+
compileOpenNextConfigEdge(sourcePath, buildDir, config.edgeExternals ?? []);
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
|
|
39
|
+
// Skip compiling for the edge runtime.
|
|
40
|
+
logger.debug("No edge runtime found in the open-next.config.ts. Using default config.");
|
|
40
41
|
}
|
|
41
42
|
return { config, buildDir };
|
|
42
43
|
}
|
package/dist/build/constant.d.ts
CHANGED
package/dist/build/constant.js
CHANGED
|
@@ -6,5 +6,25 @@ interface CopyTracedFilesOptions {
|
|
|
6
6
|
bundledNextServer: boolean;
|
|
7
7
|
skipServerFiles?: boolean;
|
|
8
8
|
}
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function getManifests(nextDir: string): {
|
|
10
|
+
buildId: string;
|
|
11
|
+
config: import("../types/next-types.js").NextConfig;
|
|
12
|
+
prerenderManifest: import("../types/next-types.js").PrerenderManifest;
|
|
13
|
+
pagesManifest: any;
|
|
14
|
+
appPathsManifest: Record<string, string>;
|
|
15
|
+
middlewareManifest: import("../types/next-types.js").MiddlewareManifest;
|
|
16
|
+
functionsConfigManifest: import("../types/next-types.js").FunctionsConfigManifest;
|
|
17
|
+
};
|
|
18
|
+
export declare function copyTracedFiles({ buildOutputPath, packagePath, outputDir, routes, bundledNextServer, skipServerFiles, }: CopyTracedFilesOptions): Promise<{
|
|
19
|
+
tracedFiles: string[];
|
|
20
|
+
manifests: {
|
|
21
|
+
buildId: string;
|
|
22
|
+
config: import("../types/next-types.js").NextConfig;
|
|
23
|
+
prerenderManifest: import("../types/next-types.js").PrerenderManifest;
|
|
24
|
+
pagesManifest: any;
|
|
25
|
+
appPathsManifest: Record<string, string>;
|
|
26
|
+
middlewareManifest: import("../types/next-types.js").MiddlewareManifest;
|
|
27
|
+
functionsConfigManifest: import("../types/next-types.js").FunctionsConfigManifest;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
10
30
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import url from "node:url";
|
|
2
2
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { loadConfig, loadPrerenderManifest } from "../adapters/config/util.js";
|
|
4
|
+
import { loadAppPathsManifest, loadBuildId, loadConfig, loadFunctionsConfigManifest, loadMiddlewareManifest, loadPagesManifest, loadPrerenderManifest, } from "../adapters/config/util.js";
|
|
5
5
|
import { getCrossPlatformPathRegex } from "../utils/regex.js";
|
|
6
6
|
import logger from "../logger.js";
|
|
7
|
-
import { MIDDLEWARE_TRACE_FILE } from "./constant.js";
|
|
7
|
+
import { INSTRUMENTATION_TRACE_FILE, MIDDLEWARE_TRACE_FILE, } from "./constant.js";
|
|
8
8
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
9
9
|
//TODO: we need to figure which packages we could safely remove
|
|
10
10
|
const EXCLUDED_PACKAGES = [
|
|
@@ -22,6 +22,17 @@ function copyPatchFile(outputDir) {
|
|
|
22
22
|
const outputPatchFile = path.join(outputDir, "patchedAsyncStorage.cjs");
|
|
23
23
|
copyFileSync(patchFile, outputPatchFile);
|
|
24
24
|
}
|
|
25
|
+
export function getManifests(nextDir) {
|
|
26
|
+
return {
|
|
27
|
+
buildId: loadBuildId(nextDir),
|
|
28
|
+
config: loadConfig(nextDir),
|
|
29
|
+
prerenderManifest: loadPrerenderManifest(nextDir),
|
|
30
|
+
pagesManifest: loadPagesManifest(nextDir),
|
|
31
|
+
appPathsManifest: loadAppPathsManifest(nextDir),
|
|
32
|
+
middlewareManifest: loadMiddlewareManifest(nextDir),
|
|
33
|
+
functionsConfigManifest: loadFunctionsConfigManifest(nextDir),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
25
36
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
26
37
|
export async function copyTracedFiles({ buildOutputPath, packagePath, outputDir, routes, bundledNextServer, skipServerFiles, }) {
|
|
27
38
|
const tsStart = Date.now();
|
|
@@ -44,12 +55,12 @@ export async function copyTracedFiles({ buildOutputPath, packagePath, outputDir,
|
|
|
44
55
|
});
|
|
45
56
|
}
|
|
46
57
|
// create directory for pages
|
|
47
|
-
if (existsSync(path.join(
|
|
58
|
+
if (existsSync(path.join(standaloneNextDir, "server/pages"))) {
|
|
48
59
|
mkdirSync(path.join(outputNextDir, "server/pages"), {
|
|
49
60
|
recursive: true,
|
|
50
61
|
});
|
|
51
62
|
}
|
|
52
|
-
if (existsSync(path.join(
|
|
63
|
+
if (existsSync(path.join(standaloneNextDir, "server/app"))) {
|
|
53
64
|
mkdirSync(path.join(outputNextDir, "server/app"), {
|
|
54
65
|
recursive: true,
|
|
55
66
|
});
|
|
@@ -100,10 +111,18 @@ File ${fullFilePath} does not exist
|
|
|
100
111
|
}
|
|
101
112
|
}
|
|
102
113
|
};
|
|
114
|
+
// Check for instrumentation trace file
|
|
115
|
+
if (existsSync(path.join(dotNextDir, INSTRUMENTATION_TRACE_FILE))) {
|
|
116
|
+
// We still need to copy the nft.json file so that computeCopyFilesForPage doesn't throw
|
|
117
|
+
copyFileSync(path.join(dotNextDir, INSTRUMENTATION_TRACE_FILE), path.join(standaloneNextDir, INSTRUMENTATION_TRACE_FILE));
|
|
118
|
+
computeCopyFilesForPage("instrumentation");
|
|
119
|
+
logger.debug("Adding instrumentation trace files");
|
|
120
|
+
}
|
|
103
121
|
if (existsSync(path.join(dotNextDir, MIDDLEWARE_TRACE_FILE))) {
|
|
104
122
|
// We still need to copy the nft.json file so that computeCopyFilesForPage doesn't throw
|
|
105
123
|
copyFileSync(path.join(dotNextDir, MIDDLEWARE_TRACE_FILE), path.join(standaloneNextDir, MIDDLEWARE_TRACE_FILE));
|
|
106
124
|
computeCopyFilesForPage("middleware");
|
|
125
|
+
logger.debug("Adding node middleware trace files");
|
|
107
126
|
}
|
|
108
127
|
const hasPageDir = routes.some((route) => route.startsWith("pages/"));
|
|
109
128
|
const hasAppDir = routes.some((route) => route.startsWith("app/"));
|
|
@@ -191,7 +210,7 @@ File ${fullFilePath} does not exist
|
|
|
191
210
|
// Maybe even move this to s3 directly
|
|
192
211
|
if (hasPageDir) {
|
|
193
212
|
// First we get truly static files - i.e. pages without getStaticProps
|
|
194
|
-
const staticFiles = Object.values(
|
|
213
|
+
const staticFiles = Object.values(loadPagesManifest(standaloneNextDir));
|
|
195
214
|
// Then we need to get all fallback: true dynamic routes html
|
|
196
215
|
const prerenderManifest = loadPrerenderManifest(standaloneNextDir);
|
|
197
216
|
const config = loadConfig(standaloneNextDir);
|
|
@@ -213,4 +232,8 @@ File ${fullFilePath} does not exist
|
|
|
213
232
|
.forEach((file) => copyStaticFile(`server/${file}`));
|
|
214
233
|
}
|
|
215
234
|
logger.debug("copyTracedFiles:", Date.now() - tsStart, "ms");
|
|
235
|
+
return {
|
|
236
|
+
tracedFiles: Array.from(filesToCopy.values()),
|
|
237
|
+
manifests: getManifests(standaloneNextDir),
|
|
238
|
+
};
|
|
216
239
|
}
|
|
@@ -26,7 +26,7 @@ export async function createImageOptimizationBundle(options) {
|
|
|
26
26
|
},
|
|
27
27
|
}),
|
|
28
28
|
];
|
|
29
|
-
if (buildHelper.compareSemver(options.nextVersion, "14.1.1")
|
|
29
|
+
if (buildHelper.compareSemver(options.nextVersion, ">=", "14.1.1")) {
|
|
30
30
|
plugins.push(openNextReplacementPlugin({
|
|
31
31
|
name: "opennext-14.1.1-image-optimization",
|
|
32
32
|
target: getCrossPlatformPathRegex("plugins/image-optimization/image-optimization.js"),
|
|
@@ -58,6 +58,7 @@ export async function createMiddleware(options, { forceOnlyBuildOnce = false } =
|
|
|
58
58
|
outfile: path.join(options.buildDir, "middleware.mjs"),
|
|
59
59
|
middlewareInfo: edgeMiddlewareInfo,
|
|
60
60
|
options,
|
|
61
|
+
overrides: config.default.override,
|
|
61
62
|
onlyBuildOnce: true,
|
|
62
63
|
name: "middleware",
|
|
63
64
|
});
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
import { ContentUpdater } from "../plugins/content-updater.js";
|
|
1
3
|
import * as buildHelper from "./helper.js";
|
|
2
|
-
|
|
4
|
+
import { type CodePatcher } from "./patch/codePatcher.js";
|
|
5
|
+
interface CodeCustomization {
|
|
6
|
+
additionalCodePatches?: CodePatcher[];
|
|
7
|
+
additionalPlugins?: (contentUpdater: ContentUpdater) => Plugin[];
|
|
8
|
+
}
|
|
9
|
+
export declare function createServerBundle(options: buildHelper.BuildOptions, codeCustomization?: CodeCustomization): Promise<void>;
|
|
10
|
+
export {};
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { loadMiddlewareManifest } from "../adapters/config/util.js";
|
|
3
4
|
import logger from "../logger.js";
|
|
4
5
|
import { minifyAll } from "../minimize-js.js";
|
|
6
|
+
import { ContentUpdater } from "../plugins/content-updater.js";
|
|
5
7
|
import { openNextReplacementPlugin } from "../plugins/replacement.js";
|
|
6
8
|
import { openNextResolvePlugin } from "../plugins/resolve.js";
|
|
7
9
|
import { getCrossPlatformPathRegex } from "../utils/regex.js";
|
|
8
10
|
import { bundleNextServer } from "./bundleNextServer.js";
|
|
9
11
|
import { compileCache } from "./compileCache.js";
|
|
10
12
|
import { copyTracedFiles } from "./copyTracedFiles.js";
|
|
11
|
-
import { generateEdgeBundle } from "./edge/createEdgeBundle.js";
|
|
13
|
+
import { copyMiddlewareResources, generateEdgeBundle, } from "./edge/createEdgeBundle.js";
|
|
12
14
|
import * as buildHelper from "./helper.js";
|
|
13
15
|
import { installDependencies } from "./installDeps.js";
|
|
14
|
-
|
|
16
|
+
import { applyCodePatches } from "./patch/codePatcher.js";
|
|
17
|
+
import { patchFetchCacheForISR, patchUnstableCacheForISR, } from "./patch/patchFetchCacheISR.js";
|
|
18
|
+
import { patchFetchCacheSetMissingWaitUntil } from "./patch/patchFetchCacheWaitUntil.js";
|
|
19
|
+
export async function createServerBundle(options, codeCustomization) {
|
|
15
20
|
const { config } = options;
|
|
16
21
|
const foundRoutes = new Set();
|
|
17
22
|
// Get all functions to build
|
|
@@ -29,7 +34,7 @@ export async function createServerBundle(options) {
|
|
|
29
34
|
await generateEdgeBundle(name, options, fnOptions);
|
|
30
35
|
}
|
|
31
36
|
else {
|
|
32
|
-
await generateBundle(name, options, fnOptions);
|
|
37
|
+
await generateBundle(name, options, fnOptions, codeCustomization);
|
|
33
38
|
}
|
|
34
39
|
});
|
|
35
40
|
//TODO: throw an error if not all edge runtime routes has been bundled in a separate function
|
|
@@ -67,7 +72,7 @@ export async function createServerBundle(options) {
|
|
|
67
72
|
patterns: ["*"],
|
|
68
73
|
});
|
|
69
74
|
}
|
|
70
|
-
async function generateBundle(name, options, fnOptions) {
|
|
75
|
+
async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
71
76
|
const { appPath, appBuildOutputPath, config, outputDir, monorepoRoot } = options;
|
|
72
77
|
logger.info(`Building server function: ${name}...`);
|
|
73
78
|
// Create output folder
|
|
@@ -78,45 +83,60 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
78
83
|
// `.next/standalone/package/path` (ie. `.next`, `server.js`).
|
|
79
84
|
// We need to output the handler file inside the package path.
|
|
80
85
|
const packagePath = buildHelper.getPackagePath(options);
|
|
81
|
-
|
|
86
|
+
const outPackagePath = path.join(outputPath, packagePath);
|
|
87
|
+
fs.mkdirSync(outPackagePath, { recursive: true });
|
|
82
88
|
const ext = fnOptions.runtime === "deno" ? "mjs" : "cjs";
|
|
83
|
-
fs.copyFileSync(path.join(options.buildDir, `cache.${ext}`), path.join(
|
|
89
|
+
fs.copyFileSync(path.join(options.buildDir, `cache.${ext}`), path.join(outPackagePath, "cache.cjs"));
|
|
84
90
|
if (fnOptions.runtime === "deno") {
|
|
85
91
|
addDenoJson(outputPath, packagePath);
|
|
86
92
|
}
|
|
87
93
|
// Bundle next server if necessary
|
|
88
94
|
const isBundled = fnOptions.experimentalBundledNextServer ?? false;
|
|
89
95
|
if (isBundled) {
|
|
90
|
-
await bundleNextServer(
|
|
96
|
+
await bundleNextServer(outPackagePath, appPath, {
|
|
91
97
|
minify: options.minify,
|
|
92
98
|
});
|
|
93
99
|
}
|
|
94
100
|
// Copy middleware
|
|
95
101
|
if (!config.middleware?.external) {
|
|
96
|
-
fs.copyFileSync(path.join(options.buildDir, "middleware.mjs"), path.join(
|
|
102
|
+
fs.copyFileSync(path.join(options.buildDir, "middleware.mjs"), path.join(outPackagePath, "middleware.mjs"));
|
|
103
|
+
const middlewareManifest = loadMiddlewareManifest(path.join(options.appBuildOutputPath, ".next"));
|
|
104
|
+
copyMiddlewareResources(options, middlewareManifest.middleware["/"], outPackagePath);
|
|
97
105
|
}
|
|
98
106
|
// Copy open-next.config.mjs
|
|
99
|
-
buildHelper.copyOpenNextConfig(options.buildDir,
|
|
107
|
+
buildHelper.copyOpenNextConfig(options.buildDir, outPackagePath);
|
|
100
108
|
// Copy env files
|
|
101
109
|
buildHelper.copyEnvFile(appBuildOutputPath, packagePath, outputPath);
|
|
102
110
|
// Copy all necessary traced files
|
|
103
|
-
await copyTracedFiles({
|
|
111
|
+
const { tracedFiles, manifests } = await copyTracedFiles({
|
|
104
112
|
buildOutputPath: appBuildOutputPath,
|
|
105
113
|
packagePath,
|
|
106
114
|
outputDir: outputPath,
|
|
107
115
|
routes: fnOptions.routes ?? ["app/page.tsx"],
|
|
108
116
|
bundledNextServer: isBundled,
|
|
109
117
|
});
|
|
118
|
+
const additionalCodePatches = codeCustomization?.additionalCodePatches ?? [];
|
|
119
|
+
await applyCodePatches(options, tracedFiles, manifests, [
|
|
120
|
+
patchFetchCacheSetMissingWaitUntil,
|
|
121
|
+
patchFetchCacheForISR,
|
|
122
|
+
patchUnstableCacheForISR,
|
|
123
|
+
...additionalCodePatches,
|
|
124
|
+
]);
|
|
110
125
|
// Build Lambda code
|
|
111
126
|
// note: bundle in OpenNext package b/c the adapter relies on the
|
|
112
127
|
// "serverless-http" package which is not a dependency in user's
|
|
113
128
|
// Next.js app.
|
|
114
|
-
const disableNextPrebundledReact = buildHelper.compareSemver(options.nextVersion, "13.5.1")
|
|
115
|
-
buildHelper.compareSemver(options.nextVersion, "13.4.1")
|
|
129
|
+
const disableNextPrebundledReact = buildHelper.compareSemver(options.nextVersion, ">=", "13.5.1") ||
|
|
130
|
+
buildHelper.compareSemver(options.nextVersion, "<=", "13.4.1");
|
|
116
131
|
const overrides = fnOptions.override ?? {};
|
|
117
|
-
const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "13.4.13")
|
|
118
|
-
const isAfter141 = buildHelper.compareSemver(options.nextVersion, "14.1")
|
|
132
|
+
const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "<=", "13.4.13");
|
|
133
|
+
const isAfter141 = buildHelper.compareSemver(options.nextVersion, ">=", "14.1");
|
|
134
|
+
const isAfter142 = buildHelper.compareSemver(options.nextVersion, ">=", "14.2");
|
|
119
135
|
const disableRouting = isBefore13413 || config.middleware?.external;
|
|
136
|
+
const updater = new ContentUpdater(options);
|
|
137
|
+
const additionalPlugins = codeCustomization?.additionalPlugins
|
|
138
|
+
? codeCustomization.additionalPlugins(updater)
|
|
139
|
+
: [];
|
|
120
140
|
const plugins = [
|
|
121
141
|
openNextReplacementPlugin({
|
|
122
142
|
name: `requestHandlerOverride ${name}`,
|
|
@@ -124,6 +144,7 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
124
144
|
deletes: [
|
|
125
145
|
...(disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : []),
|
|
126
146
|
...(disableRouting ? ["withRouting"] : []),
|
|
147
|
+
...(isAfter142 ? ["patchAsyncStorage"] : []),
|
|
127
148
|
],
|
|
128
149
|
}),
|
|
129
150
|
openNextReplacementPlugin({
|
|
@@ -141,6 +162,9 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
141
162
|
fnName: name,
|
|
142
163
|
overrides,
|
|
143
164
|
}),
|
|
165
|
+
...additionalPlugins,
|
|
166
|
+
// The content updater plugin must be the last plugin
|
|
167
|
+
updater.plugin,
|
|
144
168
|
];
|
|
145
169
|
const outfileExt = fnOptions.runtime === "deno" ? "ts" : "mjs";
|
|
146
170
|
await buildHelper.esbuildAsync({
|
|
@@ -213,7 +237,7 @@ function addMonorepoEntrypoint(outputPath, packagePath) {
|
|
|
213
237
|
// that re-exports the real handler.
|
|
214
238
|
// Always use posix path for import path
|
|
215
239
|
const packagePosixPath = packagePath.split(path.sep).join(path.posix.sep);
|
|
216
|
-
fs.writeFileSync(path.join(outputPath, "index.mjs"), `export
|
|
240
|
+
fs.writeFileSync(path.join(outputPath, "index.mjs"), `export { handler } from "./${packagePosixPath}/index.mjs";`);
|
|
217
241
|
}
|
|
218
242
|
async function minifyServerBundle(outputDir) {
|
|
219
243
|
logger.info("Minimizing server function...");
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { type Plugin } from "esbuild";
|
|
1
2
|
import type { MiddlewareInfo } from "../../types/next-types";
|
|
2
3
|
import type { IncludedConverter, IncludedOriginResolver, LazyLoadedOverride, OverrideOptions, SplittedFunctionOptions } from "../../types/open-next";
|
|
3
4
|
import type { OriginResolver } from "../../types/overrides.js";
|
|
5
|
+
import { ContentUpdater } from "../../plugins/content-updater.js";
|
|
4
6
|
import { type BuildOptions } from "../helper.js";
|
|
5
7
|
type Override = OverrideOptions & {
|
|
6
8
|
originResolver?: LazyLoadedOverride<OriginResolver> | IncludedOriginResolver;
|
|
@@ -17,7 +19,12 @@ interface BuildEdgeBundleOptions {
|
|
|
17
19
|
additionalExternals?: string[];
|
|
18
20
|
onlyBuildOnce?: boolean;
|
|
19
21
|
name: string;
|
|
22
|
+
additionalPlugins?: (contentUpdater: ContentUpdater) => Plugin[];
|
|
20
23
|
}
|
|
21
|
-
export declare function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }: BuildEdgeBundleOptions): Promise<void>;
|
|
22
|
-
export declare function generateEdgeBundle(name: string, options: BuildOptions, fnOptions: SplittedFunctionOptions): Promise<void>;
|
|
24
|
+
export declare function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, additionalPlugins: additionalPluginsFn, }: BuildEdgeBundleOptions): Promise<void>;
|
|
25
|
+
export declare function generateEdgeBundle(name: string, options: BuildOptions, fnOptions: SplittedFunctionOptions, additionalPlugins?: (contentUpdater: ContentUpdater) => Plugin[]): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Copy wasm files and assets into the destDir.
|
|
28
|
+
*/
|
|
29
|
+
export declare function copyMiddlewareResources(options: BuildOptions, middlewareInfo: MiddlewareInfo | undefined, destDir: string): void;
|
|
23
30
|
export {};
|
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { build } from "esbuild";
|
|
5
5
|
import { loadMiddlewareManifest } from "../../adapters/config/util.js";
|
|
6
6
|
import logger from "../../logger.js";
|
|
7
|
+
import { ContentUpdater } from "../../plugins/content-updater.js";
|
|
7
8
|
import { openNextEdgePlugins } from "../../plugins/edge.js";
|
|
8
9
|
import { openNextExternalMiddlewarePlugin } from "../../plugins/externalMiddleware.js";
|
|
9
10
|
import { openNextReplacementPlugin } from "../../plugins/replacement.js";
|
|
@@ -11,13 +12,17 @@ import { openNextResolvePlugin } from "../../plugins/resolve.js";
|
|
|
11
12
|
import { getCrossPlatformPathRegex } from "../../utils/regex.js";
|
|
12
13
|
import { isEdgeRuntime } from "../helper.js";
|
|
13
14
|
import { copyOpenNextConfig, esbuildAsync } from "../helper.js";
|
|
14
|
-
export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }) {
|
|
15
|
-
const
|
|
15
|
+
export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, additionalPlugins: additionalPluginsFn, }) {
|
|
16
|
+
const isInCloudflare = await isEdgeRuntime(overrides);
|
|
16
17
|
function override(target) {
|
|
17
18
|
return typeof overrides?.[target] === "string"
|
|
18
19
|
? overrides[target]
|
|
19
20
|
: undefined;
|
|
20
21
|
}
|
|
22
|
+
const contentUpdater = new ContentUpdater(options);
|
|
23
|
+
const additionalPlugins = additionalPluginsFn
|
|
24
|
+
? additionalPluginsFn(contentUpdater)
|
|
25
|
+
: [];
|
|
21
26
|
await esbuildAsync({
|
|
22
27
|
entryPoints: [entrypoint],
|
|
23
28
|
bundle: true,
|
|
@@ -51,8 +56,11 @@ export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, opt
|
|
|
51
56
|
openNextEdgePlugins({
|
|
52
57
|
middlewareInfo,
|
|
53
58
|
nextDir: path.join(options.appBuildOutputPath, ".next"),
|
|
54
|
-
|
|
59
|
+
isInCloudflare,
|
|
55
60
|
}),
|
|
61
|
+
...additionalPlugins,
|
|
62
|
+
// The content updater plugin must be the last plugin
|
|
63
|
+
contentUpdater.plugin,
|
|
56
64
|
],
|
|
57
65
|
treeShaking: true,
|
|
58
66
|
alias: {
|
|
@@ -89,7 +97,7 @@ Object.defineProperty = function(o, p, a) {
|
|
|
89
97
|
return defaultDefineProperty(o, p, a);
|
|
90
98
|
};
|
|
91
99
|
|
|
92
|
-
${
|
|
100
|
+
${isInCloudflare
|
|
93
101
|
? ""
|
|
94
102
|
: `
|
|
95
103
|
const require = (await import("node:module")).createRequire(import.meta.url);
|
|
@@ -117,7 +125,7 @@ Object.defineProperty = function(o, p, a) {
|
|
|
117
125
|
});
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
|
-
export async function generateEdgeBundle(name, options, fnOptions) {
|
|
128
|
+
export async function generateEdgeBundle(name, options, fnOptions, additionalPlugins = () => []) {
|
|
121
129
|
logger.info(`Generating edge bundle for: ${name}`);
|
|
122
130
|
const buildOutputDotNextDir = path.join(options.appBuildOutputPath, ".next");
|
|
123
131
|
// Create output folder
|
|
@@ -133,18 +141,7 @@ export async function generateEdgeBundle(name, options, fnOptions) {
|
|
|
133
141
|
throw new Error("Only one function is supported for now");
|
|
134
142
|
}
|
|
135
143
|
const middlewareInfo = functions[0];
|
|
136
|
-
|
|
137
|
-
const wasmFiles = middlewareInfo.wasm;
|
|
138
|
-
mkdirSync(path.join(outputDir, "wasm"), { recursive: true });
|
|
139
|
-
for (const wasmFile of wasmFiles) {
|
|
140
|
-
fs.copyFileSync(path.join(buildOutputDotNextDir, wasmFile.filePath), path.join(outputDir, `wasm/${wasmFile.name}.wasm`));
|
|
141
|
-
}
|
|
142
|
-
// Copy assets
|
|
143
|
-
const assets = middlewareInfo.assets;
|
|
144
|
-
mkdirSync(path.join(outputDir, "assets"), { recursive: true });
|
|
145
|
-
for (const asset of assets) {
|
|
146
|
-
fs.copyFileSync(path.join(buildOutputDotNextDir, asset.filePath), path.join(outputDir, `assets/${asset.name}`));
|
|
147
|
-
}
|
|
144
|
+
copyMiddlewareResources(options, middlewareInfo, outputDir);
|
|
148
145
|
await buildEdgeBundle({
|
|
149
146
|
middlewareInfo,
|
|
150
147
|
entrypoint: path.join(options.openNextDistDir, "adapters/edge-adapter.js"),
|
|
@@ -153,5 +150,19 @@ export async function generateEdgeBundle(name, options, fnOptions) {
|
|
|
153
150
|
overrides: fnOptions.override,
|
|
154
151
|
additionalExternals: options.config.edgeExternals,
|
|
155
152
|
name,
|
|
153
|
+
additionalPlugins,
|
|
156
154
|
});
|
|
157
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Copy wasm files and assets into the destDir.
|
|
158
|
+
*/
|
|
159
|
+
export function copyMiddlewareResources(options, middlewareInfo, destDir) {
|
|
160
|
+
mkdirSync(path.join(destDir, "wasm"), { recursive: true });
|
|
161
|
+
for (const file of middlewareInfo?.wasm ?? []) {
|
|
162
|
+
fs.copyFileSync(path.join(options.appBuildOutputPath, ".next", file.filePath), path.join(destDir, `wasm/${file.name}.wasm`));
|
|
163
|
+
}
|
|
164
|
+
mkdirSync(path.join(destDir, "assets"), { recursive: true });
|
|
165
|
+
for (const file of middlewareInfo?.assets ?? []) {
|
|
166
|
+
fs.copyFileSync(path.join(options.appBuildOutputPath, ".next", file.filePath), path.join(destDir, `assets/${file.name}`));
|
|
167
|
+
}
|
|
168
|
+
}
|
package/dist/build/helper.d.ts
CHANGED
|
@@ -51,15 +51,16 @@ export declare function getHtmlPages(dotNextPath: string): Set<string>;
|
|
|
51
51
|
export declare function getBuildId(options: BuildOptions): string;
|
|
52
52
|
export declare function getOpenNextVersion(): string;
|
|
53
53
|
export declare function getNextVersion(appPath: string): string;
|
|
54
|
+
export type SemverOp = "=" | ">=" | "<=" | ">" | "<";
|
|
54
55
|
/**
|
|
55
56
|
* Compare two semver versions.
|
|
56
57
|
*
|
|
57
58
|
* @param v1 - First version. Can be "latest", otherwise it should be a valid semver version in the format of `major.minor.patch`. Usually is the next version from the package.json without canary suffix. If minor or patch are missing, they are considered 0.
|
|
58
59
|
* @param v2 - Second version. Should not be "latest", it should be a valid semver version in the format of `major.minor.patch`. If minor or patch are missing, they are considered 0.
|
|
59
60
|
* @example
|
|
60
|
-
*
|
|
61
|
+
* compareSemver("2.0.0", ">=", "1.0.0") === true
|
|
61
62
|
*/
|
|
62
|
-
export declare function compareSemver(v1: string, v2: string):
|
|
63
|
+
export declare function compareSemver(v1: string, operator: SemverOp, v2: string): boolean;
|
|
63
64
|
export declare function copyOpenNextConfig(inputDir: string, outputDir: string, isEdge?: boolean): void;
|
|
64
65
|
export declare function copyEnvFile(appPath: string, packagePath: string, outputPath: string): void;
|
|
65
66
|
/**
|
package/dist/build/helper.js
CHANGED
|
@@ -213,29 +213,54 @@ export function getNextVersion(appPath) {
|
|
|
213
213
|
* @param v1 - First version. Can be "latest", otherwise it should be a valid semver version in the format of `major.minor.patch`. Usually is the next version from the package.json without canary suffix. If minor or patch are missing, they are considered 0.
|
|
214
214
|
* @param v2 - Second version. Should not be "latest", it should be a valid semver version in the format of `major.minor.patch`. If minor or patch are missing, they are considered 0.
|
|
215
215
|
* @example
|
|
216
|
-
*
|
|
216
|
+
* compareSemver("2.0.0", ">=", "1.0.0") === true
|
|
217
217
|
*/
|
|
218
|
-
export function compareSemver(v1, v2) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if
|
|
222
|
-
|
|
223
|
-
|
|
218
|
+
export function compareSemver(v1, operator, v2) {
|
|
219
|
+
// - = 0 when versions are equal
|
|
220
|
+
// - > 0 if v1 > v2
|
|
221
|
+
// - < 0 if v2 > v1
|
|
222
|
+
let versionDiff = 0;
|
|
223
|
+
if (v1 === "latest") {
|
|
224
|
+
versionDiff = 1;
|
|
224
225
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
else {
|
|
227
|
+
if (/^[^\d]/.test(v1)) {
|
|
228
|
+
// biome-ignore lint/style/noParameterAssign:
|
|
229
|
+
v1 = v1.substring(1);
|
|
230
|
+
}
|
|
231
|
+
if (/^[^\d]/.test(v2)) {
|
|
232
|
+
// biome-ignore lint/style/noParameterAssign:
|
|
233
|
+
v2 = v2.substring(1);
|
|
234
|
+
}
|
|
235
|
+
const [major1, minor1 = 0, patch1 = 0] = v1.split(".").map(Number);
|
|
236
|
+
const [major2, minor2 = 0, patch2 = 0] = v2.split(".").map(Number);
|
|
237
|
+
if (Number.isNaN(major1) || Number.isNaN(major2)) {
|
|
238
|
+
throw new Error("The major version is required.");
|
|
239
|
+
}
|
|
240
|
+
if (major1 !== major2) {
|
|
241
|
+
versionDiff = major1 - major2;
|
|
242
|
+
}
|
|
243
|
+
else if (minor1 !== minor2) {
|
|
244
|
+
versionDiff = minor1 - minor2;
|
|
245
|
+
}
|
|
246
|
+
else if (patch1 !== patch2) {
|
|
247
|
+
versionDiff = patch1 - patch2;
|
|
248
|
+
}
|
|
228
249
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
250
|
+
switch (operator) {
|
|
251
|
+
case "=":
|
|
252
|
+
return versionDiff === 0;
|
|
253
|
+
case ">=":
|
|
254
|
+
return versionDiff >= 0;
|
|
255
|
+
case "<=":
|
|
256
|
+
return versionDiff <= 0;
|
|
257
|
+
case ">":
|
|
258
|
+
return versionDiff > 0;
|
|
259
|
+
case "<":
|
|
260
|
+
return versionDiff < 0;
|
|
261
|
+
default:
|
|
262
|
+
throw new Error(`Unsupported operator: ${operator}`);
|
|
233
263
|
}
|
|
234
|
-
if (major1 !== major2)
|
|
235
|
-
return major1 - major2;
|
|
236
|
-
if (minor1 !== minor2)
|
|
237
|
-
return minor1 - minor2;
|
|
238
|
-
return patch1 - patch2;
|
|
239
264
|
}
|
|
240
265
|
export function copyOpenNextConfig(inputDir, outputDir, isEdge = false) {
|
|
241
266
|
// Copy open-next.config.mjs
|
|
@@ -292,7 +317,7 @@ export async function isEdgeRuntime(overrides) {
|
|
|
292
317
|
return false;
|
|
293
318
|
}
|
|
294
319
|
if (typeof overrides.wrapper === "string") {
|
|
295
|
-
return ["cloudflare-edge", "cloudflare"].includes(overrides.wrapper);
|
|
320
|
+
return ["cloudflare-edge", "cloudflare", "cloudflare-node"].includes(overrides.wrapper);
|
|
296
321
|
}
|
|
297
322
|
return (await overrides?.wrapper?.())?.edgeRuntime;
|
|
298
323
|
}
|