@opennextjs/aws 3.4.2 → 3.5.0
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.d.ts +2 -61
- package/dist/adapters/cache.js +68 -34
- package/dist/adapters/config/index.d.ts +1 -0
- package/dist/adapters/config/index.js +3 -1
- package/dist/adapters/config/util.d.ts +2 -1
- package/dist/adapters/config/util.js +13 -3
- package/dist/adapters/dynamo-provider.js +8 -0
- package/dist/adapters/edge-adapter.js +4 -10
- package/dist/adapters/image-optimization-adapter.d.ts +3 -2
- package/dist/adapters/image-optimization-adapter.js +3 -3
- package/dist/adapters/middleware.js +12 -8
- package/dist/build/compileConfig.js +1 -1
- package/dist/build/compileTagCacheProvider.js +1 -0
- package/dist/build/constant.d.ts +1 -0
- package/dist/build/constant.js +2 -0
- package/dist/build/copyTracedFiles.d.ts +10 -1
- package/dist/build/copyTracedFiles.js +22 -12
- package/dist/build/createAssets.d.ts +3 -1
- package/dist/build/createAssets.js +2 -2
- package/dist/build/createMiddleware.js +18 -5
- package/dist/build/createServerBundle.js +7 -1
- package/dist/build/edge/createEdgeBundle.js +14 -12
- package/dist/build/generateOutput.js +4 -6
- package/dist/build/middleware/buildNodeMiddleware.d.ts +3 -0
- package/dist/build/middleware/buildNodeMiddleware.js +97 -0
- package/dist/core/createMainHandler.js +0 -1
- package/dist/core/edgeFunctionHandler.js +3 -1
- package/dist/core/nodeMiddlewareHandler.d.ts +4 -0
- package/dist/core/nodeMiddlewareHandler.js +25 -0
- package/dist/core/requestHandler.d.ts +3 -2
- package/dist/core/requestHandler.js +58 -25
- package/dist/core/routing/cacheInterceptor.js +7 -6
- package/dist/core/routing/i18n/index.d.ts +2 -0
- package/dist/core/routing/i18n/index.js +1 -1
- package/dist/core/routing/matcher.js +13 -12
- package/dist/core/routing/middleware.js +14 -29
- package/dist/core/routing/queue.d.ts +1 -0
- package/dist/core/routing/queue.js +41 -0
- package/dist/core/routing/util.d.ts +12 -3
- package/dist/core/routing/util.js +24 -50
- package/dist/core/routingHandler.d.ts +2 -1
- package/dist/core/routingHandler.js +10 -4
- package/dist/core/util.d.ts +1 -4
- package/dist/core/util.js +7 -15
- package/dist/overrides/converters/aws-apigw-v1.js +4 -3
- package/dist/overrides/converters/aws-apigw-v2.js +4 -3
- package/dist/overrides/converters/aws-cloudfront.js +6 -4
- package/dist/overrides/converters/edge.js +1 -10
- package/dist/overrides/converters/node.js +10 -8
- package/dist/overrides/converters/utils.d.ts +7 -0
- package/dist/overrides/converters/utils.js +9 -0
- package/dist/overrides/imageLoader/s3-lite.d.ts +3 -0
- package/dist/overrides/imageLoader/s3-lite.js +61 -0
- package/dist/overrides/tagCache/dummy.js +1 -0
- package/dist/overrides/tagCache/dynamodb-lite.js +1 -0
- package/dist/overrides/tagCache/dynamodb-nextMode.d.ts +7 -0
- package/dist/overrides/tagCache/dynamodb-nextMode.js +119 -0
- package/dist/overrides/tagCache/dynamodb.js +1 -0
- package/dist/overrides/tagCache/fs-dev.js +1 -0
- package/dist/overrides/wrappers/aws-lambda-streaming.js +1 -1
- package/dist/overrides/wrappers/aws-lambda.js +3 -1
- package/dist/overrides/wrappers/cloudflare-edge.js +3 -2
- package/dist/overrides/wrappers/cloudflare-node.js +5 -8
- package/dist/overrides/wrappers/dummy.js +2 -2
- package/dist/overrides/wrappers/express-dev.js +4 -4
- package/dist/overrides/wrappers/node.js +2 -2
- package/dist/plugins/edge.d.ts +1 -3
- package/dist/plugins/edge.js +4 -11
- package/dist/plugins/externalMiddleware.d.ts +2 -0
- package/dist/plugins/externalMiddleware.js +10 -0
- package/dist/plugins/resolve.js +2 -2
- package/dist/types/cache.d.ts +34 -4
- package/dist/types/global.d.ts +19 -31
- package/dist/types/next-types.d.ts +13 -0
- package/dist/types/open-next.d.ts +12 -5
- package/dist/types/overrides.d.ts +72 -6
- package/dist/utils/cache.d.ts +3 -0
- package/dist/utils/cache.js +32 -0
- package/dist/utils/promise.d.ts +3 -1
- package/dist/utils/promise.js +18 -11
- package/dist/utils/regex.js +1 -1
- package/package.json +5 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Readable } from "node:stream";
|
|
2
2
|
import type { Meta } from "./cache";
|
|
3
|
-
import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin, ResolvedRoute, StreamCreator } from "./open-next";
|
|
3
|
+
import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin, ResolvedRoute, StreamCreator, WaitUntil } from "./open-next";
|
|
4
4
|
export interface QueueMessage {
|
|
5
5
|
MessageDeduplicationId: string;
|
|
6
6
|
MessageBody: {
|
|
@@ -32,12 +32,24 @@ export type CachedFile = {
|
|
|
32
32
|
body: string;
|
|
33
33
|
meta?: Meta;
|
|
34
34
|
};
|
|
35
|
-
export type
|
|
35
|
+
export type CachedFetchValue = {
|
|
36
|
+
kind: "FETCH";
|
|
37
|
+
data: {
|
|
38
|
+
headers: {
|
|
39
|
+
[k: string]: string;
|
|
40
|
+
};
|
|
41
|
+
body: string;
|
|
42
|
+
url: string;
|
|
43
|
+
status?: number;
|
|
44
|
+
tags?: string[];
|
|
45
|
+
};
|
|
46
|
+
tags?: string[];
|
|
47
|
+
};
|
|
36
48
|
export type WithLastModified<T> = {
|
|
37
49
|
lastModified?: number;
|
|
38
50
|
value?: T;
|
|
39
51
|
};
|
|
40
|
-
export type CacheValue<IsFetch extends boolean> = (IsFetch extends true ?
|
|
52
|
+
export type CacheValue<IsFetch extends boolean> = (IsFetch extends true ? CachedFetchValue : CachedFile) & {
|
|
41
53
|
revalidate?: number | false;
|
|
42
54
|
};
|
|
43
55
|
export type IncrementalCache = {
|
|
@@ -46,7 +58,57 @@ export type IncrementalCache = {
|
|
|
46
58
|
delete(key: string): Promise<void>;
|
|
47
59
|
name: string;
|
|
48
60
|
};
|
|
49
|
-
|
|
61
|
+
type BaseTagCache = {
|
|
62
|
+
name: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* On get :
|
|
66
|
+
We have to check for every tag (after reading the incremental cache) that they have not been revalidated.
|
|
67
|
+
|
|
68
|
+
In DynamoDB, this would require 1 GetItem per tag (including internal one), more realistically 1 BatchGetItem per get (In terms of pricing, it would be billed as multiple single GetItem)
|
|
69
|
+
|
|
70
|
+
On set :
|
|
71
|
+
We don't have to do anything here
|
|
72
|
+
|
|
73
|
+
On revalidateTag for each tag :
|
|
74
|
+
We have to update a single entry for this tag
|
|
75
|
+
|
|
76
|
+
Pros :
|
|
77
|
+
- No need to prepopulate DDB
|
|
78
|
+
- Very little write
|
|
79
|
+
|
|
80
|
+
Cons :
|
|
81
|
+
- Might be slower on read
|
|
82
|
+
- One page request (i.e. GET request) could require to check a lot of tags (And some of them multiple time when used with the fetch cache)
|
|
83
|
+
- Almost impossible to do automatic cdn revalidation by itself
|
|
84
|
+
*/
|
|
85
|
+
export type NextModeTagCache = BaseTagCache & {
|
|
86
|
+
mode: "nextMode";
|
|
87
|
+
hasBeenRevalidated(tags: string[], lastModified?: number): Promise<boolean>;
|
|
88
|
+
writeTags(tags: string[]): Promise<void>;
|
|
89
|
+
getPathsByTags?: (tags: string[]) => Promise<string[]>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* On get :
|
|
93
|
+
We just check for the cache key in the tag cache. If it has been revalidated we just return null, otherwise we continue
|
|
94
|
+
|
|
95
|
+
On set :
|
|
96
|
+
We have to write both the incremental cache and check the tag cache for non existing tag/key combination. For non existing tag/key combination, we have to add them
|
|
97
|
+
|
|
98
|
+
On revalidateTag for each tag :
|
|
99
|
+
We have to update every possible combination for the requested tag
|
|
100
|
+
|
|
101
|
+
Pros :
|
|
102
|
+
- Very fast on read
|
|
103
|
+
- Only one query per get (On DynamoDB it's a lot cheaper)
|
|
104
|
+
- Can allow for automatic cdn invalidation on revalidateTag
|
|
105
|
+
|
|
106
|
+
Cons :
|
|
107
|
+
- Lots of write on set and revalidateTag
|
|
108
|
+
- Needs to be prepopulated at build time to work properly
|
|
109
|
+
*/
|
|
110
|
+
export type OriginalTagCache = BaseTagCache & {
|
|
111
|
+
mode?: "original";
|
|
50
112
|
getByTag(tag: string): Promise<string[]>;
|
|
51
113
|
getByPath(path: string): Promise<string[]>;
|
|
52
114
|
getLastModified(path: string, lastModified?: number): Promise<number>;
|
|
@@ -55,15 +117,19 @@ export type TagCache = {
|
|
|
55
117
|
path: string;
|
|
56
118
|
revalidatedAt?: number;
|
|
57
119
|
}[]): Promise<void>;
|
|
58
|
-
name: string;
|
|
59
120
|
};
|
|
121
|
+
export type TagCache = NextModeTagCache | OriginalTagCache;
|
|
60
122
|
export type WrapperHandler<E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult> = (handler: OpenNextHandler<E, R>, converter: Converter<E, R>) => Promise<(...args: any[]) => any>;
|
|
61
123
|
export type Wrapper<E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult> = BaseOverride & {
|
|
62
124
|
wrapper: WrapperHandler<E, R>;
|
|
63
125
|
supportStreaming: boolean;
|
|
64
126
|
edgeRuntime?: boolean;
|
|
65
127
|
};
|
|
66
|
-
export type
|
|
128
|
+
export type OpenNextHandlerOptions = {
|
|
129
|
+
streamCreator?: StreamCreator;
|
|
130
|
+
waitUntil?: WaitUntil;
|
|
131
|
+
};
|
|
132
|
+
export type OpenNextHandler<E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult> = (event: E, options?: OpenNextHandlerOptions) => Promise<R>;
|
|
67
133
|
export type Converter<E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult> = BaseOverride & {
|
|
68
134
|
convertFrom: (event: any) => Promise<E>;
|
|
69
135
|
convertTo: (result: R, originalRequest?: any) => Promise<any>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CacheValue, WithLastModified } from "../types/overrides";
|
|
2
|
+
export declare function hasBeenRevalidated(key: string, tags: string[], cacheEntry: WithLastModified<CacheValue<any>>): Promise<boolean>;
|
|
3
|
+
export declare function getTagsFromValue(value?: CacheValue<false>): string[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export async function hasBeenRevalidated(key, tags, cacheEntry) {
|
|
2
|
+
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
const value = cacheEntry.value;
|
|
6
|
+
if (!value) {
|
|
7
|
+
// We should never reach this point
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if ("type" in cacheEntry && cacheEntry.type === "page") {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const lastModified = cacheEntry.lastModified ?? Date.now();
|
|
14
|
+
if (globalThis.tagCache.mode === "nextMode") {
|
|
15
|
+
return await globalThis.tagCache.hasBeenRevalidated(tags, lastModified);
|
|
16
|
+
}
|
|
17
|
+
// TODO: refactor this, we should introduce a new method in the tagCache interface so that both implementations use hasBeenRevalidated
|
|
18
|
+
const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
|
|
19
|
+
return _lastModified === -1;
|
|
20
|
+
}
|
|
21
|
+
export function getTagsFromValue(value) {
|
|
22
|
+
if (!value) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
// The try catch is necessary for older version of next.js that may fail on this
|
|
26
|
+
try {
|
|
27
|
+
return value.meta?.headers?.["x-next-cache-tags"]?.split(",") ?? [];
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
package/dist/utils/promise.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WaitUntil } from "../types/open-next";
|
|
1
2
|
/**
|
|
2
3
|
* A `Promise.withResolvers` implementation that exposes the `resolve` and
|
|
3
4
|
* `reject` functions on a `Promise`.
|
|
@@ -16,6 +17,7 @@ export declare class DetachedPromiseRunner {
|
|
|
16
17
|
add<T>(promise: Promise<T>): void;
|
|
17
18
|
await(): Promise<void>;
|
|
18
19
|
}
|
|
19
|
-
export declare function runWithOpenNextRequestContext<T>({ isISRRevalidation }: {
|
|
20
|
+
export declare function runWithOpenNextRequestContext<T>({ isISRRevalidation, waitUntil, }: {
|
|
20
21
|
isISRRevalidation: boolean;
|
|
22
|
+
waitUntil?: WaitUntil;
|
|
21
23
|
}, fn: () => Promise<T>): Promise<T>;
|
package/dist/utils/promise.js
CHANGED
|
@@ -47,23 +47,22 @@ export class DetachedPromiseRunner {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
async function awaitAllDetachedPromise() {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
|
|
50
|
+
const store = globalThis.__openNextAls.getStore();
|
|
51
|
+
const promisesToAwait = store?.pendingPromiseRunner.await() ?? Promise.resolve();
|
|
52
|
+
if (store?.waitUntil) {
|
|
53
|
+
store.waitUntil(promisesToAwait);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
await promisesToAwait;
|
|
57
57
|
}
|
|
58
58
|
function provideNextAfterProvider() {
|
|
59
|
-
/** This should be considered unstable until `unstable_after` is stablized. */
|
|
60
59
|
const NEXT_REQUEST_CONTEXT_SYMBOL = Symbol.for("@next/request-context");
|
|
61
60
|
// This is needed by some lib that relies on the vercel request context to properly await stuff.
|
|
62
61
|
// Remove this when vercel builder is updated to provide '@next/request-context'.
|
|
63
62
|
const VERCEL_REQUEST_CONTEXT_SYMBOL = Symbol.for("@vercel/request-context");
|
|
64
|
-
const
|
|
65
|
-
const waitUntil =
|
|
66
|
-
((promise) =>
|
|
63
|
+
const store = globalThis.__openNextAls.getStore();
|
|
64
|
+
const waitUntil = store?.waitUntil ??
|
|
65
|
+
((promise) => store?.pendingPromiseRunner.add(promise));
|
|
67
66
|
const nextAfterContext = {
|
|
68
67
|
get: () => ({
|
|
69
68
|
waitUntil,
|
|
@@ -78,15 +77,23 @@ function provideNextAfterProvider() {
|
|
|
78
77
|
globalThis[VERCEL_REQUEST_CONTEXT_SYMBOL] = nextAfterContext;
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
|
-
export function runWithOpenNextRequestContext({ isISRRevalidation }, fn) {
|
|
80
|
+
export function runWithOpenNextRequestContext({ isISRRevalidation, waitUntil, }, fn) {
|
|
82
81
|
return globalThis.__openNextAls.run({
|
|
83
82
|
requestId: Math.random().toString(36),
|
|
84
83
|
pendingPromiseRunner: new DetachedPromiseRunner(),
|
|
85
84
|
isISRRevalidation,
|
|
85
|
+
waitUntil,
|
|
86
86
|
}, async () => {
|
|
87
87
|
provideNextAfterProvider();
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
let result;
|
|
89
|
+
try {
|
|
90
|
+
result = await fn();
|
|
91
|
+
// We always await all detached promises before returning the result
|
|
92
|
+
// However we don't want to catch errors here, we want to let the parent handle it
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await awaitAllDetachedPromise();
|
|
96
|
+
}
|
|
90
97
|
return result;
|
|
91
98
|
});
|
|
92
99
|
}
|
package/dist/utils/regex.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* getCrossPlatformPathRegex(String.raw`\./middleware\.(mjs|cjs)`, { escape: false })
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
|
-
export function getCrossPlatformPathRegex(regex, { escape: shouldEscape = true, flags = "
|
|
13
|
+
export function getCrossPlatformPathRegex(regex, { escape: shouldEscape = true, flags = "" } = {}) {
|
|
14
14
|
const newExpr = (shouldEscape ? regex.replace(/([[\]().*+?^$|{}\\])/g, "\\$1") : regex).replaceAll("/", String.raw `(?:\/|\\)`);
|
|
15
15
|
return new RegExp(newExpr, flags);
|
|
16
16
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"access": "public"
|
|
4
4
|
},
|
|
5
5
|
"name": "@opennextjs/aws",
|
|
6
|
-
"version": "3.
|
|
6
|
+
"version": "3.5.0",
|
|
7
7
|
"bin": {
|
|
8
8
|
"open-next": "./dist/index.js"
|
|
9
9
|
},
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
"homepage": "https://opennext.js.org/aws",
|
|
14
14
|
"main": "./dist/index.js",
|
|
15
15
|
"exports": {
|
|
16
|
-
"./*":
|
|
16
|
+
"./*": {
|
|
17
|
+
"default": "./dist/*",
|
|
18
|
+
"types": "./dist/*.d.ts"
|
|
19
|
+
}
|
|
17
20
|
},
|
|
18
21
|
"typesVersions": {
|
|
19
22
|
"*": {
|
|
@@ -35,7 +38,6 @@
|
|
|
35
38
|
"@aws-sdk/client-lambda": "^3.398.0",
|
|
36
39
|
"@aws-sdk/client-s3": "^3.398.0",
|
|
37
40
|
"@aws-sdk/client-sqs": "^3.398.0",
|
|
38
|
-
"@esbuild-plugins/node-resolve": "0.2.2",
|
|
39
41
|
"@node-minify/core": "^8.0.6",
|
|
40
42
|
"@node-minify/terser": "^8.0.6",
|
|
41
43
|
"@tsconfig/node18": "^1.0.1",
|
|
@@ -44,7 +46,6 @@
|
|
|
44
46
|
"esbuild": "0.19.2",
|
|
45
47
|
"express": "5.0.1",
|
|
46
48
|
"path-to-regexp": "^6.3.0",
|
|
47
|
-
"promise.series": "^0.2.0",
|
|
48
49
|
"urlpattern-polyfill": "^10.0.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|