@opennextjs/aws 3.2.1 → 3.2.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/README.md +15 -1
- package/dist/adapters/cache.d.ts +0 -23
- package/dist/adapters/cache.js +10 -12
- package/dist/adapters/config/index.js +1 -1
- package/dist/adapters/config/util.js +2 -2
- package/dist/adapters/dynamo-provider.js +3 -5
- package/dist/adapters/edge-adapter.d.ts +0 -3
- package/dist/adapters/edge-adapter.js +43 -38
- package/dist/adapters/image-optimization-adapter.js +4 -4
- package/dist/adapters/logger.d.ts +0 -3
- package/dist/adapters/logger.js +3 -5
- package/dist/adapters/middleware.js +42 -18
- package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +0 -3
- package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +0 -3
- package/dist/adapters/revalidate.js +2 -2
- package/dist/adapters/server-adapter.d.ts +0 -3
- package/dist/adapters/server-adapter.js +3 -1
- package/dist/adapters/util.js +2 -2
- package/dist/build/bundleNextServer.d.ts +3 -1
- package/dist/build/bundleNextServer.js +3 -3
- package/dist/build/compileConfig.js +1 -1
- package/dist/build/copyTracedFiles.js +14 -25
- package/dist/build/createAssets.js +35 -26
- package/dist/build/createImageOptimizationBundle.js +1 -1
- package/dist/build/createMiddleware.js +7 -2
- package/dist/build/createRevalidationBundle.js +1 -1
- package/dist/build/createServerBundle.js +23 -29
- package/dist/build/createWarmerBundle.js +1 -1
- package/dist/build/edge/createEdgeBundle.d.ts +7 -3
- package/dist/build/edge/createEdgeBundle.js +12 -5
- package/dist/build/generateOutput.js +7 -13
- package/dist/build/helper.d.ts +22 -4
- package/dist/build/helper.js +26 -12
- package/dist/build/installDeps.js +1 -1
- package/dist/build/patch/patchedAsyncStorage.js +1 -1
- package/dist/build/utils.js +3 -2
- package/dist/build/validateConfig.js +1 -0
- package/dist/core/createGenericHandler.d.ts +2 -4
- package/dist/core/createGenericHandler.js +1 -2
- package/dist/core/createMainHandler.d.ts +0 -17
- package/dist/core/createMainHandler.js +5 -4
- package/dist/core/edgeFunctionHandler.d.ts +1 -51
- package/dist/core/patchAsyncStorage.js +5 -6
- package/dist/core/requestHandler.js +98 -89
- package/dist/core/require-hooks.js +8 -7
- package/dist/core/resolve.d.ts +13 -7
- package/dist/core/resolve.js +29 -35
- package/dist/core/routing/cacheInterceptor.js +12 -13
- package/dist/core/routing/i18n/accept-header.js +3 -2
- package/dist/core/routing/matcher.d.ts +2 -4
- package/dist/core/routing/matcher.js +17 -26
- package/dist/core/routing/middleware.js +17 -16
- package/dist/core/routing/util.d.ts +0 -13
- package/dist/core/routing/util.js +25 -87
- package/dist/core/routingHandler.d.ts +2 -0
- package/dist/core/routingHandler.js +30 -12
- package/dist/core/util.js +5 -3
- package/dist/helpers/withSST.d.ts +1 -1
- package/dist/http/openNextResponse.d.ts +5 -9
- package/dist/http/openNextResponse.js +29 -31
- package/dist/http/request.d.ts +0 -3
- package/dist/http/request.js +4 -2
- package/dist/http/util.d.ts +1 -1
- package/dist/http/util.js +8 -12
- package/dist/minimize-js.js +19 -19
- package/dist/overrides/converters/aws-apigw-v1.d.ts +2 -2
- package/dist/overrides/converters/aws-apigw-v1.js +2 -1
- package/dist/overrides/converters/aws-apigw-v2.d.ts +2 -2
- package/dist/overrides/converters/aws-apigw-v2.js +6 -7
- package/dist/overrides/converters/aws-cloudfront.d.ts +2 -2
- package/dist/overrides/converters/aws-cloudfront.js +11 -30
- package/dist/overrides/converters/dummy.d.ts +1 -1
- package/dist/overrides/converters/edge.d.ts +2 -1
- package/dist/overrides/converters/edge.js +11 -15
- package/dist/overrides/converters/node.d.ts +1 -1
- package/dist/overrides/converters/node.js +1 -1
- package/dist/overrides/converters/sqs-revalidate.d.ts +1 -1
- package/dist/overrides/imageLoader/dummy.d.ts +1 -1
- package/dist/overrides/imageLoader/host.d.ts +1 -1
- package/dist/overrides/imageLoader/s3.d.ts +1 -1
- package/dist/overrides/imageLoader/s3.js +1 -1
- package/dist/overrides/incrementalCache/dummy.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3-lite.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3-lite.js +15 -19
- package/dist/overrides/incrementalCache/s3.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3.js +1 -1
- package/dist/overrides/originResolver/dummy.d.ts +1 -1
- package/dist/overrides/originResolver/pattern-env.d.ts +1 -1
- package/dist/overrides/originResolver/pattern-env.js +10 -11
- package/dist/overrides/proxyExternalRequest/dummy.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/dummy.js +7 -0
- package/dist/overrides/proxyExternalRequest/fetch.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/fetch.js +25 -0
- package/dist/overrides/proxyExternalRequest/node.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/node.js +67 -0
- package/dist/overrides/queue/dummy.d.ts +1 -1
- package/dist/overrides/queue/sqs-lite.d.ts +1 -1
- package/dist/overrides/queue/sqs-lite.js +7 -9
- package/dist/overrides/queue/sqs.d.ts +1 -1
- package/dist/overrides/queue/sqs.js +1 -1
- package/dist/overrides/tagCache/constants.js +2 -2
- package/dist/overrides/tagCache/dummy.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb-lite.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb-lite.js +10 -12
- package/dist/overrides/tagCache/dynamodb.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb.js +2 -2
- package/dist/overrides/warmer/aws-lambda.d.ts +1 -1
- package/dist/overrides/warmer/dummy.d.ts +1 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +2 -2
- package/dist/overrides/wrappers/aws-lambda.d.ts +2 -2
- package/dist/overrides/wrappers/cloudflare.d.ts +2 -1
- package/dist/overrides/wrappers/cloudflare.js +20 -2
- package/dist/overrides/wrappers/dummy.d.ts +2 -2
- package/dist/overrides/wrappers/node.d.ts +2 -2
- package/dist/overrides/wrappers/node.js +3 -3
- package/dist/plugins/edge.js +6 -5
- package/dist/plugins/replacement.js +2 -2
- package/dist/plugins/resolve.d.ts +3 -1
- package/dist/plugins/resolve.js +4 -1
- package/dist/types/aws-lambda.d.ts +2 -5
- package/dist/types/cache.d.ts +0 -2
- package/dist/types/global.d.ts +188 -0
- package/dist/types/next-types.d.ts +1 -3
- package/dist/types/open-next.d.ts +15 -41
- package/dist/types/overrides.d.ts +87 -0
- package/dist/utils/promise.d.ts +3 -0
- package/dist/utils/promise.js +44 -0
- package/dist/utils/stream.d.ts +0 -1
- package/package.json +2 -2
- package/dist/overrides/incrementalCache/types.d.ts +0 -34
- package/dist/overrides/queue/types.d.ts +0 -12
- package/dist/overrides/tagCache/types.d.ts +0 -11
- package/dist/overrides/tagCache/types.js +0 -1
- /package/dist/{overrides/incrementalCache/types.js → types/global.js} +0 -0
- /package/dist/{overrides/queue/types.js → types/overrides.js} +0 -0
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ OpenNext aims to support all Next.js 14 features. Some features are work in prog
|
|
|
36
36
|
- [x] Image optimization
|
|
37
37
|
- [x] [NextAuth.js](https://next-auth.js.org)
|
|
38
38
|
- [x] Running at edge
|
|
39
|
-
- [x] [Almost no coldstart (
|
|
39
|
+
- [x] [Almost no coldstart (\*)](#coldstart)
|
|
40
40
|
|
|
41
41
|
## Who is using OpenNext?
|
|
42
42
|
|
|
@@ -56,6 +56,20 @@ This will output A LOT of additional logs to the console. This also disable mini
|
|
|
56
56
|
|
|
57
57
|
You can read more about the configuration in the [docs](https://opennext.js.org/aws/config)
|
|
58
58
|
|
|
59
|
+
## Preleases
|
|
60
|
+
|
|
61
|
+
Besides the standard npm releases we also automatically publish prerelease packages on branch pushes (using [`pkg.pr.new`](https://github.com/stackblitz-labs/pkg.pr.new)):
|
|
62
|
+
|
|
63
|
+
- `https://pkg.pr.new/@opennextjs/aws@main`:
|
|
64
|
+
Updated with every push to the `main` branch, this prerelease contains the most up to date yet (reasonably) stable version of the package.
|
|
65
|
+
- `https://pkg.pr.new/@opennextjs/aws@experimental`
|
|
66
|
+
Updated with every push to the `experimental` branch, this prerelease contains the latest experimental version of the package (containing features that we want to test/experiment on before committing to).
|
|
67
|
+
|
|
68
|
+
Which you can simply install directly with your package manager of choice, for example:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm i https://pkg.pr.new/@opennextjs/aws@main
|
|
72
|
+
```
|
|
59
73
|
|
|
60
74
|
## Contribute
|
|
61
75
|
|
package/dist/adapters/cache.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import type { IncrementalCache } from "../overrides/incrementalCache/types.js";
|
|
4
|
-
import type { TagCache } from "../overrides/tagCache/types.js";
|
|
5
1
|
interface CachedFetchValue {
|
|
6
2
|
kind: "FETCH";
|
|
7
3
|
data: {
|
|
@@ -56,16 +52,6 @@ type IncrementalCacheContext = {
|
|
|
56
52
|
fetchIdx?: number | undefined;
|
|
57
53
|
tags?: string[] | undefined;
|
|
58
54
|
};
|
|
59
|
-
interface CacheHandlerContext {
|
|
60
|
-
fs?: never;
|
|
61
|
-
dev?: boolean;
|
|
62
|
-
flushToDisk?: boolean;
|
|
63
|
-
serverDistDir?: string;
|
|
64
|
-
maxMemoryCacheSize?: number;
|
|
65
|
-
_appDir: boolean;
|
|
66
|
-
_requestHeaders: never;
|
|
67
|
-
fetchCacheKeyPrefix?: string;
|
|
68
|
-
}
|
|
69
55
|
interface CacheHandlerValue {
|
|
70
56
|
lastModified?: number;
|
|
71
57
|
age?: number;
|
|
@@ -73,16 +59,7 @@ interface CacheHandlerValue {
|
|
|
73
59
|
value: IncrementalCacheValue | null;
|
|
74
60
|
}
|
|
75
61
|
export declare function hasCacheExtension(key: string): boolean;
|
|
76
|
-
declare global {
|
|
77
|
-
var incrementalCache: IncrementalCache;
|
|
78
|
-
var tagCache: TagCache;
|
|
79
|
-
var disableDynamoDBCache: boolean;
|
|
80
|
-
var disableIncrementalCache: boolean;
|
|
81
|
-
var lastModified: Record<string, number>;
|
|
82
|
-
var isNextAfter15: boolean;
|
|
83
|
-
}
|
|
84
62
|
export default class S3Cache {
|
|
85
|
-
constructor(_ctx: CacheHandlerContext);
|
|
86
63
|
get(key: string, options?: boolean | {
|
|
87
64
|
fetchCache?: boolean;
|
|
88
65
|
kindHint?: "app" | "pages" | "fetch";
|
package/dist/adapters/cache.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isBinaryContentType } from "./binary
|
|
2
|
-
import { debug, error, warn } from "./logger
|
|
1
|
+
import { isBinaryContentType } from "./binary";
|
|
2
|
+
import { debug, error, warn } from "./logger";
|
|
3
3
|
/** Beginning single backslash is intentional, to look for the dot + the extension. Do not escape it again. */
|
|
4
4
|
const CACHE_EXTENSION_REGEX = /\.(cache|fetch)$/;
|
|
5
5
|
export function hasCacheExtension(key) {
|
|
@@ -18,7 +18,6 @@ function isFetchCache(options) {
|
|
|
18
18
|
}
|
|
19
19
|
// We need to use globalThis client here as this class can be defined at load time in next 12 but client is not available at load time
|
|
20
20
|
export default class S3Cache {
|
|
21
|
-
constructor(_ctx) { }
|
|
22
21
|
async get(key,
|
|
23
22
|
// fetchCache is for next 13.5 and above, kindHint is for next 14 and above and boolean is for earlier versions
|
|
24
23
|
options) {
|
|
@@ -82,7 +81,7 @@ export default class S3Cache {
|
|
|
82
81
|
// If some tags are stale we need to force revalidation
|
|
83
82
|
return null;
|
|
84
83
|
}
|
|
85
|
-
const requestId = globalThis.
|
|
84
|
+
const requestId = globalThis.__openNextAls.getStore()?.requestId ?? "";
|
|
86
85
|
globalThis.lastModified[requestId] = _lastModified;
|
|
87
86
|
if (cacheData?.type === "route") {
|
|
88
87
|
return {
|
|
@@ -97,7 +96,7 @@ export default class S3Cache {
|
|
|
97
96
|
},
|
|
98
97
|
};
|
|
99
98
|
}
|
|
100
|
-
|
|
99
|
+
if (cacheData?.type === "page" || cacheData?.type === "app") {
|
|
101
100
|
if (globalThis.isNextAfter15 && cacheData?.type === "app") {
|
|
102
101
|
return {
|
|
103
102
|
lastModified: _lastModified,
|
|
@@ -122,7 +121,7 @@ export default class S3Cache {
|
|
|
122
121
|
},
|
|
123
122
|
};
|
|
124
123
|
}
|
|
125
|
-
|
|
124
|
+
if (cacheData?.type === "redirect") {
|
|
126
125
|
return {
|
|
127
126
|
lastModified: _lastModified,
|
|
128
127
|
value: {
|
|
@@ -131,10 +130,8 @@ export default class S3Cache {
|
|
|
131
130
|
},
|
|
132
131
|
};
|
|
133
132
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
133
|
+
warn("Unknown cache type", cacheData);
|
|
134
|
+
return null;
|
|
138
135
|
}
|
|
139
136
|
catch (e) {
|
|
140
137
|
// We can usually ignore errors here as they are usually due to cache not being found
|
|
@@ -148,7 +145,7 @@ export default class S3Cache {
|
|
|
148
145
|
}
|
|
149
146
|
// This one might not even be necessary anymore
|
|
150
147
|
// Better be safe than sorry
|
|
151
|
-
const detachedPromise = globalThis.
|
|
148
|
+
const detachedPromise = globalThis.__openNextAls
|
|
152
149
|
.getStore()
|
|
153
150
|
?.pendingPromiseRunner.withResolvers();
|
|
154
151
|
try {
|
|
@@ -158,7 +155,7 @@ export default class S3Cache {
|
|
|
158
155
|
else {
|
|
159
156
|
switch (data.kind) {
|
|
160
157
|
case "ROUTE":
|
|
161
|
-
case "APP_ROUTE":
|
|
158
|
+
case "APP_ROUTE": {
|
|
162
159
|
const { body, status, headers } = data;
|
|
163
160
|
await globalThis.incrementalCache.set(key, {
|
|
164
161
|
type: "route",
|
|
@@ -171,6 +168,7 @@ export default class S3Cache {
|
|
|
171
168
|
},
|
|
172
169
|
}, false);
|
|
173
170
|
break;
|
|
171
|
+
}
|
|
174
172
|
case "PAGE":
|
|
175
173
|
case "PAGES": {
|
|
176
174
|
const { html, pageData, status, headers } = data;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
2
|
import { createGenericHandler } from "../core/createGenericHandler.js";
|
|
3
3
|
import { resolveTagCache } from "../core/resolve.js";
|
|
4
4
|
const PHYSICAL_RESOURCE_ID = "dynamodb-cache";
|
|
@@ -11,19 +11,17 @@ async function defaultHandler(event) {
|
|
|
11
11
|
switch (event.requestType) {
|
|
12
12
|
case "delete":
|
|
13
13
|
return remove();
|
|
14
|
-
case "create":
|
|
15
|
-
case "update":
|
|
16
14
|
default:
|
|
17
15
|
return insert(event.requestType);
|
|
18
16
|
}
|
|
19
17
|
}
|
|
20
18
|
async function insert(requestType) {
|
|
21
|
-
const file = readFileSync(
|
|
19
|
+
const file = readFileSync("dynamodb-cache.json", "utf8");
|
|
22
20
|
const data = JSON.parse(file);
|
|
23
21
|
const parsedData = data.map((item) => ({
|
|
24
22
|
tag: item.tag.S,
|
|
25
23
|
path: item.path.S,
|
|
26
|
-
revalidatedAt: parseInt(item.revalidatedAt.N),
|
|
24
|
+
revalidatedAt: Number.parseInt(item.revalidatedAt.N),
|
|
27
25
|
}));
|
|
28
26
|
await tagCache.writeTags(parsedData);
|
|
29
27
|
return {
|
|
@@ -1,49 +1,54 @@
|
|
|
1
|
+
import { runWithOpenNextRequestContext } from "../utils/promise";
|
|
1
2
|
import { emptyReadableStream } from "../utils/stream";
|
|
2
3
|
// We import it like that so that the edge plugin can replace it
|
|
3
4
|
import { NextConfig } from "../adapters/config";
|
|
4
5
|
import { createGenericHandler } from "../core/createGenericHandler";
|
|
5
6
|
import { convertBodyToReadableStream, convertToQueryString, } from "../core/routing/util";
|
|
7
|
+
globalThis.__openNextAls = new AsyncLocalStorage();
|
|
6
8
|
const defaultHandler = async (internalEvent) => {
|
|
7
9
|
globalThis.isEdgeRuntime = true;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
// We run everything in the async local storage context so that it is available in edge runtime functions
|
|
11
|
+
return runWithOpenNextRequestContext({ isISRRevalidation: false }, async () => {
|
|
12
|
+
const host = internalEvent.headers.host
|
|
13
|
+
? `https://${internalEvent.headers.host}`
|
|
14
|
+
: "http://localhost:3000";
|
|
15
|
+
const initialUrl = new URL(internalEvent.rawPath, host);
|
|
16
|
+
initialUrl.search = convertToQueryString(internalEvent.query);
|
|
17
|
+
const url = initialUrl.toString();
|
|
18
|
+
// @ts-expect-error - This is bundled
|
|
19
|
+
const handler = await import("./middleware.mjs");
|
|
20
|
+
const response = await handler.default({
|
|
21
|
+
headers: internalEvent.headers,
|
|
22
|
+
method: internalEvent.method || "GET",
|
|
23
|
+
nextConfig: {
|
|
24
|
+
basePath: NextConfig.basePath,
|
|
25
|
+
i18n: NextConfig.i18n,
|
|
26
|
+
trailingSlash: NextConfig.trailingSlash,
|
|
27
|
+
},
|
|
28
|
+
url,
|
|
29
|
+
body: convertBodyToReadableStream(internalEvent.method, internalEvent.body),
|
|
30
|
+
});
|
|
31
|
+
const responseHeaders = {};
|
|
32
|
+
response.headers.forEach((value, key) => {
|
|
33
|
+
if (key.toLowerCase() === "set-cookie") {
|
|
34
|
+
responseHeaders[key] = responseHeaders[key]
|
|
35
|
+
? [...responseHeaders[key], value]
|
|
36
|
+
: [value];
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
responseHeaders[key] = value;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const body = response.body ?? emptyReadableStream();
|
|
43
|
+
return {
|
|
44
|
+
type: "core",
|
|
45
|
+
statusCode: response.status,
|
|
46
|
+
headers: responseHeaders,
|
|
47
|
+
body: body,
|
|
48
|
+
// Do we need to handle base64 encoded response?
|
|
49
|
+
isBase64Encoded: false,
|
|
50
|
+
};
|
|
26
51
|
});
|
|
27
|
-
const responseHeaders = {};
|
|
28
|
-
response.headers.forEach((value, key) => {
|
|
29
|
-
if (key.toLowerCase() === "set-cookie") {
|
|
30
|
-
responseHeaders[key] = responseHeaders[key]
|
|
31
|
-
? [...responseHeaders[key], value]
|
|
32
|
-
: [value];
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
responseHeaders[key] = value;
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
const body = response.body ?? emptyReadableStream();
|
|
39
|
-
return {
|
|
40
|
-
type: "core",
|
|
41
|
-
statusCode: response.status,
|
|
42
|
-
headers: responseHeaders,
|
|
43
|
-
body: body,
|
|
44
|
-
// Do we need to handle base64 encoded response?
|
|
45
|
-
isBase64Encoded: false,
|
|
46
|
-
};
|
|
47
52
|
};
|
|
48
53
|
export const handler = await createGenericHandler({
|
|
49
54
|
handler: defaultHandler,
|
|
@@ -46,7 +46,7 @@ export async function defaultHandler(event, streamCreator) {
|
|
|
46
46
|
// It might be useful for cases where the user wants to use a different host than the one in the request
|
|
47
47
|
// It could even allow to have multiple hosts for the image optimization by setting the HOST environment variable in the wrapper for example
|
|
48
48
|
if (!process.env.HOST) {
|
|
49
|
-
const headersHost = headers["x-forwarded-host"] || headers
|
|
49
|
+
const headersHost = headers["x-forwarded-host"] || headers.host;
|
|
50
50
|
process.env.HOST = headersHost;
|
|
51
51
|
}
|
|
52
52
|
const imageParams = validateImageParams(headers, queryString === null ? undefined : queryString);
|
|
@@ -104,7 +104,7 @@ function buildSuccessResponse(result, streamCreator, etag) {
|
|
|
104
104
|
};
|
|
105
105
|
debug("result", result);
|
|
106
106
|
if (etag) {
|
|
107
|
-
headers
|
|
107
|
+
headers.ETag = etag;
|
|
108
108
|
}
|
|
109
109
|
if (streamCreator) {
|
|
110
110
|
const response = new OpenNextNodeResponse(() => void 0, async () => void 0, streamCreator);
|
|
@@ -125,7 +125,7 @@ function buildFailureResponse(e, streamCreator) {
|
|
|
125
125
|
const response = new OpenNextNodeResponse(() => void 0, async () => void 0, streamCreator);
|
|
126
126
|
response.writeHead(500, {
|
|
127
127
|
Vary: "Accept",
|
|
128
|
-
"Cache-Control":
|
|
128
|
+
"Cache-Control": "public,max-age=60,immutable",
|
|
129
129
|
"Content-Type": "application/json",
|
|
130
130
|
});
|
|
131
131
|
response.end(e?.message || e?.toString() || "An error occurred");
|
|
@@ -137,7 +137,7 @@ function buildFailureResponse(e, streamCreator) {
|
|
|
137
137
|
headers: {
|
|
138
138
|
Vary: "Accept",
|
|
139
139
|
// For failed images, allow client to retry after 1 minute.
|
|
140
|
-
"Cache-Control":
|
|
140
|
+
"Cache-Control": "public,max-age=60,immutable",
|
|
141
141
|
"Content-Type": "application/json",
|
|
142
142
|
},
|
|
143
143
|
body: toReadableStream(e?.message || e?.toString() || "An error occurred"),
|
package/dist/adapters/logger.js
CHANGED
|
@@ -29,14 +29,12 @@ export function error(...args) {
|
|
|
29
29
|
debug(...args);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
if (error.logLevel === 1) {
|
|
33
33
|
warn(...args);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
36
|
+
console.error(...args);
|
|
37
|
+
return;
|
|
40
38
|
}
|
|
41
39
|
else {
|
|
42
40
|
console.error(...args);
|
|
@@ -1,32 +1,56 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runWithOpenNextRequestContext } from "../utils/promise";
|
|
2
|
+
import { debug, error } from "../adapters/logger";
|
|
2
3
|
import { createGenericHandler } from "../core/createGenericHandler";
|
|
3
|
-
import { resolveIncrementalCache, resolveOriginResolver, resolveQueue, resolveTagCache, } from "../core/resolve";
|
|
4
|
+
import { resolveIncrementalCache, resolveOriginResolver, resolveProxyRequest, resolveQueue, resolveTagCache, } from "../core/resolve";
|
|
4
5
|
import routingHandler from "../core/routingHandler";
|
|
5
6
|
globalThis.internalFetch = fetch;
|
|
7
|
+
globalThis.__openNextAls = new AsyncLocalStorage();
|
|
6
8
|
const defaultHandler = async (internalEvent) => {
|
|
7
9
|
const originResolver = await resolveOriginResolver(globalThis.openNextConfig.middleware?.originResolver);
|
|
10
|
+
const externalRequestProxy = await resolveProxyRequest(globalThis.openNextConfig.middleware?.override?.proxyExternalRequest);
|
|
8
11
|
//#override includeCacheInMiddleware
|
|
9
12
|
globalThis.tagCache = await resolveTagCache(globalThis.openNextConfig.middleware?.override?.tagCache);
|
|
10
13
|
globalThis.queue = await resolveQueue(globalThis.openNextConfig.middleware?.override?.queue);
|
|
11
14
|
globalThis.incrementalCache = await resolveIncrementalCache(globalThis.openNextConfig.middleware?.override?.incrementalCache);
|
|
12
15
|
//#endOverride
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
// We run everything in the async local storage context so that it is available in the external middleware
|
|
17
|
+
return runWithOpenNextRequestContext({ isISRRevalidation: internalEvent.headers["x-isr"] === "1" }, async () => {
|
|
18
|
+
const result = await routingHandler(internalEvent);
|
|
19
|
+
if ("internalEvent" in result) {
|
|
20
|
+
debug("Middleware intercepted event", internalEvent);
|
|
21
|
+
if (!result.isExternalRewrite) {
|
|
22
|
+
const origin = await originResolver.resolve(result.internalEvent.rawPath);
|
|
23
|
+
return {
|
|
24
|
+
type: "middleware",
|
|
25
|
+
internalEvent: result.internalEvent,
|
|
26
|
+
isExternalRewrite: result.isExternalRewrite,
|
|
27
|
+
origin,
|
|
28
|
+
isISR: result.isISR,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return externalRequestProxy.proxy(result.internalEvent);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
error("External request failed.", e);
|
|
36
|
+
return {
|
|
37
|
+
type: "middleware",
|
|
38
|
+
internalEvent: {
|
|
39
|
+
...result.internalEvent,
|
|
40
|
+
rawPath: "/500",
|
|
41
|
+
url: "/500",
|
|
42
|
+
method: "GET",
|
|
43
|
+
},
|
|
44
|
+
// On error we need to rewrite to the 500 page which is an internal rewrite
|
|
45
|
+
isExternalRewrite: false,
|
|
46
|
+
origin: false,
|
|
47
|
+
isISR: result.isISR,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
19
50
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
isExternalRewrite: result.isExternalRewrite,
|
|
24
|
-
origin,
|
|
25
|
-
isISR: result.isISR,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
debug("Middleware response", result);
|
|
29
|
-
return result;
|
|
51
|
+
debug("Middleware response", result);
|
|
52
|
+
return result;
|
|
53
|
+
});
|
|
30
54
|
};
|
|
31
55
|
export const handler = await createGenericHandler({
|
|
32
56
|
handler: defaultHandler,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
5
2
|
import type { APIGatewayProxyEventHeaders } from "aws-lambda";
|
|
6
3
|
import type { NextConfig } from "next/dist/server/config-shared";
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
5
2
|
import type { APIGatewayProxyEventHeaders } from "aws-lambda";
|
|
6
3
|
import type { NextConfig } from "next/dist/server/config-shared";
|
|
@@ -8,7 +8,7 @@ const defaultHandler = async (event) => {
|
|
|
8
8
|
const failedRecords = [];
|
|
9
9
|
for (const record of event.records) {
|
|
10
10
|
const { host, url } = record;
|
|
11
|
-
debug(
|
|
11
|
+
debug("Revalidating stale page", { host, url });
|
|
12
12
|
// Make a HEAD request to the page to revalidate it. This will trigger
|
|
13
13
|
// the page to be re-rendered and cached in S3
|
|
14
14
|
// - HEAD request is used b/c it's not necessary to make a GET request
|
|
@@ -39,7 +39,7 @@ const defaultHandler = async (event) => {
|
|
|
39
39
|
resolve(res);
|
|
40
40
|
});
|
|
41
41
|
req.on("error", (err) => {
|
|
42
|
-
error(
|
|
42
|
+
error("Error revalidating page", { host, url });
|
|
43
43
|
reject(err);
|
|
44
44
|
});
|
|
45
45
|
req.end();
|
|
@@ -8,6 +8,7 @@ import { setNodeEnv } from "./util.js";
|
|
|
8
8
|
setNodeEnv();
|
|
9
9
|
setBuildIdEnv();
|
|
10
10
|
setNextjsServerWorkingDirectory();
|
|
11
|
+
// Because next is messing with fetch, we have to make sure that we use an untouched version of fetch
|
|
11
12
|
globalThis.internalFetch = fetch;
|
|
12
13
|
/////////////
|
|
13
14
|
// Handler //
|
|
@@ -17,7 +18,8 @@ export const handler = await createMainHandler();
|
|
|
17
18
|
// Helper functions //
|
|
18
19
|
//////////////////////
|
|
19
20
|
function setNextjsServerWorkingDirectory() {
|
|
20
|
-
// WORKAROUND: Set `NextServer` working directory (AWS specific)
|
|
21
|
+
// WORKAROUND: Set `NextServer` working directory (AWS specific)
|
|
22
|
+
// See https://opennext.js.org/aws/v2/advanced/workaround#workaround-set-nextserver-working-directory-aws-specific
|
|
21
23
|
process.chdir(__dirname);
|
|
22
24
|
}
|
|
23
25
|
function setBuildIdEnv() {
|
package/dist/adapters/util.js
CHANGED
|
@@ -23,6 +23,6 @@ export function parseNumberFromEnv(envValue) {
|
|
|
23
23
|
if (typeof envValue !== "string") {
|
|
24
24
|
return envValue;
|
|
25
25
|
}
|
|
26
|
-
const parsedValue = parseInt(envValue);
|
|
27
|
-
return isNaN(parsedValue) ? undefined : parsedValue;
|
|
26
|
+
const parsedValue = Number.parseInt(envValue);
|
|
27
|
+
return Number.isNaN(parsedValue) ? undefined : parsedValue;
|
|
28
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { build } from "esbuild";
|
|
3
|
-
import path from "path";
|
|
4
4
|
const externals = [
|
|
5
5
|
// This one was causing trouble, don't know why
|
|
6
6
|
"../experimental/testmode/server",
|
|
@@ -35,7 +35,7 @@ const externals = [
|
|
|
35
35
|
// Adding it cause to add a lot of unnecessary deps
|
|
36
36
|
"next/dist/compiled/next-server",
|
|
37
37
|
];
|
|
38
|
-
export async function bundleNextServer(outputDir, appPath) {
|
|
38
|
+
export async function bundleNextServer(outputDir, appPath, { debug = false }) {
|
|
39
39
|
const require = createRequire(`${appPath}/package.json`);
|
|
40
40
|
const entrypoint = require.resolve("next/dist/esm/server/next-server.js");
|
|
41
41
|
await build({
|
|
@@ -46,7 +46,7 @@ export async function bundleNextServer(outputDir, appPath) {
|
|
|
46
46
|
// packages: "external",
|
|
47
47
|
format: "cjs",
|
|
48
48
|
external: externals,
|
|
49
|
-
minify:
|
|
49
|
+
minify: !debug,
|
|
50
50
|
outfile: path.join(outputDir, "next-server.runtime.prod.js"),
|
|
51
51
|
sourcemap: false,
|
|
52
52
|
plugins: [
|
|
@@ -23,7 +23,7 @@ export async function compileOpenNextConfig(baseDir, openNextConfigPath, nodeExt
|
|
|
23
23
|
configPath = `file://${configPath}`;
|
|
24
24
|
const config = (await import(configPath)).default;
|
|
25
25
|
if (!config || !config.default) {
|
|
26
|
-
logger.error(
|
|
26
|
+
logger.error("config.default cannot be empty, it should be at least {}, see more info here: https://opennext.js.org/config#configuration-file");
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
29
|
validateConfig(config);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import url from "node:url";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync,
|
|
3
|
-
import path from "path";
|
|
2
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
import logger from "../logger.js";
|
|
5
5
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
6
6
|
function copyPatchFile(outputDir) {
|
|
@@ -15,9 +15,7 @@ export async function copyTracedFiles(buildOutputPath, packagePath, outputDir, r
|
|
|
15
15
|
const standaloneDir = path.join(dotNextDir, "standalone");
|
|
16
16
|
const standaloneNextDir = path.join(standaloneDir, packagePath, ".next");
|
|
17
17
|
const outputNextDir = path.join(outputDir, packagePath, ".next");
|
|
18
|
-
const extractFiles = (files, from = standaloneNextDir) =>
|
|
19
|
-
return files.map((f) => path.resolve(from, f));
|
|
20
|
-
};
|
|
18
|
+
const extractFiles = (files, from = standaloneNextDir) => files.map((f) => path.resolve(from, f));
|
|
21
19
|
// On next 14+, we might not have to include those files
|
|
22
20
|
// For next 13, we need to include them otherwise we get runtime error
|
|
23
21
|
const requiredServerFiles = JSON.parse(readFileSync(path.join(dotNextDir, bundledNextServer
|
|
@@ -59,13 +57,11 @@ See the docs for more information on how to bundle edge runtime functions.
|
|
|
59
57
|
--------------------------------------------------------------------------------
|
|
60
58
|
`);
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
throw new Error(`
|
|
60
|
+
throw new Error(`
|
|
64
61
|
--------------------------------------------------------------------------------
|
|
65
62
|
We cannot find the route for ${pagePath}.
|
|
66
63
|
File ${fullFilePath} does not exist
|
|
67
64
|
--------------------------------------------------------------------------------`);
|
|
68
|
-
}
|
|
69
65
|
}
|
|
70
66
|
const dir = path.dirname(fullFilePath);
|
|
71
67
|
extractFiles(requiredFiles.files, path.join(standaloneNextDir, dir)).forEach((f) => {
|
|
@@ -144,20 +140,15 @@ File ${fullFilePath} does not exist
|
|
|
144
140
|
copyFileSync(from, to);
|
|
145
141
|
}
|
|
146
142
|
});
|
|
147
|
-
readdirSync(standaloneNextDir)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
copyFileSync(path.join(standaloneNextDir, f), path.join(outputNextDir, f));
|
|
151
|
-
});
|
|
143
|
+
readdirSync(standaloneNextDir)
|
|
144
|
+
.filter((fileOrDir) => !statSync(path.join(standaloneNextDir, fileOrDir)).isDirectory())
|
|
145
|
+
.forEach((file) => copyFileSync(path.join(standaloneNextDir, file), path.join(outputNextDir, file)));
|
|
152
146
|
// We then need to copy all the files at the root of server
|
|
153
147
|
mkdirSync(path.join(outputNextDir, "server"), { recursive: true });
|
|
154
|
-
readdirSync(path.join(standaloneNextDir, "server"))
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
copyFileSync(path.join(standaloneNextDir, "server", f), path.join(path.join(outputNextDir, "server"), f));
|
|
159
|
-
}
|
|
160
|
-
});
|
|
148
|
+
readdirSync(path.join(standaloneNextDir, "server"))
|
|
149
|
+
.filter((fileOrDir) => !statSync(path.join(standaloneNextDir, "server", fileOrDir)).isDirectory())
|
|
150
|
+
.filter((file) => file !== "server.js")
|
|
151
|
+
.forEach((file) => copyFileSync(path.join(standaloneNextDir, "server", file), path.join(path.join(outputNextDir, "server"), file)));
|
|
161
152
|
// Copy patch file
|
|
162
153
|
copyPatchFile(path.join(outputDir, packagePath));
|
|
163
154
|
// TODO: Recompute all the files.
|
|
@@ -198,11 +189,9 @@ File ${fullFilePath} does not exist
|
|
|
198
189
|
}
|
|
199
190
|
}
|
|
200
191
|
});
|
|
201
|
-
staticFiles
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
});
|
|
192
|
+
staticFiles
|
|
193
|
+
.filter((file) => file.endsWith(".html"))
|
|
194
|
+
.forEach((file) => copyStaticFile(`server/${file}`));
|
|
206
195
|
}
|
|
207
196
|
logger.debug("copyTracedFiles:", Date.now() - tsStart, "ms");
|
|
208
197
|
}
|