Skip to content

Commit e9c0d42

Browse files
committed
feat(wrangler/cli): add tab completions
1 parent 0856306 commit e9c0d42

File tree

4 files changed

+336
-1
lines changed

4 files changed

+336
-1
lines changed

packages/wrangler/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
},
7878
"devDependencies": {
7979
"@aws-sdk/client-s3": "^3.721.0",
80+
"@bomb.sh/tab": "^0.0.7",
8081
"@cloudflare/cli": "workspace:*",
8182
"@cloudflare/containers-shared": "workspace:*",
8283
"@cloudflare/eslint-config-shared": "workspace:*",

packages/wrangler/src/complete.ts

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// NOTE: The provided option-value completions can be customized or removed as needed.
2+
// NOTE: Descriptions and flags based on https://developers.cloudflare.com/workers/wrangler/commands/
3+
4+
import t from "@bomb.sh/tab";
5+
6+
export function setupCompletions() {
7+
// Global flags that work on every command
8+
t.option("help", "Show help");
9+
t.option("h", "Alias for --help");
10+
t.option("config", "Path to Wrangler configuration file");
11+
t.option("c", "Alias for --config");
12+
t.option("cwd", "Run as if Wrangler was started in the specified directory");
13+
t.option("env", "Environment to use for operations and selecting .env/.dev.vars files");
14+
t.option("e", "Alias for --env");
15+
t.option("env-file", "Path to .env file to load (can be specified multiple times)");
16+
t.option("version", "Show version number");
17+
t.option("v", "Alias for --version");
18+
19+
// wrangler docs
20+
t.command("docs", "📚 Open Wrangler's command documentation in your browser");
21+
22+
// wrangler init
23+
const init = t.command("init", "📥 Initialize a basic Worker");
24+
init.option("yes", "Answer yes to all questions");
25+
init.option("from-dash", "Initialize a Worker from the Cloudflare dashboard");
26+
27+
// wrangler dev - Start a local server for developing your Worker
28+
const dev = t.command("dev", "👂 Start a local server for developing your Worker");
29+
dev.option("name", "Name of the Worker");
30+
dev.option("port", "Port to listen on", (complete) => {
31+
complete("8787", "Default Wrangler port");
32+
complete("3000", "Alternative port");
33+
complete("8080", "Alternative port");
34+
});
35+
dev.option("ip", "IP address to listen on", (complete) => {
36+
complete("0.0.0.0", "All interfaces");
37+
complete("127.0.0.1", "Localhost only");
38+
});
39+
dev.option("inspector-port", "Port for devtools to connect to");
40+
dev.option("compatibility-date", "Date in yyyy-mm-dd format for Workers runtime version");
41+
dev.option("compatibility-flags", "Flags to use for compatibility checks");
42+
dev.option("compatibility-flag", "Alias for compatibility-flags");
43+
dev.option("latest", "Use the latest version of the Workers runtime");
44+
dev.option("assets", "Folder of static assets to be served");
45+
dev.option("no-bundle", "Skip internal build steps");
46+
dev.option("env", "Perform on a specific environment");
47+
dev.option("var", "Inject key:value pairs as variables");
48+
dev.option("define", "Replace global identifiers in your code");
49+
dev.option("tsconfig", "Path to a custom tsconfig.json file");
50+
dev.option("minify", "Minify the script");
51+
dev.option("persist-to", "Specify directory to use for local persistence");
52+
dev.option("remote", "Develop against remote resources on Cloudflare's network");
53+
dev.option("test-scheduled", "Expose /__scheduled route for testing Cron Triggers");
54+
dev.option("log-level", "Specify Wrangler's logging level", (complete) => {
55+
complete("debug", "Debug level logging");
56+
complete("info", "Info level logging");
57+
complete("log", "Log level logging");
58+
complete("warn", "Warning level logging");
59+
complete("error", "Error level logging");
60+
complete("none", "No logging");
61+
});
62+
dev.option("show-interactive-dev-session", "Show interactive dev session");
63+
dev.option("alias", "Specify modules to alias using module aliasing");
64+
65+
// wrangler deploy - Deploy your Worker to Cloudflare
66+
const deploy = t.command("deploy", "🆙 Deploy a Worker to Cloudflare");
67+
deploy.option("name", "Name of the Worker");
68+
deploy.option("no-bundle", "Skip internal build steps");
69+
deploy.option("env", "Perform on a specific environment");
70+
deploy.option("outdir", "Path to directory where Wrangler will write bundled Worker files");
71+
deploy.option("compatibility-date", "Date in yyyy-mm-dd format for Workers runtime version");
72+
deploy.option("compatibility-flags", "Flags to use for compatibility checks");
73+
deploy.option("compatibility-flag", "Alias for compatibility-flags");
74+
deploy.option("latest", "Use the latest version of the Workers runtime");
75+
deploy.option("assets", "Folder of static assets to be served");
76+
deploy.option("var", "Inject key:value pairs as variables");
77+
deploy.option("define", "Replace global identifiers in your code");
78+
deploy.option("triggers", "Cron schedules to attach");
79+
deploy.option("schedule", "Alias for triggers");
80+
deploy.option("schedules", "Alias for triggers");
81+
deploy.option("routes", "Routes where this Worker will be deployed");
82+
deploy.option("route", "Alias for routes");
83+
deploy.option("tsconfig", "Path to a custom tsconfig.json file");
84+
deploy.option("minify", "Minify the bundled Worker before deploying");
85+
deploy.option("dry-run", "Compile without deploying to live servers");
86+
deploy.option("keep-vars", "Prevent Wrangler from overriding environment variables");
87+
deploy.option("dispatch-namespace", "Workers for Platforms dispatch namespace");
88+
deploy.option("metafile", "Write build metadata from esbuild");
89+
90+
// wrangler deployments - List and view deployments
91+
t.command("deployments", "🚢 List and view the current and past deployments for your Worker");
92+
t.command("deployments list", "List deployments");
93+
t.command("deployments status", "View deployment status");
94+
t.command("deployments view", "View deployment details");
95+
96+
// wrangler rollback
97+
t.command("rollback", "🔙 Rollback a deployment for a Worker");
98+
99+
// wrangler versions - Retrieve details for recent versions
100+
t.command("versions", "🫧 List, view, upload and deploy Versions of your Worker");
101+
t.command("versions view", "View a specific version");
102+
t.command("versions list", "List all versions");
103+
t.command("versions upload", "Upload a new version");
104+
t.command("versions deploy", "Deploy a version");
105+
t.command("versions secret", "Manage secrets for versions");
106+
t.command("versions secret put", "Add or update a secret");
107+
t.command("versions secret delete", "Delete a secret");
108+
t.command("versions secret list", "List all secrets");
109+
t.command("versions secret bulk", "Bulk operations on secrets");
110+
111+
// wrangler delete
112+
t.command("delete", "🗑 Delete a Worker from Cloudflare");
113+
114+
// wrangler tail - Start a log tailing session
115+
const tail = t.command("tail", "🦚 Start a session to livestream logs from a deployed Worker");
116+
tail.option("format", "Format for log output", (complete) => {
117+
complete("json", "JSON format");
118+
complete("pretty", "Pretty format");
119+
});
120+
tail.option("status", "Filter by invocation status", (complete) => {
121+
complete("ok", "Successful invocations");
122+
complete("error", "Failed invocations");
123+
complete("canceled", "Canceled invocations");
124+
});
125+
126+
// wrangler secret - Manage the secret variables for a Worker
127+
t.command("secret", "🤫 Manage the secret variables for a Worker");
128+
t.command("secret put", "Create or update a secret");
129+
t.command("secret delete", "Delete a secret");
130+
t.command("secret list", "List all secrets");
131+
t.command("secret bulk", "Manage multiple secret variables for a Worker");
132+
133+
// wrangler types - Generate types from bindings
134+
const types = t.command("types", "📝 Generate types from bindings and module rules in configuration");
135+
types.option("env-interface", "Name of the interface to generate for the environment object");
136+
types.option("include-runtime", "Generate runtime types based on compatibility settings");
137+
types.option("include-env", "Generate Env types based on Worker bindings");
138+
types.option("strict-vars", "Generate literal and union types for vars bindings");
139+
types.option("config", "Path(s) to Wrangler configuration file");
140+
141+
// wrangler kv - Manage Workers KV Namespaces
142+
t.command("kv", "🗂️ Manage Workers KV Namespaces");
143+
t.command("kv namespace", "Manage Workers KV namespaces");
144+
t.command("kv namespace create", "Create a new KV namespace");
145+
t.command("kv namespace list", "List all KV namespaces");
146+
t.command("kv namespace delete", "Delete a KV namespace");
147+
t.command("kv namespace rename", "Rename a KV namespace");
148+
t.command("kv key", "Manage key-value pairs within a Workers KV namespace");
149+
t.command("kv key put", "Write a single key-value pair");
150+
t.command("kv key get", "Read a single value by key");
151+
t.command("kv key delete", "Remove a single key-value pair");
152+
t.command("kv key list", "List all keys in a namespace");
153+
t.command("kv bulk", "Manage multiple key-value pairs within a Workers KV namespace in batches");
154+
t.command("kv bulk put", "Write multiple key-value pairs");
155+
t.command("kv bulk get", "Read multiple values by keys");
156+
t.command("kv bulk delete", "Delete multiple key-value pairs");
157+
158+
// wrangler queues - Configure Workers Queues
159+
t.command("queues", "📬 Configure Workers Queues");
160+
t.command("queues list", "List all queues");
161+
t.command("queues create", "Create a queue");
162+
t.command("queues delete", "Delete a queue");
163+
t.command("queues info", "Get queue information");
164+
t.command("queues update", "Update a queue");
165+
t.command("queues purge", "Purge messages from a queue");
166+
t.command("queues pause-delivery", "Pause queue delivery");
167+
t.command("queues resume-delivery", "Resume queue delivery");
168+
t.command("queues consumer", "Manage queue consumers");
169+
t.command("queues consumer add", "Add a consumer");
170+
t.command("queues consumer remove", "Remove a consumer");
171+
t.command("queues subscription", "Manage queue subscriptions");
172+
t.command("queues subscription create", "Create a subscription");
173+
t.command("queues subscription list", "List subscriptions");
174+
t.command("queues subscription delete", "Delete a subscription");
175+
176+
// wrangler r2 - Manage Workers R2 buckets and objects
177+
t.command("r2", "📦 Manage Workers R2 buckets & objects");
178+
t.command("r2 bucket", "Manage R2 buckets");
179+
t.command("r2 bucket create", "Create a new R2 bucket");
180+
t.command("r2 bucket list", "List all R2 buckets");
181+
t.command("r2 bucket delete", "Delete an R2 bucket");
182+
t.command("r2 bucket info", "Get information about an R2 bucket");
183+
t.command("r2 bucket update", "Update R2 bucket settings");
184+
t.command("r2 bucket cors", "Manage CORS settings for an R2 bucket");
185+
t.command("r2 bucket lifecycle", "Manage lifecycle rules for an R2 bucket");
186+
t.command("r2 bucket domain", "Manage custom domains for an R2 bucket");
187+
t.command("r2 object", "Manage R2 objects");
188+
t.command("r2 object get", "Download an object from an R2 bucket");
189+
t.command("r2 object put", "Upload an object to an R2 bucket");
190+
t.command("r2 object delete", "Delete an object from an R2 bucket");
191+
192+
// wrangler d1 - Interact with D1
193+
t.command("d1", "🗄 Manage Workers D1 databases");
194+
t.command("d1 create", "Create a D1 database");
195+
t.command("d1 list", "List all D1 databases");
196+
t.command("d1 delete", "Delete a D1 database");
197+
t.command("d1 info", "Get information about a D1 database");
198+
t.command("d1 execute", "Execute SQL queries against a D1 database");
199+
t.command("d1 export", "Export a D1 database");
200+
t.command("d1 migrations", "Manage D1 database migrations");
201+
t.command("d1 migrations list", "List all migrations");
202+
t.command("d1 migrations create", "Create a new migration");
203+
t.command("d1 migrations apply", "Apply pending migrations");
204+
205+
// wrangler vectorize - Interact with Vectorize indexes
206+
t.command("vectorize", "🧮 Manage Vectorize indexes");
207+
t.command("vectorize create", "Create a Vectorize index");
208+
t.command("vectorize list", "List Vectorize indexes");
209+
t.command("vectorize delete", "Delete a Vectorize index");
210+
t.command("vectorize get", "Get information about a Vectorize index");
211+
t.command("vectorize insert", "Insert vectors into a Vectorize index");
212+
t.command("vectorize query", "Query vectors in a Vectorize index");
213+
214+
// wrangler hyperdrive - Manage your Hyperdrives
215+
t.command("hyperdrive", "🚀 Manage Hyperdrive databases");
216+
t.command("hyperdrive create", "Create a Hyperdrive configuration");
217+
t.command("hyperdrive list", "List Hyperdrive configurations");
218+
t.command("hyperdrive delete", "Delete a Hyperdrive configuration");
219+
t.command("hyperdrive get", "Get a Hyperdrive configuration");
220+
t.command("hyperdrive update", "Update a Hyperdrive configuration");
221+
222+
// wrangler pages - Configure Cloudflare Pages
223+
t.command("pages", "⚡️ Configure Cloudflare Pages");
224+
t.command("pages project", "Manage Pages projects");
225+
t.command("pages project create", "Create a Pages project");
226+
t.command("pages project list", "List Pages projects");
227+
t.command("pages project delete", "Delete a Pages project");
228+
t.command("pages dev", "Develop your full-stack Pages application locally");
229+
t.command("pages deploy", "Deploy a Pages project");
230+
t.command("pages deployment", "Manage Pages deployments");
231+
t.command("pages deployment list", "List deployments");
232+
t.command("pages deployment tail", "Tail deployment logs");
233+
234+
// wrangler workflows - Manage and configure Workflows
235+
t.command("workflows", "🔁 Manage and configure Workflows");
236+
t.command("workflows list", "List workflows");
237+
t.command("workflows describe", "Describe a workflow");
238+
t.command("workflows trigger", "Trigger a workflow");
239+
t.command("workflows instances", "Manage workflow instances");
240+
t.command("workflows instances list", "List workflow instances");
241+
t.command("workflows instances describe", "Describe a workflow instance");
242+
t.command("workflows instances pause", "Pause a workflow instance");
243+
t.command("workflows instances resume", "Resume a workflow instance");
244+
t.command("workflows instances terminate", "Terminate a workflow instance");
245+
246+
// wrangler pipelines - Configure Cloudflare Pipelines
247+
t.command("pipelines", "🚰 Configure Cloudflare Pipelines");
248+
249+
// wrangler ai - Manage AI models
250+
t.command("ai", "🤖 Manage AI models");
251+
252+
// wrangler dispatch-namespace - Interact with a dispatch namespace
253+
t.command("dispatch-namespace", "🏗️ Interact with a dispatch namespace");
254+
255+
// wrangler mtls-certificate - Manage certificates used for mTLS connections
256+
t.command("mtls-certificate", "🪪 Manage certificates used for mTLS connections");
257+
258+
// wrangler cert - Manage certificates used for mTLS and CA chain connections
259+
t.command("cert", "🪪 Manage certificates used for mTLS and Certificate Authority (CA) chain connections");
260+
t.command("cert upload", "Upload a certificate");
261+
t.command("cert upload mtls-certificate", "Upload an mTLS certificate");
262+
t.command("cert upload certificate-authority", "Upload a CA certificate");
263+
t.command("cert list", "List certificates");
264+
t.command("cert delete", "Delete a certificate");
265+
266+
// wrangler secrets-store - Manage the Secrets Store
267+
t.command("secrets-store", "🔐 Manage the Secrets Store");
268+
t.command("secrets-store secret", "Manage account secrets within a secrets store");
269+
t.command("secrets-store store", "Manage your store within secrets store");
270+
271+
// wrangler telemetry - Configure whether Wrangler can collect anonymous usage data
272+
t.command("telemetry", "Configure whether Wrangler can collect anonymous usage data");
273+
t.command("telemetry disable", "Disable telemetry collection");
274+
t.command("telemetry enable", "Enable telemetry collection");
275+
t.command("telemetry status", "Check telemetry collection status");
276+
277+
// wrangler check - Validate your Worker
278+
t.command("check", "Validate your Worker");
279+
t.command("check startup", "Generate a CPU profile of your Worker's startup phase");
280+
281+
// wrangler login/logout/whoami
282+
t.command("login", "🔓 Authorize Wrangler with your Cloudflare account using OAuth");
283+
t.command("logout", "🚪 Remove Wrangler's authorization for accessing your account");
284+
t.command("whoami", "🕵️ Retrieve your user information and test your authentication configuration");
285+
286+
return t;
287+
}
288+
289+
// Handle completion requests from the shell
290+
export function handleCompletion(args: string[]) {
291+
const shell = args[0];
292+
293+
if (shell === "--") {
294+
// Parse completion request from shell
295+
setupCompletions();
296+
t.parse(args.slice(1));
297+
} else {
298+
// Generate shell completion script
299+
setupCompletions();
300+
t.setup("wrangler", "wrangler", shell);
301+
}
302+
}
303+
304+

packages/wrangler/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
import { renderError } from "./cfetch";
3434
import { checkNamespace, checkStartupCommand } from "./check/commands";
3535
import { cloudchamber } from "./cloudchamber";
36+
import { handleCompletion } from "./complete";
3637
import { readConfig } from "./config";
3738
import { getDefaultEnvFiles, loadDotEnv } from "./config/dot-env";
3839
import { containers } from "./containers";
@@ -1587,6 +1588,12 @@ export function createCLIParser(argv: string[]) {
15871588
export async function main(argv: string[]): Promise<void> {
15881589
setupSentry();
15891590

1591+
// Handle shell completion requests
1592+
if (argv[0] === "complete") {
1593+
handleCompletion(argv.slice(1));
1594+
return;
1595+
}
1596+
15901597
checkMacOSVersion({ shouldThrow: false });
15911598

15921599
const startTime = Date.now();

pnpm-lock.yaml

Lines changed: 24 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)