@opennextjs/aws 3.6.5 → 3.6.6
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 +1 -1
- package/dist/build/copyTracedFiles.js +10 -5
- package/dist/build/createAssets.js +55 -51
- package/dist/build/createServerBundle.js +0 -1
- package/dist/build/patch/patches/index.d.ts +0 -1
- package/dist/build/patch/patches/index.js +0 -1
- package/dist/build/patch/patches/patchNextServer.d.ts +13 -3
- package/dist/build/patch/patches/patchNextServer.js +82 -44
- package/dist/core/routing/cacheInterceptor.js +2 -1
- package/dist/core/routing/matcher.js +4 -3
- package/dist/overrides/converters/edge.js +7 -1
- package/dist/types/next-types.d.ts +2 -0
- package/package.json +1 -1
- package/dist/build/patch/patches/dropBabel.d.ts +0 -20
- package/dist/build/patch/patches/dropBabel.js +0 -72
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ OpenNext takes the Next.js build output and converts it into packages that can b
|
|
|
23
23
|
|
|
24
24
|
## Features
|
|
25
25
|
|
|
26
|
-
OpenNext aims to support all Next.js
|
|
26
|
+
OpenNext aims to support all Next.js 15 features. Some features are work in progress. If you are running into any problems make sure to check the [docs](https://opennext.js.org/aws) first before you open a [new issue](/issues/new) or visit our [Discord](https://discord.gg/opennextjs) to let us know!
|
|
27
27
|
|
|
28
28
|
- [x] App & Pages Router
|
|
29
29
|
- [x] API routes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import url from "node:url";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { loadAppPathsManifest, loadBuildId, loadConfig, loadFunctionsConfigManifest, loadMiddlewareManifest, loadPagesManifest, loadPrerenderManifest, } from "../adapters/config/util.js";
|
|
5
5
|
import { getCrossPlatformPathRegex } from "../utils/regex.js";
|
|
@@ -223,15 +223,15 @@ File ${serverPath} does not exist
|
|
|
223
223
|
copyFileSync(path.join(standaloneNextDir, filePath), path.join(outputNextDir, filePath));
|
|
224
224
|
}
|
|
225
225
|
};
|
|
226
|
+
const manifests = getManifests(standaloneNextDir);
|
|
227
|
+
const { config, prerenderManifest, pagesManifest } = manifests;
|
|
226
228
|
// Get all the static files - Should be only for pages dir
|
|
227
229
|
// Ideally we would filter only those that might get accessed in this specific functions
|
|
228
230
|
// Maybe even move this to s3 directly
|
|
229
231
|
if (hasPageDir) {
|
|
230
232
|
// First we get truly static files - i.e. pages without getStaticProps
|
|
231
|
-
const staticFiles = Object.values(
|
|
233
|
+
const staticFiles = Object.values(pagesManifest);
|
|
232
234
|
// Then we need to get all fallback: true dynamic routes html
|
|
233
|
-
const prerenderManifest = loadPrerenderManifest(standaloneNextDir);
|
|
234
|
-
const config = loadConfig(standaloneNextDir);
|
|
235
235
|
const locales = config.i18n?.locales;
|
|
236
236
|
Object.values(prerenderManifest.dynamicRoutes).forEach((route) => {
|
|
237
237
|
if (typeof route.fallback === "string") {
|
|
@@ -249,10 +249,15 @@ File ${serverPath} does not exist
|
|
|
249
249
|
.filter((file) => file.endsWith(".html"))
|
|
250
250
|
.forEach((file) => copyStaticFile(`server/${file}`));
|
|
251
251
|
}
|
|
252
|
+
// Copy .next/static/css from standalone to output dir
|
|
253
|
+
// needed for optimizeCss feature to work
|
|
254
|
+
if (config.experimental.optimizeCss) {
|
|
255
|
+
cpSync(path.join(standaloneNextDir, "static", "css"), path.join(outputNextDir, "static", "css"), { recursive: true });
|
|
256
|
+
}
|
|
252
257
|
logger.debug("copyTracedFiles:", Date.now() - tsStart, "ms");
|
|
253
258
|
return {
|
|
254
259
|
tracedFiles,
|
|
255
260
|
nodePackages,
|
|
256
|
-
manifests
|
|
261
|
+
manifests,
|
|
257
262
|
};
|
|
258
263
|
}
|
|
@@ -62,44 +62,46 @@ export function createCacheAssets(options) {
|
|
|
62
62
|
const packagePath = buildHelper.getPackagePath(options);
|
|
63
63
|
const buildId = buildHelper.getBuildId(options);
|
|
64
64
|
let useTagCache = false;
|
|
65
|
-
// Copy pages to cache folder
|
|
66
65
|
const dotNextPath = path.join(appBuildOutputPath, ".next/standalone", packagePath);
|
|
67
|
-
const
|
|
68
|
-
|
|
66
|
+
const outputCachePath = path.join(outputDir, "cache", buildId);
|
|
67
|
+
fs.mkdirSync(outputCachePath, { recursive: true });
|
|
68
|
+
const sourceDirs = [".next/server/pages", ".next/server/app"]
|
|
69
69
|
.map((dir) => path.join(dotNextPath, dir))
|
|
70
|
-
.filter(fs.existsSync)
|
|
71
|
-
.forEach((dir) => fs.cpSync(dir, outputPath, { recursive: true }));
|
|
72
|
-
// Remove non-cache files
|
|
70
|
+
.filter(fs.existsSync);
|
|
73
71
|
const htmlPages = buildHelper.getHtmlPages(dotNextPath);
|
|
74
|
-
|
|
72
|
+
const isFileSkipped = (relativePath) => relativePath.endsWith(".js") ||
|
|
75
73
|
relativePath.endsWith(".js.nft.json") ||
|
|
76
|
-
(relativePath.endsWith(".html") && htmlPages.has(relativePath))
|
|
74
|
+
(relativePath.endsWith(".html") && htmlPages.has(relativePath));
|
|
77
75
|
// Merge cache files into a single file
|
|
78
76
|
const cacheFilesPath = {};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
// Process each source directory
|
|
78
|
+
sourceDirs.forEach((sourceDir) => {
|
|
79
|
+
buildHelper.traverseFiles(sourceDir, ({ relativePath }) => !isFileSkipped(relativePath), ({ absolutePath, relativePath }) => {
|
|
80
|
+
const ext = path.extname(absolutePath);
|
|
81
|
+
switch (ext) {
|
|
82
|
+
case ".meta":
|
|
83
|
+
case ".html":
|
|
84
|
+
case ".json":
|
|
85
|
+
case ".body":
|
|
86
|
+
case ".rsc": {
|
|
87
|
+
const newFilePath = path
|
|
88
|
+
.join(outputCachePath, relativePath)
|
|
89
|
+
.substring(0, path.join(outputCachePath, relativePath).length - ext.length)
|
|
90
|
+
.replace(/\.prefetch$/, "")
|
|
91
|
+
.concat(".cache");
|
|
92
|
+
cacheFilesPath[newFilePath] = {
|
|
93
|
+
[ext.slice(1)]: absolutePath,
|
|
94
|
+
...cacheFilesPath[newFilePath],
|
|
95
|
+
};
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case ".map":
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
logger.warn(`Unknown file extension: ${ext}`);
|
|
102
|
+
break;
|
|
96
103
|
}
|
|
97
|
-
|
|
98
|
-
break;
|
|
99
|
-
default:
|
|
100
|
-
logger.warn(`Unknown file extension: ${ext}`);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
104
|
+
});
|
|
103
105
|
});
|
|
104
106
|
// Generate cache file
|
|
105
107
|
Object.entries(cacheFilesPath).forEach(([cacheFilePath, files]) => {
|
|
@@ -122,6 +124,8 @@ export function createCacheAssets(options) {
|
|
|
122
124
|
: "utf8")
|
|
123
125
|
: undefined,
|
|
124
126
|
};
|
|
127
|
+
// Ensure directory exists before writing
|
|
128
|
+
fs.mkdirSync(path.dirname(cacheFilePath), { recursive: true });
|
|
125
129
|
fs.writeFileSync(cacheFilePath, JSON.stringify(cacheFileContent));
|
|
126
130
|
});
|
|
127
131
|
// We need to traverse the cache to find every .meta file
|
|
@@ -149,36 +153,36 @@ export function createCacheAssets(options) {
|
|
|
149
153
|
if (!options.config.dangerous?.disableTagCache) {
|
|
150
154
|
// Compute dynamodb cache data
|
|
151
155
|
// Traverse files inside cache to find all meta files and cache tags associated with them
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
fileData.headers["x-next-cache-tags"]
|
|
157
|
-
.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
156
|
+
sourceDirs.forEach((sourceDir) => {
|
|
157
|
+
buildHelper.traverseFiles(sourceDir, ({ absolutePath, relativePath }) => absolutePath.endsWith(".meta") && !isFileSkipped(relativePath), ({ absolutePath, relativePath }) => {
|
|
158
|
+
const fileContent = fs.readFileSync(absolutePath, "utf8");
|
|
159
|
+
const fileData = JSON.parse(fileContent);
|
|
160
|
+
if (fileData.headers?.["x-next-cache-tags"]) {
|
|
161
|
+
fileData.headers["x-next-cache-tags"]
|
|
162
|
+
.split(",")
|
|
163
|
+
.forEach((tag) => {
|
|
164
|
+
// TODO: We should split the tag using getDerivedTags from next.js or maybe use an in house implementation
|
|
165
|
+
metaFiles.push({
|
|
166
|
+
tag: { S: path.posix.join(buildId, tag.trim()) },
|
|
167
|
+
path: {
|
|
168
|
+
S: path.posix.join(buildId, relativePath.replace(".meta", "")),
|
|
169
|
+
},
|
|
170
|
+
// We don't care about the revalidation time here, we just need to make sure it's there
|
|
171
|
+
revalidatedAt: { N: "1" },
|
|
172
|
+
});
|
|
167
173
|
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
170
176
|
});
|
|
171
177
|
if (metaFiles.length > 0) {
|
|
172
178
|
useTagCache = true;
|
|
173
179
|
const providerPath = path.join(outputDir, "dynamodb-provider");
|
|
174
|
-
//Copy open-next.config.mjs into the bundle
|
|
180
|
+
// Copy open-next.config.mjs into the bundle
|
|
175
181
|
fs.mkdirSync(providerPath, { recursive: true });
|
|
176
182
|
buildHelper.copyOpenNextConfig(options.buildDir, providerPath);
|
|
177
183
|
// TODO: check if metafiles doesn't contain duplicates
|
|
178
184
|
fs.writeFileSync(path.join(providerPath, "dynamodb-cache.json"), JSON.stringify(metaFiles));
|
|
179
185
|
}
|
|
180
186
|
}
|
|
181
|
-
// We need to remove files later because we need the metafiles for dynamodb tags cache
|
|
182
|
-
buildHelper.removeFiles(outputPath, ({ relativePath }) => !relativePath.endsWith(".cache"));
|
|
183
187
|
return { useTagCache, metaFiles };
|
|
184
188
|
}
|
|
@@ -126,7 +126,6 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
126
126
|
patches.patchEnvVars,
|
|
127
127
|
patches.patchBackgroundRevalidation,
|
|
128
128
|
patches.patchUseCacheForISR,
|
|
129
|
-
patches.patchDropBabel,
|
|
130
129
|
...additionalCodePatches,
|
|
131
130
|
]);
|
|
132
131
|
// Build Lambda code
|
|
@@ -3,4 +3,3 @@ export { patchNextServer } from "./patchNextServer.js";
|
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
|
-
export { patchDropBabel } from "./dropBabel.js";
|
|
@@ -3,4 +3,3 @@ export { patchNextServer } from "./patchNextServer.js";
|
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
|
-
export { patchDropBabel } from "./dropBabel.js";
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { CodePatcher } from "../codePatcher.js";
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
|
|
2
|
+
export declare const disablePreloadingRule = "\nrule:\n kind: statement_block\n inside:\n kind: if_statement\n any:\n - has:\n kind: member_expression\n pattern: this.nextConfig.experimental.preloadEntriesOnStart\n stopBy: end\n - has:\n kind: binary_expression\n pattern: appDocumentPreloading === true\n stopBy: end\nfix:\n '{}'\n";
|
|
3
|
+
export declare const removeMiddlewareManifestRule = "\nrule:\n kind: statement_block\n inside:\n kind: method_definition\n has:\n kind: property_identifier\n regex: ^getMiddlewareManifest$\nfix:\n '{return null;}'\n";
|
|
4
|
+
/**
|
|
5
|
+
* Swaps the body for a throwing implementation
|
|
6
|
+
*
|
|
7
|
+
* @param methodName The name of the method
|
|
8
|
+
* @returns A rule to replace the body with a `throw`
|
|
9
|
+
*/
|
|
10
|
+
export declare function createEmptyBodyRule(methodName: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
13
|
+
*/
|
|
14
|
+
export declare const errorInspectRule = "\nrule:\n pattern: require(\"./node-environment-extensions/error-inspect\");\nfix: |-\n // Removed by OpenNext\n // require(\"./node-environment-extensions/error-inspect\");\n";
|
|
5
15
|
export declare const patchNextServer: CodePatcher;
|
|
@@ -1,51 +1,24 @@
|
|
|
1
|
+
import { getCrossPlatformPathRegex } from "../../../utils/regex.js";
|
|
1
2
|
import { createPatchCode } from "../astCodePatcher.js";
|
|
2
|
-
//
|
|
3
|
-
export const minimalRule = `
|
|
4
|
-
rule:
|
|
5
|
-
kind: member_expression
|
|
6
|
-
pattern: process.env.NEXT_MINIMAL
|
|
7
|
-
any:
|
|
8
|
-
- inside:
|
|
9
|
-
kind: parenthesized_expression
|
|
10
|
-
stopBy: end
|
|
11
|
-
inside:
|
|
12
|
-
kind: if_statement
|
|
13
|
-
any:
|
|
14
|
-
- inside:
|
|
15
|
-
kind: statement_block
|
|
16
|
-
inside:
|
|
17
|
-
kind: method_definition
|
|
18
|
-
any:
|
|
19
|
-
- has: {kind: property_identifier, field: name, regex: runEdgeFunction}
|
|
20
|
-
- has: {kind: property_identifier, field: name, regex: runMiddleware}
|
|
21
|
-
- has: {kind: property_identifier, field: name, regex: imageOptimizer}
|
|
22
|
-
- has:
|
|
23
|
-
kind: statement_block
|
|
24
|
-
has:
|
|
25
|
-
kind: expression_statement
|
|
26
|
-
pattern: res.statusCode = 400;
|
|
27
|
-
fix:
|
|
28
|
-
'true'
|
|
29
|
-
`;
|
|
30
|
-
// This rule will disable the background preloading of route done by NextServer by default during the creation of NextServer
|
|
3
|
+
// Disable the background preloading of route done by NextServer by default during the creation of NextServer
|
|
31
4
|
export const disablePreloadingRule = `
|
|
32
5
|
rule:
|
|
33
6
|
kind: statement_block
|
|
34
7
|
inside:
|
|
35
8
|
kind: if_statement
|
|
36
|
-
any:
|
|
37
|
-
- has:
|
|
9
|
+
any:
|
|
10
|
+
- has:
|
|
38
11
|
kind: member_expression
|
|
39
12
|
pattern: this.nextConfig.experimental.preloadEntriesOnStart
|
|
40
13
|
stopBy: end
|
|
41
|
-
- has:
|
|
14
|
+
- has:
|
|
42
15
|
kind: binary_expression
|
|
43
16
|
pattern: appDocumentPreloading === true
|
|
44
17
|
stopBy: end
|
|
45
18
|
fix:
|
|
46
19
|
'{}'
|
|
47
20
|
`;
|
|
48
|
-
//
|
|
21
|
+
// Mostly for splitted edge functions so that we don't try to match them on the other non edge functions
|
|
49
22
|
export const removeMiddlewareManifestRule = `
|
|
50
23
|
rule:
|
|
51
24
|
kind: statement_block
|
|
@@ -53,39 +26,104 @@ rule:
|
|
|
53
26
|
kind: method_definition
|
|
54
27
|
has:
|
|
55
28
|
kind: property_identifier
|
|
56
|
-
regex: getMiddlewareManifest
|
|
29
|
+
regex: ^getMiddlewareManifest$
|
|
57
30
|
fix:
|
|
58
31
|
'{return null;}'
|
|
59
32
|
`;
|
|
33
|
+
/**
|
|
34
|
+
* Swaps the body for a throwing implementation
|
|
35
|
+
*
|
|
36
|
+
* @param methodName The name of the method
|
|
37
|
+
* @returns A rule to replace the body with a `throw`
|
|
38
|
+
*/
|
|
39
|
+
export function createEmptyBodyRule(methodName) {
|
|
40
|
+
return `
|
|
41
|
+
rule:
|
|
42
|
+
pattern:
|
|
43
|
+
selector: method_definition
|
|
44
|
+
context: "class { async ${methodName}($$$PARAMS) { $$$_ } }"
|
|
45
|
+
fix: |-
|
|
46
|
+
async ${methodName}($$$PARAMS) {
|
|
47
|
+
throw new Error("${methodName} should not be called with OpenNext");
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
53
|
+
*/
|
|
54
|
+
export const errorInspectRule = `
|
|
55
|
+
rule:
|
|
56
|
+
pattern: require("./node-environment-extensions/error-inspect");
|
|
57
|
+
fix: |-
|
|
58
|
+
// Removed by OpenNext
|
|
59
|
+
// require("./node-environment-extensions/error-inspect");
|
|
60
|
+
`;
|
|
61
|
+
const pathFilter = getCrossPlatformPathRegex(String.raw `/next/dist/server/next-server\.js$`, {
|
|
62
|
+
escape: false,
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Patches to avoid pulling babel (~4MB).
|
|
66
|
+
*
|
|
67
|
+
* Details:
|
|
68
|
+
* - empty `NextServer#runMiddleware` and `NextServer#runEdgeFunction` that are not used
|
|
69
|
+
* - drop `next/dist/server/node-environment-extensions/error-inspect.js`
|
|
70
|
+
*/
|
|
71
|
+
const babelPatches = [
|
|
72
|
+
// Empty the body of `NextServer#runMiddleware`
|
|
73
|
+
{
|
|
74
|
+
field: {
|
|
75
|
+
pathFilter,
|
|
76
|
+
contentFilter: /runMiddleware\(/,
|
|
77
|
+
patchCode: createPatchCode(createEmptyBodyRule("runMiddleware")),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
// Empty the body of `NextServer#runEdgeFunction`
|
|
81
|
+
{
|
|
82
|
+
field: {
|
|
83
|
+
pathFilter,
|
|
84
|
+
contentFilter: /runEdgeFunction\(/,
|
|
85
|
+
patchCode: createPatchCode(createEmptyBodyRule("runEdgeFunction")),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
// Drop `error-inspect` that pulls babel
|
|
89
|
+
{
|
|
90
|
+
field: {
|
|
91
|
+
pathFilter,
|
|
92
|
+
contentFilter: /error-inspect/,
|
|
93
|
+
patchCode: createPatchCode(errorInspectRule),
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
60
97
|
export const patchNextServer = {
|
|
61
98
|
name: "patch-next-server",
|
|
62
99
|
patches: [
|
|
63
|
-
//
|
|
100
|
+
// Empty the body of `NextServer#imageOptimizer` - unused in OpenNext
|
|
64
101
|
{
|
|
65
|
-
versions: ">=15.0.0",
|
|
66
102
|
field: {
|
|
67
|
-
pathFilter
|
|
68
|
-
contentFilter: /
|
|
69
|
-
patchCode: createPatchCode(
|
|
103
|
+
pathFilter,
|
|
104
|
+
contentFilter: /imageOptimizer\(/,
|
|
105
|
+
patchCode: createPatchCode(createEmptyBodyRule("imageOptimizer")),
|
|
70
106
|
},
|
|
71
107
|
},
|
|
72
|
-
// Disable Next background preloading done at creation of `
|
|
108
|
+
// Disable Next background preloading done at creation of `NextServer`
|
|
73
109
|
{
|
|
74
|
-
versions: ">=
|
|
110
|
+
versions: ">=14.0.0",
|
|
75
111
|
field: {
|
|
76
|
-
pathFilter
|
|
112
|
+
pathFilter,
|
|
77
113
|
contentFilter: /this\.nextConfig\.experimental\.preloadEntriesOnStart/,
|
|
78
114
|
patchCode: createPatchCode(disablePreloadingRule),
|
|
79
115
|
},
|
|
80
116
|
},
|
|
81
117
|
// Don't match edge functions in `NextServer`
|
|
82
118
|
{
|
|
83
|
-
|
|
119
|
+
// Next 12 and some version of 13 use the bundled middleware/edge function
|
|
120
|
+
versions: ">=14.0.0",
|
|
84
121
|
field: {
|
|
85
|
-
pathFilter
|
|
122
|
+
pathFilter,
|
|
86
123
|
contentFilter: /getMiddlewareManifest/,
|
|
87
124
|
patchCode: createPatchCode(removeMiddlewareManifestRule),
|
|
88
125
|
},
|
|
89
126
|
},
|
|
127
|
+
...babelPatches,
|
|
90
128
|
],
|
|
91
129
|
};
|
|
@@ -92,7 +92,8 @@ async function generateResult(event, localizedPath, cachedValue, lastModified) {
|
|
|
92
92
|
const cacheControl = await computeCacheControl(localizedPath, body, event.headers.host, cachedValue.revalidate, lastModified);
|
|
93
93
|
return {
|
|
94
94
|
type: "core",
|
|
95
|
-
|
|
95
|
+
// sometimes other status codes can be cached, like 404. For these cases, we should return the correct status code
|
|
96
|
+
statusCode: cachedValue.meta?.status ?? 200,
|
|
96
97
|
body: toReadableStream(body, false),
|
|
97
98
|
isBase64Encoded: false,
|
|
98
99
|
headers: {
|
|
@@ -259,7 +259,8 @@ export function handleRedirects(event, redirects) {
|
|
|
259
259
|
}
|
|
260
260
|
export function fixDataPage(internalEvent, buildId) {
|
|
261
261
|
const { rawPath, query } = internalEvent;
|
|
262
|
-
const
|
|
262
|
+
const basePath = NextConfig.basePath ?? "";
|
|
263
|
+
const dataPattern = `${basePath}/_next/data/${buildId}`;
|
|
263
264
|
// Return 404 for data requests that don't match the buildId
|
|
264
265
|
if (rawPath.startsWith("/_next/data") && !rawPath.startsWith(dataPattern)) {
|
|
265
266
|
return {
|
|
@@ -273,9 +274,9 @@ export function fixDataPage(internalEvent, buildId) {
|
|
|
273
274
|
};
|
|
274
275
|
}
|
|
275
276
|
if (rawPath.startsWith(dataPattern) && rawPath.endsWith(".json")) {
|
|
276
|
-
const newPath = rawPath
|
|
277
|
+
const newPath = `${basePath}${rawPath
|
|
277
278
|
.slice(dataPattern.length, -".json".length)
|
|
278
|
-
.replace(/^\/index$/, "/")
|
|
279
|
+
.replace(/^\/index$/, "/")}`;
|
|
279
280
|
query.__nextDataReq = "1";
|
|
280
281
|
return {
|
|
281
282
|
...internalEvent,
|
|
@@ -2,6 +2,8 @@ import { Buffer } from "node:buffer";
|
|
|
2
2
|
import cookieParser from "cookie";
|
|
3
3
|
import { parseSetCookieHeader } from "../../http/util";
|
|
4
4
|
import { getQueryFromSearchParams } from "./utils.js";
|
|
5
|
+
// https://fetch.spec.whatwg.org/#statuses
|
|
6
|
+
const NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);
|
|
5
7
|
const converter = {
|
|
6
8
|
convertFrom: async (event) => {
|
|
7
9
|
const url = new URL(event.url);
|
|
@@ -77,7 +79,11 @@ const converter = {
|
|
|
77
79
|
headers.set(key, value);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
|
-
return
|
|
82
|
+
// We should not return a body for statusCode's that doesn't allow bodies
|
|
83
|
+
const body = NULL_BODY_STATUSES.has(result.statusCode)
|
|
84
|
+
? null
|
|
85
|
+
: result.body;
|
|
86
|
+
return new Response(body, {
|
|
81
87
|
status: result.statusCode,
|
|
82
88
|
headers,
|
|
83
89
|
});
|
|
@@ -72,10 +72,12 @@ export interface NextConfig {
|
|
|
72
72
|
experimental: {
|
|
73
73
|
serverActions?: boolean;
|
|
74
74
|
appDir?: boolean;
|
|
75
|
+
optimizeCss?: boolean;
|
|
75
76
|
};
|
|
76
77
|
images: ImageConfig;
|
|
77
78
|
poweredByHeader?: boolean;
|
|
78
79
|
serverExternalPackages?: string[];
|
|
80
|
+
deploymentId?: string;
|
|
79
81
|
}
|
|
80
82
|
export interface RouteDefinition {
|
|
81
83
|
page: string;
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Patches to avoid pulling babel (~4MB).
|
|
3
|
-
*
|
|
4
|
-
* Details:
|
|
5
|
-
* - empty `NextServer#runMiddleware` and `NextServer#runEdgeFunction` that are not used
|
|
6
|
-
* - drop `next/dist/server/node-environment-extensions/error-inspect.js`
|
|
7
|
-
*/
|
|
8
|
-
import type { CodePatcher } from "../codePatcher.js";
|
|
9
|
-
export declare const patchDropBabel: CodePatcher;
|
|
10
|
-
/**
|
|
11
|
-
* Swaps the body for a throwing implementation
|
|
12
|
-
*
|
|
13
|
-
* @param methodName The name of the method
|
|
14
|
-
* @returns A rule to replace the body with a `throw`
|
|
15
|
-
*/
|
|
16
|
-
export declare function createEmptyBodyRule(methodName: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
19
|
-
*/
|
|
20
|
-
export declare const errorInspectRule = "\nrule:\n pattern: require(\"./node-environment-extensions/error-inspect\");\nfix: |-\n // Removed by OpenNext\n // require(\"./node-environment-extensions/error-inspect\");\n";
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Patches to avoid pulling babel (~4MB).
|
|
3
|
-
*
|
|
4
|
-
* Details:
|
|
5
|
-
* - empty `NextServer#runMiddleware` and `NextServer#runEdgeFunction` that are not used
|
|
6
|
-
* - drop `next/dist/server/node-environment-extensions/error-inspect.js`
|
|
7
|
-
*/
|
|
8
|
-
import { getCrossPlatformPathRegex } from "../../../utils/regex.js";
|
|
9
|
-
import { patchCode } from "../astCodePatcher.js";
|
|
10
|
-
export const patchDropBabel = {
|
|
11
|
-
name: "patch-drop-babel",
|
|
12
|
-
patches: [
|
|
13
|
-
// Empty the body of `NextServer#runMiddleware`
|
|
14
|
-
{
|
|
15
|
-
field: {
|
|
16
|
-
pathFilter: getCrossPlatformPathRegex(String.raw `/next/dist/server/next-server\.js$`, {
|
|
17
|
-
escape: false,
|
|
18
|
-
}),
|
|
19
|
-
contentFilter: /runMiddleware\(/,
|
|
20
|
-
patchCode: async ({ code }) => patchCode(code, createEmptyBodyRule("runMiddleware")),
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
// Empty the body of `NextServer#runEdgeFunction`
|
|
24
|
-
{
|
|
25
|
-
field: {
|
|
26
|
-
pathFilter: getCrossPlatformPathRegex(String.raw `/next/dist/server/next-server\.js$`, {
|
|
27
|
-
escape: false,
|
|
28
|
-
}),
|
|
29
|
-
contentFilter: /runEdgeFunction\(/,
|
|
30
|
-
patchCode: async ({ code }) => patchCode(code, createEmptyBodyRule("runEdgeFunction")),
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
// Drop `error-inspect` that pulls babel
|
|
34
|
-
{
|
|
35
|
-
field: {
|
|
36
|
-
pathFilter: getCrossPlatformPathRegex(String.raw `next/dist/server/node-environment\.js$`, {
|
|
37
|
-
escape: false,
|
|
38
|
-
}),
|
|
39
|
-
contentFilter: /error-inspect/,
|
|
40
|
-
patchCode: async ({ code }) => patchCode(code, errorInspectRule),
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Swaps the body for a throwing implementation
|
|
47
|
-
*
|
|
48
|
-
* @param methodName The name of the method
|
|
49
|
-
* @returns A rule to replace the body with a `throw`
|
|
50
|
-
*/
|
|
51
|
-
export function createEmptyBodyRule(methodName) {
|
|
52
|
-
return `
|
|
53
|
-
rule:
|
|
54
|
-
pattern:
|
|
55
|
-
selector: method_definition
|
|
56
|
-
context: "class { async ${methodName}($$$PARAMS) { $$$_ } }"
|
|
57
|
-
fix: |-
|
|
58
|
-
async ${methodName}($$$PARAMS) {
|
|
59
|
-
throw new Error("${methodName} should not be called with OpenNext");
|
|
60
|
-
}
|
|
61
|
-
`;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
65
|
-
*/
|
|
66
|
-
export const errorInspectRule = `
|
|
67
|
-
rule:
|
|
68
|
-
pattern: require("./node-environment-extensions/error-inspect");
|
|
69
|
-
fix: |-
|
|
70
|
-
// Removed by OpenNext
|
|
71
|
-
// require("./node-environment-extensions/error-inspect");
|
|
72
|
-
`;
|