Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b5d94a1
refactor: narrow middleware config without type assertion
314systems Apr 28, 2026
1d24faf
refactor: remove unnecessary optional chaining
314systems Apr 28, 2026
b73989a
refactor: remove unnecessary type assertion
314systems Apr 28, 2026
a0123e7
refactor: remove unnecessary optional chaining
314systems Apr 28, 2026
dd8cca0
chore: fix unnecessary conditional lint warning
314systems Apr 28, 2026
060c183
refactor: remove unnecessary optional chaining
314systems Apr 28, 2026
98640e3
refactor: remove unnecessary nullish coalescing for revalidatedAt
314systems Apr 28, 2026
63fd71f
refactor: validate queue service binding before assignment
314systems Apr 28, 2026
ee1498b
refactor: remove optional chaining for stdout and stderr in runWrangler
314systems Apr 28, 2026
74474bc
refactor: remove nullish coalescing for routes in generateBundle func…
314systems Apr 28, 2026
71879cc
fix: restore optional chaining for __openNextAls in KV tag cache
314systems Apr 28, 2026
eaf0fe0
refactor: simplify stale and expire properties in cached tag value
314systems Apr 28, 2026
e3d02ec
refactor: remove redundant string from tag cache filter union
314systems Apr 28, 2026
8e6ecad
refactor: remove unnecessary optional chaining
314systems Apr 28, 2026
9314fd8
refactor: remove non-null assertions in image query parameter validators
314systems Apr 28, 2026
48ba2c0
refactor: replace non-null assertions with optional chaining in verce…
314systems Apr 28, 2026
0c4098b
refactor: improve date extraction logic in getLatestCompatDate function
314systems Apr 28, 2026
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: 4 additions & 2 deletions packages/cloudflare/src/api/durable-objects/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ export class DOQueueHandler extends DurableObject<CloudflareEnv> {

constructor(ctx: DurableObjectState, env: CloudflareEnv) {
super(ctx, env);
this.service = env.WORKER_SELF_REFERENCE!;
// If there is no service binding, we throw an error because we can't revalidate without it
if (!this.service) throw new IgnorableError("No service binding for cache revalidation worker");
if (!env.WORKER_SELF_REFERENCE) {
throw new IgnorableError("No service binding for cache revalidation worker");
}
this.service = env.WORKER_SELF_REFERENCE;
this.sql = ctx.storage.sql;

this.maxRevalidations = env.NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/src/api/overrides/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function computeCacheKey(key: string, options: KeyOptions) {

export function isPurgeCacheEnabled(): boolean {
// The `?` is required at `openNextConfig?` or the Open Next build fails because of a type error
const cdnInvalidation = globalThis.openNextConfig?.default?.override?.cdnInvalidation;
const cdnInvalidation = globalThis.openNextConfig.default?.override?.cdnInvalidation;

return cdnInvalidation !== undefined && cdnInvalidation !== "dummy";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class D1NextModeTagCache implements NextModeTagCache {
const row = rowsByKey.get(this.getCacheKey(tag));
const value: D1TagValue | null = row
? {
revalidatedAt: (row[1] as number) ?? 0,
revalidatedAt: row[1] as number,
stale: (row[2] as number) ?? null,
expire: (row[3] as number) ?? null,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,16 +304,16 @@ class ShardedDOTagCache implements NextModeTagCache {
return {
tag,
revalidatedAt: parsed,
stale: parsed as number | null,
expire: null as number | null,
stale: parsed,
expire: null,
};
}
const data = parsed as TagData;
return {
tag,
revalidatedAt: data.revalidatedAt ?? 0,
stale: data.stale ?? null,
expire: data.expire ?? null,
revalidatedAt: data.revalidatedAt,
stale: data.stale,
expire: data.expire,
};
} catch (e) {
debugCache("Error while parsing cached value", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type KVTagValue =
| { revalidatedAt: number; stale?: number | null; expire?: number | null };

function getRevalidatedAt(value: KVTagValue): number {
return typeof value === "number" ? value : (value.revalidatedAt ?? 0);
return typeof value === "number" ? value : value.revalidatedAt;
}

function getStale(value: KVTagValue): number | null {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface WithFilterOptions {
* @param tag The tag to filter.
* @returns true if the tag should be forwarded, false otherwise.
*/
filterFn: (tag: string | NextModeTagCacheWriteInput) => boolean;
filterFn: (tag: NextModeTagCacheWriteInput) => boolean;
}

/**
Expand Down Expand Up @@ -69,7 +69,7 @@ export function withFilter({ tagCache, filterFn }: WithFilterOptions): NextModeT
* This is used to filter out internal soft tags.
* Can be used if `revalidatePath` is not used.
*/
export function softTagFilter(tag: string | NextModeTagCacheWriteInput): boolean {
export function softTagFilter(tag: NextModeTagCacheWriteInput): boolean {
if (typeof tag === "string") {
return !tag.startsWith("_N_T_");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ async function generateBundle(
buildOutputPath: appBuildOutputPath,
packagePath,
outputDir: outputPath,
routes: fnOptions.routes ?? ["app/page.tsx"],
routes: fnOptions.routes,
bundledNextServer: isBundled,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ export function patchVercelOgLibrary(buildOpts: BuildOptions): boolean {
writeFileSync(outputEdgePath, ast.commitEdits(edits));

if (matches.length > 0) {
const fontFileName = matches[0]!.getMatch("PATH")!.text();
renameSync(path.join(outputDir, fontFileName), path.join(outputDir, `${fontFileName}.bin`));
const fontFileName = matches[0]?.getMatch("PATH")?.text();
if (fontFileName) {
renameSync(path.join(outputDir, fontFileName), path.join(outputDir, `${fontFileName}.bin`));
}
}
}

Expand Down
28 changes: 14 additions & 14 deletions packages/cloudflare/src/cli/build/utils/ensure-cf-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logger from "@opennextjs/aws/logger.js";
import type { ExternalMiddlewareConfig } from "@opennextjs/aws/types/open-next.js";

import type { OpenNextConfig } from "../../../api/config.js";

Expand All @@ -9,24 +8,25 @@ import type { OpenNextConfig } from "../../../api/config.js";
* @param config OpenNext configuration.
*/
export function ensureCloudflareConfig(config: OpenNextConfig) {
const mwIsMiddlewareExternal = config.middleware?.external === true;
const mwConfig = mwIsMiddlewareExternal ? (config.middleware as ExternalMiddlewareConfig) : undefined;
const { middleware } = config;
const mwConfig = middleware?.external === true ? middleware : undefined;
const mwIsMiddlewareExternal = mwConfig !== undefined;

const requirements = {
// Check for the default function
dftUseCloudflareWrapper: config.default?.override?.wrapper === "cloudflare-node",
dftUseEdgeConverter: config.default?.override?.converter === "edge",
dftUseFetchProxy: config.default?.override?.proxyExternalRequest === "fetch",
dftUseCloudflareWrapper: config.default.override?.wrapper === "cloudflare-node",
dftUseEdgeConverter: config.default.override?.converter === "edge",
dftUseFetchProxy: config.default.override?.proxyExternalRequest === "fetch",
dftMaybeUseCache:
config.default?.override?.incrementalCache === "dummy" ||
typeof config.default?.override?.incrementalCache === "function",
config.default.override?.incrementalCache === "dummy" ||
typeof config.default.override?.incrementalCache === "function",
dftMaybeUseTagCache:
config.default?.override?.tagCache === "dummy" ||
typeof config.default?.override?.incrementalCache === "function",
config.default.override?.tagCache === "dummy" ||
typeof config.default.override?.incrementalCache === "function",
dftMaybeUseQueue:
config.default?.override?.queue === "dummy" ||
config.default?.override?.queue === "direct" ||
typeof config.default?.override?.queue === "function",
config.default.override?.queue === "dummy" ||
config.default.override?.queue === "direct" ||
typeof config.default.override?.queue === "function",
// Check for the middleware function
mwIsMiddlewareExternal,
mwUseCloudflareWrapper: mwConfig?.override?.wrapper === "cloudflare-edge",
Expand All @@ -35,7 +35,7 @@ export function ensureCloudflareConfig(config: OpenNextConfig) {
hasCryptoExternal: config.edgeExternals?.includes("node:crypto"),
};

if (config.default?.override?.queue === "direct") {
if (config.default.override?.queue === "direct") {
logger.warn("The direct mode queue is not recommended for use in production.");
}

Expand Down
14 changes: 7 additions & 7 deletions packages/cloudflare/src/cli/commands/skew-protection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ export async function getDeploymentMapping(
process.exit(1);
}

const apiToken = envVars.CF_WORKERS_SCRIPTS_API_TOKEN!;
const accountId = envVars.CF_ACCOUNT_ID!;
const apiToken = envVars.CF_WORKERS_SCRIPTS_API_TOKEN;
const accountId = envVars.CF_ACCOUNT_ID;

const client = new Cloudflare({ apiToken });
const scriptName = envVars.CF_WORKER_NAME!;
const scriptName = envVars.CF_WORKER_NAME;

const deployedVersions = await listWorkerVersions(scriptName, {
client,
accountId,
maxNumberOfVersions: config.cloudflare?.skewProtection?.maxNumberOfVersions,
afterTimeMs: config.cloudflare?.skewProtection?.maxVersionAgeDays
? Date.now() - config.cloudflare?.skewProtection?.maxVersionAgeDays * MS_PER_DAY
maxNumberOfVersions: config.cloudflare.skewProtection.maxNumberOfVersions,
afterTimeMs: config.cloudflare.skewProtection.maxVersionAgeDays
? Date.now() - config.cloudflare.skewProtection.maxVersionAgeDays * MS_PER_DAY
: undefined,
});

Expand Down Expand Up @@ -257,7 +257,7 @@ export async function listWorkerVersions(
}
}
} catch (e) {
if (e instanceof NotFoundError && e.status === 404) {
if (e instanceof NotFoundError) {
// The worker has not been deployed before, no previous versions.
return [];
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cloudflare/src/cli/commands/utils/run-wrangler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ export function runWrangler(
);

const success = result.status === 0;
const stdout = result.stdout?.toString() ?? "";
const stderr = result.stderr?.toString() ?? "";
const stdout = result.stdout.toString();
const stderr = result.stderr.toString();

if (!noLogs) {
// When not piping logs, stderr is captured but should still be visible to the user
Expand Down
20 changes: 10 additions & 10 deletions packages/cloudflare/src/cli/templates/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,23 +486,22 @@ type ErrorResult = {
function validateUrlQueryParameter(requestURL: URL): ErrorResult | { url: string; static: boolean } {
// There should be a single "url" parameter.
const urls = requestURL.searchParams.getAll("url");
if (urls.length < 1) {
const [url, ...rest] = urls;
if (url === undefined) {
const result: ErrorResult = {
ok: false,
message: '"url" parameter is required',
};
return result;
}
if (urls.length > 1) {
if (rest.length > 0) {
const result: ErrorResult = {
ok: false,
message: '"url" parameter cannot be an array',
};
return result;
}

const url = urls[0]!;

if (url.length > 3072) {
const result: ErrorResult = {
ok: false,
Expand Down Expand Up @@ -574,21 +573,22 @@ function validateUrlQueryParameter(requestURL: URL): ErrorResult | { url: string
*/
function validateWidthQueryParameter(requestURL: URL): ErrorResult | number {
const widthQueryValues = requestURL.searchParams.getAll("w");
if (widthQueryValues.length < 1) {
const [widthQueryValue, ...rest] = widthQueryValues;

if (widthQueryValue === undefined) {
const result: ErrorResult = {
ok: false,
message: '"w" parameter (width) is required',
};
return result;
}
if (widthQueryValues.length > 1) {
if (rest.length > 0) {
const result: ErrorResult = {
ok: false,
message: '"w" parameter (width) cannot be an array',
};
return result;
}
const widthQueryValue = widthQueryValues[0]!;
if (!/^[0-9]+$/.test(widthQueryValue)) {
const result: ErrorResult = {
ok: false,
Expand Down Expand Up @@ -624,21 +624,21 @@ function validateWidthQueryParameter(requestURL: URL): ErrorResult | number {
*/
function validateQualityQueryParameter(requestURL: URL): ErrorResult | number {
const qualityQueryValues = requestURL.searchParams.getAll("q");
if (qualityQueryValues.length < 1) {
const [qualityQueryValue, ...rest] = qualityQueryValues;
if (qualityQueryValue === undefined) {
const result: ErrorResult = {
ok: false,
message: '"q" parameter (quality) is required',
};
return result;
}
if (qualityQueryValues.length > 1) {
if (rest.length > 0) {
const result: ErrorResult = {
ok: false,
message: '"q" parameter (quality) cannot be an array',
};
return result;
}
const qualityQueryValue = qualityQueryValues[0]!;
if (!/^[0-9]+$/.test(qualityQueryValue)) {
const result: ErrorResult = {
ok: false,
Expand Down
16 changes: 10 additions & 6 deletions packages/cloudflare/src/cli/utils/create-wrangler-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,18 @@ async function getLatestCompatDate(): Promise<string | undefined> {
// The format of the workerd version is `major.yyyymmdd.patch`.
const match = latestWorkerdVersion.match(/\d+\.(\d{4})(\d{2})(\d{2})\.\d+/);

if (match) {
const [, year, month, day] = match;
const compatDate = `${year}-${month}-${day}`;
if (!match) {
return undefined;
}
const [, year, month, day] = match;
if (!year || !month || !day) {
return undefined;
}
const compatDate = `${year}-${month}-${day}`;

const currentDate = new Date().toISOString().slice(0, 10);
const currentDate = new Date().toISOString().slice(0, 10);

return compatDate < currentDate ? compatDate : currentDate;
}
return compatDate < currentDate ? compatDate : currentDate;
} catch {
/* empty */
}
Expand Down
Loading