From 18819a2d6218f1fb5c6d38881129b3bdff5699b6 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 22 Oct 2026 16:47:08 +0100 Subject: [PATCH 1/3] fix(workers): use a consistent Worker identifier flag --- .changeset/consistent-worker-identifiers.md | 10 + packages/cli/generator/plugin/args.ts | 23 +- packages/cli/generator/plugin/emit/builder.ts | 4 +- packages/cli/generator/plugin/emit/handler.ts | 3 +- packages/cli/generator/plugin/emit/index.ts | 13 +- packages/cli/generator/plugin/emit/sdk.ts | 6 +- packages/cli/generator/plugin/files.ts | 35 +-- .../commands/workers-identifiers.test.ts | 251 ++++++++++++++++++ .../generator/plugin/arg-derivation.test.ts | 66 +++++ packages/cli/src/__tests__/help.test.ts | 11 +- .../commands/_generated/_meta/commands.json | 73 +++-- .../commands/_generated/_meta/schemas.json | 12 +- .../src/commands/_generated/workers/delete.ts | 22 +- .../_generated/workers/deployments/create.ts | 6 +- .../_generated/workers/deployments/delete.ts | 6 +- .../_generated/workers/deployments/get.ts | 6 +- .../_generated/workers/deployments/list.ts | 6 +- .../src/commands/_generated/workers/get.ts | 22 +- .../_generated/workers/secrets/bulk.ts | 12 +- .../_generated/workers/secrets/delete.ts | 6 +- .../_generated/workers/secrets/get.ts | 6 +- .../_generated/workers/secrets/list.ts | 6 +- .../_generated/workers/secrets/update.ts | 6 +- .../_generated/workers/versions/delete.ts | 13 +- .../_generated/workers/versions/get.ts | 13 +- .../_generated/workers/versions/list.ts | 13 +- .../_generated/workers/versions/profile.ts | 15 +- 27 files changed, 511 insertions(+), 154 deletions(-) create mode 100644 .changeset/consistent-worker-identifiers.md create mode 100644 packages/cli/src/__tests__/commands/workers-identifiers.test.ts diff --git a/.changeset/consistent-worker-identifiers.md b/.changeset/consistent-worker-identifiers.md new file mode 100644 index 0000000000..e2c512720c --- /dev/null +++ b/.changeset/consistent-worker-identifiers.md @@ -0,0 +1,10 @@ +--- +"cf": patch +--- + +Use `--worker` consistently across generated `cf workers` commands + +Accept `--worker` for Worker and version operations that previously required +`--worker-id` or a positional Worker identifier. Keep `--worker-id` and +`--script-name` as aliases, and retain positional input for `cf workers get` +and `cf workers delete`. diff --git a/packages/cli/generator/plugin/args.ts b/packages/cli/generator/plugin/args.ts index f9b9cd7aa8..b680c1d985 100644 --- a/packages/cli/generator/plugin/args.ts +++ b/packages/cli/generator/plugin/args.ts @@ -145,7 +145,7 @@ export function multipartFileFlagDescription(field: MultipartField): string { export const positionals = (d: Derived): Arg[] => d.args.filter((a) => a.positional); export const options = (d: Derived): Arg[] => - d.args.filter((a) => !a.positional); + d.args.filter((a) => !a.positional || (isPath(a) && a.isWorkerName)); export const bodyOptions = (d: Derived): Arg[] => d.args.filter((a) => isBody(a) && !a.positional); export const queryArgs = (d: Derived): Arg[] => @@ -220,8 +220,10 @@ export function isZonePathParam(name: string): boolean { return ZONE_ARG_NAMES.includes(flagName(name)); } +export const WORKER_ALIASES = ["script-name", "worker-id"]; + export function isWorkerName(name: string): boolean { - return WORKER_NAME_ARGS.includes(name); + return WORKER_NAME_ARGS.includes(name) || kebab(name) === "worker-id"; } const PAIR = "{account_or_zone}/{account_or_zone_id}"; @@ -264,7 +266,7 @@ export function accountOrZoneLocal( /** The argv key that holds the value of the `{wire}` placeholder. */ export function pathParamReadKey(args: readonly Arg[], wire: string): string { const arg = args.find( - (a) => a.origin.in === "path" && a.origin.name === wire && !a.isWorkerName + (a) => a.origin.in === "path" && a.origin.name === wire ); return kebab(arg ? arg.name : wire); } @@ -328,10 +330,16 @@ interface Classification { isWorkerName: boolean; } -function classify(name: string, workers: boolean): Classification { +function classify( + name: string, + workers: boolean, + pathParam = false +): Classification { return { isZone: ZONE_ARG_NAMES.includes(name), - isWorkerName: workers && isWorkerName(name), + isWorkerName: + workers && + (pathParam ? isWorkerName(name) : WORKER_NAME_ARGS.includes(name)), }; } @@ -729,16 +737,17 @@ function pathParams( continue; } const parameter = op.pathParams.find((a) => a.name === p); - const cls = classify(flagName(p), workers); + const cls = classify(flagName(p), workers, true); if (cls.isZone) { names.refuseOverride({ in: "path", name: p }, "--zone"); continue; } const defaultValue = o.nullish("default"); const subjectPositional = p === subject; + // Keep the legacy Worker-ID positional alongside the canonical --worker. // Defaults fill URL segments without consuming a positional slot. const positional = - !cls.isWorkerName && + (!cls.isWorkerName || kebab(p) === "worker-id") && defaultValue === undefined && truthy(o.nullish("positional") ?? subjectPositional); if (cls.isWorkerName) { diff --git a/packages/cli/generator/plugin/emit/builder.ts b/packages/cli/generator/plugin/emit/builder.ts index 82df371d1e..fd37c1168a 100644 --- a/packages/cli/generator/plugin/emit/builder.ts +++ b/packages/cli/generator/plugin/emit/builder.ts @@ -7,6 +7,7 @@ import { optionDefaults, options as optionArgs, positionals, + WORKER_ALIASES, } from "../args.js"; import { kebab, obj, stringify, type Value } from "../js.js"; import { type Ctx, escapeSingle } from "./index.js"; @@ -87,7 +88,8 @@ export function builderLines(ctx: Ctx): string[] { option(name, [ ["type", type], ["array", scalarArray ? true : undefined], - ["alias", arg.isWorkerName ? "script-name" : undefined], + ["alias", arg.isWorkerName ? WORKER_ALIASES : undefined], + ["group", arg.isWorkerName && arg.positional ? "Options:" : undefined], ["description", arg.description], ["choices", arg.choices], ["default", defaults.get(arg.name)], diff --git a/packages/cli/generator/plugin/emit/handler.ts b/packages/cli/generator/plugin/emit/handler.ts index c78e457be2..99cffbb92d 100644 --- a/packages/cli/generator/plugin/emit/handler.ts +++ b/packages/cli/generator/plugin/emit/handler.ts @@ -205,7 +205,8 @@ export function dryRun(ctx: Ctx): string[] { positional, firstPositionalIsZone: false, accountId: "${__cfDryRunAccountId ?? ''}", - scriptName: "${argv[\"worker\"] ?? ''}", + scriptName: + '${argv["worker"] == null ? \'\' : encodeURIComponent(String(argv["worker"]))}', zone: "${argv.zone ?? argv.zoneId ?? ''}", param, }); diff --git a/packages/cli/generator/plugin/emit/index.ts b/packages/cli/generator/plugin/emit/index.ts index 466c3b6190..6f04502a56 100644 --- a/packages/cli/generator/plugin/emit/index.ts +++ b/packages/cli/generator/plugin/emit/index.ts @@ -17,6 +17,7 @@ import { headerArgs, isBody, isPath, + isWorkerName, options, pathParamReadKey, positionals, @@ -176,10 +177,7 @@ export function substitutePath(path: string, ctx: PathTemplate): string { if (ACCOUNT_PATH_PARAMS.includes(name)) { return ctx.accountId; } - if ( - ctx.needsWorkerName && - (name === "script_name" || name === "scriptName") - ) { + if (ctx.needsWorkerName && isWorkerName(name)) { return ctx.scriptName; } if (ZONE_PATH_PARAMS.includes(name)) { @@ -253,7 +251,6 @@ export function context( root: string ): [Ctx, string] { const kind = outputKind(op); - const workers = resource === "workers"; const path = op.path; const combined = hasAccountOrZoneScope(path); const pathNeedsAccount = @@ -272,9 +269,7 @@ export function context( const positional = positionals(derived); const firstPositionalIsZone = positional[0]?.isZone === true; const needsZoneId = firstPositionalIsZone || pathNeedsZone || combined; - const pathNeedsWorker = - workers && - (path.includes("{script_name}") || path.includes("{scriptName}")); + const pathNeedsWorker = derived.args.some((a) => isPath(a) && a.isWorkerName); const firstPositionalIsWorkerName = positional[0]?.isWorkerName === true; const needsWorkerName = firstPositionalIsWorkerName || pathNeedsWorker; @@ -324,7 +319,7 @@ export function context( positional, firstPositionalIsZone, accountId: "${accountId}", - scriptName: "${scriptName}", + scriptName: "${encodeURIComponent(scriptName)}", zone: "${argv.zoneId}", param, }); diff --git a/packages/cli/generator/plugin/emit/sdk.ts b/packages/cli/generator/plugin/emit/sdk.ts index 8b64982aba..13a608fdf3 100644 --- a/packages/cli/generator/plugin/emit/sdk.ts +++ b/packages/cli/generator/plugin/emit/sdk.ts @@ -12,6 +12,7 @@ import { ACCOUNT_PATH_PARAMS, accountOrZoneLocal, isBody, + isWorkerName, pathParamReadKey, queryArgs, ZONE_PATH_PARAMS, @@ -43,10 +44,7 @@ function pathValue(ctx: Ctx, name: string): string { if (ZONE_PATH_PARAMS.includes(name)) { return ctx.firstPositionalIsZone ? "zone_id" : "zoneId"; } - if ( - ctx.needsWorkerName && - (name === "script_name" || name === "scriptName") - ) { + if (ctx.needsWorkerName && isWorkerName(name)) { return "scriptName"; } return argvKey(pathParamReadKey(ctx.derived.args, name)); diff --git a/packages/cli/generator/plugin/files.ts b/packages/cli/generator/plugin/files.ts index 14c6fa42d5..0c6ae953c9 100644 --- a/packages/cli/generator/plugin/files.ts +++ b/packages/cli/generator/plugin/files.ts @@ -10,13 +10,13 @@ import { derive, downgradeOptionalParents, isBody, - isWorkerName, isZonePathParam, multipartFileFlagDescription, optionDefaults, options as optionArgs, positionals, scalar, + WORKER_ALIASES, } from "./args.js"; import { requiresConfirmation } from "./confirmation.js"; import { @@ -251,32 +251,6 @@ class Walk { const positional = positionals(derived); const options = optionArgs(derived); const defaults = optionDefaults(derived, op); - if (resource === "workers") { - for (const p of op.pathParams) { - if (!isWorkerName(p.name.replaceAll("_", "-"))) { - continue; - } - if (options.some((a) => a.name === "worker")) { - continue; - } - options.push({ - name: "worker", - description: p.description ?? `The ${p.name.replaceAll("_", " ")}`, - type: "string", - choices: undefined, - default: undefined, - required: true, - positional: false, - origin: { in: "path", name: p.name }, - conflicts: undefined, - implies: undefined, - secret: false, - fromFile: undefined, - isZone: false, - isWorkerName: true, - }); - } - } const fullPath = [resource]; if (group !== undefined) { fullPath.push(...group.split("/")); @@ -286,7 +260,7 @@ class Walk { const positionalUsage = positional .map((a) => { const name = a.type === "array" ? `${a.name}...` : a.name; - return a.required ? `<${name}>` : `[${name}]`; + return a.required && !a.isWorkerName ? `<${name}>` : `[${name}]`; }) .join(" "); const suffix = options.length === 0 ? "" : " [options]"; @@ -299,7 +273,7 @@ class Walk { m["name"] = a.name; m["position"] = i; m["type"] = scalar(a.type); - m["required"] = a.required; + m["required"] = a.required && !a.isWorkerName; m["description"] = a.description; if (a.choices !== undefined && a.choices.length > 0) { m["enum"] = a.choices; @@ -312,6 +286,9 @@ class Walk { m["type"] = scalar(a.type); m["required"] = a.required; m["description"] = a.description; + if (a.isWorkerName) { + m["alias"] = WORKER_ALIASES; + } const dflt = defaults.get(a.name); if (dflt !== undefined) { m["default"] = dflt; diff --git a/packages/cli/src/__tests__/commands/workers-identifiers.test.ts b/packages/cli/src/__tests__/commands/workers-identifiers.test.ts new file mode 100644 index 0000000000..0f7d810c9b --- /dev/null +++ b/packages/cli/src/__tests__/commands/workers-identifiers.test.ts @@ -0,0 +1,251 @@ +import { readFileSync } from "node:fs"; +import { runInTempDir } from "@cloudflare/workers-utils/test-helpers"; +import { http, HttpResponse } from "msw/http"; +import { + afterEach, + beforeEach, + describe, + expect, + it, + vi, +} from "vite-plus/test"; +import { server, setupMsw, TEST_BASE_URL } from "../helpers/msw.js"; +import { runCf } from "../helpers/run-cf.js"; +import type { CommandsMetadata } from "../../lib/command-meta.js"; + +describe("cf workers identifiers", () => { + runInTempDir(); + setupMsw(); + + const ENV = { + CLOUDFLARE_API_TOKEN: "test-token", + CLOUDFLARE_API_BASE_URL: TEST_BASE_URL, + CLOUDFLARE_ACCOUNT_ID: "test-account", + }; + const ACCOUNT = `${TEST_BASE_URL}/accounts/test-account`; + const flags = ["--worker", "--worker-id", "--script-name"]; + const commands = [ + { args: ["get"], path: "/workers/workers/my-worker" }, + { args: ["versions", "list"], path: "/workers/workers/my-worker/versions" }, + { + args: ["versions", "get", "latest"], + path: "/workers/workers/my-worker/versions/latest", + }, + { + args: ["deployments", "list"], + path: "/workers/scripts/my-worker/deployments", + }, + { args: ["secrets", "list"], path: "/workers/scripts/my-worker/secrets" }, + ]; + let logSpy: ReturnType; + + beforeEach(() => { + logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + vi.spyOn(process.stdout, "write").mockImplementation(() => true); + vi.spyOn(process.stderr, "write").mockImplementation(() => true); + }); + + afterEach(() => vi.restoreAllMocks()); + + it.each(["get", "delete"])( + "%s help lists --worker as an option", + async (name) => { + await runCf(["workers", name, "--help"], ENV); + expect( + logSpy.mock.calls.map((call: unknown[]) => String(call[0])).join("\n") + ).toContain("--worker"); + } + ); + + for (const { args, path } of commands) { + it.each(flags)(`${args.join(" ")} accepts %s`, async (flag) => { + const request = vi.fn(() => + HttpResponse.json({ success: true, result: { id: "response-id" } }) + ); + server.use(http.get(`${ACCOUNT}${path}`, request)); + const result = await runCf(["workers", ...args, flag, "my-worker"], ENV); + expect(result.exitCode).toBe(0); + expect(request).toHaveBeenCalledOnce(); + }); + + it(`${args.join(" ")} still requires a Worker`, async () => { + await expect(runCf(["workers", ...args], ENV)).rejects.toThrow( + "--worker " + ); + }); + + it.each(flags)(`${args.join(" ")} previews %s`, async (flag) => { + await runCf(["workers", ...args, flag, "my/worker", "--dry-run"], ENV); + const output = JSON.parse(String(logSpy.mock.calls[0]?.[0])); + expect(output).toMatchObject({ + url: `https://api.cloudflare.com/client/v4/accounts/test-account${path.replace("my-worker", "my%2Fworker")}`, + pathParams: { worker: "my/worker" }, + }); + }); + } + + it.each(["get", "delete"])( + "%s retains positional Worker input", + async (name) => { + const request = vi.fn(() => + HttpResponse.json({ success: true, result: { id: "my-worker" } }) + ); + const route = `${ACCOUNT}/workers/workers/my-worker`; + server.use((name === "delete" ? http.delete : http.get)(route, request)); + await runCf( + [ + "workers", + name, + "my-worker", + ...(name === "delete" ? ["--force"] : []), + ], + ENV + ); + expect(request).toHaveBeenCalledOnce(); + } + ); + + it.each(flags)("delete accepts %s", async (flag) => { + const request = vi.fn(() => + HttpResponse.json({ success: true, result: null }) + ); + server.use(http.delete(`${ACCOUNT}/workers/workers/my-worker`, request)); + await runCf(["workers", "delete", flag, "my-worker", "--force"], ENV); + expect(request).toHaveBeenCalledOnce(); + }); + + it("profile encodes --worker in the raw response request", async () => { + const request = vi.fn(() => new HttpResponse("profile-data")); + server.use( + http.post( + `${ACCOUNT}/workers/workers/my%2Fworker/versions/latest/profile`, + request + ) + ); + await runCf( + [ + "workers", + "versions", + "profile", + "latest", + "--worker", + "my/worker", + "--duration-ms", + "10", + ], + ENV + ); + expect(request).toHaveBeenCalledOnce(); + }); + + it.each(flags)( + "versions delete sends %s with the version positional", + async (flag) => { + const request = vi.fn(() => + HttpResponse.json({ success: true, result: null }) + ); + server.use( + http.delete( + `${ACCOUNT}/workers/workers/my-worker/versions/latest`, + request + ) + ); + await runCf( + [ + "workers", + "versions", + "delete", + "latest", + flag, + "my-worker", + "--force", + ], + ENV + ); + expect(request).toHaveBeenCalledOnce(); + } + ); + + it("uses --worker throughout the secret, version, and deployment sequence", async () => { + const secret = vi.fn(() => + HttpResponse.json({ success: true, result: {} }) + ); + const versions = vi.fn(() => + HttpResponse.json({ success: true, result: [] }) + ); + const deployment = vi.fn(() => + HttpResponse.json({ success: true, result: {} }) + ); + server.use( + http.put(`${ACCOUNT}/workers/scripts/my-worker/secrets`, secret), + http.get(`${ACCOUNT}/workers/workers/my-worker/versions`, versions), + http.post(`${ACCOUNT}/workers/scripts/my-worker/deployments`, deployment) + ); + await runCf( + [ + "workers", + "secrets", + "update", + "API_KEY", + "--worker", + "my-worker", + "--text", + "value", + "--type", + "secret_text", + ], + ENV + ); + await runCf(["workers", "versions", "list", "--worker", "my-worker"], ENV); + await runCf( + [ + "workers", + "deployments", + "create", + "--worker", + "my-worker", + "--versions", + '[{"version_id":"version-1","percentage":100}]', + "--strategy", + "percentage", + ], + ENV + ); + expect(secret).toHaveBeenCalledOnce(); + expect(versions).toHaveBeenCalledOnce(); + expect(deployment).toHaveBeenCalledOnce(); + }); + + it("advertises the canonical flag and aliases in generated metadata", () => { + const metadata = JSON.parse( + readFileSync( + new URL( + "../../commands/_generated/_meta/commands.json", + import.meta.url + ), + "utf8" + ) + ) as CommandsMetadata; + for (const { args } of commands) { + const command = metadata.commands.find( + (entry) => + entry.command === + `cf workers ${args.filter((arg) => arg !== "latest").join(" ")}` + ); + expect(command?.options).toContainEqual( + expect.objectContaining({ + name: "worker", + required: true, + alias: ["script-name", "worker-id"], + }) + ); + expect( + command?.options.some((option) => option.name === "worker-id") + ).toBe(false); + } + const get = metadata.commands.find( + (entry) => entry.command === "cf workers get" + ); + expect(get?.arguments).toMatchObject([{ name: "worker", required: false }]); + }); +}); diff --git a/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts b/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts index 41eea88d9a..0ea152c9cc 100644 --- a/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts +++ b/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts @@ -3,6 +3,7 @@ import { accountOrZoneLocal, type Derived, derive, + options, } from "../../../../generator/plugin/args.js"; import { bodyParam, @@ -163,6 +164,54 @@ describe("deriveArgsFromOp path params", () => { ["consumer_id", "consumer"], ]; + it.each(["worker_id", "workerId", "script_name", "scriptName"])( + "normalizes the Workers path parameter %s without changing its wire name", + (name) => { + const d = derived( + method(undefined, "list"), + "workers", + pathOperation(`/accounts/{account_id}/workers/{${name}}/versions`, [ + [name, undefined], + ]) + ); + expect(d.args).toMatchObject([ + { + name: "worker", + isWorkerName: true, + positional: false, + origin: { in: "path", name }, + }, + ]); + } + ); + + it("keeps the legacy Worker positional available as a flag", () => { + const d = derived( + method(undefined, "get"), + "workers", + pathOperation("/accounts/{account_id}/workers/workers/{worker_id}", [ + ["worker_id", undefined], + ]) + ); + expect(d.args).toMatchObject([ + { name: "worker", isWorkerName: true, positional: true }, + ]); + expect(options(d)).toEqual(d.args); + }); + + it("leaves Worker identifiers outside the Workers root unchanged", () => { + const d = derived( + method(undefined, "get"), + "example", + pathOperation("/accounts/{account_id}/example/{worker_id}", [ + ["worker_id", undefined], + ]) + ); + expect(d.args).toMatchObject([ + { name: "worker-id", isWorkerName: false, positional: true }, + ]); + }); + it("keeps a defaulted path parameter optional beside a body positional", () => { const op = pathOperation( "/accounts/{account_id}/namespaces/{namespace}/things", @@ -352,6 +401,23 @@ describe("deriveArgsFromOp path params", () => { }); describe("deriveArgsFromOp body flags", () => { + it("does not treat Worker-ID body fields as the Worker path selector", () => { + const d = derived( + method(undefined, "create"), + "workers", + operation("post", "/accounts/{account_id}/workers", { + bodyParams: [ + bodyParam("worker_id", "string", ["worker_id"], { required: true }), + ], + hasRequestBody: true, + requestContentTypes: ["application/json"], + }) + ); + expect(d.args).toMatchObject([ + { name: "worker-id", required: true, isWorkerName: false }, + ]); + }); + it.each(["temporaryAccount", "eventCode"])( "rejects the camelCase body field %s, which resolves to a global", (name) => { diff --git a/packages/cli/src/__tests__/help.test.ts b/packages/cli/src/__tests__/help.test.ts index d32a056b25..bb5f135c22 100644 --- a/packages/cli/src/__tests__/help.test.ts +++ b/packages/cli/src/__tests__/help.test.ts @@ -44,15 +44,8 @@ describe("help formatting", () => { process.stdout.columns = 0; const help = await buildCli(["workers", "--help"]).cli.getHelp(); - const triggersLine = help - .split("\n") - .find((line) => line.includes("Manage triggers")); - - expect(triggersLine).toContain("cf workers triggers"); - expect(triggersLine).not.toContain("etc.)"); - expect( - help.split("\n").some((line) => line.trim().endsWith("triggers etc.)")) - ).toBe(true); + process.stdout.columns = 80; + expect(help).toBe(await buildCli(["workers", "--help"]).cli.getHelp()); }); it("sorts root commands alphabetically", async () => { diff --git a/packages/cli/src/commands/_generated/_meta/commands.json b/packages/cli/src/commands/_generated/_meta/commands.json index d0e354b3c0..c58893d884 100644 --- a/packages/cli/src/commands/_generated/_meta/commands.json +++ b/packages/cli/src/commands/_generated/_meta/commands.json @@ -135773,17 +135773,24 @@ "fullPath": ["workers", "delete"], "description": "Delete a Worker and all its associated resources (versions, deployments, etc.).", "summary": "Delete Worker", - "usage": "cf workers delete [options]", + "usage": "cf workers delete [worker] [options]", "arguments": [ { - "name": "worker-id", + "name": "worker", "position": 0, "type": "string", - "required": true, + "required": false, "description": "Identifier for the Worker, which can be ID or name." } ], "options": [ + { + "name": "worker", + "type": "string", + "required": true, + "description": "Identifier for the Worker, which can be ID or name.", + "alias": ["script-name", "worker-id"] + }, { "name": "delete-with-references", "type": "boolean", @@ -135826,7 +135833,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "bypass-deployment-checks", @@ -135902,7 +135910,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "dry-run", @@ -135948,7 +135957,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "dry-run", @@ -135978,7 +135988,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "since", @@ -136025,17 +136036,24 @@ "fullPath": ["workers", "get"], "description": "Get details about a specific Worker.", "summary": "Get Worker", - "usage": "cf workers get ", + "usage": "cf workers get [worker] [options]", "arguments": [ { - "name": "worker-id", + "name": "worker", "position": 0, "type": "string", - "required": true, + "required": false, "description": "Identifier for the Worker, which can be ID or name." } ], "options": [ + { + "name": "worker", + "type": "string", + "required": true, + "description": "Identifier for the Worker, which can be ID or name.", + "alias": ["script-name", "worker-id"] + }, { "name": "dry-run", "type": "boolean", @@ -136169,7 +136187,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "secrets", @@ -136231,7 +136250,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "url-encoded", @@ -136283,7 +136303,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "url-encoded", @@ -136319,7 +136340,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "dry-run", @@ -136357,7 +136379,8 @@ "name": "worker", "type": "string", "required": true, - "description": "Name of the script." + "description": "Name of the script.", + "alias": ["script-name", "worker-id"] }, { "name": "text", @@ -136553,10 +136576,11 @@ ], "options": [ { - "name": "worker-id", + "name": "worker", "type": "string", "required": true, - "description": "Identifier for the Worker, which can be ID or name." + "description": "Identifier for the Worker, which can be ID or name.", + "alias": ["script-name", "worker-id"] }, { "name": "dry-run", @@ -136599,10 +136623,11 @@ ], "options": [ { - "name": "worker-id", + "name": "worker", "type": "string", "required": true, - "description": "Identifier for the Worker, which can be ID or name." + "description": "Identifier for the Worker, which can be ID or name.", + "alias": ["script-name", "worker-id"] }, { "name": "include", @@ -136636,10 +136661,11 @@ "arguments": [], "options": [ { - "name": "worker-id", + "name": "worker", "type": "string", "required": true, - "description": "Identifier for the Worker, which can be ID or name." + "description": "Identifier for the Worker, which can be ID or name.", + "alias": ["script-name", "worker-id"] }, { "name": "page", @@ -136686,10 +136712,11 @@ ], "options": [ { - "name": "worker-id", + "name": "worker", "type": "string", "required": true, - "description": "Identifies the Worker by ID or name." + "description": "Identifies the Worker by ID or name.", + "alias": ["script-name", "worker-id"] }, { "name": "actor-id", diff --git a/packages/cli/src/commands/_generated/_meta/schemas.json b/packages/cli/src/commands/_generated/_meta/schemas.json index dea83731d1..6a445db4f7 100644 --- a/packages/cli/src/commands/_generated/_meta/schemas.json +++ b/packages/cli/src/commands/_generated/_meta/schemas.json @@ -99212,7 +99212,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "positional": true, "type": "string", "required": true @@ -99396,7 +99396,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "positional": true, "type": "string", "required": true @@ -99699,7 +99699,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "type": "string", "required": true }, @@ -99727,7 +99727,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "type": "string", "required": true }, @@ -99762,7 +99762,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "type": "string", "required": true } @@ -99796,7 +99796,7 @@ }, { "name": "worker_id", - "flag": "worker-id", + "flag": "worker", "type": "string", "required": true }, diff --git a/packages/cli/src/commands/_generated/workers/delete.ts b/packages/cli/src/commands/_generated/workers/delete.ts index e4572129f3..72b8fe7351 100644 --- a/packages/cli/src/commands/_generated/workers/delete.ts +++ b/packages/cli/src/commands/_generated/workers/delete.ts @@ -9,6 +9,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { formatDryRun } from "#lib/dry-run.js"; @@ -21,12 +22,17 @@ import { runWithTelemetry } from "#lib/telemetry/index.js"; function builder(yargs: Argv) { return yargs .usage( - "$0 workers delete \n\nDelete a Worker and all its associated resources (versions, deployments, etc.)." + "$0 workers delete [worker]\n\nDelete a Worker and all its associated resources (versions, deployments, etc.)." ) - .positional("worker-id", { + .positional("worker", { type: "string", description: "Identifier for the Worker, which can be ID or name.", - demandOption: true, + }) + .option("worker", { + type: "string", + alias: ["script-name", "worker-id"], + group: "Options:", + description: "Identifier for the Worker, which can be ID or name.", }) .option("delete-with-references", { type: "boolean", @@ -49,7 +55,7 @@ function builder(yargs: Argv) { type Args = InferArgs; const command: CommandModule = { - command: "delete ", + command: "delete [worker]", describe: "Delete Worker", builder, handler: async (argv): Promise => @@ -71,8 +77,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}`, - pathParams: { "worker-id": String(argv["worker-id"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}`, + pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", }); @@ -81,6 +87,8 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if ( !(await confirmDelete({ @@ -94,7 +102,7 @@ const command: CommandModule = { const result = await withProgress(`Deleting`, async () => client.send(operation, { account_id: accountId, - worker_id: argv["worker-id"], + worker_id: scriptName, ...queryParams, }) ); diff --git a/packages/cli/src/commands/_generated/workers/deployments/create.ts b/packages/cli/src/commands/_generated/workers/deployments/create.ts index bb600bb083..0ea2e92b98 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/create.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/create.ts @@ -29,7 +29,7 @@ function builder(yargs: Argv) { ) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("bypass-deployment-checks", { @@ -147,8 +147,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments create", method: "POST", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/deployments`, - pathParams: { "script-name": String(argv["script-name"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments`, + pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "json", body: diff --git a/packages/cli/src/commands/_generated/workers/deployments/delete.ts b/packages/cli/src/commands/_generated/workers/deployments/delete.ts index 9e959b03b9..f88e3a9ce7 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/delete.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/delete.ts @@ -31,7 +31,7 @@ function builder(yargs: Argv) { }) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("dry-run", { @@ -69,9 +69,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, pathParams: { - "script-name": String(argv["script-name"] ?? ""), + worker: String(argv["worker"] ?? ""), "deployment-id": String(argv["deployment-id"] ?? ""), }, bodyKind: "none", diff --git a/packages/cli/src/commands/_generated/workers/deployments/get.ts b/packages/cli/src/commands/_generated/workers/deployments/get.ts index 5b32c6afc1..b025f8a892 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/get.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/get.ts @@ -30,7 +30,7 @@ function builder(yargs: Argv) { }) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("dry-run", { @@ -61,9 +61,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, pathParams: { - "script-name": String(argv["script-name"] ?? ""), + worker: String(argv["worker"] ?? ""), "deployment-id": String(argv["deployment-id"] ?? ""), }, bodyKind: "none", diff --git a/packages/cli/src/commands/_generated/workers/deployments/list.ts b/packages/cli/src/commands/_generated/workers/deployments/list.ts index 4f8cf1a77a..eb8e3cc37f 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/list.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/list.ts @@ -25,7 +25,7 @@ function builder(yargs: Argv) { ) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("since", { @@ -72,8 +72,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/deployments`, - pathParams: { "script-name": String(argv["script-name"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments`, + pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", }); diff --git a/packages/cli/src/commands/_generated/workers/get.ts b/packages/cli/src/commands/_generated/workers/get.ts index 8c433db42a..7356e2759b 100644 --- a/packages/cli/src/commands/_generated/workers/get.ts +++ b/packages/cli/src/commands/_generated/workers/get.ts @@ -9,6 +9,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { formatDryRun } from "#lib/dry-run.js"; @@ -19,11 +20,16 @@ import { runWithTelemetry } from "#lib/telemetry/index.js"; function builder(yargs: Argv) { return yargs - .usage("$0 workers get \n\nGet details about a specific Worker.") - .positional("worker-id", { + .usage("$0 workers get [worker]\n\nGet details about a specific Worker.") + .positional("worker", { type: "string", description: "Identifier for the Worker, which can be ID or name.", - demandOption: true, + }) + .option("worker", { + type: "string", + alias: ["script-name", "worker-id"], + group: "Options:", + description: "Identifier for the Worker, which can be ID or name.", }) .option("dry-run", { type: "boolean", @@ -35,7 +41,7 @@ function builder(yargs: Argv) { type Args = InferArgs; const command: CommandModule = { - command: "get ", + command: "get [worker]", describe: "Get Worker", builder, handler: async (argv): Promise => @@ -53,8 +59,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}`, - pathParams: { "worker-id": String(argv["worker-id"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}`, + pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "none", }); return; @@ -62,11 +68,13 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { account_id: accountId, - worker_id: argv["worker-id"], + worker_id: scriptName, }) ); formatOutput(result, { successLabel: `Loaded` }); diff --git a/packages/cli/src/commands/_generated/workers/secrets/bulk.ts b/packages/cli/src/commands/_generated/workers/secrets/bulk.ts index da08aeb5a7..31221cbce5 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/bulk.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/bulk.ts @@ -32,7 +32,7 @@ function builder(yargs: Argv) { ) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("secrets", { @@ -92,8 +92,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets bulk", method: "PATCH", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/secrets-bulk`, - pathParams: { "script-name": String(argv["script-name"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets-bulk`, + pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: argv.file !== undefined ? "octet-stream" : "json", body: argv.file !== undefined @@ -131,7 +131,7 @@ const command: CommandModule = { requestApi( client, "PATCH", - `/accounts/${accountId}/workers/scripts/${scriptName}/secrets-bulk`, + `/accounts/${accountId}/workers/scripts/${encodeURIComponent(scriptName)}/secrets-bulk`, { body: fileContent, headers: { "Content-Type": "application/merge-patch+json" }, @@ -148,7 +148,7 @@ const command: CommandModule = { requestApi( client, "PATCH", - `/accounts/${accountId}/workers/scripts/${scriptName}/secrets-bulk`, + `/accounts/${accountId}/workers/scripts/${encodeURIComponent(scriptName)}/secrets-bulk`, { body: bodyData } ) ); @@ -174,7 +174,7 @@ const command: CommandModule = { requestApi( client, "PATCH", - `/accounts/${accountId}/workers/scripts/${scriptName}/secrets-bulk`, + `/accounts/${accountId}/workers/scripts/${encodeURIComponent(scriptName)}/secrets-bulk`, { body: bodyData } ) ); diff --git a/packages/cli/src/commands/_generated/workers/secrets/delete.ts b/packages/cli/src/commands/_generated/workers/secrets/delete.ts index 04923274f7..be1de82255 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/delete.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/delete.ts @@ -31,7 +31,7 @@ function builder(yargs: Argv) { }) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("url-encoded", { @@ -77,9 +77,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, pathParams: { - "script-name": String(argv["script-name"] ?? ""), + worker: String(argv["worker"] ?? ""), "secret-name": String(argv["secret-name"] ?? ""), }, query: queryParams, diff --git a/packages/cli/src/commands/_generated/workers/secrets/get.ts b/packages/cli/src/commands/_generated/workers/secrets/get.ts index 593269b53c..a3f36dba40 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/get.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/get.ts @@ -30,7 +30,7 @@ function builder(yargs: Argv) { }) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("url-encoded", { @@ -69,9 +69,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, pathParams: { - "script-name": String(argv["script-name"] ?? ""), + worker: String(argv["worker"] ?? ""), "secret-name": String(argv["secret-name"] ?? ""), }, query: queryParams, diff --git a/packages/cli/src/commands/_generated/workers/secrets/list.ts b/packages/cli/src/commands/_generated/workers/secrets/list.ts index 43ca50a7a4..64878f0b72 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/list.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/list.ts @@ -25,7 +25,7 @@ function builder(yargs: Argv) { ) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("dry-run", { @@ -56,8 +56,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/secrets`, - pathParams: { "script-name": String(argv["script-name"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets`, + pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "none", }); return; diff --git a/packages/cli/src/commands/_generated/workers/secrets/update.ts b/packages/cli/src/commands/_generated/workers/secrets/update.ts index f9ccecc278..9bcecef747 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/update.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/update.ts @@ -36,7 +36,7 @@ function builder(yargs: Argv) { }) .option("worker", { type: "string", - alias: "script-name", + alias: ["script-name", "worker-id"], description: "Name of the script.", }) .option("text", { type: "string", description: "The secret value to use." }) @@ -123,8 +123,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets update", method: "PUT", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] ?? ""}/secrets`, - pathParams: { "script-name": String(argv["script-name"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets`, + pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "json", body: argv.body !== undefined diff --git a/packages/cli/src/commands/_generated/workers/versions/delete.ts b/packages/cli/src/commands/_generated/workers/versions/delete.ts index 36ec52d2ea..05824275f9 100644 --- a/packages/cli/src/commands/_generated/workers/versions/delete.ts +++ b/packages/cli/src/commands/_generated/workers/versions/delete.ts @@ -9,6 +9,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { formatDryRun } from "#lib/dry-run.js"; @@ -29,10 +30,10 @@ function builder(yargs: Argv) { 'Identifier for the version, which can be a UUID, a UUID prefix (minimum length 8), or the literal "latest" to operate on the most recently created version.', demandOption: true, }) - .option("worker-id", { + .option("worker", { type: "string", + alias: ["script-name", "worker-id"], description: "Identifier for the Worker, which can be ID or name.", - demandOption: true, }) .option("dry-run", { type: "boolean", @@ -69,9 +70,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, pathParams: { - "worker-id": String(argv["worker-id"] ?? ""), + worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), }, bodyKind: "none", @@ -81,6 +82,8 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if ( !(await confirmDelete({ @@ -94,7 +97,7 @@ const command: CommandModule = { const result = await withProgress(`Deleting`, async () => client.send(operation, { account_id: accountId, - worker_id: argv["worker-id"], + worker_id: scriptName, version_id: argv["version-id"], }) ); diff --git a/packages/cli/src/commands/_generated/workers/versions/get.ts b/packages/cli/src/commands/_generated/workers/versions/get.ts index ceab561532..ecee57a28f 100644 --- a/packages/cli/src/commands/_generated/workers/versions/get.ts +++ b/packages/cli/src/commands/_generated/workers/versions/get.ts @@ -9,6 +9,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { formatDryRun } from "#lib/dry-run.js"; @@ -28,10 +29,10 @@ function builder(yargs: Argv) { 'Identifier for the version, which can be a UUID, a UUID prefix (minimum length 8), or the literal "latest" to operate on the most recently created version.', demandOption: true, }) - .option("worker-id", { + .option("worker", { type: "string", + alias: ["script-name", "worker-id"], description: "Identifier for the Worker, which can be ID or name.", - demandOption: true, }) .option("include", { type: "string", @@ -70,9 +71,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, pathParams: { - "worker-id": String(argv["worker-id"] ?? ""), + worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), }, query: queryParams, @@ -83,11 +84,13 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { account_id: accountId, - worker_id: argv["worker-id"], + worker_id: scriptName, version_id: argv["version-id"], ...queryParams, }) diff --git a/packages/cli/src/commands/_generated/workers/versions/list.ts b/packages/cli/src/commands/_generated/workers/versions/list.ts index b531b736ea..ba062fb2d7 100644 --- a/packages/cli/src/commands/_generated/workers/versions/list.ts +++ b/packages/cli/src/commands/_generated/workers/versions/list.ts @@ -9,6 +9,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { formatDryRun } from "#lib/dry-run.js"; @@ -20,10 +21,10 @@ import { runWithTelemetry } from "#lib/telemetry/index.js"; function builder(yargs: Argv) { return yargs .usage("$0 workers versions list\n\nList all versions for a Worker.") - .option("worker-id", { + .option("worker", { type: "string", + alias: ["script-name", "worker-id"], description: "Identifier for the Worker, which can be ID or name.", - demandOption: true, }) .option("page", { type: "number", description: "Current page." }) .option("per-page", { type: "number", description: "Items per-page." }) @@ -59,8 +60,8 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}/versions`, - pathParams: { "worker-id": String(argv["worker-id"] ?? "") }, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions`, + pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", }); @@ -69,11 +70,13 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { account_id: accountId, - worker_id: argv["worker-id"], + worker_id: scriptName, ...queryParams, }) ); diff --git a/packages/cli/src/commands/_generated/workers/versions/profile.ts b/packages/cli/src/commands/_generated/workers/versions/profile.ts index 19719db2f6..9aa46e3414 100644 --- a/packages/cli/src/commands/_generated/workers/versions/profile.ts +++ b/packages/cli/src/commands/_generated/workers/versions/profile.ts @@ -8,6 +8,7 @@ import type { Argv, CommandModule } from "yargs"; import { createCommandClient, getAccountId, + getWorkerName, resolveAccountIdSilent, } from "#lib/auth.js"; import { compactBody, parseBody, setNestedValue } from "#lib/body-parser.js"; @@ -30,10 +31,10 @@ function builder(yargs: Argv) { 'Identifies the version by UUID or UUID prefix with a minimum length of eight characters. Use "latest" to select the most recently created version, which may not be deployed. Use "latest-deployed" to profile a version in the active deployment. Versions are tried in order of traffic share until one has a loaded isolate.', demandOption: true, }) - .option("worker-id", { + .option("worker", { type: "string", + alias: ["script-name", "worker-id"], description: "Identifies the Worker by ID or name.", - demandOption: true, }) .option("actor-id", { type: "string", @@ -96,9 +97,9 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions profile", method: "POST", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker-id"] == null ? "" : encodeURIComponent(String(argv["worker-id"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}/profile`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}/profile`, pathParams: { - "worker-id": String(argv["worker-id"] ?? ""), + worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), }, bodyKind: "json", @@ -127,12 +128,14 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.body !== undefined) { const bodyData = parsedBody; const __cfRawBytes = await withProgress(`Creating`, async () => fetchRawBytes( - `/accounts/${accountId}/workers/workers/${encodeURIComponent(String(argv["worker-id"]))}/versions/${encodeURIComponent(String(argv["version-id"]))}/profile`, + `/accounts/${accountId}/workers/workers/${encodeURIComponent(scriptName)}/versions/${encodeURIComponent(String(argv["version-id"]))}/profile`, { method: "POST", local: argv.local === true, @@ -181,7 +184,7 @@ const command: CommandModule = { setNestedValue(bodyData, ["profile_type"], argv["profile-type"]); const __cfRawBytes = await withProgress(`Creating`, async () => fetchRawBytes( - `/accounts/${accountId}/workers/workers/${encodeURIComponent(String(argv["worker-id"]))}/versions/${encodeURIComponent(String(argv["version-id"]))}/profile`, + `/accounts/${accountId}/workers/workers/${encodeURIComponent(scriptName)}/versions/${encodeURIComponent(String(argv["version-id"]))}/profile`, { method: "POST", local: argv.local === true, From 27717e10404da96cc3258a18051b76ec81dec6e3 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 4 Nov 2026 21:23:21 +0000 Subject: [PATCH 2/3] fix(workers): validate identifiers before dry runs --- .changeset/consistent-worker-identifiers.md | 2 +- docs/architecture.md | 5 ++-- packages/cli/generator/plugin/args.ts | 2 +- packages/cli/generator/plugin/emit/handler.ts | 21 ++++++++-------- .../commands/workers-identifiers.test.ts | 24 +++++++++++++++---- .../generator/plugin/arg-derivation.test.ts | 16 +++++++++++++ .../src/commands/_generated/workers/delete.ts | 7 +++--- .../_generated/workers/deployments/create.ts | 7 +++--- .../_generated/workers/deployments/delete.ts | 6 ++--- .../_generated/workers/deployments/get.ts | 6 ++--- .../_generated/workers/deployments/list.ts | 7 +++--- .../src/commands/_generated/workers/get.ts | 6 ++--- .../_generated/workers/secrets/bulk.ts | 6 ++--- .../_generated/workers/secrets/delete.ts | 7 +++--- .../_generated/workers/secrets/get.ts | 7 +++--- .../_generated/workers/secrets/list.ts | 6 ++--- .../_generated/workers/secrets/update.ts | 6 ++--- .../_generated/workers/versions/delete.ts | 6 ++--- .../_generated/workers/versions/get.ts | 7 +++--- .../_generated/workers/versions/list.ts | 7 +++--- .../_generated/workers/versions/profile.ts | 6 ++--- packages/cli/src/lib/context.ts | 4 ++-- .../src/__tests__/delete.test.ts | 2 +- .../__tests__/versions/versions.list.test.ts | 2 +- .../__tests__/versions/versions.view.test.ts | 2 +- 25 files changed, 107 insertions(+), 70 deletions(-) diff --git a/.changeset/consistent-worker-identifiers.md b/.changeset/consistent-worker-identifiers.md index e2c512720c..b06fda83ab 100644 --- a/.changeset/consistent-worker-identifiers.md +++ b/.changeset/consistent-worker-identifiers.md @@ -1,5 +1,5 @@ --- -"cf": patch +"cf": minor --- Use `--worker` consistently across generated `cf workers` commands diff --git a/docs/architecture.md b/docs/architecture.md index 1f007e4849..75b7cde117 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -297,9 +297,10 @@ Practical extensions of this rule: `resolve.ts`, which validates the domain and calls `client.zones.list()` for the selected account. Keep this exception contained in those global context/resolution helpers. -- **Worker-name flag** (`--worker`, with `--script-name` as an alias) is a +- **Worker-name flag** (`--worker`, with `--script-name` and `--worker-id` as aliases) is a generator-side product-scoped affordance, selected by - `resourceName === "workers"` in `isWorkerNameArg`. Add similar scoped checks + `resource === "workers"` in argument derivation. Generated `workers get` and + `workers delete` also accept the Worker as a positional argument. Add similar scoped checks rather than spreading product names. - **Product-specific hand-written commands are documented exceptions.** Three shadow generated leaves. Two exist because the request body's real schema sits behind a sibling diff --git a/packages/cli/generator/plugin/args.ts b/packages/cli/generator/plugin/args.ts index b680c1d985..5a232f1e54 100644 --- a/packages/cli/generator/plugin/args.ts +++ b/packages/cli/generator/plugin/args.ts @@ -412,7 +412,7 @@ function cfOwnedFlags(facts: { "f", ...(facts.hasFileUpload ? ["file"] : []), ...(facts.binaryOutput ? ["text"] : []), - ...(facts.workerArg ? ["script-name"] : []), + ...(facts.workerArg ? ["worker", ...WORKER_ALIASES] : []), ]; } diff --git a/packages/cli/generator/plugin/emit/handler.ts b/packages/cli/generator/plugin/emit/handler.ts index 99cffbb92d..ca25b8b1eb 100644 --- a/packages/cli/generator/plugin/emit/handler.ts +++ b/packages/cli/generator/plugin/emit/handler.ts @@ -83,6 +83,15 @@ export function handler(ctx: Ctx): string[] { function prelude(ctx: Ctx): string[] { const lines: string[] = []; + if (ctx.needsWorkerName) { + const read = ctx.firstPositionalIsWorkerName + ? argvKey(kebab((positionals(ctx.derived)[0] as Arg).name)) + : 'argv["worker"]'; + lines.push( + ` const scriptName = getWorkerName({ scriptName: ${read} });` + ); + lines.push(` ${read} = scriptName;`); + } if (ctx.hasParams) { lines.push(""); lines.push(" const queryParams: Record = {"); @@ -205,8 +214,7 @@ export function dryRun(ctx: Ctx): string[] { positional, firstPositionalIsZone: false, accountId: "${__cfDryRunAccountId ?? ''}", - scriptName: - '${argv["worker"] == null ? \'\' : encodeURIComponent(String(argv["worker"]))}', + scriptName: "${encodeURIComponent(scriptName)}", zone: "${argv.zone ?? argv.zoneId ?? ''}", param, }); @@ -406,15 +414,6 @@ function auth(ctx: Ctx): string[] { lines.push(" argv.zoneId = zoneId;"); } } - if (ctx.needsWorkerName) { - const read = ctx.firstPositionalIsWorkerName - ? argvKey(kebab((positionals(ctx.derived)[0] as Arg).name)) - : 'argv["worker"]'; - lines.push( - ` const scriptName = getWorkerName({ scriptName: ${read} });` - ); - lines.push(` ${read} = scriptName;`); - } return lines; } diff --git a/packages/cli/src/__tests__/commands/workers-identifiers.test.ts b/packages/cli/src/__tests__/commands/workers-identifiers.test.ts index 0f7d810c9b..b3ce3c2322 100644 --- a/packages/cli/src/__tests__/commands/workers-identifiers.test.ts +++ b/packages/cli/src/__tests__/commands/workers-identifiers.test.ts @@ -68,11 +68,15 @@ describe("cf workers identifiers", () => { expect(request).toHaveBeenCalledOnce(); }); - it(`${args.join(" ")} still requires a Worker`, async () => { - await expect(runCf(["workers", ...args], ENV)).rejects.toThrow( - "--worker " - ); - }); + it.each([false, true])( + `${args.join(" ")} requires a Worker (dry run: %s)`, + async (dryRun) => { + await expect( + runCf(["workers", ...args, ...(dryRun ? ["--dry-run"] : [])], ENV) + ).rejects.toThrow("--worker "); + expect(logSpy).not.toHaveBeenCalled(); + } + ); it.each(flags)(`${args.join(" ")} previews %s`, async (flag) => { await runCf(["workers", ...args, flag, "my/worker", "--dry-run"], ENV); @@ -84,6 +88,16 @@ describe("cf workers identifiers", () => { }); } + it.each([false, true])( + "requires a Worker before delete confirmation or preview (dry run: %s)", + async (dryRun) => { + await expect( + runCf(["workers", "delete", ...(dryRun ? ["--dry-run"] : [])], ENV) + ).rejects.toThrow("--worker "); + expect(logSpy).not.toHaveBeenCalled(); + } + ); + it.each(["get", "delete"])( "%s retains positional Worker input", async (name) => { diff --git a/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts b/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts index 0ea152c9cc..98ba651205 100644 --- a/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts +++ b/packages/cli/src/__tests__/generator/plugin/arg-derivation.test.ts @@ -747,6 +747,22 @@ describe("cf-owned flag clashes", () => { ); }); + it.each(["worker", "worker-id", "script-name"])( + "reserves --%s where cf selects a Worker", + (flag) => { + const op = pathOperation( + "/accounts/{account_id}/workers/workers/{worker_id}", + [["worker_id", undefined]] + ); + op.queryParams = queryOperation("selector").queryParams; + expect(() => + derived(method({ selector: { flagName: flag } }, "get"), "workers", op) + ).toThrow( + `--${flag} (from x-forge-params["selector"].flagName), which is a flag cf adds to this command.` + ); + } + ); + it("lists every clash of an operation in one error", () => { const op = post({ bodyParams: [ diff --git a/packages/cli/src/commands/_generated/workers/delete.ts b/packages/cli/src/commands/_generated/workers/delete.ts index 72b8fe7351..3854ad9c9a 100644 --- a/packages/cli/src/commands/_generated/workers/delete.ts +++ b/packages/cli/src/commands/_generated/workers/delete.ts @@ -69,6 +69,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { force: argv["delete-with-references"], }; @@ -77,7 +80,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}`, pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", @@ -87,8 +90,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if ( !(await confirmDelete({ diff --git a/packages/cli/src/commands/_generated/workers/deployments/create.ts b/packages/cli/src/commands/_generated/workers/deployments/create.ts index 0ea2e92b98..4ced6b8306 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/create.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/create.ts @@ -139,6 +139,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { force: argv["bypass-deployment-checks"], }; @@ -147,7 +150,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments create", method: "POST", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/deployments`, pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "json", @@ -173,8 +176,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if (argv.body !== undefined) { const bodyData = parsedBody; diff --git a/packages/cli/src/commands/_generated/workers/deployments/delete.ts b/packages/cli/src/commands/_generated/workers/deployments/delete.ts index f88e3a9ce7..33040ad339 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/delete.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/delete.ts @@ -64,12 +64,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers deployments delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "deployment-id": String(argv["deployment-id"] ?? ""), @@ -81,8 +83,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if ( !(await confirmDelete({ diff --git a/packages/cli/src/commands/_generated/workers/deployments/get.ts b/packages/cli/src/commands/_generated/workers/deployments/get.ts index b025f8a892..588d7ceddd 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/get.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/get.ts @@ -56,12 +56,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers deployments get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/deployments/${argv["deployment-id"] == null ? "" : encodeURIComponent(String(argv["deployment-id"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "deployment-id": String(argv["deployment-id"] ?? ""), @@ -73,8 +75,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/deployments/list.ts b/packages/cli/src/commands/_generated/workers/deployments/list.ts index eb8e3cc37f..a15b668415 100644 --- a/packages/cli/src/commands/_generated/workers/deployments/list.ts +++ b/packages/cli/src/commands/_generated/workers/deployments/list.ts @@ -61,6 +61,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { since: argv["since"], until: argv["until"], @@ -72,7 +75,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers deployments list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/deployments`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/deployments`, pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", @@ -82,8 +85,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/get.ts b/packages/cli/src/commands/_generated/workers/get.ts index 7356e2759b..d448dfbfe1 100644 --- a/packages/cli/src/commands/_generated/workers/get.ts +++ b/packages/cli/src/commands/_generated/workers/get.ts @@ -54,12 +54,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}`, pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "none", }); @@ -68,8 +70,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/secrets/bulk.ts b/packages/cli/src/commands/_generated/workers/secrets/bulk.ts index 31221cbce5..028475b84d 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/bulk.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/bulk.ts @@ -77,6 +77,8 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if ( argv.body === undefined && argv.file === undefined && @@ -92,7 +94,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets bulk", method: "PATCH", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets-bulk`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/secrets-bulk`, pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: argv.file !== undefined ? "octet-stream" : "json", body: @@ -122,8 +124,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if (argv.file !== undefined) { const fileContent = readFileForFlag(argv.file); diff --git a/packages/cli/src/commands/_generated/workers/secrets/delete.ts b/packages/cli/src/commands/_generated/workers/secrets/delete.ts index be1de82255..d1157525c0 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/delete.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/delete.ts @@ -69,6 +69,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { url_encoded: argv["url-encoded"], }; @@ -77,7 +80,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "secret-name": String(argv["secret-name"] ?? ""), @@ -90,8 +93,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if ( !(await confirmDelete({ diff --git a/packages/cli/src/commands/_generated/workers/secrets/get.ts b/packages/cli/src/commands/_generated/workers/secrets/get.ts index a3f36dba40..ea37042e84 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/get.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/get.ts @@ -61,6 +61,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { url_encoded: argv["url-encoded"], }; @@ -69,7 +72,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers secrets get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/secrets/${argv["secret-name"] == null ? "" : encodeURIComponent(String(argv["secret-name"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "secret-name": String(argv["secret-name"] ?? ""), @@ -82,8 +85,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/secrets/list.ts b/packages/cli/src/commands/_generated/workers/secrets/list.ts index 64878f0b72..a168a5dcb7 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/list.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/list.ts @@ -51,12 +51,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers secrets list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/secrets`, pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "none", }); @@ -65,8 +67,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/secrets/update.ts b/packages/cli/src/commands/_generated/workers/secrets/update.ts index 9bcecef747..41855d92aa 100644 --- a/packages/cli/src/commands/_generated/workers/secrets/update.ts +++ b/packages/cli/src/commands/_generated/workers/secrets/update.ts @@ -118,12 +118,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers secrets update", method: "PUT", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/secrets`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/scripts/${encodeURIComponent(scriptName)}/secrets`, pathParams: { worker: String(argv["worker"] ?? "") }, bodyKind: "json", body: @@ -159,8 +161,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if (argv.body !== undefined) { const bodyData = parsedBody; diff --git a/packages/cli/src/commands/_generated/workers/versions/delete.ts b/packages/cli/src/commands/_generated/workers/versions/delete.ts index 05824275f9..05dd35f8c8 100644 --- a/packages/cli/src/commands/_generated/workers/versions/delete.ts +++ b/packages/cli/src/commands/_generated/workers/versions/delete.ts @@ -65,12 +65,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers versions delete", method: "DELETE", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), @@ -82,8 +84,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if ( !(await confirmDelete({ diff --git a/packages/cli/src/commands/_generated/workers/versions/get.ts b/packages/cli/src/commands/_generated/workers/versions/get.ts index ecee57a28f..8340d727ac 100644 --- a/packages/cli/src/commands/_generated/workers/versions/get.ts +++ b/packages/cli/src/commands/_generated/workers/versions/get.ts @@ -63,6 +63,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { include: argv["include"], }; @@ -71,7 +74,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions get", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}`, pathParams: { worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), @@ -84,8 +87,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/versions/list.ts b/packages/cli/src/commands/_generated/workers/versions/list.ts index ba062fb2d7..738d44c80e 100644 --- a/packages/cli/src/commands/_generated/workers/versions/list.ts +++ b/packages/cli/src/commands/_generated/workers/versions/list.ts @@ -51,6 +51,9 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; + const queryParams: Record = { page: argv["page"], per_page: argv["per-page"], @@ -60,7 +63,7 @@ const command: CommandModule = { formatDryRun({ command: "cf workers versions list", method: "GET", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}/versions`, pathParams: { worker: String(argv["worker"] ?? "") }, query: queryParams, bodyKind: "none", @@ -70,8 +73,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; const result = await withProgress(`Loading`, async () => client.send(operation, { diff --git a/packages/cli/src/commands/_generated/workers/versions/profile.ts b/packages/cli/src/commands/_generated/workers/versions/profile.ts index 9aa46e3414..e4a6a4c1f2 100644 --- a/packages/cli/src/commands/_generated/workers/versions/profile.ts +++ b/packages/cli/src/commands/_generated/workers/versions/profile.ts @@ -92,12 +92,14 @@ const command: CommandModule = { }, argv as Record, async () => { + const scriptName = getWorkerName({ scriptName: argv["worker"] }); + argv["worker"] = scriptName; if (argv.dryRun) { const __cfDryRunAccountId = await resolveAccountIdSilent(); formatDryRun({ command: "cf workers versions profile", method: "POST", - url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${argv["worker"] == null ? "" : encodeURIComponent(String(argv["worker"]))}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}/profile`, + url: `https://api.cloudflare.com/client/v4/accounts/${__cfDryRunAccountId ?? ""}/workers/workers/${encodeURIComponent(scriptName)}/versions/${argv["version-id"] == null ? "" : encodeURIComponent(String(argv["version-id"]))}/profile`, pathParams: { worker: String(argv["worker"] ?? ""), "version-id": String(argv["version-id"] ?? ""), @@ -128,8 +130,6 @@ const command: CommandModule = { const client = await createCommandClient(argv); const accountId = argv.local ? LOCAL_ACCOUNT_ID : await getAccountId(); argv.accountId = accountId; - const scriptName = getWorkerName({ scriptName: argv["worker"] }); - argv["worker"] = scriptName; if (argv.body !== undefined) { const bodyData = parsedBody; diff --git a/packages/cli/src/lib/context.ts b/packages/cli/src/lib/context.ts index 5f821961f7..1d97037222 100644 --- a/packages/cli/src/lib/context.ts +++ b/packages/cli/src/lib/context.ts @@ -201,8 +201,8 @@ async function resolveZoneValue( /** * Get the Worker name. Called by generated commands under `cf workers *`. * - * Yargs populates `scriptName` from either the positional arg or `--worker` - * (aliased as `--script-name` / `--name`), so this is just a guard against + * Yargs populates `worker` from either the positional arg or `--worker` + * (aliased as `--script-name` / `--worker-id`), so this is just a guard against * missing input. */ export function getWorkerName(argv?: { scriptName?: string }): string { diff --git a/packages/wrangler-tests/src/__tests__/delete.test.ts b/packages/wrangler-tests/src/__tests__/delete.test.ts index 22b39ac692..c0f566d5c2 100644 --- a/packages/wrangler-tests/src/__tests__/delete.test.ts +++ b/packages/wrangler-tests/src/__tests__/delete.test.ts @@ -68,7 +68,7 @@ describe("delete", () => { "method": "DELETE", "url": "https://api.cloudflare.com/client/v4/accounts/some-account-id/workers/workers/xyz", "pathParams": { - "worker-id": "xyz" + "worker": "xyz" }, "query": {}, "bodyKind": "none" diff --git a/packages/wrangler-tests/src/__tests__/versions/versions.list.test.ts b/packages/wrangler-tests/src/__tests__/versions/versions.list.test.ts index 7c9239f22d..95d342faf4 100644 --- a/packages/wrangler-tests/src/__tests__/versions/versions.list.test.ts +++ b/packages/wrangler-tests/src/__tests__/versions/versions.list.test.ts @@ -17,7 +17,7 @@ describe("versions list", () => { describe("without wrangler.toml", () => { test("fails with no args", async ({ expect }) => { await expect(runWrangler("workers versions list")).rejects.toThrow( - /Missing required argument: worker-id/ + "--worker " ); }); diff --git a/packages/wrangler-tests/src/__tests__/versions/versions.view.test.ts b/packages/wrangler-tests/src/__tests__/versions/versions.view.test.ts index 4414c55746..7879431fcf 100644 --- a/packages/wrangler-tests/src/__tests__/versions/versions.view.test.ts +++ b/packages/wrangler-tests/src/__tests__/versions/versions.view.test.ts @@ -31,7 +31,7 @@ describe("versions view", () => { test("fails with positional version-id arg only", async ({ expect }) => { await expect( runWrangler(`workers versions get ${VERSION_ID}`) - ).rejects.toThrow(/Missing required argument: worker-id/); + ).rejects.toThrow("--worker "); }); test("succeeds with positional version-id arg and --name arg", async ({ From aae9c95b9a23cdae45cf74c92a25f861453c1947 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 5 Nov 2026 11:32:28 +0000 Subject: [PATCH 3/3] fix(workers): keep selection flags in the shared help group --- .changeset/consistent-worker-identifiers.md | 2 ++ packages/cli/generator/plugin/emit/builder.ts | 4 ++- packages/cli/generator/plugin/emit/handler.ts | 3 +++ packages/cli/src/__tests__/help.test.ts | 26 +++++++++++++++++++ .../src/commands/_generated/workers/delete.ts | 3 ++- .../src/commands/_generated/workers/get.ts | 3 ++- 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/.changeset/consistent-worker-identifiers.md b/.changeset/consistent-worker-identifiers.md index b06fda83ab..d599e7ddeb 100644 --- a/.changeset/consistent-worker-identifiers.md +++ b/.changeset/consistent-worker-identifiers.md @@ -8,3 +8,5 @@ Accept `--worker` for Worker and version operations that previously required `--worker-id` or a positional Worker identifier. Keep `--worker-id` and `--script-name` as aliases, and retain positional input for `cf workers get` and `cf workers delete`. + +Keep the Worker flag alongside the other command options in help. diff --git a/packages/cli/generator/plugin/emit/builder.ts b/packages/cli/generator/plugin/emit/builder.ts index fd37c1168a..d7232e85b9 100644 --- a/packages/cli/generator/plugin/emit/builder.ts +++ b/packages/cli/generator/plugin/emit/builder.ts @@ -89,13 +89,15 @@ export function builderLines(ctx: Ctx): string[] { ["type", type], ["array", scalarArray ? true : undefined], ["alias", arg.isWorkerName ? WORKER_ALIASES : undefined], - ["group", arg.isWorkerName && arg.positional ? "Options:" : undefined], ["description", arg.description], ["choices", arg.choices], ["default", defaults.get(arg.name)], ["demandOption", demand ? true : undefined], ]) ); + if (arg.isWorkerName && arg.positional) { + lines.push(`.group(${stringify(name)}, theme.brand('Options'))`); + } // Resolve `@file` before yargs validates `choices` against the value, // so the handler gets the file's contents without reading it twice. if (arg.fromFile !== undefined && hasChoices(arg)) { diff --git a/packages/cli/generator/plugin/emit/handler.ts b/packages/cli/generator/plugin/emit/handler.ts index ca25b8b1eb..aabd0b8b60 100644 --- a/packages/cli/generator/plugin/emit/handler.ts +++ b/packages/cli/generator/plugin/emit/handler.ts @@ -1133,6 +1133,9 @@ export function imports(ctx: Ctx): Imports { } i.from(`${lib}/output.js`, ["formatOutput"]); i.from(`${lib}/dry-run.js`, ["formatDryRun"]); + if (positionals(d).some((arg) => arg.isWorkerName)) { + i.from(`${lib}/ui/theme.js`, ["theme"]); + } if ((ctx.op.bodyUnions?.length ?? 0) > 0 && d.hasBodyParams) { i.from(`${lib}/body-unions.js`, ["validateBodyUnions"]); } diff --git a/packages/cli/src/__tests__/help.test.ts b/packages/cli/src/__tests__/help.test.ts index bb5f135c22..8f1d7c01d9 100644 --- a/packages/cli/src/__tests__/help.test.ts +++ b/packages/cli/src/__tests__/help.test.ts @@ -150,6 +150,32 @@ describe("help formatting", () => { ); }); + it.each([ + ["get", 0], + ["get", 3], + ["delete", 0], + ["delete", 3], + ] as const)( + "%s keeps Worker selection in one options section (color level %i)", + async (name, level) => { + const previousLevel = chalk.level; + try { + chalk.level = level; + const help = await buildCli(["workers", name, "--help"]).cli.getHelp(); + const sections = help.split(theme.brand("Options")); + expect(sections).toHaveLength(2); + const options = sections[1]?.split("\n\n")[0]; + expect(options).toContain("--worker"); + expect(options).toContain("--dry-run"); + if (name === "delete") { + expect(options).toContain("--force"); + } + } finally { + chalk.level = previousLevel; + } + } + ); + it("italicizes the API hint and colors the schema command when enabled", () => { const previousLevel = chalk.level; try { diff --git a/packages/cli/src/commands/_generated/workers/delete.ts b/packages/cli/src/commands/_generated/workers/delete.ts index 3854ad9c9a..c4fbce5b48 100644 --- a/packages/cli/src/commands/_generated/workers/delete.ts +++ b/packages/cli/src/commands/_generated/workers/delete.ts @@ -18,6 +18,7 @@ import { formatOutput } from "#lib/output.js"; import { withProgress } from "#lib/progress.js"; import { confirmDelete } from "#lib/prompt.js"; import { runWithTelemetry } from "#lib/telemetry/index.js"; +import { theme } from "#lib/ui/theme.js"; function builder(yargs: Argv) { return yargs @@ -31,9 +32,9 @@ function builder(yargs: Argv) { .option("worker", { type: "string", alias: ["script-name", "worker-id"], - group: "Options:", description: "Identifier for the Worker, which can be ID or name.", }) + .group("worker", theme.brand("Options")) .option("delete-with-references", { type: "boolean", description: diff --git a/packages/cli/src/commands/_generated/workers/get.ts b/packages/cli/src/commands/_generated/workers/get.ts index d448dfbfe1..b836f93086 100644 --- a/packages/cli/src/commands/_generated/workers/get.ts +++ b/packages/cli/src/commands/_generated/workers/get.ts @@ -17,6 +17,7 @@ import { LOCAL_ACCOUNT_ID } from "#lib/local.js"; import { formatOutput } from "#lib/output.js"; import { withProgress } from "#lib/progress.js"; import { runWithTelemetry } from "#lib/telemetry/index.js"; +import { theme } from "#lib/ui/theme.js"; function builder(yargs: Argv) { return yargs @@ -28,9 +29,9 @@ function builder(yargs: Argv) { .option("worker", { type: "string", alias: ["script-name", "worker-id"], - group: "Options:", description: "Identifier for the Worker, which can be ID or name.", }) + .group("worker", theme.brand("Options")) .option("dry-run", { type: "boolean", description: "Validate and show what would happen without executing",