@opennextjs/aws 3.7.0 → 3.7.2
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/middleware.js +9 -7
- package/dist/build/createServerBundle.js +2 -0
- package/dist/build/generateOutput.js +4 -2
- package/dist/build/installDeps.js +22 -0
- package/dist/build/patch/codePatcher.d.ts +19 -12
- package/dist/build/patch/codePatcher.js +21 -38
- package/dist/build/patch/patches/patchBackgroundRevalidation.d.ts +2 -4
- package/dist/build/patch/patches/patchBackgroundRevalidation.js +2 -4
- package/dist/build/patch/patches/patchEnvVar.js +9 -15
- package/dist/build/patch/patches/patchFetchCacheISR.d.ts +3 -3
- package/dist/build/patch/patches/patchFetchCacheISR.js +13 -19
- package/dist/build/patch/patches/patchFetchCacheWaitUntil.js +3 -5
- package/dist/build/patch/patches/patchNextServer.js +18 -30
- package/dist/build/validateConfig.js +3 -1
- package/dist/core/createGenericHandler.js +4 -2
- package/dist/core/requestHandler.js +13 -2
- package/dist/core/resolve.d.ts +2 -2
- package/dist/core/routing/cacheInterceptor.js +8 -0
- package/dist/plugins/content-updater.d.ts +4 -3
- package/dist/plugins/content-updater.js +4 -5
- package/dist/types/open-next.d.ts +44 -30
- package/package.json +1 -1
|
@@ -7,14 +7,16 @@ import routingHandler, { INTERNAL_EVENT_REQUEST_ID, INTERNAL_HEADER_INITIAL_URL,
|
|
|
7
7
|
globalThis.internalFetch = fetch;
|
|
8
8
|
globalThis.__openNextAls = new AsyncLocalStorage();
|
|
9
9
|
const defaultHandler = async (internalEvent, options) => {
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
10
|
+
// We know that the middleware is external when this adapter is used
|
|
11
|
+
const middlewareConfig = globalThis.openNextConfig
|
|
12
|
+
.middleware;
|
|
13
|
+
const originResolver = await resolveOriginResolver(middlewareConfig?.originResolver);
|
|
14
|
+
const externalRequestProxy = await resolveProxyRequest(middlewareConfig?.override?.proxyExternalRequest);
|
|
15
|
+
const assetResolver = await resolveAssetResolver(middlewareConfig?.assetResolver);
|
|
14
16
|
//#override includeCacheInMiddleware
|
|
15
|
-
globalThis.tagCache = await resolveTagCache(
|
|
16
|
-
globalThis.queue = await resolveQueue(
|
|
17
|
-
globalThis.incrementalCache = await resolveIncrementalCache(
|
|
17
|
+
globalThis.tagCache = await resolveTagCache(middlewareConfig?.override?.tagCache);
|
|
18
|
+
globalThis.queue = await resolveQueue(middlewareConfig?.override?.queue);
|
|
19
|
+
globalThis.incrementalCache = await resolveIncrementalCache(middlewareConfig?.override?.incrementalCache);
|
|
18
20
|
//#endOverride
|
|
19
21
|
const requestId = Math.random().toString(36);
|
|
20
22
|
// We run everything in the async local storage context so that it is available in the external middleware
|
|
@@ -139,6 +139,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
139
139
|
const isAfter141 = buildHelper.compareSemver(options.nextVersion, ">=", "14.1");
|
|
140
140
|
const isAfter142 = buildHelper.compareSemver(options.nextVersion, ">=", "14.2");
|
|
141
141
|
const isAfter152 = buildHelper.compareSemver(options.nextVersion, ">=", "15.2.0");
|
|
142
|
+
const isAfter154 = buildHelper.compareSemver(options.nextVersion, ">=", "15.4.0");
|
|
142
143
|
const disableRouting = isBefore13413 || config.middleware?.external;
|
|
143
144
|
const updater = new ContentUpdater(options);
|
|
144
145
|
const additionalPlugins = codeCustomization?.additionalPlugins
|
|
@@ -153,6 +154,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
153
154
|
...(disableRouting ? ["withRouting"] : []),
|
|
154
155
|
...(isAfter142 ? ["patchAsyncStorage"] : []),
|
|
155
156
|
...(isAfter141 ? ["appendPrefetch"] : []),
|
|
157
|
+
...(isAfter154 ? [] : ["setInitialURL"]),
|
|
156
158
|
],
|
|
157
159
|
}),
|
|
158
160
|
openNextReplacementPlugin({
|
|
@@ -61,11 +61,13 @@ export async function generateOutput(options) {
|
|
|
61
61
|
const edgeFunctions = {};
|
|
62
62
|
const isExternalMiddleware = config.middleware?.external ?? false;
|
|
63
63
|
if (isExternalMiddleware) {
|
|
64
|
+
const middlewareConfig = options.config
|
|
65
|
+
.middleware;
|
|
64
66
|
edgeFunctions.middleware = {
|
|
65
67
|
bundle: ".open-next/middleware",
|
|
66
68
|
handler: "handler.handler",
|
|
67
|
-
pathResolver: await extractOverrideName("pattern-env",
|
|
68
|
-
...(await extractOverrideFn(
|
|
69
|
+
pathResolver: await extractOverrideName("pattern-env", middlewareConfig.originResolver),
|
|
70
|
+
...(await extractOverrideFn(middlewareConfig.override)),
|
|
69
71
|
};
|
|
70
72
|
}
|
|
71
73
|
// Add edge functions
|
|
@@ -35,6 +35,28 @@ export function installDependencies(outputDir, installOptions) {
|
|
|
35
35
|
});
|
|
36
36
|
// Copy the node_modules to the outputDir
|
|
37
37
|
fs.cpSync(path.join(tempInstallDir, "node_modules"), path.join(outputDir, "node_modules"), { recursive: true, force: true, dereference: true });
|
|
38
|
+
// This is a workaround for Node `22.17.0` and `22.17.1`
|
|
39
|
+
// https://github.com/nodejs/node/issues/59168
|
|
40
|
+
const nodeVersion = process.version;
|
|
41
|
+
if (nodeVersion === "v22.17.0" || nodeVersion === "v22.17.1") {
|
|
42
|
+
const tempBinDir = path.join(tempInstallDir, "node_modules", ".bin");
|
|
43
|
+
const outputBinDir = path.join(outputDir, "node_modules", ".bin");
|
|
44
|
+
for (const fileName of fs.readdirSync(tempBinDir)) {
|
|
45
|
+
const symlinkPath = path.join(tempBinDir, fileName);
|
|
46
|
+
const stat = fs.lstatSync(symlinkPath);
|
|
47
|
+
if (stat.isSymbolicLink()) {
|
|
48
|
+
const linkTarget = fs.readlinkSync(symlinkPath);
|
|
49
|
+
const realFilePath = path.resolve(tempBinDir, linkTarget);
|
|
50
|
+
const outputFilePath = path.join(outputBinDir, fileName);
|
|
51
|
+
if (fs.existsSync(outputFilePath)) {
|
|
52
|
+
fs.unlinkSync(outputFilePath);
|
|
53
|
+
}
|
|
54
|
+
fs.copyFileSync(realFilePath, outputFilePath);
|
|
55
|
+
fs.chmodSync(outputFilePath, "755");
|
|
56
|
+
logger.debug(`Replaced symlink ${fileName} with actual file`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
38
60
|
// Cleanup tempDir
|
|
39
61
|
fs.rmSync(tempInstallDir, { recursive: true, force: true });
|
|
40
62
|
logger.info(`Dependencies installed for ${name}`);
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { getManifests } from "../copyTracedFiles.js";
|
|
2
2
|
import * as buildHelper from "../helper.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
3
|
+
/**
|
|
4
|
+
* Accepted formats:
|
|
5
|
+
* - `">=16.0.0"`
|
|
6
|
+
* - `"<=16.0.0"`
|
|
7
|
+
* - `">=16.0.0 <=17.0.0"`
|
|
8
|
+
*
|
|
9
|
+
* **Be careful with spaces**
|
|
10
|
+
*/
|
|
11
|
+
export type Versions = `>=${number}.${number}.${number} <=${number}.${number}.${number}` | `>=${number}.${number}.${number}` | `<=${number}.${number}.${number}`;
|
|
13
12
|
export type PatchCodeFn = (args: {
|
|
14
13
|
/**
|
|
15
14
|
* The code of the file that needs to be patched
|
|
@@ -32,15 +31,23 @@ interface IndividualPatch {
|
|
|
32
31
|
pathFilter: RegExp;
|
|
33
32
|
contentFilter?: RegExp;
|
|
34
33
|
patchCode: PatchCodeFn;
|
|
34
|
+
versions?: Versions;
|
|
35
35
|
}
|
|
36
36
|
export interface CodePatcher {
|
|
37
37
|
name: string;
|
|
38
|
-
patches: IndividualPatch
|
|
38
|
+
patches: IndividualPatch[];
|
|
39
39
|
}
|
|
40
40
|
export declare function parseVersions(versions?: Versions): {
|
|
41
41
|
before?: string;
|
|
42
42
|
after?: string;
|
|
43
43
|
};
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Check whether the version is in the range
|
|
46
|
+
*
|
|
47
|
+
* @param version A semver version
|
|
48
|
+
* @param versionRange A version range
|
|
49
|
+
* @returns whether the version satisfies the range
|
|
50
|
+
*/
|
|
51
|
+
export declare function isVersionInRange(version: string, versionRange?: Versions): boolean;
|
|
45
52
|
export declare function applyCodePatches(buildOptions: buildHelper.BuildOptions, tracedFiles: string[], manifests: ReturnType<typeof getManifests>, codePatcher: CodePatcher[]): Promise<void>;
|
|
46
53
|
export {};
|
|
@@ -39,50 +39,33 @@ export function parseVersions(versions) {
|
|
|
39
39
|
after,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
// before only
|
|
60
|
-
if (before) {
|
|
61
|
-
if (buildHelper.compareSemver(version, "<=", before)) {
|
|
62
|
-
result.push(field.field);
|
|
63
|
-
}
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
// after only
|
|
67
|
-
if (after) {
|
|
68
|
-
if (buildHelper.compareSemver(version, ">=", after)) {
|
|
69
|
-
result.push(field.field);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
42
|
+
/**
|
|
43
|
+
* Check whether the version is in the range
|
|
44
|
+
*
|
|
45
|
+
* @param version A semver version
|
|
46
|
+
* @param versionRange A version range
|
|
47
|
+
* @returns whether the version satisfies the range
|
|
48
|
+
*/
|
|
49
|
+
export function isVersionInRange(version, versionRange) {
|
|
50
|
+
const { before, after } = parseVersions(versionRange);
|
|
51
|
+
let inRange = true;
|
|
52
|
+
if (before) {
|
|
53
|
+
inRange &&= buildHelper.compareSemver(version, "<=", before);
|
|
54
|
+
}
|
|
55
|
+
if (after) {
|
|
56
|
+
inRange &&= buildHelper.compareSemver(version, ">=", after);
|
|
72
57
|
}
|
|
73
|
-
return
|
|
58
|
+
return inRange;
|
|
74
59
|
}
|
|
75
60
|
export async function applyCodePatches(buildOptions, tracedFiles, manifests, codePatcher) {
|
|
76
|
-
const nextVersion = buildOptions.nextVersion;
|
|
77
61
|
logger.time("Applying code patches");
|
|
78
62
|
// We first filter against the version
|
|
79
63
|
// We also flatten the array of patches so that we get both the name and all the necessary patches
|
|
80
|
-
const patchesToApply = codePatcher.flatMap(({ name, patches }) =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
patch,
|
|
84
|
-
|
|
85
|
-
: [{ name, patch: patches }]);
|
|
64
|
+
const patchesToApply = codePatcher.flatMap(({ name, patches }) => {
|
|
65
|
+
return patches
|
|
66
|
+
.filter(({ versions }) => isVersionInRange(buildOptions.nextVersion, versions))
|
|
67
|
+
.map((patch) => ({ patch, name }));
|
|
68
|
+
});
|
|
86
69
|
await Promise.all(tracedFiles.map(async (filePath) => {
|
|
87
70
|
// We check the filename against the filter to see if we should apply the patch
|
|
88
71
|
const patchMatchingPath = patchesToApply.filter(({ patch }) => {
|
|
@@ -3,9 +3,7 @@ export declare const patchBackgroundRevalidation: {
|
|
|
3
3
|
name: string;
|
|
4
4
|
patches: {
|
|
5
5
|
versions: ">=14.1.0";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
patchCode: import("../codePatcher.js").PatchCodeFn;
|
|
9
|
-
};
|
|
6
|
+
pathFilter: RegExp;
|
|
7
|
+
patchCode: import("../codePatcher.js").PatchCodeFn;
|
|
10
8
|
}[];
|
|
11
9
|
};
|
|
@@ -18,10 +18,8 @@ export const patchBackgroundRevalidation = {
|
|
|
18
18
|
{
|
|
19
19
|
// TODO: test for earlier versions of Next
|
|
20
20
|
versions: ">=14.1.0",
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
patchCode: createPatchCode(rule),
|
|
24
|
-
},
|
|
21
|
+
pathFilter: getCrossPlatformPathRegex("server/response-cache/index.js"),
|
|
22
|
+
patchCode: createPatchCode(rule),
|
|
25
23
|
},
|
|
26
24
|
],
|
|
27
25
|
};
|
|
@@ -24,29 +24,23 @@ export const patchEnvVars = {
|
|
|
24
24
|
// This patch will set the `NEXT_RUNTIME` env var to "node" to avoid loading unnecessary edge deps at runtime
|
|
25
25
|
{
|
|
26
26
|
versions: ">=15.0.0",
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
patchCode: createPatchCode(envVarRuleCreator("NEXT_RUNTIME", '"node"')),
|
|
31
|
-
},
|
|
27
|
+
pathFilter: /module\.compiled\.js$/,
|
|
28
|
+
contentFilter: /process\.env\.NEXT_RUNTIME/,
|
|
29
|
+
patchCode: createPatchCode(envVarRuleCreator("NEXT_RUNTIME", '"node"')),
|
|
32
30
|
},
|
|
33
31
|
// This patch will set `NODE_ENV` to production to avoid loading unnecessary dev deps at runtime
|
|
34
32
|
{
|
|
35
33
|
versions: ">=15.0.0",
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
patchCode: createPatchCode(envVarRuleCreator("NODE_ENV", '"production"')),
|
|
40
|
-
},
|
|
34
|
+
pathFilter: /(module\.compiled|react\/index|react\/jsx-runtime|react-dom\/index)\.js$/,
|
|
35
|
+
contentFilter: /process\.env\.NODE_ENV/,
|
|
36
|
+
patchCode: createPatchCode(envVarRuleCreator("NODE_ENV", '"production"')),
|
|
41
37
|
},
|
|
42
38
|
// This patch will set `TURBOPACK` env to false to avoid loading turbopack related deps at runtime
|
|
43
39
|
{
|
|
44
40
|
versions: ">=15.0.0",
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
patchCode: createPatchCode(envVarRuleCreator("TURBOPACK", "false")),
|
|
49
|
-
},
|
|
41
|
+
pathFilter: /module\.compiled\.js$/,
|
|
42
|
+
contentFilter: /process\.env\.TURBOPACK/,
|
|
43
|
+
patchCode: createPatchCode(envVarRuleCreator("TURBOPACK", "false")),
|
|
50
44
|
},
|
|
51
45
|
],
|
|
52
46
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CodePatcher } from "../codePatcher.js";
|
|
2
|
-
export declare const fetchRule = "\nrule:\n kind: member_expression\n pattern: $WORK_STORE.isOnDemandRevalidate\n inside:\n kind: ternary_expression\n all:\n - has: {kind: 'null'}\n - has
|
|
3
|
-
export declare const unstable_cacheRule = "\nrule:\n kind: member_expression\n pattern: $STORE_OR_CACHE.isOnDemandRevalidate\n inside:\n kind: if_statement\n stopBy: end\n has:\n kind: statement_block\n has:\n kind: variable_declarator\n has
|
|
4
|
-
export declare const useCacheRule = "\nrule:\n kind: member_expression\n pattern: $STORE_OR_CACHE.isOnDemandRevalidate\n inside:\n kind: binary_expression\n has
|
|
2
|
+
export declare const fetchRule = "\nrule:\n kind: member_expression\n pattern: $WORK_STORE.isOnDemandRevalidate\n inside:\n kind: ternary_expression\n all:\n - has: {kind: 'null'}\n - has:\n kind: await_expression\n has:\n kind: call_expression\n all:\n - has:\n kind: member_expression\n has:\n kind: property_identifier\n field: property\n regex: get\n - has:\n kind: arguments\n has:\n kind: object\n has:\n kind: pair\n all:\n - has:\n kind: property_identifier\n field: key\n regex: softTags\n inside:\n kind: variable_declarator\n\nfix:\n ($WORK_STORE.isOnDemandRevalidate && !globalThis.__openNextAls?.getStore()?.isISRRevalidation)\n";
|
|
3
|
+
export declare const unstable_cacheRule = "\nrule:\n kind: member_expression\n pattern: $STORE_OR_CACHE.isOnDemandRevalidate\n inside:\n kind: if_statement\n stopBy: end\n has:\n kind: statement_block\n has:\n kind: variable_declarator\n has:\n kind: await_expression\n has:\n kind: call_expression\n all:\n - has:\n kind: member_expression\n has:\n kind: property_identifier\n field: property\n regex: get\n - has:\n kind: arguments\n has:\n kind: object\n has:\n kind: pair\n all:\n - has:\n kind: property_identifier\n field: key\n regex: softTags\n stopBy: end\nfix:\n ($STORE_OR_CACHE.isOnDemandRevalidate && !globalThis.__openNextAls?.getStore()?.isISRRevalidation)\n";
|
|
4
|
+
export declare const useCacheRule = "\nrule:\n kind: member_expression\n pattern: $STORE_OR_CACHE.isOnDemandRevalidate\n inside:\n kind: binary_expression\n has:\n kind: member_expression\n pattern: $STORE_OR_CACHE.isDraftMode\n inside:\n kind: if_statement\n stopBy: end\n has:\n kind: return_statement\n any:\n - has:\n kind: 'true'\n - has:\n regex: '!0'\n stopBy: end\nfix:\n '($STORE_OR_CACHE.isOnDemandRevalidate && !globalThis.__openNextAls?.getStore()?.isISRRevalidation)'";
|
|
5
5
|
export declare const patchFetchCacheForISR: CodePatcher;
|
|
6
6
|
export declare const patchUnstableCacheForISR: CodePatcher;
|
|
7
7
|
export declare const patchUseCacheForISR: CodePatcher;
|
|
@@ -9,7 +9,7 @@ rule:
|
|
|
9
9
|
kind: ternary_expression
|
|
10
10
|
all:
|
|
11
11
|
- has: {kind: 'null'}
|
|
12
|
-
- has:
|
|
12
|
+
- has:
|
|
13
13
|
kind: await_expression
|
|
14
14
|
has:
|
|
15
15
|
kind: call_expression
|
|
@@ -48,7 +48,7 @@ rule:
|
|
|
48
48
|
kind: statement_block
|
|
49
49
|
has:
|
|
50
50
|
kind: variable_declarator
|
|
51
|
-
has:
|
|
51
|
+
has:
|
|
52
52
|
kind: await_expression
|
|
53
53
|
has:
|
|
54
54
|
kind: call_expression
|
|
@@ -80,13 +80,13 @@ rule:
|
|
|
80
80
|
pattern: $STORE_OR_CACHE.isOnDemandRevalidate
|
|
81
81
|
inside:
|
|
82
82
|
kind: binary_expression
|
|
83
|
-
has:
|
|
83
|
+
has:
|
|
84
84
|
kind: member_expression
|
|
85
85
|
pattern: $STORE_OR_CACHE.isDraftMode
|
|
86
86
|
inside:
|
|
87
87
|
kind: if_statement
|
|
88
88
|
stopBy: end
|
|
89
|
-
has:
|
|
89
|
+
has:
|
|
90
90
|
kind: return_statement
|
|
91
91
|
any:
|
|
92
92
|
- has:
|
|
@@ -101,11 +101,9 @@ export const patchFetchCacheForISR = {
|
|
|
101
101
|
patches: [
|
|
102
102
|
{
|
|
103
103
|
versions: ">=14.0.0",
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
patchCode: createPatchCode(fetchRule, Lang.JavaScript),
|
|
108
|
-
},
|
|
104
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `(server/chunks/.*\.js|.*\.runtime\..*\.js|patch-fetch\.js)$`, { escape: false }),
|
|
105
|
+
contentFilter: /\.isOnDemandRevalidate/,
|
|
106
|
+
patchCode: createPatchCode(fetchRule, Lang.JavaScript),
|
|
109
107
|
},
|
|
110
108
|
],
|
|
111
109
|
};
|
|
@@ -114,11 +112,9 @@ export const patchUnstableCacheForISR = {
|
|
|
114
112
|
patches: [
|
|
115
113
|
{
|
|
116
114
|
versions: ">=14.2.0",
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
patchCode: createPatchCode(unstable_cacheRule, Lang.JavaScript),
|
|
121
|
-
},
|
|
115
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `(server/chunks/.*\.js|.*\.runtime\..*\.js|spec-extension/unstable-cache\.js)$`, { escape: false }),
|
|
116
|
+
contentFilter: /\.isOnDemandRevalidate/,
|
|
117
|
+
patchCode: createPatchCode(unstable_cacheRule, Lang.JavaScript),
|
|
122
118
|
},
|
|
123
119
|
],
|
|
124
120
|
};
|
|
@@ -127,11 +123,9 @@ export const patchUseCacheForISR = {
|
|
|
127
123
|
patches: [
|
|
128
124
|
{
|
|
129
125
|
versions: ">=15.3.0",
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
patchCode: createPatchCode(useCacheRule, Lang.JavaScript),
|
|
134
|
-
},
|
|
126
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `(server/chunks/.*\.js|\.runtime\..*\.js|use-cache/use-cache-wrapper\.js)$`, { escape: false }),
|
|
127
|
+
contentFilter: /\.isOnDemandRevalidate/,
|
|
128
|
+
patchCode: createPatchCode(useCacheRule, Lang.JavaScript),
|
|
135
129
|
},
|
|
136
130
|
],
|
|
137
131
|
};
|
|
@@ -26,11 +26,9 @@ export const patchFetchCacheSetMissingWaitUntil = {
|
|
|
26
26
|
patches: [
|
|
27
27
|
{
|
|
28
28
|
versions: ">=15.0.0",
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
patchCode: createPatchCode(rule),
|
|
33
|
-
},
|
|
29
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `(server/chunks/.*\.js|.*\.runtime\..*\.js|patch-fetch\.js)$`, { escape: false }),
|
|
30
|
+
contentFilter: /arrayBuffer\(\)\s*\.then/,
|
|
31
|
+
patchCode: createPatchCode(rule),
|
|
34
32
|
},
|
|
35
33
|
],
|
|
36
34
|
};
|
|
@@ -71,27 +71,21 @@ const pathFilter = getCrossPlatformPathRegex(String.raw `/next/dist/server/next-
|
|
|
71
71
|
const babelPatches = [
|
|
72
72
|
// Empty the body of `NextServer#runMiddleware`
|
|
73
73
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
patchCode: createPatchCode(createEmptyBodyRule("runMiddleware")),
|
|
78
|
-
},
|
|
74
|
+
pathFilter,
|
|
75
|
+
contentFilter: /runMiddleware\(/,
|
|
76
|
+
patchCode: createPatchCode(createEmptyBodyRule("runMiddleware")),
|
|
79
77
|
},
|
|
80
78
|
// Empty the body of `NextServer#runEdgeFunction`
|
|
81
79
|
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
patchCode: createPatchCode(createEmptyBodyRule("runEdgeFunction")),
|
|
86
|
-
},
|
|
80
|
+
pathFilter,
|
|
81
|
+
contentFilter: /runEdgeFunction\(/,
|
|
82
|
+
patchCode: createPatchCode(createEmptyBodyRule("runEdgeFunction")),
|
|
87
83
|
},
|
|
88
84
|
// Drop `error-inspect` that pulls babel
|
|
89
85
|
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
patchCode: createPatchCode(errorInspectRule),
|
|
94
|
-
},
|
|
86
|
+
pathFilter,
|
|
87
|
+
contentFilter: /error-inspect/,
|
|
88
|
+
patchCode: createPatchCode(errorInspectRule),
|
|
95
89
|
},
|
|
96
90
|
];
|
|
97
91
|
export const patchNextServer = {
|
|
@@ -99,30 +93,24 @@ export const patchNextServer = {
|
|
|
99
93
|
patches: [
|
|
100
94
|
// Empty the body of `NextServer#imageOptimizer` - unused in OpenNext
|
|
101
95
|
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
patchCode: createPatchCode(createEmptyBodyRule("imageOptimizer")),
|
|
106
|
-
},
|
|
96
|
+
pathFilter,
|
|
97
|
+
contentFilter: /imageOptimizer\(/,
|
|
98
|
+
patchCode: createPatchCode(createEmptyBodyRule("imageOptimizer")),
|
|
107
99
|
},
|
|
108
100
|
// Disable Next background preloading done at creation of `NextServer`
|
|
109
101
|
{
|
|
110
102
|
versions: ">=14.0.0",
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
patchCode: createPatchCode(disablePreloadingRule),
|
|
115
|
-
},
|
|
103
|
+
pathFilter,
|
|
104
|
+
contentFilter: /this\.nextConfig\.experimental\.preloadEntriesOnStart/,
|
|
105
|
+
patchCode: createPatchCode(disablePreloadingRule),
|
|
116
106
|
},
|
|
117
107
|
// Don't match edge functions in `NextServer`
|
|
118
108
|
{
|
|
119
109
|
// Next 12 and some version of 13 use the bundled middleware/edge function
|
|
120
110
|
versions: ">=14.0.0",
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
patchCode: createPatchCode(removeMiddlewareManifestRule),
|
|
125
|
-
},
|
|
111
|
+
pathFilter,
|
|
112
|
+
contentFilter: /getMiddlewareManifest/,
|
|
113
|
+
patchCode: createPatchCode(removeMiddlewareManifestRule),
|
|
126
114
|
},
|
|
127
115
|
...babelPatches,
|
|
128
116
|
],
|
|
@@ -72,7 +72,9 @@ export function validateConfig(config) {
|
|
|
72
72
|
It is safe to disable if you only use page router`);
|
|
73
73
|
}
|
|
74
74
|
validateFunctionOptions(config.imageOptimization ?? {});
|
|
75
|
-
|
|
75
|
+
if (config.middleware?.external === true) {
|
|
76
|
+
validateFunctionOptions(config.middleware ?? {});
|
|
77
|
+
}
|
|
76
78
|
//@ts-expect-error - Revalidate custom wrapper type is different
|
|
77
79
|
validateFunctionOptions(config.revalidate ?? {});
|
|
78
80
|
//@ts-expect-error - Warmer custom wrapper type is different
|
|
@@ -4,8 +4,10 @@ export async function createGenericHandler(handler) {
|
|
|
4
4
|
// @ts-expect-error `./open-next.config.mjs` exists only in the build output
|
|
5
5
|
const config = await import("./open-next.config.mjs").then((m) => m.default);
|
|
6
6
|
globalThis.openNextConfig = config;
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const handlerConfig = config[handler.type];
|
|
8
|
+
const override = handlerConfig && "override" in handlerConfig
|
|
9
|
+
? handlerConfig.override
|
|
10
|
+
: undefined;
|
|
9
11
|
// From the config, we create the converter
|
|
10
12
|
const converter = await resolveConverter(override?.converter);
|
|
11
13
|
// Then we create the handler
|
|
@@ -4,7 +4,7 @@ import { runWithOpenNextRequestContext } from "../utils/promise";
|
|
|
4
4
|
import { NextConfig } from "../adapters/config/index";
|
|
5
5
|
import { debug, error } from "../adapters/logger";
|
|
6
6
|
import { patchAsyncStorage } from "./patchAsyncStorage";
|
|
7
|
-
import { constructNextUrl, convertRes, convertToQuery, createServerResponse, } from "./routing/util";
|
|
7
|
+
import { constructNextUrl, convertRes, convertToQuery, convertToQueryString, createServerResponse, } from "./routing/util";
|
|
8
8
|
import routingHandler, { INTERNAL_EVENT_REQUEST_ID, INTERNAL_HEADER_INITIAL_URL, INTERNAL_HEADER_RESOLVED_ROUTES, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_HEADER_PREFIX_LEN, } from "./routingHandler";
|
|
9
9
|
import { requestHandler, setNextjsPrebundledReact } from "./util";
|
|
10
10
|
// This is used to identify requests in the cache
|
|
@@ -167,7 +167,10 @@ async function processRequest(req, res, routingResult) {
|
|
|
167
167
|
// Here we try to apply as much request metadata as possible
|
|
168
168
|
// We apply every metadata from `resolve-routes` https://github.com/vercel/next.js/blob/916f105b97211de50f8580f0b39c9e7c60de4886/packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
169
169
|
// and `router-server` https://github.com/vercel/next.js/blob/916f105b97211de50f8580f0b39c9e7c60de4886/packages/next/src/server/lib/router-server.ts
|
|
170
|
-
const initialURL = new URL(
|
|
170
|
+
const initialURL = new URL(
|
|
171
|
+
// We always assume that only the routing layer can set this header.
|
|
172
|
+
routingResult.internalEvent.headers[INTERNAL_HEADER_INITIAL_URL] ??
|
|
173
|
+
routingResult.initialURL);
|
|
171
174
|
let invokeStatus;
|
|
172
175
|
if (routingResult.internalEvent.rawPath === "/500") {
|
|
173
176
|
invokeStatus = 500;
|
|
@@ -194,6 +197,13 @@ async function processRequest(req, res, routingResult) {
|
|
|
194
197
|
setNextjsPrebundledReact(routingResult.internalEvent.rawPath);
|
|
195
198
|
//#endOverride
|
|
196
199
|
// Next Server
|
|
200
|
+
// TODO: only enable this on Next 15.4+
|
|
201
|
+
// We need to set the pathname to the data request path
|
|
202
|
+
//#override setInitialURL
|
|
203
|
+
req.url =
|
|
204
|
+
initialURL.pathname +
|
|
205
|
+
convertToQueryString(routingResult.internalEvent.query);
|
|
206
|
+
//#endOverride
|
|
197
207
|
await requestHandler(requestMetadata)(req, res);
|
|
198
208
|
}
|
|
199
209
|
catch (e) {
|
|
@@ -253,6 +263,7 @@ async function tryRenderError(type, res, internalEvent) {
|
|
|
253
263
|
}
|
|
254
264
|
catch (e) {
|
|
255
265
|
error("NextJS request failed.", e);
|
|
266
|
+
res.statusCode = 500;
|
|
256
267
|
res.setHeader("Content-Type", "application/json");
|
|
257
268
|
res.end(JSON.stringify({
|
|
258
269
|
message: "Server failed to respond.",
|
package/dist/core/resolve.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseEventOrResult, DefaultOverrideOptions, InternalEvent, InternalResult, OpenNextConfig, OverrideOptions } from "../types/open-next";
|
|
1
|
+
import type { BaseEventOrResult, DefaultOverrideOptions, ExternalMiddlewareConfig, InternalEvent, InternalResult, OpenNextConfig, OverrideOptions } from "../types/open-next";
|
|
2
2
|
import type { Converter, TagCache, Wrapper } from "../types/overrides";
|
|
3
3
|
type RemoveUndefined<T> = T extends undefined ? never : T;
|
|
4
4
|
export declare function resolveConverter<E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult>(converter: DefaultOverrideOptions<E, R>["converter"]): Promise<Converter<E, R>>;
|
|
@@ -34,7 +34,7 @@ export declare function resolveImageLoader(imageLoader: RemoveUndefined<OpenNext
|
|
|
34
34
|
* @returns
|
|
35
35
|
* @__PURE__
|
|
36
36
|
*/
|
|
37
|
-
export declare function resolveOriginResolver(originResolver: RemoveUndefined<
|
|
37
|
+
export declare function resolveOriginResolver(originResolver: RemoveUndefined<ExternalMiddlewareConfig>["originResolver"]): Promise<import("../types/overrides").OriginResolver>;
|
|
38
38
|
/**
|
|
39
39
|
* @returns
|
|
40
40
|
* @__PURE__
|
|
@@ -144,6 +144,14 @@ export async function cacheInterceptor(event) {
|
|
|
144
144
|
if (Boolean(event.headers["next-action"]) ||
|
|
145
145
|
Boolean(event.headers["x-prerender-revalidate"]))
|
|
146
146
|
return event;
|
|
147
|
+
// Check for Next.js preview mode cookies
|
|
148
|
+
const cookies = event.headers.cookie || "";
|
|
149
|
+
const hasPreviewData = cookies.includes("__prerender_bypass") ||
|
|
150
|
+
cookies.includes("__next_preview_data");
|
|
151
|
+
if (hasPreviewData) {
|
|
152
|
+
debug("Preview mode detected, passing through to handler");
|
|
153
|
+
return event;
|
|
154
|
+
}
|
|
147
155
|
// We localize the path in case i18n is enabled
|
|
148
156
|
let localizedPath = localizePath(event);
|
|
149
157
|
// If using basePath we need to remove it from the path
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { OnLoadOptions, Plugin, PluginBuild } from "esbuild";
|
|
7
7
|
import type { BuildOptions } from "../build/helper";
|
|
8
|
-
import { type
|
|
8
|
+
import { type Versions } from "../build/patch/codePatcher.js";
|
|
9
9
|
export type * from "esbuild";
|
|
10
10
|
/**
|
|
11
11
|
* The callbacks returns either an updated content or undefined if the content is unchanged.
|
|
@@ -23,6 +23,7 @@ export type OnUpdateOptions = OnLoadOptions & {
|
|
|
23
23
|
};
|
|
24
24
|
export type Updater = OnUpdateOptions & {
|
|
25
25
|
callback: Callback;
|
|
26
|
+
versions?: Versions;
|
|
26
27
|
};
|
|
27
28
|
export declare class ContentUpdater {
|
|
28
29
|
private buildOptions;
|
|
@@ -34,10 +35,10 @@ export declare class ContentUpdater {
|
|
|
34
35
|
* The callbacks are called in order of registration.
|
|
35
36
|
*
|
|
36
37
|
* @param name The name of the plugin (must be unique).
|
|
37
|
-
* @param
|
|
38
|
+
* @param updaters A list of code updaters
|
|
38
39
|
* @returns A noop ESBuild plugin.
|
|
39
40
|
*/
|
|
40
|
-
updateContent(name: string,
|
|
41
|
+
updateContent(name: string, updaters: Updater[]): Plugin;
|
|
41
42
|
/**
|
|
42
43
|
* Returns an ESBuild plugin applying the registered updates.
|
|
43
44
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The updater allows multiple plugins to update the content.
|
|
5
5
|
*/
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
|
-
import {
|
|
7
|
+
import { isVersionInRange } from "../build/patch/codePatcher.js";
|
|
8
8
|
export class ContentUpdater {
|
|
9
9
|
buildOptions;
|
|
10
10
|
updaters = new Map();
|
|
@@ -17,15 +17,14 @@ export class ContentUpdater {
|
|
|
17
17
|
* The callbacks are called in order of registration.
|
|
18
18
|
*
|
|
19
19
|
* @param name The name of the plugin (must be unique).
|
|
20
|
-
* @param
|
|
20
|
+
* @param updaters A list of code updaters
|
|
21
21
|
* @returns A noop ESBuild plugin.
|
|
22
22
|
*/
|
|
23
|
-
updateContent(name,
|
|
23
|
+
updateContent(name, updaters) {
|
|
24
24
|
if (this.updaters.has(name)) {
|
|
25
25
|
throw new Error(`Plugin "${name}" already registered`);
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
this.updaters.set(name, updaters);
|
|
27
|
+
this.updaters.set(name, updaters.filter(({ versions }) => isVersionInRange(this.buildOptions.nextVersion, versions)));
|
|
29
28
|
return {
|
|
30
29
|
name,
|
|
31
30
|
setup() { },
|
|
@@ -244,43 +244,56 @@ export interface SplittedFunctionOptions extends FunctionOptions {
|
|
|
244
244
|
*/
|
|
245
245
|
patterns: string[];
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* MiddlewareConfig that applies to both external and internal middlewares
|
|
249
|
+
*
|
|
250
|
+
* Note: this type is internal and included in both `ExternalMiddlewareConfig` and `InternalMiddlewareConfig`
|
|
251
|
+
*/
|
|
252
|
+
type CommonMiddlewareConfig = {
|
|
253
|
+
/**
|
|
254
|
+
* The assetResolver is used to resolve assets in the routing layer.
|
|
255
|
+
*
|
|
256
|
+
* @default "dummy"
|
|
257
|
+
*/
|
|
258
|
+
assetResolver?: IncludedAssetResolver | LazyLoadedOverride<AssetResolver>;
|
|
259
|
+
};
|
|
260
|
+
/** MiddlewareConfig that applies to external middlewares only */
|
|
261
|
+
export type ExternalMiddlewareConfig = DefaultFunctionOptions & CommonMiddlewareConfig & {
|
|
262
|
+
external: true;
|
|
263
|
+
/**
|
|
264
|
+
* The runtime used by next for the middleware.
|
|
265
|
+
* @default "edge"
|
|
266
|
+
*/
|
|
267
|
+
runtime?: "node" | "edge";
|
|
268
|
+
/**
|
|
269
|
+
* The override options for the middleware.
|
|
270
|
+
* By default the lite override are used (.i.e. s3-lite, dynamodb-lite, sqs-lite)
|
|
271
|
+
* @default undefined
|
|
272
|
+
*/
|
|
273
|
+
override?: OverrideOptions;
|
|
274
|
+
/**
|
|
275
|
+
* Origin resolver is used to resolve the origin for internal rewrite.
|
|
276
|
+
* By default, it uses the pattern-env origin resolver.
|
|
277
|
+
* Pattern env uses pattern set in split function options and an env variable OPEN_NEXT_ORIGIN
|
|
278
|
+
* OPEN_NEXT_ORIGIN should be a json stringified object with the key of the splitted function as key and the origin as value
|
|
279
|
+
* @default "pattern-env"
|
|
280
|
+
*/
|
|
281
|
+
originResolver?: IncludedOriginResolver | LazyLoadedOverride<OriginResolver>;
|
|
282
|
+
};
|
|
283
|
+
/** MiddlewareConfig that applies to internal middlewares only */
|
|
284
|
+
export type InternalMiddlewareConfig = {
|
|
285
|
+
external: false;
|
|
286
|
+
} & CommonMiddlewareConfig;
|
|
247
287
|
export interface OpenNextConfig {
|
|
248
288
|
default: FunctionOptions;
|
|
249
289
|
functions?: Record<string, SplittedFunctionOptions>;
|
|
250
290
|
/**
|
|
251
291
|
* Override the default middleware
|
|
252
|
-
*
|
|
292
|
+
* When `external` is true, the middleware need to be deployed separately.
|
|
253
293
|
* It supports both edge and node runtime.
|
|
254
|
-
* @default undefined
|
|
294
|
+
* @default undefined - Which is equivalent to `external: false`
|
|
255
295
|
*/
|
|
256
|
-
middleware?:
|
|
257
|
-
external: true;
|
|
258
|
-
/**
|
|
259
|
-
* The runtime used by next for the middleware.
|
|
260
|
-
* @default "edge"
|
|
261
|
-
*/
|
|
262
|
-
runtime?: "node" | "edge";
|
|
263
|
-
/**
|
|
264
|
-
* The override options for the middleware.
|
|
265
|
-
* By default the lite override are used (.i.e. s3-lite, dynamodb-lite, sqs-lite)
|
|
266
|
-
* @default undefined
|
|
267
|
-
*/
|
|
268
|
-
override?: OverrideOptions;
|
|
269
|
-
/**
|
|
270
|
-
* Origin resolver is used to resolve the origin for internal rewrite.
|
|
271
|
-
* By default, it uses the pattern-env origin resolver.
|
|
272
|
-
* Pattern env uses pattern set in split function options and an env variable OPEN_NEXT_ORIGIN
|
|
273
|
-
* OPEN_NEXT_ORIGIN should be a json stringified object with the key of the splitted function as key and the origin as value
|
|
274
|
-
* @default "pattern-env"
|
|
275
|
-
*/
|
|
276
|
-
originResolver?: IncludedOriginResolver | LazyLoadedOverride<OriginResolver>;
|
|
277
|
-
/**
|
|
278
|
-
* The assetResolver is used to resolve assets in the routing layer.
|
|
279
|
-
*
|
|
280
|
-
* @default "dummy"
|
|
281
|
-
*/
|
|
282
|
-
assetResolver?: IncludedAssetResolver | LazyLoadedOverride<AssetResolver>;
|
|
283
|
-
};
|
|
296
|
+
middleware?: ExternalMiddlewareConfig | InternalMiddlewareConfig;
|
|
284
297
|
/**
|
|
285
298
|
* Override the default warmer
|
|
286
299
|
* By default, works for lambda only.
|
|
@@ -362,3 +375,4 @@ export interface OpenNextConfig {
|
|
|
362
375
|
*/
|
|
363
376
|
edgeExternals?: string[];
|
|
364
377
|
}
|
|
378
|
+
export {};
|