@opennextjs/aws 3.4.0 → 3.4.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/cache.js +17 -12
- package/dist/adapters/logger.js +2 -2
- package/dist/build/createAssets.js +2 -2
- package/dist/build/createServerBundle.js +4 -5
- package/dist/build/generateOutput.js +1 -1
- package/dist/build/helper.d.ts +11 -2
- package/dist/build/helper.js +28 -5
- package/dist/core/edgeFunctionHandler.js +2 -1
- package/dist/core/routing/cacheInterceptor.js +5 -2
- package/dist/core/routing/matcher.js +4 -2
- package/dist/overrides/incrementalCache/multi-tier-ddb-s3.js +1 -1
- package/dist/overrides/proxyExternalRequest/fetch.js +2 -1
- package/dist/overrides/tagCache/dynamodb-lite.js +8 -4
- package/dist/overrides/tagCache/dynamodb.js +8 -4
- package/dist/overrides/wrappers/cloudflare-node.js +5 -0
- package/dist/types/global.d.ts +12 -11
- package/dist/types/overrides.d.ts +1 -1
- package/package.json +1 -1
package/dist/adapters/cache.js
CHANGED
|
@@ -16,7 +16,7 @@ export default class Cache {
|
|
|
16
16
|
async get(key,
|
|
17
17
|
// fetchCache is for next 13.5 and above, kindHint is for next 14 and above and boolean is for earlier versions
|
|
18
18
|
options) {
|
|
19
|
-
if (globalThis.disableIncrementalCache) {
|
|
19
|
+
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
const softTags = typeof options === "object" ? options.softTags : [];
|
|
@@ -28,14 +28,14 @@ export default class Cache {
|
|
|
28
28
|
async getFetchCache(key, softTags, tags) {
|
|
29
29
|
debug("get fetch cache", { key, softTags, tags });
|
|
30
30
|
try {
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const cachedEntry = await globalThis.incrementalCache.get(key, true);
|
|
32
|
+
if (cachedEntry?.value === undefined)
|
|
33
|
+
return null;
|
|
34
|
+
const _lastModified = await globalThis.tagCache.getLastModified(key, cachedEntry?.lastModified);
|
|
33
35
|
if (_lastModified === -1) {
|
|
34
36
|
// If some tags are stale we need to force revalidation
|
|
35
37
|
return null;
|
|
36
38
|
}
|
|
37
|
-
if (value === undefined)
|
|
38
|
-
return null;
|
|
39
39
|
// For cases where we don't have tags, we need to ensure that the soft tags are not being revalidated
|
|
40
40
|
// We only need to check for the path as it should already contain all the tags
|
|
41
41
|
if ((tags ?? []).length === 0) {
|
|
@@ -44,7 +44,7 @@ export default class Cache {
|
|
|
44
44
|
!tag.endsWith("layout") &&
|
|
45
45
|
!tag.endsWith("page"));
|
|
46
46
|
if (path) {
|
|
47
|
-
const pathLastModified = await globalThis.tagCache.getLastModified(path.replace("_N_T_/", ""), lastModified);
|
|
47
|
+
const pathLastModified = await globalThis.tagCache.getLastModified(path.replace("_N_T_/", ""), cachedEntry.lastModified);
|
|
48
48
|
if (pathLastModified === -1) {
|
|
49
49
|
// In case the path has been revalidated, we don't want to use the fetch cache
|
|
50
50
|
return null;
|
|
@@ -53,7 +53,7 @@ export default class Cache {
|
|
|
53
53
|
}
|
|
54
54
|
return {
|
|
55
55
|
lastModified: _lastModified,
|
|
56
|
-
value: value,
|
|
56
|
+
value: cachedEntry.value,
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
catch (e) {
|
|
@@ -64,13 +64,17 @@ export default class Cache {
|
|
|
64
64
|
}
|
|
65
65
|
async getIncrementalCache(key) {
|
|
66
66
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const cachedEntry = await globalThis.incrementalCache.get(key, false);
|
|
68
|
+
if (!cachedEntry?.value) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const meta = cachedEntry.value.meta;
|
|
72
|
+
const _lastModified = await globalThis.tagCache.getLastModified(key, cachedEntry?.lastModified);
|
|
70
73
|
if (_lastModified === -1) {
|
|
71
74
|
// If some tags are stale we need to force revalidation
|
|
72
75
|
return null;
|
|
73
76
|
}
|
|
77
|
+
const cacheData = cachedEntry?.value;
|
|
74
78
|
const requestId = globalThis.__openNextAls.getStore()?.requestId ?? "";
|
|
75
79
|
globalThis.lastModified[requestId] = _lastModified;
|
|
76
80
|
if (cacheData?.type === "route") {
|
|
@@ -130,7 +134,7 @@ export default class Cache {
|
|
|
130
134
|
}
|
|
131
135
|
}
|
|
132
136
|
async set(key, data, ctx) {
|
|
133
|
-
if (globalThis.disableIncrementalCache) {
|
|
137
|
+
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
|
|
134
138
|
return;
|
|
135
139
|
}
|
|
136
140
|
// This one might not even be necessary anymore
|
|
@@ -242,7 +246,8 @@ export default class Cache {
|
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
async revalidateTag(tags) {
|
|
245
|
-
|
|
249
|
+
const config = globalThis.openNextConfig.dangerous;
|
|
250
|
+
if (config?.disableTagCache || config?.disableIncrementalCache) {
|
|
246
251
|
return;
|
|
247
252
|
}
|
|
248
253
|
try {
|
package/dist/adapters/logger.js
CHANGED
|
@@ -21,9 +21,9 @@ const isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplaye
|
|
|
21
21
|
export function error(...args) {
|
|
22
22
|
// we try to catch errors from the aws-sdk client and downplay some of them
|
|
23
23
|
if (args.some((arg) => isDownplayedErrorLog(arg))) {
|
|
24
|
-
debug(...args);
|
|
24
|
+
return debug(...args);
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
if (args.some((arg) => isOpenNextError(arg))) {
|
|
27
27
|
// In case of an internal error, we log it with the appropriate log level
|
|
28
28
|
const error = args.find((arg) => isOpenNextError(arg));
|
|
29
29
|
if (error.logLevel < getOpenNextErrorLogLevel()) {
|
|
@@ -44,8 +44,8 @@ export function createStaticAssets(options) {
|
|
|
44
44
|
export function createCacheAssets(options) {
|
|
45
45
|
logger.info("Bundling cache assets...");
|
|
46
46
|
const { appBuildOutputPath, outputDir } = options;
|
|
47
|
-
const packagePath =
|
|
48
|
-
const buildId = buildHelper.getBuildId(
|
|
47
|
+
const packagePath = buildHelper.getPackagePath(options);
|
|
48
|
+
const buildId = buildHelper.getBuildId(options);
|
|
49
49
|
let useTagCache = false;
|
|
50
50
|
// Copy pages to cache folder
|
|
51
51
|
const dotNextPath = path.join(appBuildOutputPath, ".next/standalone", packagePath);
|
|
@@ -36,10 +36,9 @@ export async function createServerBundle(options) {
|
|
|
36
36
|
// We build every other function than default before so we know which route there is left
|
|
37
37
|
await Promise.all(promises);
|
|
38
38
|
const remainingRoutes = new Set();
|
|
39
|
-
const { appBuildOutputPath
|
|
40
|
-
const packagePath = path.relative(monorepoRoot, appBuildOutputPath);
|
|
39
|
+
const { appBuildOutputPath } = options;
|
|
41
40
|
// Find remaining routes
|
|
42
|
-
const serverPath = path.join(appBuildOutputPath, ".next
|
|
41
|
+
const serverPath = path.join(appBuildOutputPath, ".next/standalone", buildHelper.getPackagePath(options), ".next/server");
|
|
43
42
|
// Find app dir routes
|
|
44
43
|
if (fs.existsSync(path.join(serverPath, "app"))) {
|
|
45
44
|
const appPath = path.join(serverPath, "app");
|
|
@@ -78,7 +77,7 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
78
77
|
// `node_modules` inside `.next/standalone`, and others inside
|
|
79
78
|
// `.next/standalone/package/path` (ie. `.next`, `server.js`).
|
|
80
79
|
// We need to output the handler file inside the package path.
|
|
81
|
-
const packagePath =
|
|
80
|
+
const packagePath = buildHelper.getPackagePath(options);
|
|
82
81
|
fs.mkdirSync(path.join(outputPath, packagePath), { recursive: true });
|
|
83
82
|
const ext = fnOptions.runtime === "deno" ? "mjs" : "cjs";
|
|
84
83
|
fs.copyFileSync(path.join(options.buildDir, `cache.${ext}`), path.join(outputPath, packagePath, "cache.cjs"));
|
|
@@ -110,7 +109,7 @@ async function generateBundle(name, options, fnOptions) {
|
|
|
110
109
|
buildHelper.compareSemver(options.nextVersion, "13.4.1") <= 0;
|
|
111
110
|
const overrides = fnOptions.override ?? {};
|
|
112
111
|
const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "13.4.13") <= 0;
|
|
113
|
-
const isAfter141 = buildHelper.compareSemver(options.nextVersion, "14.
|
|
112
|
+
const isAfter141 = buildHelper.compareSemver(options.nextVersion, "14.1") >= 0;
|
|
114
113
|
const disableRouting = isBefore13413 || config.middleware?.external;
|
|
115
114
|
const plugins = [
|
|
116
115
|
openNextReplacementPlugin({
|
|
@@ -167,7 +167,7 @@ export async function generateOutput(options) {
|
|
|
167
167
|
const patterns = "patterns" in value ? value.patterns : ["*"];
|
|
168
168
|
patterns.forEach((pattern) => {
|
|
169
169
|
behaviors.push({
|
|
170
|
-
pattern: prefixer(pattern.replace(/BUILD_ID/, getBuildId(
|
|
170
|
+
pattern: prefixer(pattern.replace(/BUILD_ID/, getBuildId(options))),
|
|
171
171
|
origin: value.placement === "global" ? undefined : key,
|
|
172
172
|
edgeFunction: value.placement === "global"
|
|
173
173
|
? key
|
package/dist/build/helper.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare function normalizeOptions(config: OpenNextConfig, distDir: string
|
|
|
15
15
|
openNextVersion: string;
|
|
16
16
|
openNextDistDir: string;
|
|
17
17
|
outputDir: string;
|
|
18
|
-
packager: "
|
|
18
|
+
packager: "bun" | "npm" | "yarn" | "pnpm";
|
|
19
19
|
tempBuildDir: string;
|
|
20
20
|
};
|
|
21
21
|
export declare function esbuildSync(esbuildOptions: ESBuildOptions, options: BuildOptions): void;
|
|
@@ -48,9 +48,17 @@ export declare function traverseFiles(root: string, conditionFn: (paths: Travers
|
|
|
48
48
|
*/
|
|
49
49
|
export declare function removeFiles(root: string, conditionFn: (paths: TraversePath) => boolean): void;
|
|
50
50
|
export declare function getHtmlPages(dotNextPath: string): Set<string>;
|
|
51
|
-
export declare function getBuildId(
|
|
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
|
+
/**
|
|
55
|
+
* Compare two semver versions.
|
|
56
|
+
*
|
|
57
|
+
* @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
|
+
* @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
|
+
* @example
|
|
60
|
+
* compareSemver("1.0.0", "1.0.0") // 0
|
|
61
|
+
*/
|
|
54
62
|
export declare function compareSemver(v1: string, v2: string): number;
|
|
55
63
|
export declare function copyOpenNextConfig(inputDir: string, outputDir: string, isEdge?: boolean): void;
|
|
56
64
|
export declare function copyEnvFile(appPath: string, packagePath: string, outputPath: string): void;
|
|
@@ -73,3 +81,4 @@ export declare function initOutputDir(options: BuildOptions): void;
|
|
|
73
81
|
* @returns Whether the edge runtime is used
|
|
74
82
|
*/
|
|
75
83
|
export declare function isEdgeRuntime(overrides: DefaultOverrideOptions | undefined): Promise<boolean | undefined>;
|
|
84
|
+
export declare function getPackagePath(options: BuildOptions): string;
|
package/dist/build/helper.js
CHANGED
|
@@ -45,10 +45,12 @@ function findMonorepoRoot(appPath) {
|
|
|
45
45
|
let currentPath = appPath;
|
|
46
46
|
while (currentPath !== "/") {
|
|
47
47
|
const found = [
|
|
48
|
+
// bun can generate yaml lock files (`bun install --yarn`) so bun should be before yarn
|
|
49
|
+
{ file: "bun.lockb", packager: "bun" },
|
|
50
|
+
{ file: "bun.lock", packager: "bun" },
|
|
48
51
|
{ file: "package-lock.json", packager: "npm" },
|
|
49
52
|
{ file: "yarn.lock", packager: "yarn" },
|
|
50
53
|
{ file: "pnpm-lock.yaml", packager: "pnpm" },
|
|
51
|
-
{ file: "bun.lockb", packager: "bun" },
|
|
52
54
|
].find((f) => fs.existsSync(path.join(currentPath, f.file)));
|
|
53
55
|
if (found) {
|
|
54
56
|
if (currentPath !== appPath) {
|
|
@@ -99,12 +101,15 @@ export function esbuildSync(esbuildOptions, options) {
|
|
|
99
101
|
}
|
|
100
102
|
export async function esbuildAsync(esbuildOptions, options) {
|
|
101
103
|
const { openNextVersion, debug, minify } = options;
|
|
104
|
+
// Dump ESBuild build metadata to file in debug mode
|
|
105
|
+
const metafile = debug && esbuildOptions.outfile !== undefined;
|
|
102
106
|
const result = await buildAsync({
|
|
103
107
|
target: "esnext",
|
|
104
108
|
format: "esm",
|
|
105
109
|
platform: "node",
|
|
106
110
|
bundle: true,
|
|
107
111
|
minify,
|
|
112
|
+
metafile,
|
|
108
113
|
mainFields: ["module", "main"],
|
|
109
114
|
sourcemap: debug ? "inline" : false,
|
|
110
115
|
sourcesContent: false,
|
|
@@ -127,6 +132,10 @@ export async function esbuildAsync(esbuildOptions, options) {
|
|
|
127
132
|
result.errors.forEach((error) => logger.error(error));
|
|
128
133
|
throw new Error(`There was a problem bundling ${esbuildOptions.entryPoints[0]}.`);
|
|
129
134
|
}
|
|
135
|
+
if (result.metafile) {
|
|
136
|
+
const metaFile = `${esbuildOptions.outfile}.meta.json`;
|
|
137
|
+
fs.writeFileSync(metaFile, JSON.stringify(result.metafile, null, 2));
|
|
138
|
+
}
|
|
130
139
|
}
|
|
131
140
|
/**
|
|
132
141
|
* Recursively traverse files in a directory and call `callbackFn` when `conditionFn` returns true
|
|
@@ -178,9 +187,9 @@ export function getHtmlPages(dotNextPath) {
|
|
|
178
187
|
.map(([_, value]) => value.replace(/^pages\//, ""))
|
|
179
188
|
.reduce((acc, page) => acc.add(page), new Set());
|
|
180
189
|
}
|
|
181
|
-
export function getBuildId(
|
|
190
|
+
export function getBuildId(options) {
|
|
182
191
|
return fs
|
|
183
|
-
.readFileSync(path.join(
|
|
192
|
+
.readFileSync(path.join(options.appBuildOutputPath, ".next/BUILD_ID"), "utf-8")
|
|
184
193
|
.trim();
|
|
185
194
|
}
|
|
186
195
|
export function getOpenNextVersion() {
|
|
@@ -198,6 +207,14 @@ export function getNextVersion(appPath) {
|
|
|
198
207
|
// Drop the -canary.n suffix
|
|
199
208
|
return version.split("-")[0];
|
|
200
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Compare two semver versions.
|
|
212
|
+
*
|
|
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
|
+
* @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
|
+
* @example
|
|
216
|
+
* compareSemver("1.0.0", "1.0.0") // 0
|
|
217
|
+
*/
|
|
201
218
|
export function compareSemver(v1, v2) {
|
|
202
219
|
if (v1 === "latest")
|
|
203
220
|
return 1;
|
|
@@ -209,8 +226,11 @@ export function compareSemver(v1, v2) {
|
|
|
209
226
|
// biome-ignore lint/style/noParameterAssign:
|
|
210
227
|
v2 = v2.substring(1);
|
|
211
228
|
}
|
|
212
|
-
const [major1, minor1, patch1] = v1.split(".").map(Number);
|
|
213
|
-
const [major2, minor2, patch2] = v2.split(".").map(Number);
|
|
229
|
+
const [major1, minor1 = 0, patch1 = 0] = v1.split(".").map(Number);
|
|
230
|
+
const [major2, minor2 = 0, patch2 = 0] = v2.split(".").map(Number);
|
|
231
|
+
if (Number.isNaN(major1) || Number.isNaN(major2)) {
|
|
232
|
+
throw new Error("The major version is required.");
|
|
233
|
+
}
|
|
214
234
|
if (major1 !== major2)
|
|
215
235
|
return major1 - major2;
|
|
216
236
|
if (minor1 !== minor2)
|
|
@@ -276,3 +296,6 @@ export async function isEdgeRuntime(overrides) {
|
|
|
276
296
|
}
|
|
277
297
|
return (await overrides?.wrapper?.())?.edgeRuntime;
|
|
278
298
|
}
|
|
299
|
+
export function getPackagePath(options) {
|
|
300
|
+
return path.relative(options.monorepoRoot, options.appBuildOutputPath);
|
|
301
|
+
}
|
|
@@ -6,7 +6,8 @@ export default async function edgeFunctionHandler(request) {
|
|
|
6
6
|
if (!correspondingRoute) {
|
|
7
7
|
throw new Error(`No route found for ${request.url}`);
|
|
8
8
|
}
|
|
9
|
-
const
|
|
9
|
+
const entry = await self._ENTRIES[`middleware_${correspondingRoute.name}`];
|
|
10
|
+
const result = await entry.default({
|
|
10
11
|
page: correspondingRoute.page,
|
|
11
12
|
request: {
|
|
12
13
|
...request,
|
|
@@ -120,7 +120,10 @@ export async function cacheInterceptor(event) {
|
|
|
120
120
|
try {
|
|
121
121
|
const cachedData = await globalThis.incrementalCache.get(localizedPath);
|
|
122
122
|
debug("cached data in interceptor", cachedData);
|
|
123
|
-
if (cachedData
|
|
123
|
+
if (!cachedData?.value) {
|
|
124
|
+
return event;
|
|
125
|
+
}
|
|
126
|
+
if (cachedData?.value?.type === "app") {
|
|
124
127
|
// We need to check the tag cache now
|
|
125
128
|
const _lastModified = await globalThis.tagCache.getLastModified(localizedPath, cachedData.lastModified);
|
|
126
129
|
if (_lastModified === -1) {
|
|
@@ -129,7 +132,7 @@ export async function cacheInterceptor(event) {
|
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
134
|
const host = event.headers.host;
|
|
132
|
-
switch (cachedData
|
|
135
|
+
switch (cachedData?.value?.type) {
|
|
133
136
|
case "app":
|
|
134
137
|
case "page":
|
|
135
138
|
return generateResult(event, localizedPath, cachedData.value, cachedData.lastModified);
|
|
@@ -166,8 +166,9 @@ export function handleRewrites(event, rewrites) {
|
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
168
|
function handleTrailingSlashRedirect(event) {
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
// When rawPath is `//domain`, `url.host` would be `domain`.
|
|
170
|
+
// https://github.com/opennextjs/opennextjs-aws/issues/355
|
|
171
|
+
const url = new URL(event.rawPath, "http://localhost");
|
|
171
172
|
if (
|
|
172
173
|
// Someone is trying to redirect to a different origin, let's not do that
|
|
173
174
|
url.host !== "localhost" ||
|
|
@@ -176,6 +177,7 @@ function handleTrailingSlashRedirect(event) {
|
|
|
176
177
|
event.rawPath.startsWith("/api/")) {
|
|
177
178
|
return false;
|
|
178
179
|
}
|
|
180
|
+
const emptyBody = emptyReadableStream();
|
|
179
181
|
if (NextConfig.trailingSlash &&
|
|
180
182
|
!event.headers["x-nextjs-data"] &&
|
|
181
183
|
!event.rawPath.endsWith("/") &&
|
|
@@ -3,7 +3,8 @@ const fetchProxy = {
|
|
|
3
3
|
name: "fetch-proxy",
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
proxy: async (internalEvent) => {
|
|
6
|
-
const { url, headers, method, body } = internalEvent;
|
|
6
|
+
const { url, headers: eventHeaders, method, body } = internalEvent;
|
|
7
|
+
const headers = Object.fromEntries(Object.entries(eventHeaders).filter(([key]) => key.toLowerCase() !== "cf-connecting-ip"));
|
|
7
8
|
const response = await fetch(url, {
|
|
8
9
|
method,
|
|
9
10
|
headers,
|
|
@@ -49,8 +49,9 @@ function buildDynamoObject(path, tags, revalidatedAt) {
|
|
|
49
49
|
const tagCache = {
|
|
50
50
|
async getByPath(path) {
|
|
51
51
|
try {
|
|
52
|
-
if (globalThis.
|
|
52
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
53
53
|
return [];
|
|
54
|
+
}
|
|
54
55
|
const { CACHE_DYNAMO_TABLE, NEXT_BUILD_ID } = process.env;
|
|
55
56
|
const result = await awsFetch(JSON.stringify({
|
|
56
57
|
TableName: CACHE_DYNAMO_TABLE,
|
|
@@ -79,8 +80,9 @@ const tagCache = {
|
|
|
79
80
|
},
|
|
80
81
|
async getByTag(tag) {
|
|
81
82
|
try {
|
|
82
|
-
if (globalThis.
|
|
83
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
83
84
|
return [];
|
|
85
|
+
}
|
|
84
86
|
const { CACHE_DYNAMO_TABLE, NEXT_BUILD_ID } = process.env;
|
|
85
87
|
const result = await awsFetch(JSON.stringify({
|
|
86
88
|
TableName: CACHE_DYNAMO_TABLE,
|
|
@@ -107,8 +109,9 @@ const tagCache = {
|
|
|
107
109
|
},
|
|
108
110
|
async getLastModified(key, lastModified) {
|
|
109
111
|
try {
|
|
110
|
-
if (globalThis.
|
|
112
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
111
113
|
return lastModified ?? Date.now();
|
|
114
|
+
}
|
|
112
115
|
const { CACHE_DYNAMO_TABLE } = process.env;
|
|
113
116
|
const result = await awsFetch(JSON.stringify({
|
|
114
117
|
TableName: CACHE_DYNAMO_TABLE,
|
|
@@ -139,8 +142,9 @@ const tagCache = {
|
|
|
139
142
|
async writeTags(tags) {
|
|
140
143
|
try {
|
|
141
144
|
const { CACHE_DYNAMO_TABLE } = process.env;
|
|
142
|
-
if (globalThis.
|
|
145
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
143
146
|
return;
|
|
147
|
+
}
|
|
144
148
|
const dataChunks = chunk(tags, MAX_DYNAMO_BATCH_WRITE_ITEM_COUNT).map((Items) => ({
|
|
145
149
|
RequestItems: {
|
|
146
150
|
[CACHE_DYNAMO_TABLE ?? ""]: Items.map((Item) => ({
|
|
@@ -27,8 +27,9 @@ function buildDynamoObject(path, tags, revalidatedAt) {
|
|
|
27
27
|
const tagCache = {
|
|
28
28
|
async getByPath(path) {
|
|
29
29
|
try {
|
|
30
|
-
if (globalThis.
|
|
30
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
31
31
|
return [];
|
|
32
|
+
}
|
|
32
33
|
const result = await dynamoClient.send(new QueryCommand({
|
|
33
34
|
TableName: CACHE_DYNAMO_TABLE,
|
|
34
35
|
IndexName: "revalidate",
|
|
@@ -52,8 +53,9 @@ const tagCache = {
|
|
|
52
53
|
},
|
|
53
54
|
async getByTag(tag) {
|
|
54
55
|
try {
|
|
55
|
-
if (globalThis.
|
|
56
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
56
57
|
return [];
|
|
58
|
+
}
|
|
57
59
|
const { Items } = await dynamoClient.send(new QueryCommand({
|
|
58
60
|
TableName: CACHE_DYNAMO_TABLE,
|
|
59
61
|
KeyConditionExpression: "#tag = :tag",
|
|
@@ -75,8 +77,9 @@ const tagCache = {
|
|
|
75
77
|
},
|
|
76
78
|
async getLastModified(key, lastModified) {
|
|
77
79
|
try {
|
|
78
|
-
if (globalThis.
|
|
80
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
79
81
|
return lastModified ?? Date.now();
|
|
82
|
+
}
|
|
80
83
|
const result = await dynamoClient.send(new QueryCommand({
|
|
81
84
|
TableName: CACHE_DYNAMO_TABLE,
|
|
82
85
|
IndexName: "revalidate",
|
|
@@ -102,8 +105,9 @@ const tagCache = {
|
|
|
102
105
|
},
|
|
103
106
|
async writeTags(tags) {
|
|
104
107
|
try {
|
|
105
|
-
if (globalThis.
|
|
108
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
106
109
|
return;
|
|
110
|
+
}
|
|
107
111
|
const dataChunks = chunk(tags, MAX_DYNAMO_BATCH_WRITE_ITEM_COUNT).map((Items) => ({
|
|
108
112
|
RequestItems: {
|
|
109
113
|
[CACHE_DYNAMO_TABLE ?? ""]: Items.map((Item) => ({
|
|
@@ -26,6 +26,11 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
|
|
|
26
26
|
for (const cookie of cookies) {
|
|
27
27
|
responseHeaders.append("Set-Cookie", cookie);
|
|
28
28
|
}
|
|
29
|
+
// TODO(vicb): this is a workaround to make PPR work with `wrangler dev`
|
|
30
|
+
// See https://github.com/cloudflare/workers-sdk/issues/8004
|
|
31
|
+
if (url.hostname === "localhost") {
|
|
32
|
+
responseHeaders.set("Content-Encoding", "identity");
|
|
33
|
+
}
|
|
29
34
|
const { readable, writable } = new TransformStream({
|
|
30
35
|
transform(chunk, controller) {
|
|
31
36
|
controller.enqueue(Uint8Array.from(chunk.chunk ?? chunk));
|
package/dist/types/global.d.ts
CHANGED
|
@@ -29,16 +29,17 @@ export interface RequestData {
|
|
|
29
29
|
body?: ReadableStream<Uint8Array>;
|
|
30
30
|
signal: AbortSignal;
|
|
31
31
|
}
|
|
32
|
+
interface Entry {
|
|
33
|
+
default: (props: {
|
|
34
|
+
page: string;
|
|
35
|
+
request: RequestData;
|
|
36
|
+
}) => Promise<{
|
|
37
|
+
response: Response;
|
|
38
|
+
waitUntil: Promise<void>;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
32
41
|
interface Entries {
|
|
33
|
-
[k: string]:
|
|
34
|
-
default: (props: {
|
|
35
|
-
page: string;
|
|
36
|
-
request: RequestData;
|
|
37
|
-
}) => Promise<{
|
|
38
|
-
response: Response;
|
|
39
|
-
waitUntil: Promise<void>;
|
|
40
|
-
}>;
|
|
41
|
-
};
|
|
42
|
+
[k: string]: Entry | Promise<Entry>;
|
|
42
43
|
}
|
|
43
44
|
export interface EdgeRoute {
|
|
44
45
|
name: string;
|
|
@@ -66,13 +67,13 @@ declare global {
|
|
|
66
67
|
var tagCache: TagCache;
|
|
67
68
|
/**
|
|
68
69
|
* A boolean that indicates if the DynamoDB cache is disabled.
|
|
69
|
-
*
|
|
70
|
+
* @deprecated This will be removed, use `globalThis.openNextConfig.dangerous?.disableTagCache` instead.
|
|
70
71
|
* Defined in esbuild banner for the cache adapter.
|
|
71
72
|
*/
|
|
72
73
|
var disableDynamoDBCache: boolean;
|
|
73
74
|
/**
|
|
74
75
|
* A boolean that indicates if the incremental cache is disabled.
|
|
75
|
-
*
|
|
76
|
+
* @deprecated This will be removed, use `globalThis.openNextConfig.dangerous?.disableIncrementalCache` instead.
|
|
76
77
|
* Defined in esbuild banner for the cache adapter.
|
|
77
78
|
*/
|
|
78
79
|
var disableIncrementalCache: boolean;
|
|
@@ -41,7 +41,7 @@ export type CacheValue<IsFetch extends boolean> = (IsFetch extends true ? FetchC
|
|
|
41
41
|
revalidate?: number | false;
|
|
42
42
|
};
|
|
43
43
|
export type IncrementalCache = {
|
|
44
|
-
get<IsFetch extends boolean = false>(key: string, isFetch?: IsFetch): Promise<WithLastModified<CacheValue<IsFetch
|
|
44
|
+
get<IsFetch extends boolean = false>(key: string, isFetch?: IsFetch): Promise<WithLastModified<CacheValue<IsFetch>> | null>;
|
|
45
45
|
set<IsFetch extends boolean = false>(key: string, value: CacheValue<IsFetch>, isFetch?: IsFetch): Promise<void>;
|
|
46
46
|
delete(key: string): Promise<void>;
|
|
47
47
|
name: string;
|