From 26b113faa232ac4aaf31718f56cdcd80d49e170f Mon Sep 17 00:00:00 2001 From: James Date: Mon, 9 Jun 2025 07:35:16 +0100 Subject: [PATCH 1/4] feat: pass cli arguments not used by opennext to wrangler --- .changeset/six-moons-shine.md | 5 ++ packages/cloudflare/src/cli/args.spec.ts | 29 ++++++++++++ packages/cloudflare/src/cli/args.ts | 60 ++++++++++++++++-------- 3 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 .changeset/six-moons-shine.md create mode 100644 packages/cloudflare/src/cli/args.spec.ts diff --git a/.changeset/six-moons-shine.md b/.changeset/six-moons-shine.md new file mode 100644 index 00000000..341d4e08 --- /dev/null +++ b/.changeset/six-moons-shine.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/cloudflare": patch +--- + +feat: pass cli arguments not used by opennext to wrangler diff --git a/packages/cloudflare/src/cli/args.spec.ts b/packages/cloudflare/src/cli/args.spec.ts new file mode 100644 index 00000000..8a6d2646 --- /dev/null +++ b/packages/cloudflare/src/cli/args.spec.ts @@ -0,0 +1,29 @@ +import { describe, expect, it } from "vitest"; + +import { getPassthroughArgs } from "./args.js"; + +describe("getPassthroughArgs", () => { + it("should return args not used by the cli", () => { + const args = [ + "pnpm", + "/opennextjs/cloudflare/examples/ssg-app/node_modules/@opennextjs/cloudflare/dist/cli/index.js", + "preview", + "--skipBuild", + "--preview", + "-t", + "-v=1", + "-pre", + "152", + "--pre2=1543", + ]; + + expect(getPassthroughArgs(args, { options: { skipBuild: { type: "boolean" } } })).toEqual([ + "--preview", + "-t", + "-v=1", + "-pre", + "152", + "--pre2=1543", + ]); + }); +}); diff --git a/packages/cloudflare/src/cli/args.ts b/packages/cloudflare/src/cli/args.ts index 292e3f7e..f333fab4 100644 --- a/packages/cloudflare/src/cli/args.ts +++ b/packages/cloudflare/src/cli/args.ts @@ -1,5 +1,6 @@ import { mkdirSync, type Stats, statSync } from "node:fs"; import { resolve } from "node:path"; +import type { ParseArgsConfig } from "node:util"; import { parseArgs } from "node:util"; import type { WranglerTarget } from "./utils/run-wrangler.js"; @@ -25,32 +26,33 @@ export type Arguments = ( } ) & { outputDir?: string }; +const config = { + allowPositionals: true, + strict: false, + options: { + skipBuild: { type: "boolean", short: "s", default: false }, + output: { type: "string", short: "o" }, + noMinify: { type: "boolean", default: false }, + skipWranglerConfigCheck: { type: "boolean", default: false }, + cacheChunkSize: { type: "string" }, + }, +} as const satisfies ParseArgsConfig; + export function getArgs(): Arguments { - const { positionals, values } = parseArgs({ - options: { - skipBuild: { type: "boolean", short: "s", default: false }, - output: { type: "string", short: "o" }, - noMinify: { type: "boolean", default: false }, - skipWranglerConfigCheck: { type: "boolean", default: false }, - cacheChunkSize: { type: "string" }, - }, - allowPositionals: true, - }); + const { positionals, values } = parseArgs(config); - const outputDir = values.output ? resolve(values.output) : undefined; + const outputDir = typeof values.output === "string" ? resolve(values.output) : undefined; if (outputDir) assertDirArg(outputDir, "output", true); - const passthroughArgs = getPassthroughArgs(); - switch (positionals[0]) { case "build": return { command: "build", outputDir, skipNextBuild: - values.skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)), + !!values.skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)), skipWranglerConfigCheck: - values.skipWranglerConfigCheck || + !!values.skipWranglerConfigCheck || ["1", "true", "yes"].includes(String(process.env.SKIP_WRANGLER_CONFIG_CHECK)), minify: !values.noMinify, }; @@ -60,7 +62,7 @@ export function getArgs(): Arguments { return { command: positionals[0], outputDir, - passthroughArgs, + passthroughArgs: getPassthroughArgs(process.argv, config), ...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }), }; case "populateCache": @@ -71,7 +73,7 @@ export function getArgs(): Arguments { command: "populateCache", outputDir, target: positionals[1], - environment: getWranglerEnvironmentFlag(passthroughArgs), + environment: getWranglerEnvironmentFlag(process.argv), ...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }), }; default: @@ -81,9 +83,27 @@ export function getArgs(): Arguments { } } -function getPassthroughArgs() { - const passthroughPos = process.argv.indexOf("--"); - return passthroughPos === -1 ? [] : process.argv.slice(passthroughPos + 1); +export function getPassthroughArgs(args: string[], { options = {} }: T) { + const passthroughArgs: string[] = []; + + args.forEach((fullArg, idx) => { + const [, name] = /^--?(\w+)(=.+)?$/.exec(fullArg) ?? []; + if (name && !(name in options)) { + passthroughArgs.push(fullArg); + + for (let i = idx + 1; i < args.length; i++) { + const arg = args[i]; + + if (!arg || arg.startsWith("-")) { + break; + } else { + passthroughArgs.push(arg); + } + } + } + }); + + return passthroughArgs; } function assertDirArg(path: string, argName?: string, make?: boolean) { From 1dcb950b0ad0fbce9593ca84fba75e87cae09878 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 9 Jun 2025 08:18:22 +0100 Subject: [PATCH 2/4] fix args with dash not being picked up --- packages/cloudflare/src/cli/args.spec.ts | 9 +++++++++ packages/cloudflare/src/cli/args.ts | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/cloudflare/src/cli/args.spec.ts b/packages/cloudflare/src/cli/args.spec.ts index 8a6d2646..90877ea5 100644 --- a/packages/cloudflare/src/cli/args.spec.ts +++ b/packages/cloudflare/src/cli/args.spec.ts @@ -15,6 +15,11 @@ describe("getPassthroughArgs", () => { "-pre", "152", "--pre2=1543", + "--", + "--port", + "1234", + "--inspector-port", + "1234", ]; expect(getPassthroughArgs(args, { options: { skipBuild: { type: "boolean" } } })).toEqual([ @@ -24,6 +29,10 @@ describe("getPassthroughArgs", () => { "-pre", "152", "--pre2=1543", + "--port", + "1234", + "--inspector-port", + "1234", ]); }); }); diff --git a/packages/cloudflare/src/cli/args.ts b/packages/cloudflare/src/cli/args.ts index f333fab4..28f525a9 100644 --- a/packages/cloudflare/src/cli/args.ts +++ b/packages/cloudflare/src/cli/args.ts @@ -87,7 +87,7 @@ export function getPassthroughArgs(args: string[], { const passthroughArgs: string[] = []; args.forEach((fullArg, idx) => { - const [, name] = /^--?(\w+)(=.+)?$/.exec(fullArg) ?? []; + const [, name] = /^--?(\w[\w-_]*)(=.+)?$/.exec(fullArg) ?? []; if (name && !(name in options)) { passthroughArgs.push(fullArg); From fc0c1cefa62bd9598484a818aab16bb90df981b3 Mon Sep 17 00:00:00 2001 From: James Anderson Date: Mon, 9 Jun 2025 11:04:56 +0100 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Victor Berchet --- .changeset/six-moons-shine.md | 2 +- packages/cloudflare/src/cli/args.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/six-moons-shine.md b/.changeset/six-moons-shine.md index 341d4e08..4c327421 100644 --- a/.changeset/six-moons-shine.md +++ b/.changeset/six-moons-shine.md @@ -2,4 +2,4 @@ "@opennextjs/cloudflare": patch --- -feat: pass cli arguments not used by opennext to wrangler +feat: pass cli arguments not used by `opennextjs-cloudflare` to wrangler diff --git a/packages/cloudflare/src/cli/args.ts b/packages/cloudflare/src/cli/args.ts index 28f525a9..67cc7781 100644 --- a/packages/cloudflare/src/cli/args.ts +++ b/packages/cloudflare/src/cli/args.ts @@ -26,6 +26,7 @@ export type Arguments = ( } ) & { outputDir?: string }; +// Config for parsing CLI arguments const config = { allowPositionals: true, strict: false, From efda97eddbe809bc2a656c3d6e1c23c9a397364a Mon Sep 17 00:00:00 2001 From: James Date: Wed, 11 Jun 2025 19:57:27 +0100 Subject: [PATCH 4/4] change to for and while loop with early return --- packages/cloudflare/src/cli/args.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/cloudflare/src/cli/args.ts b/packages/cloudflare/src/cli/args.ts index 67cc7781..ef9c449b 100644 --- a/packages/cloudflare/src/cli/args.ts +++ b/packages/cloudflare/src/cli/args.ts @@ -87,22 +87,21 @@ export function getArgs(): Arguments { export function getPassthroughArgs(args: string[], { options = {} }: T) { const passthroughArgs: string[] = []; - args.forEach((fullArg, idx) => { - const [, name] = /^--?(\w[\w-_]*)(=.+)?$/.exec(fullArg) ?? []; - if (name && !(name in options)) { - passthroughArgs.push(fullArg); + for (let i = 0; i < args.length; i++) { + if (args[i] === "--") { + passthroughArgs.push(...args.slice(i + 1)); + return passthroughArgs; + } - for (let i = idx + 1; i < args.length; i++) { - const arg = args[i]; + const [, name] = /^--?(\w[\w-_]*)(=.+)?$/.exec(args[i]!) ?? []; + if (name && !(name in options)) { + passthroughArgs.push(args[i]!); - if (!arg || arg.startsWith("-")) { - break; - } else { - passthroughArgs.push(arg); - } + while (!args[i + 1]?.startsWith("-")) { + passthroughArgs.push(args[++i]!); } } - }); + } return passthroughArgs; }