wrangler 0.0.0-fb43821 → 0.0.0-fe5dcfd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -10
- package/pages/functions/buildWorker.ts +62 -0
- package/pages/functions/filepath-routing.test.ts +39 -0
- package/pages/functions/filepath-routing.ts +228 -0
- package/pages/functions/identifiers.ts +78 -0
- package/pages/functions/routes.ts +158 -0
- package/pages/functions/template-worker.ts +136 -0
- package/src/__tests__/dev.test.tsx +67 -0
- package/src/__tests__/index.test.ts +42 -175
- package/src/__tests__/jest.setup.ts +22 -0
- package/src/__tests__/kv.test.ts +1199 -0
- package/src/__tests__/mock-cfetch.ts +173 -0
- package/src/__tests__/mock-dialogs.ts +65 -0
- package/src/__tests__/publish.test.ts +737 -0
- package/src/__tests__/run-in-tmp.ts +19 -0
- package/src/__tests__/run-wrangler.ts +32 -0
- package/src/__tests__/whoami.test.tsx +130 -0
- package/src/api/form_data.ts +66 -76
- package/src/api/preview.ts +4 -4
- package/src/api/worker.ts +38 -44
- package/src/cfetch/index.ts +110 -0
- package/src/cfetch/internal.ts +71 -0
- package/src/cli.ts +6 -7
- package/src/config.ts +634 -110
- package/src/dev.tsx +275 -272
- package/src/dialogs.tsx +2 -2
- package/src/index.tsx +504 -403
- package/src/inspect.ts +543 -0
- package/src/kv.tsx +109 -44
- package/src/pages.tsx +444 -222
- package/src/proxy.ts +302 -0
- package/src/publish.ts +123 -87
- package/src/sites.tsx +169 -41
- package/src/tail.tsx +5 -3
- package/src/user.tsx +64 -74
- package/src/whoami.tsx +69 -0
- package/wrangler-dist/cli.js +42792 -42619
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/mock-cfetch.js +0 -42
- package/src/api/inspect.ts +0 -430
- package/src/cfetch.ts +0 -72
package/src/index.tsx
CHANGED
|
@@ -3,11 +3,12 @@ import { render } from "ink";
|
|
|
3
3
|
import Dev from "./dev";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import makeCLI from "yargs";
|
|
6
|
-
import
|
|
7
|
-
import type yargs from "yargs";
|
|
6
|
+
import type Yargs from "yargs";
|
|
8
7
|
import { findUp } from "find-up";
|
|
9
8
|
import TOML from "@iarna/toml";
|
|
9
|
+
import { normaliseAndValidateEnvironmentsConfig } from "./config";
|
|
10
10
|
import type { Config } from "./config";
|
|
11
|
+
import { getAssetPaths } from "./sites";
|
|
11
12
|
import { confirm, prompt } from "./dialogs";
|
|
12
13
|
import { version as wranglerVersion } from "../package.json";
|
|
13
14
|
import {
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
initialise as initialiseUserConfig,
|
|
18
19
|
loginOrRefreshIfRequired,
|
|
19
20
|
getAccountId,
|
|
21
|
+
validateScopeKeys,
|
|
20
22
|
} from "./user";
|
|
21
23
|
import {
|
|
22
24
|
getNamespaceId,
|
|
@@ -25,11 +27,13 @@ import {
|
|
|
25
27
|
putKeyValue,
|
|
26
28
|
putBulkKeyValue,
|
|
27
29
|
deleteBulkKeyValue,
|
|
30
|
+
createNamespace,
|
|
31
|
+
isValidNamespaceBinding,
|
|
28
32
|
} from "./kv";
|
|
29
33
|
|
|
30
34
|
import { pages } from "./pages";
|
|
31
35
|
|
|
32
|
-
import
|
|
36
|
+
import { fetchResult, fetchRaw } from "./cfetch";
|
|
33
37
|
|
|
34
38
|
import publish from "./publish";
|
|
35
39
|
import path from "path/posix";
|
|
@@ -41,63 +45,37 @@ import onExit from "signal-exit";
|
|
|
41
45
|
import { setTimeout } from "node:timers/promises";
|
|
42
46
|
import * as fs from "node:fs";
|
|
43
47
|
import { execa } from "execa";
|
|
48
|
+
import { whoami } from "./whoami";
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
const resetColor = "\x1b[0m";
|
|
51
|
+
const fgGreenColor = "\x1b[32m";
|
|
52
|
+
|
|
53
|
+
async function readConfig(configPath?: string): Promise<Config> {
|
|
46
54
|
const config: Config = {};
|
|
47
|
-
if (!
|
|
48
|
-
|
|
55
|
+
if (!configPath) {
|
|
56
|
+
configPath = await findUp("wrangler.toml");
|
|
49
57
|
// TODO - terminate this early instead of going all the way to the root
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
if (
|
|
53
|
-
const tml: string = await readFile(
|
|
60
|
+
if (configPath) {
|
|
61
|
+
const tml: string = await readFile(configPath, "utf-8");
|
|
54
62
|
const parsed = TOML.parse(tml) as Config;
|
|
55
63
|
Object.assign(config, parsed);
|
|
56
64
|
}
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"routes",
|
|
66
|
-
"route",
|
|
67
|
-
"jsx_factory",
|
|
68
|
-
"jsx_fragment",
|
|
69
|
-
"site",
|
|
70
|
-
"triggers",
|
|
71
|
-
"usage_model",
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
Object.keys(config.env || {}).forEach((env) => {
|
|
75
|
-
inheritedFields.forEach((field) => {
|
|
76
|
-
if (config[field] !== undefined && config.env[env][field] === undefined) {
|
|
77
|
-
config.env[env][field] = config[field]; // TODO: - shallow copy?
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
const mirroredFields = ["vars", "kv_namespaces", "durable_objects"];
|
|
83
|
-
Object.keys(config.env || {}).forEach((env) => {
|
|
84
|
-
mirroredFields.forEach((field) => {
|
|
85
|
-
// if it exists on top level, it should exist on env defns
|
|
86
|
-
Object.keys(config[field] || {}).forEach((fieldKey) => {
|
|
87
|
-
if (!(fieldKey in config.env[env][field])) {
|
|
88
|
-
console.error(
|
|
89
|
-
`In your configuration, "${field}.${fieldKey}" exists at a top level, but not on "env.${env}". This is not what you probably want, since the field "${field}" is not inherited by environments. Please add "${field}.${fieldKey}" to "env.${env}".`
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
});
|
|
66
|
+
normaliseAndValidateEnvironmentsConfig(config);
|
|
67
|
+
|
|
68
|
+
if ("experimental_services" in config) {
|
|
69
|
+
console.warn(
|
|
70
|
+
"The experimental_services field is only for cloudflare internal usage right now, and is subject to change. Please do not use this on production projects"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
95
73
|
|
|
96
74
|
// todo: validate, add defaults
|
|
97
75
|
// let's just do some basics for now
|
|
98
76
|
|
|
99
77
|
// @ts-expect-error we're being sneaky here for now
|
|
100
|
-
config.__path__ =
|
|
78
|
+
config.__path__ = configPath;
|
|
101
79
|
|
|
102
80
|
return config;
|
|
103
81
|
}
|
|
@@ -105,18 +83,18 @@ async function readConfig(path?: string): Promise<Config> {
|
|
|
105
83
|
// a helper to demand one of a set of options
|
|
106
84
|
// via https://github.com/yargs/yargs/issues/1093#issuecomment-491299261
|
|
107
85
|
function demandOneOfOption(...options: string[]) {
|
|
108
|
-
return function (argv:
|
|
86
|
+
return function (argv: Yargs.Arguments) {
|
|
109
87
|
const count = options.filter((option) => argv[option]).length;
|
|
110
88
|
const lastOption = options.pop();
|
|
111
89
|
|
|
112
90
|
if (count === 0) {
|
|
113
|
-
throw new
|
|
91
|
+
throw new CommandLineArgsError(
|
|
114
92
|
`Exactly one of the arguments ${options.join(
|
|
115
93
|
", "
|
|
116
94
|
)} and ${lastOption} is required`
|
|
117
95
|
);
|
|
118
96
|
} else if (count > 1) {
|
|
119
|
-
throw new
|
|
97
|
+
throw new CommandLineArgsError(
|
|
120
98
|
`Arguments ${options.join(
|
|
121
99
|
", "
|
|
122
100
|
)} and ${lastOption} are mutually exclusive`
|
|
@@ -127,33 +105,49 @@ function demandOneOfOption(...options: string[]) {
|
|
|
127
105
|
};
|
|
128
106
|
}
|
|
129
107
|
|
|
108
|
+
class CommandLineArgsError extends Error {}
|
|
109
|
+
class DeprecationError extends Error {}
|
|
110
|
+
class NotImplementedError extends Error {}
|
|
111
|
+
|
|
130
112
|
export async function main(argv: string[]): Promise<void> {
|
|
131
|
-
const
|
|
132
|
-
.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
(
|
|
138
|
-
yargs
|
|
139
|
-
|
|
140
|
-
console.error(`\nUnknown command: ${args._}.`);
|
|
141
|
-
}
|
|
113
|
+
const wrangler = makeCLI(argv)
|
|
114
|
+
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
115
|
+
// If you want the "help info" to be displayed then throw an instance of `CommandLineArgsError`.
|
|
116
|
+
// Otherwise we just log the error that was thrown without any "help info".
|
|
117
|
+
.showHelpOnFail(false)
|
|
118
|
+
.fail((msg, error) => {
|
|
119
|
+
if (!error) {
|
|
120
|
+
// If there is only a `msg` then this came from yargs own validation, so wrap in a `CommandLineArgsError`.
|
|
121
|
+
error = new CommandLineArgsError(msg);
|
|
142
122
|
}
|
|
143
|
-
|
|
123
|
+
throw error;
|
|
124
|
+
})
|
|
144
125
|
.scriptName("wrangler")
|
|
145
126
|
.wrap(null);
|
|
146
127
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
128
|
+
// the default is to simply print the help menu
|
|
129
|
+
wrangler.command(
|
|
130
|
+
["*"],
|
|
131
|
+
false,
|
|
132
|
+
() => {},
|
|
133
|
+
(args) => {
|
|
134
|
+
if (args._.length > 0) {
|
|
135
|
+
throw new CommandLineArgsError(`Unknown command: ${args._}.`);
|
|
136
|
+
} else {
|
|
137
|
+
wrangler.showHelp("log");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
);
|
|
152
141
|
|
|
153
|
-
//
|
|
142
|
+
// You will note that we use the form for all commands where we use the builder function
|
|
143
|
+
// to define options and subcommands.
|
|
144
|
+
// Further we return the result of this builder even though it's not completely necessary.
|
|
145
|
+
// The reason is that it's required for type inference of the args in the handle function.
|
|
146
|
+
// I wish we could enforce this pattern, but this comment will have to do for now.
|
|
147
|
+
// (It's also annoying that choices[] doesn't get inferred as an enum. 🤷♂.)
|
|
154
148
|
|
|
155
149
|
// [DEPRECATED] generate
|
|
156
|
-
|
|
150
|
+
wrangler.command(
|
|
157
151
|
// we definitely want to move away from us cloning github templates
|
|
158
152
|
// we can do something better here, let's see
|
|
159
153
|
"generate [name] [template]",
|
|
@@ -171,14 +165,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
171
165
|
},
|
|
172
166
|
() => {
|
|
173
167
|
// "👯 [DEPRECATED]. Scaffold a Cloudflare Workers project from a public GitHub repository.",
|
|
174
|
-
|
|
168
|
+
throw new DeprecationError(
|
|
175
169
|
"`wrangler generate` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
176
170
|
);
|
|
177
171
|
}
|
|
178
172
|
);
|
|
179
173
|
|
|
180
174
|
// init
|
|
181
|
-
|
|
175
|
+
wrangler.command(
|
|
182
176
|
"init [name]",
|
|
183
177
|
"📥 Create a wrangler.toml configuration file",
|
|
184
178
|
(yargs) => {
|
|
@@ -195,13 +189,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
195
189
|
"\nIf you wish to use webpack then you will need to create a custom build.";
|
|
196
190
|
// TODO: Add a link to docs
|
|
197
191
|
}
|
|
198
|
-
|
|
199
|
-
return;
|
|
192
|
+
throw new CommandLineArgsError(message);
|
|
200
193
|
}
|
|
201
194
|
|
|
202
195
|
const destination = path.join(process.cwd(), "wrangler.toml");
|
|
203
196
|
if (fs.existsSync(destination)) {
|
|
204
|
-
console.
|
|
197
|
+
console.warn(`${destination} file already exists!`);
|
|
205
198
|
const result = await confirm(
|
|
206
199
|
"Do you want to continue initializing this project?"
|
|
207
200
|
);
|
|
@@ -219,9 +212,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
219
212
|
console.log(`✨ Successfully created wrangler.toml`);
|
|
220
213
|
// TODO: suggest next steps?
|
|
221
214
|
} catch (err) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
215
|
+
throw new Error(
|
|
216
|
+
`Failed to create wrangler.toml.\n${err.message ?? err}`
|
|
217
|
+
);
|
|
225
218
|
}
|
|
226
219
|
|
|
227
220
|
// if no package.json, ask, and if yes, create one
|
|
@@ -293,7 +286,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
293
286
|
);
|
|
294
287
|
|
|
295
288
|
// build
|
|
296
|
-
|
|
289
|
+
wrangler.command(
|
|
297
290
|
"build",
|
|
298
291
|
false,
|
|
299
292
|
(yargs) => {
|
|
@@ -303,14 +296,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
303
296
|
},
|
|
304
297
|
() => {
|
|
305
298
|
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
306
|
-
|
|
299
|
+
throw new DeprecationError(
|
|
307
300
|
"`wrangler build` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
308
301
|
);
|
|
309
302
|
}
|
|
310
303
|
);
|
|
311
304
|
|
|
312
305
|
// login
|
|
313
|
-
|
|
306
|
+
wrangler.command(
|
|
314
307
|
// this needs scopes as an option?
|
|
315
308
|
"login",
|
|
316
309
|
false, // we don't need to show this in the menu
|
|
@@ -341,19 +334,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
341
334
|
listScopes();
|
|
342
335
|
return;
|
|
343
336
|
}
|
|
337
|
+
if (!validateScopeKeys(args.scopes)) {
|
|
338
|
+
throw new CommandLineArgsError(
|
|
339
|
+
`One of ${args.scopes} is not a valid authentication scope. Run "wrangler login --list-scopes" to see the valid scopes.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
344
342
|
await login({ scopes: args.scopes });
|
|
345
343
|
return;
|
|
346
344
|
}
|
|
347
345
|
await login();
|
|
348
346
|
|
|
349
347
|
// TODO: would be nice if it optionally saved login
|
|
350
|
-
//
|
|
348
|
+
// credentials inside node_modules/.cache or something
|
|
351
349
|
// this way you could have multiple users on a single machine
|
|
352
350
|
}
|
|
353
351
|
);
|
|
354
352
|
|
|
355
353
|
// logout
|
|
356
|
-
|
|
354
|
+
wrangler.command(
|
|
357
355
|
// this needs scopes as an option?
|
|
358
356
|
"logout",
|
|
359
357
|
false, // we don't need to show this in the menu
|
|
@@ -365,36 +363,39 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
365
363
|
);
|
|
366
364
|
|
|
367
365
|
// whoami
|
|
368
|
-
|
|
366
|
+
wrangler.command(
|
|
369
367
|
"whoami",
|
|
370
|
-
|
|
371
|
-
// "🕵️ Retrieve your user info and test your auth config",
|
|
368
|
+
"🕵️ Retrieve your user info and test your auth config",
|
|
372
369
|
() => {},
|
|
373
|
-
(
|
|
374
|
-
|
|
370
|
+
async () => {
|
|
371
|
+
await whoami();
|
|
375
372
|
}
|
|
376
373
|
);
|
|
377
374
|
|
|
378
375
|
// config
|
|
379
|
-
|
|
376
|
+
wrangler.command(
|
|
380
377
|
"config",
|
|
381
378
|
false,
|
|
382
379
|
() => {},
|
|
383
380
|
() => {
|
|
384
381
|
// "🕵️ Authenticate Wrangler with a Cloudflare API Token",
|
|
385
|
-
|
|
382
|
+
throw new DeprecationError(
|
|
386
383
|
"`wrangler config` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
387
384
|
);
|
|
388
385
|
}
|
|
389
386
|
);
|
|
390
387
|
|
|
391
388
|
// dev
|
|
392
|
-
|
|
389
|
+
wrangler.command(
|
|
393
390
|
"dev <filename>",
|
|
394
391
|
"👂 Start a local server for developing your worker",
|
|
395
392
|
(yargs) => {
|
|
396
393
|
return yargs
|
|
397
|
-
.positional("filename", {
|
|
394
|
+
.positional("filename", {
|
|
395
|
+
describe: "entry point",
|
|
396
|
+
type: "string",
|
|
397
|
+
demandOption: true,
|
|
398
|
+
})
|
|
398
399
|
.option("name", {
|
|
399
400
|
describe: "name of the script",
|
|
400
401
|
type: "string",
|
|
@@ -408,6 +409,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
408
409
|
type: "string",
|
|
409
410
|
// TODO: get choices for the toml file?
|
|
410
411
|
})
|
|
412
|
+
.option("compatibility-date", {
|
|
413
|
+
describe: "Date to use for compatibility checks",
|
|
414
|
+
type: "string",
|
|
415
|
+
})
|
|
416
|
+
.option("compatibility-flags", {
|
|
417
|
+
describe: "Flags to use for compatibility checks",
|
|
418
|
+
type: "array",
|
|
419
|
+
alias: "compatibility-flag",
|
|
420
|
+
})
|
|
421
|
+
.option("latest", {
|
|
422
|
+
describe: "Use the latest version of the worker runtime",
|
|
423
|
+
type: "boolean",
|
|
424
|
+
default: true,
|
|
425
|
+
})
|
|
411
426
|
.option("ip", {
|
|
412
427
|
describe: "IP address to listen on",
|
|
413
428
|
type: "string",
|
|
@@ -428,7 +443,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
428
443
|
describe: "Protocol to listen to requests on, defaults to http.",
|
|
429
444
|
choices: ["http", "https"],
|
|
430
445
|
})
|
|
431
|
-
.option("public", {
|
|
446
|
+
.option("experimental-public", {
|
|
432
447
|
describe: "Static assets to be served",
|
|
433
448
|
type: "string",
|
|
434
449
|
})
|
|
@@ -436,6 +451,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
436
451
|
describe: "Root folder of static assets for Workers Sites",
|
|
437
452
|
type: "string",
|
|
438
453
|
})
|
|
454
|
+
.option("site-include", {
|
|
455
|
+
describe:
|
|
456
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.",
|
|
457
|
+
type: "string",
|
|
458
|
+
array: true,
|
|
459
|
+
})
|
|
460
|
+
.option("site-exclude", {
|
|
461
|
+
describe:
|
|
462
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded.",
|
|
463
|
+
type: "string",
|
|
464
|
+
array: true,
|
|
465
|
+
})
|
|
439
466
|
.option("upstream-protocol", {
|
|
440
467
|
default: "https",
|
|
441
468
|
describe:
|
|
@@ -455,83 +482,112 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
455
482
|
const { filename, format } = args;
|
|
456
483
|
const config = args.config as Config;
|
|
457
484
|
|
|
458
|
-
|
|
485
|
+
if (args["experimental-public"]) {
|
|
486
|
+
console.warn(
|
|
487
|
+
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (args.public) {
|
|
492
|
+
throw new Error(
|
|
493
|
+
"🚨 The --public field has been renamed to --experimental-public, and will change behaviour in the future."
|
|
494
|
+
);
|
|
495
|
+
}
|
|
459
496
|
|
|
460
497
|
if (!args.local) {
|
|
498
|
+
// -- snip, extract --
|
|
461
499
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
462
500
|
if (!loggedIn) {
|
|
463
501
|
// didn't login, let's just quit
|
|
464
502
|
console.log("Did not login, quitting...");
|
|
465
503
|
return;
|
|
466
504
|
}
|
|
505
|
+
|
|
467
506
|
if (!config.account_id) {
|
|
468
507
|
config.account_id = await getAccountId();
|
|
469
508
|
if (!config.account_id) {
|
|
470
|
-
|
|
471
|
-
return;
|
|
509
|
+
throw new Error("No account id found, quitting...");
|
|
472
510
|
}
|
|
473
511
|
}
|
|
512
|
+
// -- snip, end --
|
|
474
513
|
}
|
|
475
514
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const envRootObj = args.env ? config.env[args.env] || {} : config;
|
|
515
|
+
const environments = config.env ?? {};
|
|
516
|
+
const envRootObj = args.env ? environments[args.env] || {} : config;
|
|
479
517
|
|
|
480
518
|
// TODO: this error shouldn't actually happen,
|
|
481
519
|
// but we haven't fixed it internally yet
|
|
482
520
|
if ("durable_objects" in envRootObj) {
|
|
483
521
|
if (!(args.name || config.name)) {
|
|
484
522
|
console.warn(
|
|
485
|
-
'A worker with durable objects
|
|
523
|
+
'A worker with durable objects needs to be named, or it may not work as expected. Add a "name" into wrangler.toml, or pass it in the command line with --name.'
|
|
486
524
|
);
|
|
487
525
|
}
|
|
488
526
|
// TODO: if not already published, publish a draft worker
|
|
489
527
|
}
|
|
490
528
|
|
|
491
|
-
render(
|
|
529
|
+
const { waitUntilExit } = render(
|
|
492
530
|
<Dev
|
|
493
531
|
name={args.name || config.name}
|
|
494
|
-
entry={filename}
|
|
532
|
+
entry={path.relative(process.cwd(), filename)}
|
|
533
|
+
buildCommand={config.build || {}}
|
|
495
534
|
format={format}
|
|
496
535
|
initialMode={args.local ? "local" : "remote"}
|
|
497
536
|
jsxFactory={args["jsx-factory"] || envRootObj?.jsx_factory}
|
|
498
537
|
jsxFragment={args["jsx-fragment"] || envRootObj?.jsx_fragment}
|
|
499
538
|
accountId={config.account_id}
|
|
500
|
-
|
|
539
|
+
assetPaths={getAssetPaths(
|
|
540
|
+
config,
|
|
541
|
+
args.site,
|
|
542
|
+
args.siteInclude,
|
|
543
|
+
args.siteExclude
|
|
544
|
+
)}
|
|
501
545
|
port={args.port || config.dev?.port}
|
|
502
|
-
public={args
|
|
503
|
-
compatibilityDate={
|
|
504
|
-
|
|
546
|
+
public={args["experimental-public"]}
|
|
547
|
+
compatibilityDate={
|
|
548
|
+
args["compatibility-date"] ||
|
|
549
|
+
config.compatibility_date ||
|
|
550
|
+
new Date().toISOString().substring(0, 10)
|
|
551
|
+
}
|
|
552
|
+
compatibilityFlags={
|
|
553
|
+
(args["compatibility-flags"] as string[]) ||
|
|
554
|
+
config.compatibility_flags
|
|
555
|
+
}
|
|
505
556
|
usageModel={config.usage_model}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
557
|
+
bindings={{
|
|
558
|
+
kv_namespaces: envRootObj.kv_namespaces?.map(
|
|
559
|
+
({ binding, preview_id, id: _id }) => {
|
|
560
|
+
// In `dev`, we make folks use a separate kv namespace called
|
|
561
|
+
// `preview_id` instead of `id` so that they don't
|
|
562
|
+
// break production data. So here we check that a `preview_id`
|
|
563
|
+
// has actually been configured.
|
|
564
|
+
// This whole block of code will be obsoleted in the future
|
|
565
|
+
// when we have copy-on-write for previews on edge workers.
|
|
510
566
|
if (!preview_id) {
|
|
511
567
|
// TODO: This error has to be a _lot_ better, ideally just asking
|
|
512
568
|
// to create a preview namespace for the user automatically
|
|
513
569
|
throw new Error(
|
|
514
|
-
|
|
515
|
-
);
|
|
570
|
+
`In development, you should use a separate kv namespace than the one you'd use in production. Please create a new kv namespace with "wrangler kv:namespace create <name> --preview" and add its id as preview_id to the kv_namespace "${binding}" in your wrangler.toml`
|
|
571
|
+
); // Ugh, I really don't like this message very much
|
|
516
572
|
}
|
|
517
|
-
return {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
(obj, { name, class_name, script_name }) => {
|
|
523
|
-
return { ...obj, [name]: { class_name, script_name } };
|
|
524
|
-
},
|
|
525
|
-
{}
|
|
573
|
+
return {
|
|
574
|
+
binding,
|
|
575
|
+
id: preview_id,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
526
578
|
),
|
|
579
|
+
vars: envRootObj.vars,
|
|
580
|
+
durable_objects: envRootObj.durable_objects,
|
|
581
|
+
services: envRootObj.experimental_services,
|
|
527
582
|
}}
|
|
528
583
|
/>
|
|
529
584
|
);
|
|
585
|
+
await waitUntilExit();
|
|
530
586
|
}
|
|
531
587
|
);
|
|
532
588
|
|
|
533
589
|
// publish
|
|
534
|
-
|
|
590
|
+
wrangler.command(
|
|
535
591
|
"publish [script]",
|
|
536
592
|
"🆙 Publish your Worker to Cloudflare.",
|
|
537
593
|
(yargs) => {
|
|
@@ -548,7 +604,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
548
604
|
describe: "name to use when uploading",
|
|
549
605
|
type: "string",
|
|
550
606
|
})
|
|
551
|
-
.option("
|
|
607
|
+
.option("compatibility-date", {
|
|
608
|
+
describe: "Date to use for compatibility checks",
|
|
609
|
+
type: "string",
|
|
610
|
+
})
|
|
611
|
+
.option("compatibility-flags", {
|
|
612
|
+
describe: "Flags to use for compatibility checks",
|
|
613
|
+
type: "array",
|
|
614
|
+
alias: "compatibility-flag",
|
|
615
|
+
})
|
|
616
|
+
.option("latest", {
|
|
617
|
+
describe: "Use the latest version of the worker runtime",
|
|
618
|
+
type: "boolean",
|
|
619
|
+
default: false,
|
|
620
|
+
})
|
|
621
|
+
.option("experimental-public", {
|
|
552
622
|
describe: "Static assets to be served",
|
|
553
623
|
type: "string",
|
|
554
624
|
})
|
|
@@ -556,6 +626,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
556
626
|
describe: "Root folder of static assets for Workers Sites",
|
|
557
627
|
type: "string",
|
|
558
628
|
})
|
|
629
|
+
.option("site-include", {
|
|
630
|
+
describe:
|
|
631
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.",
|
|
632
|
+
type: "string",
|
|
633
|
+
array: true,
|
|
634
|
+
})
|
|
635
|
+
.option("site-exclude", {
|
|
636
|
+
describe:
|
|
637
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded.",
|
|
638
|
+
type: "string",
|
|
639
|
+
array: true,
|
|
640
|
+
})
|
|
559
641
|
.option("triggers", {
|
|
560
642
|
describe: "cron schedules to attach",
|
|
561
643
|
alias: ["schedule", "schedules"],
|
|
@@ -583,47 +665,77 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
583
665
|
},
|
|
584
666
|
async (args) => {
|
|
585
667
|
if (args.local) {
|
|
586
|
-
|
|
587
|
-
|
|
668
|
+
throw new NotImplementedError(
|
|
669
|
+
"🚫 Local publishing is not yet supported"
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (args["experimental-public"]) {
|
|
674
|
+
console.warn(
|
|
675
|
+
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
676
|
+
);
|
|
588
677
|
}
|
|
678
|
+
if (args.public) {
|
|
679
|
+
throw new Error(
|
|
680
|
+
"🚨 The --public field has been renamed to --experimental-public, and will change behaviour in the future."
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
|
|
589
684
|
const config = args.config as Config;
|
|
590
685
|
|
|
591
|
-
|
|
686
|
+
if (args.latest) {
|
|
687
|
+
console.warn(
|
|
688
|
+
"⚠️ Using the latest version of the Workers runtime. To silence this warning, please choose a specific version of the runtime with --compatibility-date, or add a compatibility_date to your wrangler.toml.\n"
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
592
692
|
if (!args.local) {
|
|
693
|
+
// -- snip, extract --
|
|
593
694
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
594
695
|
if (!loggedIn) {
|
|
595
696
|
// didn't login, let's just quit
|
|
596
697
|
console.log("Did not login, quitting...");
|
|
597
698
|
return;
|
|
598
699
|
}
|
|
700
|
+
|
|
599
701
|
if (!config.account_id) {
|
|
600
702
|
config.account_id = await getAccountId();
|
|
601
703
|
if (!config.account_id) {
|
|
602
|
-
|
|
603
|
-
return;
|
|
704
|
+
throw new Error("No account id found, quitting...");
|
|
604
705
|
}
|
|
605
706
|
}
|
|
707
|
+
// -- snip, end --
|
|
606
708
|
}
|
|
607
709
|
|
|
608
|
-
|
|
609
|
-
|
|
710
|
+
const assetPaths = getAssetPaths(
|
|
711
|
+
config,
|
|
712
|
+
args["experimental-public"] || args.site,
|
|
713
|
+
args.siteInclude,
|
|
714
|
+
args.siteExclude
|
|
715
|
+
);
|
|
610
716
|
await publish({
|
|
611
717
|
config: args.config as Config,
|
|
612
718
|
name: args.name,
|
|
613
719
|
script: args.script,
|
|
614
720
|
env: args.env,
|
|
721
|
+
compatibilityDate: args.latest
|
|
722
|
+
? new Date().toISOString().substring(0, 10)
|
|
723
|
+
: args["compatibility-date"],
|
|
724
|
+
compatibilityFlags: args["compatibility-flags"] as string[],
|
|
615
725
|
triggers: args.triggers,
|
|
616
726
|
jsxFactory: args["jsx-factory"],
|
|
617
727
|
jsxFragment: args["jsx-fragment"],
|
|
618
728
|
routes: args.routes,
|
|
619
|
-
|
|
620
|
-
|
|
729
|
+
assetPaths,
|
|
730
|
+
format: undefined, // TODO: add args for this
|
|
731
|
+
legacyEnv: undefined, // TODO: get this from somewhere... config?
|
|
732
|
+
experimentalPublic: args["experimental-public"] !== undefined,
|
|
621
733
|
});
|
|
622
734
|
}
|
|
623
735
|
);
|
|
624
736
|
|
|
625
737
|
// tail
|
|
626
|
-
|
|
738
|
+
wrangler.command(
|
|
627
739
|
"tail [name]",
|
|
628
740
|
"🦚 Starts a log tailing session for a deployed Worker.",
|
|
629
741
|
(yargs) => {
|
|
@@ -667,34 +779,35 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
667
779
|
// TODO: filter by client ip, which can be 'self' or an ip address
|
|
668
780
|
},
|
|
669
781
|
async (args) => {
|
|
782
|
+
if (args.local) {
|
|
783
|
+
throw new NotImplementedError(
|
|
784
|
+
`local mode is not yet supported for this command`
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
|
|
670
788
|
const config = args.config as Config;
|
|
671
789
|
|
|
672
790
|
if (!(args.name || config.name)) {
|
|
673
|
-
|
|
674
|
-
return;
|
|
791
|
+
throw new Error("Missing script name");
|
|
675
792
|
}
|
|
676
793
|
const scriptName = `${args.name || config.name}${
|
|
677
794
|
args.env ? `-${args.env}` : ""
|
|
678
795
|
}`;
|
|
679
796
|
|
|
680
797
|
// -- snip, extract --
|
|
798
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
799
|
+
if (!loggedIn) {
|
|
800
|
+
// didn't login, let's just quit
|
|
801
|
+
console.log("Did not login, quitting...");
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
681
804
|
|
|
682
|
-
if (!
|
|
683
|
-
|
|
684
|
-
if (!loggedIn) {
|
|
685
|
-
// didn't login, let's just quit
|
|
686
|
-
console.log("Did not login, quitting...");
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
805
|
+
if (!config.account_id) {
|
|
806
|
+
config.account_id = await getAccountId();
|
|
689
807
|
if (!config.account_id) {
|
|
690
|
-
|
|
691
|
-
if (!config.account_id) {
|
|
692
|
-
console.error("No account id found, quitting...");
|
|
693
|
-
return;
|
|
694
|
-
}
|
|
808
|
+
throw new Error("No account id found, quitting...");
|
|
695
809
|
}
|
|
696
810
|
}
|
|
697
|
-
|
|
698
811
|
// -- snip, end --
|
|
699
812
|
|
|
700
813
|
const accountId = config.account_id;
|
|
@@ -741,7 +854,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
741
854
|
);
|
|
742
855
|
|
|
743
856
|
// preview
|
|
744
|
-
|
|
857
|
+
wrangler.command(
|
|
745
858
|
"preview [method] [body]",
|
|
746
859
|
false,
|
|
747
860
|
(yargs) => {
|
|
@@ -767,20 +880,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
767
880
|
});
|
|
768
881
|
},
|
|
769
882
|
() => {
|
|
770
|
-
// "🔬 [DEPRECATED] Preview your code temporarily on cloudflareworkers.com"
|
|
771
|
-
|
|
883
|
+
// "🔬 [DEPRECATED] Preview your code temporarily on https://cloudflareworkers.com"
|
|
884
|
+
throw new DeprecationError(
|
|
772
885
|
"`wrangler preview` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
773
886
|
);
|
|
774
887
|
}
|
|
775
888
|
);
|
|
776
889
|
|
|
777
890
|
// route
|
|
778
|
-
|
|
891
|
+
wrangler.command(
|
|
779
892
|
"route",
|
|
780
893
|
false, // I think we want to hide this command
|
|
781
894
|
// "➡️ List or delete worker routes",
|
|
782
|
-
(
|
|
783
|
-
return
|
|
895
|
+
(routeYargs) => {
|
|
896
|
+
return routeYargs
|
|
784
897
|
.command(
|
|
785
898
|
"list",
|
|
786
899
|
"List a route associated with a zone",
|
|
@@ -804,11 +917,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
804
917
|
// TODO: use environment (current wrangler doesn't do so?)
|
|
805
918
|
const zone = args.zone || (args.config as Config).zone_id;
|
|
806
919
|
if (!zone) {
|
|
807
|
-
|
|
808
|
-
return;
|
|
920
|
+
throw new Error("missing zone id");
|
|
809
921
|
}
|
|
810
922
|
|
|
811
|
-
console.log(await
|
|
923
|
+
console.log(await fetchResult(`/zones/${zone}/workers/routes`));
|
|
812
924
|
}
|
|
813
925
|
)
|
|
814
926
|
.command(
|
|
@@ -838,7 +950,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
838
950
|
}
|
|
839
951
|
|
|
840
952
|
console.log(
|
|
841
|
-
await
|
|
953
|
+
await fetchResult(`/zones/${zone}/workers/routes/${args.id}`, {
|
|
842
954
|
method: "DELETE",
|
|
843
955
|
})
|
|
844
956
|
);
|
|
@@ -848,7 +960,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
848
960
|
);
|
|
849
961
|
|
|
850
962
|
// subdomain
|
|
851
|
-
|
|
963
|
+
wrangler.command(
|
|
852
964
|
"subdomain [name]",
|
|
853
965
|
false,
|
|
854
966
|
// "👷 Create or change your workers.dev subdomain.",
|
|
@@ -856,18 +968,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
856
968
|
return yargs.positional("name", { type: "string" });
|
|
857
969
|
},
|
|
858
970
|
() => {
|
|
859
|
-
|
|
971
|
+
throw new DeprecationError(
|
|
860
972
|
"`wrangler subdomain` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
861
973
|
);
|
|
862
974
|
}
|
|
863
975
|
);
|
|
864
976
|
|
|
865
977
|
// secret
|
|
866
|
-
|
|
978
|
+
wrangler.command(
|
|
867
979
|
"secret",
|
|
868
980
|
"🤫 Generate a secret that can be referenced in the worker script",
|
|
869
|
-
(
|
|
870
|
-
return
|
|
981
|
+
(secretYargs) => {
|
|
982
|
+
return secretYargs
|
|
871
983
|
.command(
|
|
872
984
|
"put <key>",
|
|
873
985
|
"Create or update a secret variable for a script",
|
|
@@ -889,44 +1001,42 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
889
1001
|
},
|
|
890
1002
|
async (args) => {
|
|
891
1003
|
if (args.local) {
|
|
892
|
-
|
|
893
|
-
|
|
1004
|
+
throw new NotImplementedError(
|
|
1005
|
+
"--local not implemented for this command yet"
|
|
1006
|
+
);
|
|
894
1007
|
}
|
|
895
1008
|
const config = args.config as Config;
|
|
896
1009
|
|
|
897
1010
|
// TODO: use environment (how does current wrangler do it?)
|
|
898
1011
|
const scriptName = args.name || config.name;
|
|
899
1012
|
if (!scriptName) {
|
|
900
|
-
|
|
901
|
-
return;
|
|
1013
|
+
throw new Error("Missing script name");
|
|
902
1014
|
}
|
|
903
1015
|
|
|
904
|
-
// -- snip, extract --
|
|
905
|
-
|
|
906
1016
|
if (!args.local) {
|
|
1017
|
+
// -- snip, extract --
|
|
907
1018
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
908
1019
|
if (!loggedIn) {
|
|
909
1020
|
// didn't login, let's just quit
|
|
910
1021
|
console.log("Did not login, quitting...");
|
|
911
1022
|
return;
|
|
912
1023
|
}
|
|
1024
|
+
|
|
913
1025
|
if (!config.account_id) {
|
|
914
1026
|
config.account_id = await getAccountId();
|
|
915
1027
|
if (!config.account_id) {
|
|
916
|
-
|
|
917
|
-
return;
|
|
1028
|
+
throw new Error("No account id found, quitting...");
|
|
918
1029
|
}
|
|
919
1030
|
}
|
|
1031
|
+
// -- snip, end --
|
|
920
1032
|
}
|
|
921
1033
|
|
|
922
|
-
// -- snip, end --
|
|
923
|
-
|
|
924
1034
|
const secretValue = await prompt(
|
|
925
1035
|
"Enter a secret value:",
|
|
926
1036
|
"password"
|
|
927
1037
|
);
|
|
928
1038
|
async function submitSecret() {
|
|
929
|
-
return await
|
|
1039
|
+
return await fetchResult(
|
|
930
1040
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/`,
|
|
931
1041
|
{
|
|
932
1042
|
method: "PUT",
|
|
@@ -945,7 +1055,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
945
1055
|
} catch (e) {
|
|
946
1056
|
if (e.code === 10007) {
|
|
947
1057
|
// upload a draft worker
|
|
948
|
-
await
|
|
1058
|
+
await fetchResult(
|
|
949
1059
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}`,
|
|
950
1060
|
{
|
|
951
1061
|
method: "PUT",
|
|
@@ -956,7 +1066,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
956
1066
|
content: `export default { fetch() {} }`,
|
|
957
1067
|
type: "esm",
|
|
958
1068
|
},
|
|
959
|
-
|
|
1069
|
+
bindings: {
|
|
1070
|
+
kv_namespaces: [],
|
|
1071
|
+
vars: {},
|
|
1072
|
+
durable_objects: { bindings: [] },
|
|
1073
|
+
},
|
|
960
1074
|
modules: [],
|
|
961
1075
|
}),
|
|
962
1076
|
}
|
|
@@ -990,8 +1104,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
990
1104
|
},
|
|
991
1105
|
async (args) => {
|
|
992
1106
|
if (args.local) {
|
|
993
|
-
|
|
994
|
-
|
|
1107
|
+
throw new NotImplementedError(
|
|
1108
|
+
"--local not implemented for this command yet"
|
|
1109
|
+
);
|
|
995
1110
|
}
|
|
996
1111
|
const config = args.config as Config;
|
|
997
1112
|
|
|
@@ -1001,33 +1116,31 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1001
1116
|
throw new Error("Missing script name");
|
|
1002
1117
|
}
|
|
1003
1118
|
|
|
1004
|
-
// -- snip, extract --
|
|
1005
|
-
|
|
1006
1119
|
if (!args.local) {
|
|
1120
|
+
// -- snip, extract --
|
|
1007
1121
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1008
1122
|
if (!loggedIn) {
|
|
1009
1123
|
// didn't login, let's just quit
|
|
1010
1124
|
console.log("Did not login, quitting...");
|
|
1011
1125
|
return;
|
|
1012
1126
|
}
|
|
1127
|
+
|
|
1013
1128
|
if (!config.account_id) {
|
|
1014
1129
|
config.account_id = await getAccountId();
|
|
1015
1130
|
if (!config.account_id) {
|
|
1016
|
-
|
|
1017
|
-
return;
|
|
1131
|
+
throw new Error("No account id found, quitting...");
|
|
1018
1132
|
}
|
|
1019
1133
|
}
|
|
1134
|
+
// -- snip, end --
|
|
1020
1135
|
}
|
|
1021
1136
|
|
|
1022
|
-
// -- snip, end --
|
|
1023
|
-
|
|
1024
1137
|
if (await confirm("Are you sure you want to delete this secret?")) {
|
|
1025
1138
|
console.log(
|
|
1026
1139
|
`Deleting the secret ${args.key} on script ${scriptName}.`
|
|
1027
1140
|
);
|
|
1028
1141
|
|
|
1029
1142
|
console.log(
|
|
1030
|
-
await
|
|
1143
|
+
await fetchResult(
|
|
1031
1144
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/${args.key}`,
|
|
1032
1145
|
{ method: "DELETE" }
|
|
1033
1146
|
)
|
|
@@ -1052,40 +1165,38 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1052
1165
|
},
|
|
1053
1166
|
async (args) => {
|
|
1054
1167
|
if (args.local) {
|
|
1055
|
-
|
|
1056
|
-
|
|
1168
|
+
throw new NotImplementedError(
|
|
1169
|
+
"--local not implemented for this command yet"
|
|
1170
|
+
);
|
|
1057
1171
|
}
|
|
1058
1172
|
const config = args.config as Config;
|
|
1059
1173
|
|
|
1060
1174
|
// TODO: use environment (how does current wrangler do it?)
|
|
1061
1175
|
const scriptName = args.name || config.name;
|
|
1062
1176
|
if (!scriptName) {
|
|
1063
|
-
|
|
1064
|
-
return;
|
|
1177
|
+
throw new Error("Missing script name");
|
|
1065
1178
|
}
|
|
1066
1179
|
|
|
1067
|
-
// -- snip, extract --
|
|
1068
|
-
|
|
1069
1180
|
if (!args.local) {
|
|
1181
|
+
// -- snip, extract --
|
|
1070
1182
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1071
1183
|
if (!loggedIn) {
|
|
1072
1184
|
// didn't login, let's just quit
|
|
1073
1185
|
console.log("Did not login, quitting...");
|
|
1074
1186
|
return;
|
|
1075
1187
|
}
|
|
1188
|
+
|
|
1076
1189
|
if (!config.account_id) {
|
|
1077
1190
|
config.account_id = await getAccountId();
|
|
1078
1191
|
if (!config.account_id) {
|
|
1079
|
-
|
|
1080
|
-
return;
|
|
1192
|
+
throw new Error("No account id found, quitting...");
|
|
1081
1193
|
}
|
|
1082
1194
|
}
|
|
1195
|
+
// -- snip, end --
|
|
1083
1196
|
}
|
|
1084
1197
|
|
|
1085
|
-
// -- snip, end --
|
|
1086
|
-
|
|
1087
1198
|
console.log(
|
|
1088
|
-
await
|
|
1199
|
+
await fetchResult(
|
|
1089
1200
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1090
1201
|
)
|
|
1091
1202
|
);
|
|
@@ -1096,11 +1207,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1096
1207
|
|
|
1097
1208
|
// kv
|
|
1098
1209
|
// :namespace
|
|
1099
|
-
|
|
1210
|
+
wrangler.command(
|
|
1100
1211
|
"kv:namespace",
|
|
1101
1212
|
"🗂️ Interact with your Workers KV Namespaces",
|
|
1102
|
-
(
|
|
1103
|
-
return
|
|
1213
|
+
(namespaceYargs) => {
|
|
1214
|
+
return namespaceYargs
|
|
1104
1215
|
.command(
|
|
1105
1216
|
"create <namespace>",
|
|
1106
1217
|
"Create a new namespace",
|
|
@@ -1109,6 +1220,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1109
1220
|
.positional("namespace", {
|
|
1110
1221
|
describe: "The name of the new namespace",
|
|
1111
1222
|
type: "string",
|
|
1223
|
+
demandOption: true,
|
|
1112
1224
|
})
|
|
1113
1225
|
.option("env", {
|
|
1114
1226
|
type: "string",
|
|
@@ -1120,13 +1232,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1120
1232
|
});
|
|
1121
1233
|
},
|
|
1122
1234
|
async (args) => {
|
|
1123
|
-
if (args._.length
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1235
|
+
if (args._.length > 2) {
|
|
1236
|
+
const extraArgs = args._.slice(2).join(" ");
|
|
1237
|
+
throw new CommandLineArgsError(
|
|
1238
|
+
`Unexpected additional positional arguments "${extraArgs}".`
|
|
1239
|
+
);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
if (!isValidNamespaceBinding(args.namespace)) {
|
|
1243
|
+
throw new CommandLineArgsError(
|
|
1244
|
+
`The namespace binding name "${args.namespace}" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.`
|
|
1128
1245
|
);
|
|
1129
1246
|
}
|
|
1247
|
+
|
|
1130
1248
|
const config = args.config as Config;
|
|
1131
1249
|
if (!config.name) {
|
|
1132
1250
|
console.warn(
|
|
@@ -1134,13 +1252,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1134
1252
|
);
|
|
1135
1253
|
}
|
|
1136
1254
|
|
|
1137
|
-
const
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
if (/[\W]+/.test(args.namespace)) {
|
|
1142
|
-
throw new Error("invalid binding name, needs to be js friendly");
|
|
1143
|
-
}
|
|
1255
|
+
const name = config.name || "worker";
|
|
1256
|
+
const environment = args.env ? `-${args.env}` : "";
|
|
1257
|
+
const preview = args.preview ? "_preview" : "";
|
|
1258
|
+
const title = `${name}${environment}-${args.namespace}${preview}`;
|
|
1144
1259
|
|
|
1145
1260
|
if (args.local) {
|
|
1146
1261
|
const { Miniflare } = await import("miniflare");
|
|
@@ -1151,57 +1266,43 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1151
1266
|
});
|
|
1152
1267
|
await mf.getKVNamespace(title); // this should "create" the namespace
|
|
1153
1268
|
console.log(`✨ Success! Created KV namespace ${title}`);
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
// -- snip, extract --
|
|
1158
|
-
|
|
1159
|
-
if (!args.local) {
|
|
1269
|
+
} else {
|
|
1270
|
+
// -- snip, extract --
|
|
1160
1271
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1161
1272
|
if (!loggedIn) {
|
|
1162
1273
|
// didn't login, let's just quit
|
|
1163
1274
|
console.log("Did not login, quitting...");
|
|
1164
1275
|
return;
|
|
1165
1276
|
}
|
|
1277
|
+
|
|
1166
1278
|
if (!config.account_id) {
|
|
1167
1279
|
config.account_id = await getAccountId();
|
|
1168
1280
|
if (!config.account_id) {
|
|
1169
|
-
|
|
1170
|
-
return;
|
|
1281
|
+
throw new Error("No account id found, quitting...");
|
|
1171
1282
|
}
|
|
1172
1283
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
// -- snip, end --
|
|
1284
|
+
// -- snip, end --
|
|
1176
1285
|
|
|
1177
|
-
|
|
1286
|
+
// TODO: generate a binding name stripping non alphanumeric chars
|
|
1178
1287
|
|
|
1179
|
-
|
|
1288
|
+
console.log(`🌀 Creating namespace with title "${title}"`);
|
|
1289
|
+
const namespaceId = await createNamespace(
|
|
1290
|
+
config.account_id,
|
|
1291
|
+
title
|
|
1292
|
+
);
|
|
1180
1293
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
}),
|
|
1191
|
-
}
|
|
1192
|
-
);
|
|
1294
|
+
console.log("✨ Success!");
|
|
1295
|
+
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
1296
|
+
const previewString = args.preview ? "preview_" : "";
|
|
1297
|
+
console.log(
|
|
1298
|
+
`Add the following to your configuration file in your kv_namespaces array${envString}:`
|
|
1299
|
+
);
|
|
1300
|
+
console.log(
|
|
1301
|
+
`{ binding = "${args.namespace}", ${previewString}id = "${namespaceId}" }`
|
|
1302
|
+
);
|
|
1193
1303
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
`Add the following to your configuration file in your kv_namespaces array${
|
|
1197
|
-
args.env ? ` under [env.${args.env}]` : ""
|
|
1198
|
-
}:`
|
|
1199
|
-
);
|
|
1200
|
-
console.log(
|
|
1201
|
-
`{ binding = "${args.namespace}", ${
|
|
1202
|
-
args.preview ? "preview_" : ""
|
|
1203
|
-
}id = "${response.id}" }`
|
|
1204
|
-
);
|
|
1304
|
+
// TODO: automatically write this block to the wrangler.toml config file??
|
|
1305
|
+
}
|
|
1205
1306
|
}
|
|
1206
1307
|
)
|
|
1207
1308
|
.command(
|
|
@@ -1209,42 +1310,39 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1209
1310
|
"Outputs a list of all KV namespaces associated with your account id.",
|
|
1210
1311
|
{},
|
|
1211
1312
|
async (args) => {
|
|
1212
|
-
if (args.local) {
|
|
1213
|
-
console.error(`local mode is not yet supported for this command`);
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
1313
|
const config = args.config as Config;
|
|
1218
1314
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1315
|
+
if (args.local) {
|
|
1316
|
+
throw new NotImplementedError(
|
|
1317
|
+
`local mode is not yet supported for this command`
|
|
1318
|
+
);
|
|
1319
|
+
} else {
|
|
1320
|
+
// -- snip, extract --
|
|
1222
1321
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1223
1322
|
if (!loggedIn) {
|
|
1224
1323
|
// didn't login, let's just quit
|
|
1225
1324
|
console.log("Did not login, quitting...");
|
|
1226
1325
|
return;
|
|
1227
1326
|
}
|
|
1327
|
+
|
|
1228
1328
|
if (!config.account_id) {
|
|
1229
1329
|
config.account_id = await getAccountId();
|
|
1230
1330
|
if (!config.account_id) {
|
|
1231
|
-
|
|
1232
|
-
return;
|
|
1331
|
+
throw new Error("No account id found, quitting...");
|
|
1233
1332
|
}
|
|
1234
1333
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
// -- snip, end --
|
|
1334
|
+
// -- snip, end --
|
|
1238
1335
|
|
|
1239
|
-
|
|
1336
|
+
// TODO: we should show bindings if they exist for given ids
|
|
1240
1337
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1338
|
+
console.log(
|
|
1339
|
+
JSON.stringify(
|
|
1340
|
+
await listNamespaces(config.account_id),
|
|
1341
|
+
null,
|
|
1342
|
+
" "
|
|
1343
|
+
)
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1248
1346
|
}
|
|
1249
1347
|
)
|
|
1250
1348
|
.command(
|
|
@@ -1271,27 +1369,23 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1271
1369
|
});
|
|
1272
1370
|
},
|
|
1273
1371
|
async (args) => {
|
|
1274
|
-
if (args.local) {
|
|
1275
|
-
console.error(`local mode is not yet supported for this command`);
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
1372
|
const config = args.config as Config;
|
|
1279
1373
|
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1374
|
+
if (args.local) {
|
|
1375
|
+
throw new NotImplementedError(
|
|
1376
|
+
`local mode is not yet supported for this command`
|
|
1377
|
+
);
|
|
1378
|
+
} else {
|
|
1379
|
+
let id;
|
|
1380
|
+
try {
|
|
1381
|
+
id = getNamespaceId(args);
|
|
1382
|
+
} catch (e) {
|
|
1383
|
+
throw new CommandLineArgsError(
|
|
1384
|
+
"Not able to delete namespace.\n" + e.message
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1293
1387
|
|
|
1294
|
-
|
|
1388
|
+
// -- snip, extract --
|
|
1295
1389
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1296
1390
|
if (!loggedIn) {
|
|
1297
1391
|
// didn't login, let's just quit
|
|
@@ -1302,47 +1396,45 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1302
1396
|
if (!config.account_id) {
|
|
1303
1397
|
config.account_id = await getAccountId();
|
|
1304
1398
|
if (!config.account_id) {
|
|
1305
|
-
|
|
1306
|
-
return;
|
|
1399
|
+
throw new Error("No account id found, quitting...");
|
|
1307
1400
|
}
|
|
1308
1401
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
// -- snip, end --
|
|
1402
|
+
// -- snip, end --
|
|
1312
1403
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1404
|
+
await fetchResult<{ id: string }>(
|
|
1405
|
+
`/accounts/${config.account_id}/storage/kv/namespaces/${id}`,
|
|
1406
|
+
{ method: "DELETE" }
|
|
1407
|
+
);
|
|
1317
1408
|
|
|
1318
|
-
|
|
1409
|
+
// TODO: recommend they remove it from wrangler.toml
|
|
1319
1410
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1411
|
+
// test-mf wrangler kv:namespace delete --namespace-id 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1412
|
+
// Are you sure you want to delete namespace 2a7d3d8b23fc4159b5afa489d6cfd388? [y/n]
|
|
1413
|
+
// n
|
|
1414
|
+
// 💁 Not deleting namespace 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1415
|
+
// ➜ test-mf wrangler kv:namespace delete --namespace-id 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1416
|
+
// Are you sure you want to delete namespace 2a7d3d8b23fc4159b5afa489d6cfd388? [y/n]
|
|
1417
|
+
// y
|
|
1418
|
+
// 🌀 Deleting namespace 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1419
|
+
// ✨ Success
|
|
1420
|
+
// ⚠️ Make sure to remove this "kv-namespace" entry from your configuration file!
|
|
1421
|
+
// ➜ test-mf
|
|
1331
1422
|
|
|
1332
|
-
|
|
1423
|
+
// TODO: do it automatically
|
|
1333
1424
|
|
|
1334
|
-
|
|
1425
|
+
// TODO: delete the preview namespace as well?
|
|
1426
|
+
}
|
|
1335
1427
|
}
|
|
1336
1428
|
);
|
|
1337
1429
|
}
|
|
1338
1430
|
);
|
|
1339
1431
|
|
|
1340
1432
|
// :key
|
|
1341
|
-
|
|
1433
|
+
wrangler.command(
|
|
1342
1434
|
"kv:key",
|
|
1343
1435
|
"🔑 Individually manage Workers KV key-value pairs",
|
|
1344
|
-
(
|
|
1345
|
-
return
|
|
1436
|
+
(kvKeyYargs) => {
|
|
1437
|
+
return kvKeyYargs
|
|
1346
1438
|
.command(
|
|
1347
1439
|
"put <key> [value]",
|
|
1348
1440
|
"Writes a single key/value pair to the given namespace.",
|
|
@@ -1351,6 +1443,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1351
1443
|
.positional("key", {
|
|
1352
1444
|
type: "string",
|
|
1353
1445
|
describe: "The key to write to.",
|
|
1446
|
+
demandOption: true,
|
|
1354
1447
|
})
|
|
1355
1448
|
.positional("value", {
|
|
1356
1449
|
type: "string",
|
|
@@ -1390,9 +1483,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1390
1483
|
},
|
|
1391
1484
|
async ({ key, ttl, expiration, ...args }) => {
|
|
1392
1485
|
const namespaceId = getNamespaceId(args);
|
|
1486
|
+
// One of `args.path` and `args.value` must be defined
|
|
1393
1487
|
const value = args.path
|
|
1394
1488
|
? await readFile(args.path, "utf-8")
|
|
1395
|
-
:
|
|
1489
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1490
|
+
args.value!;
|
|
1396
1491
|
const config = args.config as Config;
|
|
1397
1492
|
|
|
1398
1493
|
if (args.path) {
|
|
@@ -1414,11 +1509,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1414
1509
|
});
|
|
1415
1510
|
const ns = await mf.getKVNamespace(namespaceId);
|
|
1416
1511
|
await ns.put(key, value, { expiration, expirationTtl: ttl });
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
// -- snip, extract --
|
|
1420
|
-
|
|
1421
|
-
if (!args.local) {
|
|
1512
|
+
} else {
|
|
1513
|
+
// -- snip, extract --
|
|
1422
1514
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1423
1515
|
if (!loggedIn) {
|
|
1424
1516
|
// didn't login, let's just quit
|
|
@@ -1429,18 +1521,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1429
1521
|
if (!config.account_id) {
|
|
1430
1522
|
config.account_id = await getAccountId();
|
|
1431
1523
|
if (!config.account_id) {
|
|
1432
|
-
|
|
1433
|
-
return;
|
|
1524
|
+
throw new Error("No account id found, quitting...");
|
|
1434
1525
|
}
|
|
1435
1526
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
// -- snip, end --
|
|
1527
|
+
// -- snip, end --
|
|
1439
1528
|
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1529
|
+
await putKeyValue(config.account_id, namespaceId, key, value, {
|
|
1530
|
+
expiration,
|
|
1531
|
+
expiration_ttl: ttl,
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1444
1534
|
}
|
|
1445
1535
|
)
|
|
1446
1536
|
.command(
|
|
@@ -1461,6 +1551,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1461
1551
|
type: "string",
|
|
1462
1552
|
describe: "Perform on a specific environment",
|
|
1463
1553
|
})
|
|
1554
|
+
.option("preview", {
|
|
1555
|
+
type: "boolean",
|
|
1556
|
+
// In the case of listing keys we will default to non-preview mode
|
|
1557
|
+
default: false,
|
|
1558
|
+
describe: "Interact with a preview namespace",
|
|
1559
|
+
})
|
|
1464
1560
|
.option("prefix", {
|
|
1465
1561
|
type: "string",
|
|
1466
1562
|
describe: "A prefix to filter listed keys",
|
|
@@ -1482,12 +1578,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1482
1578
|
const ns = await mf.getKVNamespace(namespaceId);
|
|
1483
1579
|
const listResponse = await ns.list({ prefix });
|
|
1484
1580
|
console.log(JSON.stringify(listResponse.keys, null, " ")); // TODO: paginate, collate
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
// -- snip, extract --
|
|
1489
|
-
|
|
1490
|
-
if (!args.local) {
|
|
1581
|
+
} else {
|
|
1582
|
+
// -- snip, extract --
|
|
1491
1583
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1492
1584
|
if (!loggedIn) {
|
|
1493
1585
|
// didn't login, let's just quit
|
|
@@ -1498,17 +1590,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1498
1590
|
if (!config.account_id) {
|
|
1499
1591
|
config.account_id = await getAccountId();
|
|
1500
1592
|
if (!config.account_id) {
|
|
1501
|
-
|
|
1502
|
-
return;
|
|
1593
|
+
throw new Error("No account id found, quitting...");
|
|
1503
1594
|
}
|
|
1504
1595
|
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
// -- snip, end --
|
|
1596
|
+
// -- snip, end --
|
|
1508
1597
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1598
|
+
const results = await listNamespaceKeys(
|
|
1599
|
+
config.account_id,
|
|
1600
|
+
namespaceId,
|
|
1601
|
+
prefix
|
|
1602
|
+
);
|
|
1603
|
+
console.log(JSON.stringify(results, undefined, 2));
|
|
1604
|
+
}
|
|
1512
1605
|
}
|
|
1513
1606
|
)
|
|
1514
1607
|
.command(
|
|
@@ -1519,6 +1612,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1519
1612
|
.positional("key", {
|
|
1520
1613
|
describe: "The key value to get.",
|
|
1521
1614
|
type: "string",
|
|
1615
|
+
demandOption: true,
|
|
1522
1616
|
})
|
|
1523
1617
|
.option("binding", {
|
|
1524
1618
|
type: "string",
|
|
@@ -1536,6 +1630,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1536
1630
|
.option("preview", {
|
|
1537
1631
|
type: "boolean",
|
|
1538
1632
|
describe: "Interact with a preview namespace",
|
|
1633
|
+
})
|
|
1634
|
+
.option("preview", {
|
|
1635
|
+
type: "boolean",
|
|
1636
|
+
// In the case of getting key values we will default to non-preview mode
|
|
1637
|
+
default: false,
|
|
1638
|
+
describe: "Interact with a preview namespace",
|
|
1539
1639
|
});
|
|
1540
1640
|
},
|
|
1541
1641
|
async ({ key, ...args }) => {
|
|
@@ -1554,9 +1654,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1554
1654
|
return;
|
|
1555
1655
|
}
|
|
1556
1656
|
|
|
1557
|
-
// -- snip, extract --
|
|
1558
|
-
|
|
1559
1657
|
if (!args.local) {
|
|
1658
|
+
// -- snip, extract --
|
|
1560
1659
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1561
1660
|
if (!loggedIn) {
|
|
1562
1661
|
// didn't login, let's just quit
|
|
@@ -1567,20 +1666,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1567
1666
|
if (!config.account_id) {
|
|
1568
1667
|
config.account_id = await getAccountId();
|
|
1569
1668
|
if (!config.account_id) {
|
|
1570
|
-
|
|
1571
|
-
return;
|
|
1669
|
+
throw new Error("No account id found, quitting...");
|
|
1572
1670
|
}
|
|
1573
1671
|
}
|
|
1672
|
+
// -- snip, end --
|
|
1574
1673
|
}
|
|
1575
1674
|
|
|
1576
|
-
// -- snip, end --
|
|
1577
|
-
|
|
1578
|
-
// annoyingly, the API for this one doesn't return the
|
|
1579
|
-
// data in the 'standard' format. goddammit.
|
|
1580
|
-
// That's why we have the fallthrough response in cfetch.
|
|
1581
|
-
// Oh well.
|
|
1582
1675
|
console.log(
|
|
1583
|
-
await
|
|
1676
|
+
await fetchRaw(
|
|
1584
1677
|
`/accounts/${config.account_id}/storage/kv/namespaces/${namespaceId}/values/${key}`
|
|
1585
1678
|
)
|
|
1586
1679
|
);
|
|
@@ -1594,6 +1687,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1594
1687
|
.positional("key", {
|
|
1595
1688
|
describe: "The key value to delete",
|
|
1596
1689
|
type: "string",
|
|
1690
|
+
demandOption: true,
|
|
1597
1691
|
})
|
|
1598
1692
|
.option("binding", {
|
|
1599
1693
|
type: "string",
|
|
@@ -1634,9 +1728,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1634
1728
|
|
|
1635
1729
|
const config = args.config as Config;
|
|
1636
1730
|
|
|
1637
|
-
// -- snip, extract --
|
|
1638
|
-
|
|
1639
1731
|
if (!args.local) {
|
|
1732
|
+
// -- snip, extract --
|
|
1640
1733
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1641
1734
|
if (!loggedIn) {
|
|
1642
1735
|
// didn't login, let's just quit
|
|
@@ -1647,15 +1740,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1647
1740
|
if (!config.account_id) {
|
|
1648
1741
|
config.account_id = await getAccountId();
|
|
1649
1742
|
if (!config.account_id) {
|
|
1650
|
-
|
|
1651
|
-
return;
|
|
1743
|
+
throw new Error("No account id found, quitting...");
|
|
1652
1744
|
}
|
|
1653
1745
|
}
|
|
1746
|
+
// -- snip, end --
|
|
1654
1747
|
}
|
|
1655
1748
|
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
await cfetch(
|
|
1749
|
+
await fetchResult(
|
|
1659
1750
|
`/accounts/${config.account_id}/storage/kv/namespaces/${namespaceId}/values/${key}`,
|
|
1660
1751
|
{ method: "DELETE" }
|
|
1661
1752
|
);
|
|
@@ -1665,11 +1756,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1665
1756
|
);
|
|
1666
1757
|
|
|
1667
1758
|
// :bulk
|
|
1668
|
-
|
|
1759
|
+
wrangler.command(
|
|
1669
1760
|
"kv:bulk",
|
|
1670
1761
|
"💪 Interact with multiple Workers KV key-value pairs at once",
|
|
1671
|
-
(
|
|
1672
|
-
return
|
|
1762
|
+
(kvBulkYargs) => {
|
|
1763
|
+
return kvBulkYargs
|
|
1673
1764
|
.command(
|
|
1674
1765
|
"put <filename>",
|
|
1675
1766
|
"Upload multiple key-value pairs to a namespace",
|
|
@@ -1678,6 +1769,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1678
1769
|
.positional("filename", {
|
|
1679
1770
|
describe: `The JSON file of key-value pairs to upload, in form [{"key":..., "value":...}"...]`,
|
|
1680
1771
|
type: "string",
|
|
1772
|
+
demandOption: true,
|
|
1681
1773
|
})
|
|
1682
1774
|
.option("binding", {
|
|
1683
1775
|
type: "string",
|
|
@@ -1709,8 +1801,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1709
1801
|
try {
|
|
1710
1802
|
parsedContent = JSON.parse(content);
|
|
1711
1803
|
} catch (err) {
|
|
1712
|
-
|
|
1713
|
-
|
|
1804
|
+
throw new Error(
|
|
1805
|
+
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1806
|
+
);
|
|
1714
1807
|
}
|
|
1715
1808
|
|
|
1716
1809
|
if (args.local) {
|
|
@@ -1732,13 +1825,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1732
1825
|
expirationTtl: expiration_ttl,
|
|
1733
1826
|
});
|
|
1734
1827
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
// -- snip, extract --
|
|
1740
|
-
|
|
1741
|
-
if (!args.local) {
|
|
1828
|
+
} else {
|
|
1829
|
+
// -- snip, extract --
|
|
1742
1830
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1743
1831
|
if (!loggedIn) {
|
|
1744
1832
|
// didn't login, let's just quit
|
|
@@ -1749,27 +1837,26 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1749
1837
|
if (!config.account_id) {
|
|
1750
1838
|
config.account_id = await getAccountId();
|
|
1751
1839
|
if (!config.account_id) {
|
|
1752
|
-
|
|
1753
|
-
return;
|
|
1840
|
+
throw new Error("No account id found, quitting...");
|
|
1754
1841
|
}
|
|
1755
1842
|
}
|
|
1756
|
-
|
|
1843
|
+
// -- snip, end --
|
|
1757
1844
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
);
|
|
1845
|
+
console.log(
|
|
1846
|
+
await putBulkKeyValue(config.account_id, namespaceId, content)
|
|
1847
|
+
);
|
|
1848
|
+
}
|
|
1763
1849
|
}
|
|
1764
1850
|
)
|
|
1765
1851
|
.command(
|
|
1766
1852
|
"delete <filename>",
|
|
1767
|
-
"
|
|
1853
|
+
"Delete multiple key-value pairs from a namespace",
|
|
1768
1854
|
(yargs) => {
|
|
1769
1855
|
return yargs
|
|
1770
1856
|
.positional("filename", {
|
|
1771
|
-
describe: `The JSON file of
|
|
1857
|
+
describe: `The JSON file of keys to delete, in the form ["key1", "key2", ...]`,
|
|
1772
1858
|
type: "string",
|
|
1859
|
+
demandOption: true,
|
|
1773
1860
|
})
|
|
1774
1861
|
.option("binding", {
|
|
1775
1862
|
type: "string",
|
|
@@ -1797,8 +1884,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1797
1884
|
try {
|
|
1798
1885
|
parsedContent = JSON.parse(content);
|
|
1799
1886
|
} catch (err) {
|
|
1800
|
-
|
|
1801
|
-
|
|
1887
|
+
throw new Error(
|
|
1888
|
+
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1889
|
+
);
|
|
1802
1890
|
}
|
|
1803
1891
|
|
|
1804
1892
|
if (args.local) {
|
|
@@ -1812,13 +1900,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1812
1900
|
for (const key of parsedContent) {
|
|
1813
1901
|
await ns.delete(key);
|
|
1814
1902
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
// -- snip, extract --
|
|
1820
|
-
|
|
1821
|
-
if (!args.local) {
|
|
1903
|
+
} else {
|
|
1904
|
+
// -- snip, extract --
|
|
1822
1905
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1823
1906
|
if (!loggedIn) {
|
|
1824
1907
|
// didn't login, let's just quit
|
|
@@ -1829,25 +1912,27 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1829
1912
|
if (!config.account_id) {
|
|
1830
1913
|
config.account_id = await getAccountId();
|
|
1831
1914
|
if (!config.account_id) {
|
|
1832
|
-
|
|
1833
|
-
return;
|
|
1915
|
+
throw new Error("No account id found, quitting...");
|
|
1834
1916
|
}
|
|
1835
1917
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
// -- snip, end --
|
|
1918
|
+
// -- snip, end --
|
|
1839
1919
|
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1920
|
+
console.log(
|
|
1921
|
+
await deleteBulkKeyValue(
|
|
1922
|
+
config.account_id,
|
|
1923
|
+
namespaceId,
|
|
1924
|
+
content
|
|
1925
|
+
)
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1843
1928
|
}
|
|
1844
1929
|
);
|
|
1845
1930
|
}
|
|
1846
1931
|
);
|
|
1847
1932
|
|
|
1848
|
-
|
|
1933
|
+
wrangler.command("pages", "⚡️ Configure Cloudflare Pages", pages);
|
|
1849
1934
|
|
|
1850
|
-
|
|
1935
|
+
wrangler
|
|
1851
1936
|
.option("config", {
|
|
1852
1937
|
alias: "c",
|
|
1853
1938
|
describe: "Path to .toml configuration file",
|
|
@@ -1863,12 +1948,28 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1863
1948
|
default: false, // I bet this will a point of contention. We'll revisit it.
|
|
1864
1949
|
});
|
|
1865
1950
|
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1951
|
+
wrangler.group(["config", "help", "version"], "Flags:");
|
|
1952
|
+
wrangler.help().alias("h", "help");
|
|
1953
|
+
wrangler.version(wranglerVersion).alias("v", "version");
|
|
1954
|
+
wrangler.exitProcess(false);
|
|
1870
1955
|
|
|
1871
1956
|
await initialiseUserConfig();
|
|
1872
1957
|
|
|
1873
|
-
|
|
1958
|
+
try {
|
|
1959
|
+
await wrangler.parse();
|
|
1960
|
+
} catch (e) {
|
|
1961
|
+
if (e instanceof CommandLineArgsError) {
|
|
1962
|
+
wrangler.showHelp("error");
|
|
1963
|
+
console.error(""); // Just adds a bit of space
|
|
1964
|
+
console.error(e.message);
|
|
1965
|
+
} else {
|
|
1966
|
+
console.error(e.message);
|
|
1967
|
+
console.error(""); // Just adds a bit of space
|
|
1968
|
+
console.error(
|
|
1969
|
+
`${fgGreenColor}%s${resetColor}`,
|
|
1970
|
+
"If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1971
|
+
);
|
|
1972
|
+
}
|
|
1973
|
+
throw e;
|
|
1974
|
+
}
|
|
1874
1975
|
}
|