Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08874fb

Browse files
authored
refactor: code simplification (#627)
* refactor: code simplification * GitButler WIP Commit fixup! biome * fixup! tests * fixup: !format * fixup! (thank you tests) * fixup! I'll get there
1 parent 04379e2 commit 08874fb

40 files changed

+250
-235
lines changed

packages/open-next/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"@types/aws-lambda": "^8.10.109",
4848
"@types/node": "^18.16.1",
4949
"tsc-alias": "^1.8.8",
50-
"typescript": "^4.9.3"
50+
"typescript": "^5.6.3"
5151
},
5252
"bugs": {
5353
"url": "https://github.com/opennextjs/opennextjs-aws/issues"

packages/open-next/src/adapters/dynamo-provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async function insert(
5656
const parsedData = data.map((item) => ({
5757
tag: item.tag.S,
5858
path: item.path.S,
59-
revalidatedAt: parseInt(item.revalidatedAt.N),
59+
revalidatedAt: Number.parseInt(item.revalidatedAt.N),
6060
}));
6161

6262
await tagCache.writeTags(parsedData);

packages/open-next/src/adapters/server-adapter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export const handler = await createMainHandler();
2828
//////////////////////
2929

3030
function setNextjsServerWorkingDirectory() {
31-
// WORKAROUND: Set `NextServer` working directory (AWS specific) — https://github.com/serverless-stack/open-next#workaround-set-nextserver-working-directory-aws-specific
31+
// WORKAROUND: Set `NextServer` working directory (AWS specific)
32+
// See https://opennext.js.org/aws/v2/advanced/workaround#workaround-set-nextserver-working-directory-aws-specific
3233
process.chdir(__dirname);
3334
}
3435

packages/open-next/src/adapters/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function parseNumberFromEnv(
3131
return envValue;
3232
}
3333

34-
const parsedValue = parseInt(envValue);
34+
const parsedValue = Number.parseInt(envValue);
3535

3636
return isNaN(parsedValue) ? undefined : parsedValue;
3737
}

packages/open-next/src/build/createAssets.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ export function createStaticAssets(options: buildHelper.BuildOptions) {
1414
const outputPath = path.join(outputDir, "assets");
1515
fs.mkdirSync(outputPath, { recursive: true });
1616

17-
// Next.js outputs assets into multiple files. Copy into the same directory.
18-
// Copy over:
19-
// - .next/BUILD_ID => _next/BUILD_ID
20-
// - .next/static => _next/static
21-
// - public/* => *
22-
// - app/favicon.ico or src/app/favicon.ico => favicon.ico
17+
/**
18+
* Next.js outputs assets into multiple files. Copy into the same directory.
19+
*
20+
* Copy over:
21+
* - .next/BUILD_ID => BUILD_ID
22+
* - .next/static => _next/static
23+
* - public/* => *
24+
* - app/favicon.ico or src/app/favicon.ico => favicon.ico
25+
*
26+
* Note: BUILD_ID is used by the SST infra.
27+
*/
2328
fs.copyFileSync(
2429
path.join(appBuildOutputPath, ".next/BUILD_ID"),
2530
path.join(outputPath, "BUILD_ID"),

packages/open-next/src/build/createMiddleware.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import fs from "node:fs";
22
import path from "node:path";
33

44
import logger from "../logger.js";
5-
import {
6-
type MiddlewareInfo,
7-
type MiddlewareManifest,
5+
import type {
6+
MiddlewareInfo,
7+
MiddlewareManifest,
88
} from "../types/next-types.js";
99
import { buildEdgeBundle } from "./edge/createEdgeBundle.js";
1010
import * as buildHelper from "./helper.js";

packages/open-next/src/build/createServerBundle.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,25 +197,18 @@ async function generateBundle(
197197
...(disableNextPrebundledReact ? ["requireHooks"] : []),
198198
...(disableRouting ? ["trustHostHeader"] : []),
199199
...(!isBefore13413 ? ["requestHandlerHost"] : []),
200-
...(!isAfter141 ? ["stableIncrementalCache"] : []),
201-
...(isAfter141 ? ["experimentalIncrementalCacheHandler"] : []),
200+
...(isAfter141
201+
? ["experimentalIncrementalCacheHandler"]
202+
: ["stableIncrementalCache"]),
202203
],
203204
}),
204205

205206
openNextResolvePlugin({
206207
fnName: name,
207-
overrides: overrides,
208+
overrides,
208209
}),
209210
];
210211

211-
if (plugins && plugins.length > 0) {
212-
logger.debug(
213-
`Applying plugins:: [${plugins
214-
.map(({ name }) => name)
215-
.join(",")}] for Next version: ${options.nextVersion}`,
216-
);
217-
}
218-
219212
const outfileExt = fnOptions.runtime === "deno" ? "ts" : "mjs";
220213
await buildHelper.esbuildAsync(
221214
{
@@ -238,9 +231,12 @@ async function generateBundle(
238231
},
239232
plugins,
240233
alias: {
241-
"next/dist/server/next-server.js": isBundled
242-
? "./next-server.runtime.prod.js"
243-
: "next/dist/server/next-server.js",
234+
...(isBundled
235+
? {
236+
"next/dist/server/next-server.js":
237+
"./next-server.runtime.prod.js",
238+
}
239+
: {}),
244240
},
245241
},
246242
options,

packages/open-next/src/build/edge/createEdgeBundle.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export async function buildEdgeBundle({
5252
await esbuildAsync(
5353
{
5454
entryPoints: [entrypoint],
55-
// inject: ,
5655
bundle: true,
5756
outfile,
5857
external: ["node:*", "next", "@aws-sdk/*"],

packages/open-next/src/build/helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export function traverseFiles(
189189
root: string,
190190
conditionFn: (paths: TraversePath) => boolean,
191191
callbackFn: (paths: TraversePath) => void,
192-
searchingDir: string = "",
192+
searchingDir = "",
193193
) {
194194
fs.readdirSync(path.join(root, searchingDir)).forEach((file) => {
195195
const relativePath = path.join(searchingDir, file);

packages/open-next/src/core/patchAsyncStorage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ const mod = require("module");
33
const resolveFilename = mod._resolveFilename;
44

55
export function patchAsyncStorage() {
6-
mod._resolveFilename = function (
6+
mod._resolveFilename = ((
77
originalResolveFilename: typeof resolveFilename,
88
request: string,
99
parent: any,
1010
isMain: boolean,
1111
options: any,
12-
) {
12+
) => {
1313
if (
1414
request.endsWith("static-generation-async-storage.external") ||
1515
request.endsWith("static-generation-async-storage.external.js")
@@ -35,5 +35,5 @@ export function patchAsyncStorage() {
3535
);
3636

3737
// We use `bind` here to avoid referencing outside variables to create potential memory leaks.
38-
}.bind(null, resolveFilename);
38+
}).bind(null, resolveFilename);
3939
}

packages/open-next/src/core/requestHandler.ts

Lines changed: 93 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import { debug, error, warn } from "../adapters/logger";
99
import { patchAsyncStorage } from "./patchAsyncStorage";
1010
import { convertRes, createServerResponse, proxyRequest } from "./routing/util";
1111
import type { MiddlewareOutputEvent } from "./routingHandler";
12-
import routingHandler from "./routingHandler";
12+
import routingHandler, {
13+
MIDDLEWARE_HEADER_PREFIX,
14+
MIDDLEWARE_HEADER_PREFIX_LEN,
15+
} from "./routingHandler";
1316
import { requestHandler, setNextjsPrebundledReact } from "./util";
1417

1518
// This is used to identify requests in the cache
@@ -51,107 +54,103 @@ export async function openNextHandler(
5154
? preprocessResult.headers
5255
: preprocessResult.internalEvent.headers;
5356

54-
const overwrittenResponseHeaders = Object.entries(
55-
"type" in preprocessResult
56-
? preprocessResult.headers
57-
: preprocessResult.internalEvent.headers,
58-
).reduce((acc, [key, value]) => {
59-
if (!key.startsWith("x-middleware-response-")) {
60-
return acc;
61-
} else {
62-
const newKey = key.replace("x-middleware-response-", "");
63-
delete headers[key];
64-
headers[newKey] = value;
65-
return { ...acc, [newKey]: value };
57+
const overwrittenResponseHeaders: Record<string, string | string[]> = {};
58+
59+
for (const [rawKey, value] of Object.entries(headers)) {
60+
if (!rawKey.startsWith(MIDDLEWARE_HEADER_PREFIX)) {
61+
continue;
6662
}
67-
}, {});
63+
const key = rawKey.slice(MIDDLEWARE_HEADER_PREFIX_LEN);
64+
overwrittenResponseHeaders[key] = value;
65+
headers[key] = value;
66+
delete headers[rawKey];
67+
}
6868

6969
if ("type" in preprocessResult) {
70-
// // res is used only in the streaming case
70+
// response is used only in the streaming case
7171
if (responseStreaming) {
72-
const res = createServerResponse(
72+
const response = createServerResponse(
7373
internalEvent,
7474
headers,
7575
responseStreaming,
7676
);
77-
res.statusCode = preprocessResult.statusCode;
78-
res.flushHeaders();
77+
response.statusCode = preprocessResult.statusCode;
78+
response.flushHeaders();
7979
const [bodyToConsume, bodyToReturn] = preprocessResult.body.tee();
8080
for await (const chunk of bodyToConsume) {
81-
res.write(chunk);
81+
response.write(chunk);
8282
}
83-
res.end();
83+
response.end();
8484
preprocessResult.body = bodyToReturn;
8585
}
8686
return preprocessResult;
87-
} else {
88-
const preprocessedEvent = preprocessResult.internalEvent;
89-
debug("preprocessedEvent", preprocessedEvent);
90-
const reqProps = {
91-
method: preprocessedEvent.method,
92-
url: preprocessedEvent.url,
93-
//WORKAROUND: We pass this header to the serverless function to mimic a prefetch request which will not trigger revalidation since we handle revalidation differently
94-
// There is 3 way we can handle revalidation:
95-
// 1. We could just let the revalidation go as normal, but due to race condtions the revalidation will be unreliable
96-
// 2. We could alter the lastModified time of our cache to make next believe that the cache is fresh, but this could cause issues with stale data since the cdn will cache the stale data as if it was fresh
97-
// 3. OUR CHOICE: We could pass a purpose prefetch header to the serverless function to make next believe that the request is a prefetch request and not trigger revalidation (This could potentially break in the future if next changes the behavior of prefetch requests)
98-
headers: { ...headers, purpose: "prefetch" },
99-
body: preprocessedEvent.body,
100-
remoteAddress: preprocessedEvent.remoteAddress,
101-
};
102-
const requestId = Math.random().toString(36);
103-
const pendingPromiseRunner: DetachedPromiseRunner =
104-
new DetachedPromiseRunner();
105-
const isISRRevalidation = headers["x-isr"] === "1";
106-
const mergeHeadersPriority = globalThis.openNextConfig.dangerous
107-
?.headersAndCookiesPriority
108-
? globalThis.openNextConfig.dangerous.headersAndCookiesPriority(
109-
preprocessedEvent,
110-
)
111-
: "middleware";
112-
const internalResult = await globalThis.__als.run(
113-
{
114-
requestId,
115-
pendingPromiseRunner,
116-
isISRRevalidation,
117-
mergeHeadersPriority,
118-
},
119-
async () => {
120-
const preprocessedResult = preprocessResult as MiddlewareOutputEvent;
121-
const req = new IncomingMessage(reqProps);
122-
const res = createServerResponse(
123-
preprocessedEvent,
124-
overwrittenResponseHeaders,
125-
responseStreaming,
126-
);
127-
128-
await processRequest(
129-
req,
130-
res,
131-
preprocessedEvent,
132-
preprocessedResult.isExternalRewrite,
133-
);
134-
135-
const { statusCode, headers, isBase64Encoded, body } = convertRes(res);
136-
137-
const internalResult = {
138-
type: internalEvent.type,
139-
statusCode,
140-
headers,
141-
body,
142-
isBase64Encoded,
143-
};
144-
145-
// reset lastModified. We need to do this to avoid memory leaks
146-
delete globalThis.lastModified[requestId];
147-
148-
await pendingPromiseRunner.await();
149-
150-
return internalResult;
151-
},
152-
);
153-
return internalResult;
15487
}
88+
89+
const preprocessedEvent = preprocessResult.internalEvent;
90+
debug("preprocessedEvent", preprocessedEvent);
91+
const reqProps = {
92+
method: preprocessedEvent.method,
93+
url: preprocessedEvent.url,
94+
//WORKAROUND: We pass this header to the serverless function to mimic a prefetch request which will not trigger revalidation since we handle revalidation differently
95+
// There is 3 way we can handle revalidation:
96+
// 1. We could just let the revalidation go as normal, but due to race conditions the revalidation will be unreliable
97+
// 2. We could alter the lastModified time of our cache to make next believe that the cache is fresh, but this could cause issues with stale data since the cdn will cache the stale data as if it was fresh
98+
// 3. OUR CHOICE: We could pass a purpose prefetch header to the serverless function to make next believe that the request is a prefetch request and not trigger revalidation (This could potentially break in the future if next changes the behavior of prefetch requests)
99+
headers: { ...headers, purpose: "prefetch" },
100+
body: preprocessedEvent.body,
101+
remoteAddress: preprocessedEvent.remoteAddress,
102+
};
103+
const requestId = Math.random().toString(36);
104+
const pendingPromiseRunner = new DetachedPromiseRunner();
105+
const isISRRevalidation = headers["x-isr"] === "1";
106+
const mergeHeadersPriority = globalThis.openNextConfig.dangerous
107+
?.headersAndCookiesPriority
108+
? globalThis.openNextConfig.dangerous.headersAndCookiesPriority(
109+
preprocessedEvent,
110+
)
111+
: "middleware";
112+
const internalResult = await globalThis.__als.run(
113+
{
114+
requestId,
115+
pendingPromiseRunner,
116+
isISRRevalidation,
117+
mergeHeadersPriority,
118+
},
119+
async () => {
120+
const preprocessedResult = preprocessResult as MiddlewareOutputEvent;
121+
const req = new IncomingMessage(reqProps);
122+
const res = createServerResponse(
123+
preprocessedEvent,
124+
overwrittenResponseHeaders,
125+
responseStreaming,
126+
);
127+
128+
await processRequest(
129+
req,
130+
res,
131+
preprocessedEvent,
132+
preprocessedResult.isExternalRewrite,
133+
);
134+
135+
const { statusCode, headers, isBase64Encoded, body } = convertRes(res);
136+
137+
const internalResult = {
138+
type: internalEvent.type,
139+
statusCode,
140+
headers,
141+
body,
142+
isBase64Encoded,
143+
};
144+
145+
// reset lastModified. We need to do this to avoid memory leaks
146+
delete globalThis.lastModified[requestId];
147+
148+
await pendingPromiseRunner.await();
149+
150+
return internalResult;
151+
},
152+
);
153+
return internalResult;
155154
}
156155

157156
async function processRequest(
@@ -169,18 +168,16 @@ async function processRequest(
169168
// `serverHandler` is replaced at build time depending on user's
170169
// nextjs version to patch Nextjs 13.4.x and future breaking changes.
171170

172-
const { rawPath } = internalEvent;
173-
174171
if (isExternalRewrite) {
175172
return proxyRequest(internalEvent, res);
176-
} else {
177-
//#override applyNextjsPrebundledReact
178-
setNextjsPrebundledReact(rawPath);
179-
//#endOverride
180-
181-
// Next Server
182-
await requestHandler(req, res);
183173
}
174+
175+
//#override applyNextjsPrebundledReact
176+
setNextjsPrebundledReact(internalEvent.rawPath);
177+
//#endOverride
178+
179+
// Next Server
180+
await requestHandler(req, res);
184181
} catch (e: any) {
185182
// This might fail when using bundled next, importing won't do the trick either
186183
if (e.constructor.name === "NoFallbackError") {

0 commit comments

Comments
 (0)