Skip to content

Commit 9ed8d8a

Browse files
authored
feat: pass cli arguments not used by opennext to wrangler (#720)
1 parent ae31733 commit 9ed8d8a

File tree

3 files changed

+88
-20
lines changed

3 files changed

+88
-20
lines changed

.changeset/six-moons-shine.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
feat: pass cli arguments not used by `opennextjs-cloudflare` to wrangler
6+
7+
Previously, arguments had to be provided after `--` e.g. `opennextjs-cloudflare preview -- --port 12345`. This is no longer necessary, and they can be provided normally, e.g. `opennextjs-cloudflare preview --port 12345`.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { describe, expect, it } from "vitest";
2+
3+
import { getPassthroughArgs } from "./args.js";
4+
5+
describe("getPassthroughArgs", () => {
6+
it("should return args not used by the cli", () => {
7+
const args = [
8+
"pnpm",
9+
"/opennextjs/cloudflare/examples/ssg-app/node_modules/@opennextjs/cloudflare/dist/cli/index.js",
10+
"preview",
11+
"--skipBuild",
12+
"--preview",
13+
"-t",
14+
"-v=1",
15+
"-pre",
16+
"152",
17+
"--pre2=1543",
18+
"--",
19+
"--port",
20+
"1234",
21+
"--inspector-port",
22+
"1234",
23+
];
24+
25+
expect(getPassthroughArgs(args, { options: { skipBuild: { type: "boolean" } } })).toEqual([
26+
"--preview",
27+
"-t",
28+
"-v=1",
29+
"-pre",
30+
"152",
31+
"--pre2=1543",
32+
"--port",
33+
"1234",
34+
"--inspector-port",
35+
"1234",
36+
]);
37+
});
38+
});

packages/cloudflare/src/cli/args.ts

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { mkdirSync, type Stats, statSync } from "node:fs";
22
import { resolve } from "node:path";
3+
import type { ParseArgsConfig } from "node:util";
34
import { parseArgs } from "node:util";
45

56
import type { WranglerTarget } from "./utils/run-wrangler.js";
@@ -25,32 +26,34 @@ export type Arguments = (
2526
}
2627
) & { outputDir?: string };
2728

29+
// Config for parsing CLI arguments
30+
const config = {
31+
allowPositionals: true,
32+
strict: false,
33+
options: {
34+
skipBuild: { type: "boolean", short: "s", default: false },
35+
output: { type: "string", short: "o" },
36+
noMinify: { type: "boolean", default: false },
37+
skipWranglerConfigCheck: { type: "boolean", default: false },
38+
cacheChunkSize: { type: "string" },
39+
},
40+
} as const satisfies ParseArgsConfig;
41+
2842
export function getArgs(): Arguments {
29-
const { positionals, values } = parseArgs({
30-
options: {
31-
skipBuild: { type: "boolean", short: "s", default: false },
32-
output: { type: "string", short: "o" },
33-
noMinify: { type: "boolean", default: false },
34-
skipWranglerConfigCheck: { type: "boolean", default: false },
35-
cacheChunkSize: { type: "string" },
36-
},
37-
allowPositionals: true,
38-
});
43+
const { positionals, values } = parseArgs(config);
3944

40-
const outputDir = values.output ? resolve(values.output) : undefined;
45+
const outputDir = typeof values.output === "string" ? resolve(values.output) : undefined;
4146
if (outputDir) assertDirArg(outputDir, "output", true);
4247

43-
const passthroughArgs = getPassthroughArgs();
44-
4548
switch (positionals[0]) {
4649
case "build":
4750
return {
4851
command: "build",
4952
outputDir,
5053
skipNextBuild:
51-
values.skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)),
54+
!!values.skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)),
5255
skipWranglerConfigCheck:
53-
values.skipWranglerConfigCheck ||
56+
!!values.skipWranglerConfigCheck ||
5457
["1", "true", "yes"].includes(String(process.env.SKIP_WRANGLER_CONFIG_CHECK)),
5558
minify: !values.noMinify,
5659
};
@@ -60,7 +63,7 @@ export function getArgs(): Arguments {
6063
return {
6164
command: positionals[0],
6265
outputDir,
63-
passthroughArgs,
66+
passthroughArgs: getPassthroughArgs(process.argv, config),
6467
...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }),
6568
};
6669
case "populateCache":
@@ -71,7 +74,7 @@ export function getArgs(): Arguments {
7174
command: "populateCache",
7275
outputDir,
7376
target: positionals[1],
74-
environment: getWranglerEnvironmentFlag(passthroughArgs),
77+
environment: getWranglerEnvironmentFlag(process.argv),
7578
...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }),
7679
};
7780
default:
@@ -81,9 +84,29 @@ export function getArgs(): Arguments {
8184
}
8285
}
8386

84-
function getPassthroughArgs() {
85-
const passthroughPos = process.argv.indexOf("--");
86-
return passthroughPos === -1 ? [] : process.argv.slice(passthroughPos + 1);
87+
export function getPassthroughArgs<T extends ParseArgsConfig>(args: string[], { options = {} }: T) {
88+
const passthroughArgs: string[] = [];
89+
90+
for (let i = 0; i < args.length; i++) {
91+
if (args[i] === "--") {
92+
passthroughArgs.push(...args.slice(i + 1));
93+
return passthroughArgs;
94+
}
95+
96+
// look for `--arg(=value)`, `-arg(=value)`
97+
const [, name] = /^--?(\w[\w-]*)(=.+)?$/.exec(args[i]!) ?? [];
98+
if (name && !(name in options)) {
99+
passthroughArgs.push(args[i]!);
100+
101+
// Array args can have multiple values
102+
// ref https://github.com/yargs/yargs-parser/blob/main/README.md#greedy-arrays
103+
while (i < args.length - 1 && !args[i + 1]?.startsWith("-")) {
104+
passthroughArgs.push(args[++i]!);
105+
}
106+
}
107+
}
108+
109+
return passthroughArgs;
87110
}
88111

89112
function assertDirArg(path: string, argName?: string, make?: boolean) {

0 commit comments

Comments
 (0)