Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@
"import/extensions": ["error", "always", { "ignorePackages": true }]
}
},
{
"files": ["packages/open-next/**/*"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
},
{
"files": ["packages/tests-*/**", "examples/**", "examples-cloudflare/**"],
"rules": {
Expand Down
3 changes: 2 additions & 1 deletion packages/open-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
},
"scripts": {
"build": "tsc && tsc-alias",
"dev": "concurrently \"tsc -w\" \"tsc-alias -w\""
"dev": "concurrently \"tsc -w\" \"tsc-alias -w\"",
"ts:check": "tsc --noEmit"
},
"dependencies": {
"@ast-grep/napi": "^0.40.0",
Expand Down
16 changes: 11 additions & 5 deletions packages/open-next/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,24 @@ import { addDebugFile } from "./debug.js";
import type { ContentUpdater } from "./plugins/content-updater.js";
import { externalChunksPlugin, inlineRouteHandler } from "./plugins/inlineRouteHandlers.js";

export type NextAdapterOutput = {
pathname: string;
filePath: string;
assets: Record<string, unknown>;
};

export type NextAdapterOutputs = {
pages: any[];
pagesApi: any[];
appPages: any[];
appRoutes: any[];
pages: NextAdapterOutput[];
pagesApi: NextAdapterOutput[];
appPages: NextAdapterOutput[];
appRoutes: NextAdapterOutput[];
};

type NextAdapter = {
name: string;
modifyConfig: (config: NextConfig, { phase }: { phase: string }) => Promise<NextConfig>;
onBuildComplete: (props: {
routes: any;
routes: unknown;
outputs: NextAdapterOutputs;
projectDir: string;
repoRoot: string;
Expand Down
26 changes: 18 additions & 8 deletions packages/open-next/src/adapters/image-optimization-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export async function defaultHandler(
}
const result = await optimizeImage(headers, imageParams, nextConfig, downloadHandler);
return buildSuccessResponse(result, options?.streamCreator, etag);
} catch (e: any) {
} catch (e: unknown) {
error("Failed to optimize image", e);
return buildFailureResponse("Internal server error", options?.streamCreator);
}
Expand Down Expand Up @@ -129,13 +129,23 @@ function computeEtag(imageParams: { href: string; width: number; quality: number
.digest("base64");
}

function buildSuccessResponse(result: any, streamCreator?: StreamCreator, etag?: string): InternalResult {
type ImageOptimizeResult = {
contentType: string;
buffer: Buffer;
maxAge: number;
};

function buildSuccessResponse(
imageOptimizeResult: ImageOptimizeResult,
streamCreator?: StreamCreator,
etag?: string
): InternalResult {
const headers: Record<string, string> = {
Vary: "Accept",
"Content-Type": result.contentType,
"Cache-Control": `public,max-age=${result.maxAge},immutable`,
"Content-Type": imageOptimizeResult.contentType,
"Cache-Control": `public,max-age=${imageOptimizeResult.maxAge},immutable`,
};
debug("result", result);
debug("result", imageOptimizeResult);
if (etag) {
headers.ETag = etag;
}
Expand All @@ -147,13 +157,13 @@ function buildSuccessResponse(result: any, streamCreator?: StreamCreator, etag?:
streamCreator
);
response.writeHead(200, headers);
response.end(result.buffer);
response.end(imageOptimizeResult.buffer);
}

return {
type: "core",
statusCode: 200,
body: toReadableStream(result.buffer, true),
body: toReadableStream(imageOptimizeResult.buffer, true),
isBase64Encoded: true,
headers,
};
Expand Down Expand Up @@ -239,7 +249,7 @@ async function downloadHandler(_req: IncomingMessage, res: ServerResponse, url:
res.setHeader("Cache-Control", response.cacheControl);
}
}
} catch (e: any) {
} catch (e: unknown) {
error("Failed to download image", e);
throw e;
}
Expand Down
29 changes: 20 additions & 9 deletions packages/open-next/src/adapters/logger.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { isOpenNextError } from "@/utils/error.js";

export function debug(...args: any[]) {
export function debug(...args: unknown[]) {
if (globalThis.openNextDebug) {
console.log(...args);
}
}

export function warn(...args: any[]) {
export function warn(...args: unknown[]) {
console.warn(...args);
}

Expand All @@ -28,16 +28,27 @@ const DOWNPLAYED_ERROR_LOGS: AwsSdkClientCommandErrorInput[] = [
},
];

const isDownplayedErrorLog = (errorLog: AwsSdkClientCommandErrorLog) =>
DOWNPLAYED_ERROR_LOGS.some(
const isAwsSdkClientCommandErrorLog = (errorLog: unknown): errorLog is AwsSdkClientCommandErrorLog =>
errorLog !== null &&
typeof errorLog === "object" &&
"clientName" in errorLog &&
"commandName" in errorLog &&
"error" in errorLog;

const isDownplayedErrorLog = (errorLog: unknown): boolean => {
if (!isAwsSdkClientCommandErrorLog(errorLog)) {
return false;
}
return DOWNPLAYED_ERROR_LOGS.some(
(downplayedInput) =>
downplayedInput.clientName === errorLog?.clientName &&
downplayedInput.commandName === errorLog?.commandName &&
(downplayedInput.errorName === errorLog?.error?.name ||
downplayedInput.errorName === errorLog?.error?.Code)
downplayedInput.clientName === errorLog.clientName &&
downplayedInput.commandName === errorLog.commandName &&
(downplayedInput.errorName === errorLog.error?.name ||
downplayedInput.errorName === errorLog.error?.Code)
);
};

export function error(...args: any[]) {
export function error(...args: unknown[]) {
// we try to catch errors from the aws-sdk client and downplay some of them
if (args.some((arg) => isDownplayedErrorLog(arg))) {
return debug(...args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { debug } from "../../logger.js";
//#override optimizeImage
export async function optimizeImage(
headers: APIGatewayProxyEventHeaders,
// oxlint-disable-next-line @typescript-eslint/no-explicit-any - image optimization API varies across Next.js versions
imageParams: any,
nextConfig: NextConfig,
handleRequest: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { debug } from "../../logger.js";
//#override optimizeImage
export async function optimizeImage(
headers: APIGatewayProxyEventHeaders,
// oxlint-disable-next-line @typescript-eslint/no-explicit-any - image optimization API varies across Next.js versions
imageParams: any,
nextConfig: NextConfig,
handleRequest: (
Expand Down
6 changes: 3 additions & 3 deletions packages/open-next/src/build/copyAdapterFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function copyAdapterFiles(
// Copying the files from outputs to the output dir
for (const [key, value] of Object.entries(outputs)) {
if (["pages", "pagesApi", "appPages", "appRoutes"].includes(key)) {
for (const route of value as any[]) {
for (const route of value) {
const assets = route.assets;
// We need to copy the filepaths to the output dir
const relativeFilePath = path.relative(options.appPath, route.filePath);
Expand Down Expand Up @@ -58,8 +58,8 @@ export async function copyAdapterFiles(
if (symlink) {
try {
fs.symlinkSync(symlink, to);
} catch (e: any) {
if (e.code !== "EEXIST") {
} catch (e: unknown) {
if (e instanceof Error && (e as NodeJS.ErrnoException).code !== "EEXIST") {
throw e;
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/open-next/src/build/copyTracedFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ File ${serverPath} does not exist
if (symlink) {
try {
symlinkSync(symlink, to);
} catch (e: any) {
if (e.code !== "EEXIST") {
} catch (e: unknown) {
if (e instanceof Error && (e as NodeJS.ErrnoException).code !== "EEXIST") {
throw e;
}
}
Expand Down
19 changes: 14 additions & 5 deletions packages/open-next/src/build/createAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import { isBinaryContentType } from "../utils/binary.js";

import * as buildHelper from "./helper.js";

type CacheFileMeta = {
segmentPaths?: string[];
headers?: Record<string, string>;
};

type FetchCacheData = {
tags?: string[];
};

/**
* Copy the static assets to the output folder
*
Expand Down Expand Up @@ -153,10 +162,10 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
// Generate cache file
Object.entries(cacheFilesPath).forEach(([cacheFilePath, files]) => {
const cacheFileMeta = files.meta
? safeParseJsonFile(fs.readFileSync(files.meta, "utf8"), cacheFilePath)
? safeParseJsonFile<CacheFileMeta>(fs.readFileSync(files.meta, "utf8"), cacheFilePath)
: undefined;
const cacheJson = files.json
? safeParseJsonFile(fs.readFileSync(files.json, "utf8"), cacheFilePath)
? safeParseJsonFile<Record<string, unknown>>(fs.readFileSync(files.json, "utf8"), cacheFilePath)
: undefined;
if ((files.meta && !cacheFileMeta) || (files.json && !cacheJson)) {
logger.warn(`Skipping invalid cache file: ${cacheFilePath}`);
Expand Down Expand Up @@ -186,7 +195,7 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
body: files.body
? fs
.readFileSync(files.body)
.toString(isBinaryContentType(cacheFileMeta.headers["content-type"]) ? "base64" : "utf8")
.toString(isBinaryContentType(cacheFileMeta?.headers?.["content-type"]) ? "base64" : "utf8")
: undefined,
segmentData: Object.keys(segments).length > 0 ? segments : undefined,
};
Expand All @@ -211,7 +220,7 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
() => true,
({ absolutePath, relativePath }) => {
const fileContent = fs.readFileSync(absolutePath, "utf8");
const fileData = safeParseJsonFile(fileContent, absolutePath);
const fileData = safeParseJsonFile<FetchCacheData>(fileContent, absolutePath);
fileData?.tags?.forEach((tag: string) => {
metaFiles.push({
tag: { S: path.posix.join(buildId, tag) },
Expand All @@ -234,7 +243,7 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
({ absolutePath, relativePath }) => absolutePath.endsWith(".meta") && !isFileSkipped(relativePath),
({ absolutePath, relativePath }) => {
const fileContent = fs.readFileSync(absolutePath, "utf8");
const fileData = safeParseJsonFile(fileContent, absolutePath);
const fileData = safeParseJsonFile<CacheFileMeta>(fileContent, absolutePath);
if (fileData?.headers?.["x-next-cache-tags"]) {
fileData.headers["x-next-cache-tags"].split(",").forEach((tag: string) => {
// TODO: We should split the tag using getDerivedTags from next.js or maybe use an in house implementation
Expand Down
6 changes: 3 additions & 3 deletions packages/open-next/src/build/createServerBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getCrossPlatformPathRegex } from "../utils/regex.js";
import { bundleNextServer } from "./bundleNextServer.js";
import { compileCache } from "./compileCache.js";
import { copyAdapterFiles } from "./copyAdapterFiles.js";
import { copyTracedFiles } from "./copyTracedFiles.js";
import { copyTracedFiles, getManifests } from "./copyTracedFiles.js";
import { copyMiddlewareResources, generateEdgeBundle } from "./edge/createEdgeBundle.js";
import * as buildHelper from "./helper.js";
import { installDependencies } from "./installDeps.js";
Expand Down Expand Up @@ -185,7 +185,7 @@ async function generateBundle(
buildHelper.copyEnvFile(appBuildOutputPath, packagePath, outputPath);

let tracedFiles: string[] = [];
let manifests: any = {};
let manifests: ReturnType<typeof getManifests> | Record<string, never> = {};

// Copy all necessary traced files
if (config.dangerous?.useAdapterOutputs) {
Expand All @@ -206,7 +206,7 @@ async function generateBundle(

const additionalCodePatches = codeCustomization?.additionalCodePatches ?? [];

await applyCodePatches(options, tracedFiles, manifests, [
await applyCodePatches(options, tracedFiles, manifests as ReturnType<typeof getManifests>, [
patches.patchFetchCacheSetMissingWaitUntil,
patches.patchFetchCacheForISR,
patches.patchUnstableCacheForISR,
Expand Down
2 changes: 1 addition & 1 deletion packages/open-next/src/build/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function normalizeOptions(config: OpenNextConfig, distDir: string, tempBu
appPackageJsonPath = findNextPackageJsonPath(appPath, monorepoRoot);
}

const debug = Boolean(process.env.OPEN_NEXT_DEBUG) ?? false;
const debug = Boolean(process.env.OPEN_NEXT_DEBUG);

return {
appBuildOutputPath: buildOutputPath,
Expand Down
4 changes: 2 additions & 2 deletions packages/open-next/src/build/installDeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export function installDependencies(outputDir: string, installOptions?: InstallO
// Cleanup tempDir
fs.rmSync(tempInstallDir, { recursive: true, force: true });
logger.info(`Dependencies installed for ${name}`);
} catch (e: any) {
logger.error(e.toString());
} catch (e: unknown) {
logger.error(e instanceof Error ? e.message : String(e));
logger.error("Could not install dependencies");
}
}
2 changes: 1 addition & 1 deletion packages/open-next/src/core/createGenericHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function createGenericHandler<
const handlerConfig = config[handler.type];
const override =
handlerConfig && "override" in handlerConfig
? (handlerConfig.override as any as DefaultOverrideOptions<E, R>)
? (handlerConfig.override as DefaultOverrideOptions<E, R>)
: undefined;

// From the config, we create the converter
Expand Down
4 changes: 2 additions & 2 deletions packages/open-next/src/core/nodeMiddlewareHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { AsyncLocalStorage } from "node:async_hooks";
globalThis.AsyncLocalStorage = AsyncLocalStorage;

interface NodeMiddleware {
default: (req: { handler: any; request: EdgeRequest; page: "middleware" }) => Promise<{
default: (req: { handler: unknown; request: EdgeRequest; page: "middleware" }) => Promise<{
response: Response;
waitUntil: Promise<void>;
}>;
middleware: any;
middleware: unknown;
}

let _module: NodeMiddleware | undefined;
Expand Down
4 changes: 2 additions & 2 deletions packages/open-next/src/core/patchAsyncStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ export function patchAsyncStorage() {
mod._resolveFilename = ((
originalResolveFilename: typeof resolveFilename,
request: string,
parent: any,
parent: unknown,
isMain: boolean,
options: any
options: unknown
) => {
if (
request.endsWith("static-generation-async-storage.external") ||
Expand Down
8 changes: 4 additions & 4 deletions packages/open-next/src/core/requestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ async function processRequest(req: IncomingMessage, res: OpenNextNodeResponse, r
//#endOverride

await requestHandler(requestMetadata)(req, res);
} catch (e: any) {
} catch (e: unknown) {
// This might fail when using bundled next, importing won't do the trick either
if (e.constructor.name === "NoFallbackError") {
if (e instanceof Error && e.constructor.name === "NoFallbackError") {
await handleNoFallbackError(req, res, routingResult, requestMetadata);
} else {
error("NextJS request failed.", e);
Expand Down Expand Up @@ -293,8 +293,8 @@ async function handleNoFallbackError(
// ...metadata,
// })(req, res);
//TODO: find a way to do that without breaking current main
} catch (e: any) {
if (e.constructor.name === "NoFallbackError") {
} catch (e: unknown) {
if (e instanceof Error && e.constructor.name === "NoFallbackError") {
await handleNoFallbackError(req, res, routingResult, metadata, index + 1);
} else {
error("NextJS request failed.", e);
Expand Down
Loading
Loading