wrangler 0.0.0-ece06ea → 0.0.0-edc4b53
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 +24 -15
- package/pages/functions/buildWorker.ts +62 -0
- package/pages/functions/filepath-routing.test.ts +39 -0
- package/pages/functions/filepath-routing.ts +221 -0
- package/pages/functions/identifiers.ts +78 -0
- package/pages/functions/routes.ts +158 -0
- package/pages/functions/template-worker.ts +144 -0
- package/src/__tests__/dev.test.tsx +66 -0
- package/src/__tests__/index.test.ts +254 -120
- package/src/__tests__/jest.setup.ts +22 -0
- package/src/__tests__/kv.test.ts +1106 -0
- package/src/__tests__/mock-cfetch.ts +171 -0
- package/src/__tests__/mock-dialogs.ts +65 -0
- package/src/__tests__/run-in-tmp.ts +19 -0
- package/src/__tests__/run-wrangler.ts +32 -0
- package/src/api/form_data.ts +71 -98
- package/src/api/preview.ts +29 -24
- package/src/api/worker.ts +38 -44
- package/src/cfetch/index.ts +102 -0
- package/src/cfetch/internal.ts +65 -0
- package/src/cli.ts +6 -7
- package/src/config.ts +476 -113
- package/src/dev.tsx +291 -256
- package/src/dialogs.tsx +4 -12
- package/src/index.tsx +381 -252
- package/src/inspect.ts +524 -0
- package/src/kv.tsx +110 -45
- package/src/module-collection.ts +64 -0
- package/src/pages.tsx +900 -213
- package/src/proxy.ts +294 -0
- package/src/publish.ts +67 -63
- package/src/sites.tsx +10 -7
- package/src/tail.tsx +5 -3
- package/src/user.tsx +31 -33
- package/wrangler-dist/cli.js +43444 -56347
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/fixtures/init/.gitkeep +0 -0
- package/src/__tests__/mock-cfetch.js +0 -46
- package/src/api/inspect.ts +0 -441
- package/src/cfetch.ts +0 -72
- package/src/util/fetch.ts +0 -74
package/src/index.tsx
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render } from "ink";
|
|
3
|
-
import
|
|
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";
|
|
10
9
|
import type { Config } from "./config";
|
|
@@ -25,11 +24,13 @@ import {
|
|
|
25
24
|
putKeyValue,
|
|
26
25
|
putBulkKeyValue,
|
|
27
26
|
deleteBulkKeyValue,
|
|
27
|
+
createNamespace,
|
|
28
|
+
isValidNamespaceBinding,
|
|
28
29
|
} from "./kv";
|
|
29
30
|
|
|
30
31
|
import { pages } from "./pages";
|
|
31
32
|
|
|
32
|
-
import
|
|
33
|
+
import { fetchResult, fetchRaw } from "./cfetch";
|
|
33
34
|
|
|
34
35
|
import publish from "./publish";
|
|
35
36
|
import path from "path/posix";
|
|
@@ -42,15 +43,15 @@ import { setTimeout } from "node:timers/promises";
|
|
|
42
43
|
import * as fs from "node:fs";
|
|
43
44
|
import { execa } from "execa";
|
|
44
45
|
|
|
45
|
-
async function readConfig(
|
|
46
|
+
async function readConfig(configPath?: string): Promise<Config> {
|
|
46
47
|
const config: Config = {};
|
|
47
|
-
if (!
|
|
48
|
-
|
|
48
|
+
if (!configPath) {
|
|
49
|
+
configPath = await findUp("wrangler.toml");
|
|
49
50
|
// TODO - terminate this early instead of going all the way to the root
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
if (
|
|
53
|
-
const tml: string = await readFile(
|
|
53
|
+
if (configPath) {
|
|
54
|
+
const tml: string = await readFile(configPath, "utf-8");
|
|
54
55
|
const parsed = TOML.parse(tml) as Config;
|
|
55
56
|
Object.assign(config, parsed);
|
|
56
57
|
}
|
|
@@ -66,7 +67,6 @@ async function readConfig(path?: string): Promise<Config> {
|
|
|
66
67
|
"route",
|
|
67
68
|
"jsx_factory",
|
|
68
69
|
"jsx_fragment",
|
|
69
|
-
"polyfill_node",
|
|
70
70
|
"site",
|
|
71
71
|
"triggers",
|
|
72
72
|
"usage_model",
|
|
@@ -80,13 +80,18 @@ async function readConfig(path?: string): Promise<Config> {
|
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
const mirroredFields = [
|
|
83
|
+
const mirroredFields = [
|
|
84
|
+
"vars",
|
|
85
|
+
"kv_namespaces",
|
|
86
|
+
"durable_objects",
|
|
87
|
+
"experimental_services",
|
|
88
|
+
];
|
|
84
89
|
Object.keys(config.env || {}).forEach((env) => {
|
|
85
90
|
mirroredFields.forEach((field) => {
|
|
86
|
-
// if it exists on top level, it should exist on env
|
|
91
|
+
// if it exists on top level, it should exist on env definitions
|
|
87
92
|
Object.keys(config[field] || {}).forEach((fieldKey) => {
|
|
88
93
|
if (!(fieldKey in config.env[env][field])) {
|
|
89
|
-
console.
|
|
94
|
+
console.warn(
|
|
90
95
|
`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}".`
|
|
91
96
|
);
|
|
92
97
|
}
|
|
@@ -94,11 +99,17 @@ async function readConfig(path?: string): Promise<Config> {
|
|
|
94
99
|
});
|
|
95
100
|
});
|
|
96
101
|
|
|
102
|
+
if ("experimental_services" in config) {
|
|
103
|
+
console.warn(
|
|
104
|
+
"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"
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
97
108
|
// todo: validate, add defaults
|
|
98
109
|
// let's just do some basics for now
|
|
99
110
|
|
|
100
111
|
// @ts-expect-error we're being sneaky here for now
|
|
101
|
-
config.__path__ =
|
|
112
|
+
config.__path__ = configPath;
|
|
102
113
|
|
|
103
114
|
return config;
|
|
104
115
|
}
|
|
@@ -106,18 +117,18 @@ async function readConfig(path?: string): Promise<Config> {
|
|
|
106
117
|
// a helper to demand one of a set of options
|
|
107
118
|
// via https://github.com/yargs/yargs/issues/1093#issuecomment-491299261
|
|
108
119
|
function demandOneOfOption(...options: string[]) {
|
|
109
|
-
return function (argv:
|
|
120
|
+
return function (argv: Yargs.Arguments) {
|
|
110
121
|
const count = options.filter((option) => argv[option]).length;
|
|
111
122
|
const lastOption = options.pop();
|
|
112
123
|
|
|
113
124
|
if (count === 0) {
|
|
114
|
-
throw new
|
|
125
|
+
throw new CommandLineArgsError(
|
|
115
126
|
`Exactly one of the arguments ${options.join(
|
|
116
127
|
", "
|
|
117
128
|
)} and ${lastOption} is required`
|
|
118
129
|
);
|
|
119
130
|
} else if (count > 1) {
|
|
120
|
-
throw new
|
|
131
|
+
throw new CommandLineArgsError(
|
|
121
132
|
`Arguments ${options.join(
|
|
122
133
|
", "
|
|
123
134
|
)} and ${lastOption} are mutually exclusive`
|
|
@@ -128,30 +139,49 @@ function demandOneOfOption(...options: string[]) {
|
|
|
128
139
|
};
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
class CommandLineArgsError extends Error {}
|
|
143
|
+
class DeprecationError extends Error {}
|
|
144
|
+
class NotImplementedError extends Error {}
|
|
145
|
+
|
|
131
146
|
export async function main(argv: string[]): Promise<void> {
|
|
132
|
-
const
|
|
133
|
-
.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
()
|
|
139
|
-
yargs
|
|
147
|
+
const wrangler = makeCLI(argv)
|
|
148
|
+
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
149
|
+
// If you want the "help info" to be displayed then throw an instance of `CommandLineArgsError`.
|
|
150
|
+
// Otherwise we just log the error that was thrown without any "help info".
|
|
151
|
+
.showHelpOnFail(false)
|
|
152
|
+
.fail((msg, error) => {
|
|
153
|
+
if (!error) {
|
|
154
|
+
// If there is only a `msg` then this came from yargs own validation, so wrap in a `CommandLineArgsError`.
|
|
155
|
+
error = new CommandLineArgsError(msg);
|
|
140
156
|
}
|
|
141
|
-
|
|
157
|
+
throw error;
|
|
158
|
+
})
|
|
142
159
|
.scriptName("wrangler")
|
|
143
160
|
.wrap(null);
|
|
144
161
|
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
162
|
+
// the default is to simply print the help menu
|
|
163
|
+
wrangler.command(
|
|
164
|
+
["*"],
|
|
165
|
+
false,
|
|
166
|
+
() => {},
|
|
167
|
+
(args) => {
|
|
168
|
+
if (args._.length > 0) {
|
|
169
|
+
throw new CommandLineArgsError(`Unknown command: ${args._}.`);
|
|
170
|
+
} else {
|
|
171
|
+
wrangler.showHelp("log");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
);
|
|
150
175
|
|
|
151
|
-
//
|
|
176
|
+
// You will note that we use the form for all commands where we use the builder function
|
|
177
|
+
// to define options and subcommands.
|
|
178
|
+
// Further we return the result of this builder even though it's not completely necessary.
|
|
179
|
+
// The reason is that it's required for type inference of the args in the handle function.
|
|
180
|
+
// I wish we could enforce this pattern, but this comment will have to do for now.
|
|
181
|
+
// (It's also annoying that choices[] doesn't get inferred as an enum. 🤷♂.)
|
|
152
182
|
|
|
153
183
|
// [DEPRECATED] generate
|
|
154
|
-
|
|
184
|
+
wrangler.command(
|
|
155
185
|
// we definitely want to move away from us cloning github templates
|
|
156
186
|
// we can do something better here, let's see
|
|
157
187
|
"generate [name] [template]",
|
|
@@ -169,14 +199,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
169
199
|
},
|
|
170
200
|
() => {
|
|
171
201
|
// "👯 [DEPRECATED]. Scaffold a Cloudflare Workers project from a public GitHub repository.",
|
|
172
|
-
|
|
202
|
+
throw new DeprecationError(
|
|
173
203
|
"`wrangler generate` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
174
204
|
);
|
|
175
205
|
}
|
|
176
206
|
);
|
|
177
207
|
|
|
178
208
|
// init
|
|
179
|
-
|
|
209
|
+
wrangler.command(
|
|
180
210
|
"init [name]",
|
|
181
211
|
"📥 Create a wrangler.toml configuration file",
|
|
182
212
|
(yargs) => {
|
|
@@ -185,26 +215,42 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
185
215
|
type: "string",
|
|
186
216
|
});
|
|
187
217
|
},
|
|
188
|
-
async () => {
|
|
218
|
+
async (args) => {
|
|
219
|
+
if ("type" in args) {
|
|
220
|
+
let message = "The --type option is no longer supported.";
|
|
221
|
+
if (args.type === "webpack") {
|
|
222
|
+
message +=
|
|
223
|
+
"\nIf you wish to use webpack then you will need to create a custom build.";
|
|
224
|
+
// TODO: Add a link to docs
|
|
225
|
+
}
|
|
226
|
+
throw new CommandLineArgsError(message);
|
|
227
|
+
}
|
|
228
|
+
|
|
189
229
|
const destination = path.join(process.cwd(), "wrangler.toml");
|
|
190
230
|
if (fs.existsSync(destination)) {
|
|
191
|
-
console.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
`compatibility_date = "${compatibilityDate}"` + "\n"
|
|
198
|
-
);
|
|
199
|
-
console.log(`✨ Succesfully created wrangler.toml`);
|
|
200
|
-
// TODO: suggest next steps?
|
|
201
|
-
} catch (err) {
|
|
202
|
-
console.error(`Failed to create wrangler.toml`);
|
|
203
|
-
console.error(err);
|
|
204
|
-
throw err;
|
|
231
|
+
console.warn(`${destination} file already exists!`);
|
|
232
|
+
const result = await confirm(
|
|
233
|
+
"Do you want to continue initializing this project?"
|
|
234
|
+
);
|
|
235
|
+
if (!result) {
|
|
236
|
+
return;
|
|
205
237
|
}
|
|
206
238
|
}
|
|
207
239
|
|
|
240
|
+
const compatibilityDate = new Date().toISOString().substring(0, 10);
|
|
241
|
+
try {
|
|
242
|
+
await writeFile(
|
|
243
|
+
destination,
|
|
244
|
+
`compatibility_date = "${compatibilityDate}"` + "\n"
|
|
245
|
+
);
|
|
246
|
+
console.log(`✨ Successfully created wrangler.toml`);
|
|
247
|
+
// TODO: suggest next steps?
|
|
248
|
+
} catch (err) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
`Failed to create wrangler.toml.\n${err.message ?? err}`
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
208
254
|
// if no package.json, ask, and if yes, create one
|
|
209
255
|
let pathToPackageJson = await findUp("package.json");
|
|
210
256
|
|
|
@@ -241,9 +287,17 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
241
287
|
JSON.stringify(
|
|
242
288
|
{
|
|
243
289
|
compilerOptions: {
|
|
244
|
-
target: "
|
|
245
|
-
module: "
|
|
246
|
-
|
|
290
|
+
target: "esnext",
|
|
291
|
+
module: "esnext",
|
|
292
|
+
moduleResolution: "node",
|
|
293
|
+
esModuleInterop: true,
|
|
294
|
+
allowJs: true,
|
|
295
|
+
allowSyntheticDefaultImports: true,
|
|
296
|
+
isolatedModules: true,
|
|
297
|
+
noEmit: true,
|
|
298
|
+
lib: ["esnext"],
|
|
299
|
+
jsx: "react",
|
|
300
|
+
resolveJsonModule: true,
|
|
247
301
|
types: ["@cloudflare/workers-types"],
|
|
248
302
|
},
|
|
249
303
|
},
|
|
@@ -266,7 +320,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
266
320
|
);
|
|
267
321
|
|
|
268
322
|
// build
|
|
269
|
-
|
|
323
|
+
wrangler.command(
|
|
270
324
|
"build",
|
|
271
325
|
false,
|
|
272
326
|
(yargs) => {
|
|
@@ -276,14 +330,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
276
330
|
},
|
|
277
331
|
() => {
|
|
278
332
|
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
279
|
-
|
|
333
|
+
throw new DeprecationError(
|
|
280
334
|
"`wrangler build` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
281
335
|
);
|
|
282
336
|
}
|
|
283
337
|
);
|
|
284
338
|
|
|
285
339
|
// login
|
|
286
|
-
|
|
340
|
+
wrangler.command(
|
|
287
341
|
// this needs scopes as an option?
|
|
288
342
|
"login",
|
|
289
343
|
false, // we don't need to show this in the menu
|
|
@@ -320,13 +374,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
320
374
|
await login();
|
|
321
375
|
|
|
322
376
|
// TODO: would be nice if it optionally saved login
|
|
323
|
-
//
|
|
377
|
+
// credentials inside node_modules/.cache or something
|
|
324
378
|
// this way you could have multiple users on a single machine
|
|
325
379
|
}
|
|
326
380
|
);
|
|
327
381
|
|
|
328
382
|
// logout
|
|
329
|
-
|
|
383
|
+
wrangler.command(
|
|
330
384
|
// this needs scopes as an option?
|
|
331
385
|
"logout",
|
|
332
386
|
false, // we don't need to show this in the menu
|
|
@@ -338,7 +392,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
338
392
|
);
|
|
339
393
|
|
|
340
394
|
// whoami
|
|
341
|
-
|
|
395
|
+
wrangler.command(
|
|
342
396
|
"whoami",
|
|
343
397
|
false, // we don't need to show this the menu
|
|
344
398
|
// "🕵️ Retrieve your user info and test your auth config",
|
|
@@ -349,20 +403,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
349
403
|
);
|
|
350
404
|
|
|
351
405
|
// config
|
|
352
|
-
|
|
406
|
+
wrangler.command(
|
|
353
407
|
"config",
|
|
354
408
|
false,
|
|
355
409
|
() => {},
|
|
356
410
|
() => {
|
|
357
411
|
// "🕵️ Authenticate Wrangler with a Cloudflare API Token",
|
|
358
|
-
|
|
412
|
+
throw new DeprecationError(
|
|
359
413
|
"`wrangler config` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
360
414
|
);
|
|
361
415
|
}
|
|
362
416
|
);
|
|
363
417
|
|
|
364
418
|
// dev
|
|
365
|
-
|
|
419
|
+
wrangler.command(
|
|
366
420
|
"dev <filename>",
|
|
367
421
|
"👂 Start a local server for developing your worker",
|
|
368
422
|
(yargs) => {
|
|
@@ -381,6 +435,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
381
435
|
type: "string",
|
|
382
436
|
// TODO: get choices for the toml file?
|
|
383
437
|
})
|
|
438
|
+
.option("compatibility-date", {
|
|
439
|
+
describe: "Date to use for compatibility checks",
|
|
440
|
+
type: "string",
|
|
441
|
+
})
|
|
442
|
+
.option("compatibility-flags", {
|
|
443
|
+
describe: "Flags to use for compatibility checks",
|
|
444
|
+
type: "array",
|
|
445
|
+
alias: "compatibility-flag",
|
|
446
|
+
})
|
|
447
|
+
.option("latest", {
|
|
448
|
+
describe: "Use the latest version of the worker runtime",
|
|
449
|
+
type: "boolean",
|
|
450
|
+
default: true,
|
|
451
|
+
})
|
|
384
452
|
.option("ip", {
|
|
385
453
|
describe: "IP address to listen on",
|
|
386
454
|
type: "string",
|
|
@@ -401,7 +469,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
401
469
|
describe: "Protocol to listen to requests on, defaults to http.",
|
|
402
470
|
choices: ["http", "https"],
|
|
403
471
|
})
|
|
404
|
-
.option("public", {
|
|
472
|
+
.option("experimental-public", {
|
|
405
473
|
describe: "Static assets to be served",
|
|
406
474
|
type: "string",
|
|
407
475
|
})
|
|
@@ -422,16 +490,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
422
490
|
.option("jsx-fragment", {
|
|
423
491
|
describe: "The function that is called for each JSX fragment",
|
|
424
492
|
type: "string",
|
|
425
|
-
})
|
|
426
|
-
.option("polyfill-node", {
|
|
427
|
-
describe: "Try to polyfill node builtins",
|
|
428
|
-
type: "boolean",
|
|
429
493
|
});
|
|
430
494
|
},
|
|
431
495
|
async (args) => {
|
|
432
496
|
const { filename, format } = args;
|
|
433
497
|
const config = args.config as Config;
|
|
434
498
|
|
|
499
|
+
if (args["experimental-public"]) {
|
|
500
|
+
console.warn(
|
|
501
|
+
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (args.public) {
|
|
506
|
+
throw new Error(
|
|
507
|
+
"🚨 The --public field has been renamed to --experimental-public, and will change behaviour in the future."
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
435
511
|
// -- snip, extract --
|
|
436
512
|
|
|
437
513
|
if (!args.local) {
|
|
@@ -444,8 +520,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
444
520
|
if (!config.account_id) {
|
|
445
521
|
config.account_id = await getAccountId();
|
|
446
522
|
if (!config.account_id) {
|
|
447
|
-
|
|
448
|
-
return;
|
|
523
|
+
throw new Error("No account id found, quitting...");
|
|
449
524
|
}
|
|
450
525
|
}
|
|
451
526
|
}
|
|
@@ -454,17 +529,22 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
454
529
|
|
|
455
530
|
const envRootObj = args.env ? config.env[args.env] || {} : config;
|
|
456
531
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
532
|
+
// TODO: this error shouldn't actually happen,
|
|
533
|
+
// but we haven't fixed it internally yet
|
|
534
|
+
if ("durable_objects" in envRootObj) {
|
|
535
|
+
if (!(args.name || config.name)) {
|
|
536
|
+
console.warn(
|
|
537
|
+
'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.'
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
// TODO: if not already published, publish a draft worker
|
|
462
541
|
}
|
|
463
542
|
|
|
464
|
-
render(
|
|
543
|
+
const { waitUntilExit } = render(
|
|
465
544
|
<Dev
|
|
466
545
|
name={args.name || config.name}
|
|
467
|
-
entry={filename}
|
|
546
|
+
entry={path.relative(process.cwd(), filename)}
|
|
547
|
+
buildCommand={config.build || {}}
|
|
468
548
|
format={format}
|
|
469
549
|
initialMode={args.local ? "local" : "remote"}
|
|
470
550
|
jsxFactory={args["jsx-factory"] || envRootObj?.jsx_factory}
|
|
@@ -472,40 +552,51 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
472
552
|
accountId={config.account_id}
|
|
473
553
|
site={args.site || config.site?.bucket}
|
|
474
554
|
port={args.port || config.dev?.port}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
555
|
+
public={args["experimental-public"]}
|
|
556
|
+
compatibilityDate={
|
|
557
|
+
args["compatibility-date"] ||
|
|
558
|
+
config.compatibility_date ||
|
|
559
|
+
new Date().toISOString().substring(0, 10)
|
|
560
|
+
}
|
|
561
|
+
compatibilityFlags={
|
|
562
|
+
(args["compatibility-flags"] as string[]) ||
|
|
563
|
+
config.compatibility_flags
|
|
564
|
+
}
|
|
479
565
|
usageModel={config.usage_model}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
566
|
+
bindings={{
|
|
567
|
+
kv_namespaces: envRootObj.kv_namespaces?.map(
|
|
568
|
+
({ binding, preview_id, id: _id }) => {
|
|
569
|
+
// In `dev`, we make folks use a separate kv namespace called
|
|
570
|
+
// `preview_id` instead of `id` so that they don't
|
|
571
|
+
// break production data. So here we check that a `preview_id`
|
|
572
|
+
// has actually been configured.
|
|
573
|
+
// This whole block of code will be obsoleted in the future
|
|
574
|
+
// when we have copy-on-write for previews on edge workers.
|
|
484
575
|
if (!preview_id) {
|
|
485
576
|
// TODO: This error has to be a _lot_ better, ideally just asking
|
|
486
577
|
// to create a preview namespace for the user automatically
|
|
487
578
|
throw new Error(
|
|
488
|
-
|
|
489
|
-
);
|
|
579
|
+
`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`
|
|
580
|
+
); // Ugh, I really don't like this message very much
|
|
490
581
|
}
|
|
491
|
-
return {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
(obj, { name, class_name, script_name }) => {
|
|
497
|
-
return { ...obj, [name]: { class_name, script_name } };
|
|
498
|
-
},
|
|
499
|
-
{}
|
|
582
|
+
return {
|
|
583
|
+
binding,
|
|
584
|
+
id: preview_id,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
500
587
|
),
|
|
588
|
+
vars: envRootObj.vars,
|
|
589
|
+
durable_objects: envRootObj.durable_objects,
|
|
590
|
+
services: envRootObj.experimental_services,
|
|
501
591
|
}}
|
|
502
592
|
/>
|
|
503
593
|
);
|
|
594
|
+
await waitUntilExit();
|
|
504
595
|
}
|
|
505
596
|
);
|
|
506
597
|
|
|
507
598
|
// publish
|
|
508
|
-
|
|
599
|
+
wrangler.command(
|
|
509
600
|
"publish [script]",
|
|
510
601
|
"🆙 Publish your Worker to Cloudflare.",
|
|
511
602
|
(yargs) => {
|
|
@@ -522,7 +613,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
522
613
|
describe: "name to use when uploading",
|
|
523
614
|
type: "string",
|
|
524
615
|
})
|
|
525
|
-
.option("
|
|
616
|
+
.option("compatibility-date", {
|
|
617
|
+
describe: "Date to use for compatibility checks",
|
|
618
|
+
type: "string",
|
|
619
|
+
})
|
|
620
|
+
.option("compatibility-flags", {
|
|
621
|
+
describe: "Flags to use for compatibility checks",
|
|
622
|
+
type: "array",
|
|
623
|
+
alias: "compatibility-flag",
|
|
624
|
+
})
|
|
625
|
+
.option("latest", {
|
|
626
|
+
describe: "Use the latest version of the worker runtime",
|
|
627
|
+
type: "boolean",
|
|
628
|
+
default: false,
|
|
629
|
+
})
|
|
630
|
+
.option("experimental-public", {
|
|
526
631
|
describe: "Static assets to be served",
|
|
527
632
|
type: "string",
|
|
528
633
|
})
|
|
@@ -553,19 +658,34 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
553
658
|
.option("jsx-fragment", {
|
|
554
659
|
describe: "The function that is called for each JSX fragment",
|
|
555
660
|
type: "string",
|
|
556
|
-
})
|
|
557
|
-
.option("polyfill-node", {
|
|
558
|
-
describe: "Try to polyfill node builtins",
|
|
559
|
-
type: "boolean",
|
|
560
661
|
});
|
|
561
662
|
},
|
|
562
663
|
async (args) => {
|
|
563
664
|
if (args.local) {
|
|
564
|
-
|
|
565
|
-
|
|
665
|
+
throw new NotImplementedError(
|
|
666
|
+
"🚫 Local publishing is not yet supported"
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (args["experimental-public"]) {
|
|
671
|
+
console.warn(
|
|
672
|
+
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
if (args.public) {
|
|
676
|
+
throw new Error(
|
|
677
|
+
"🚨 The --public field has been renamed to --experimental-public, and will change behaviour in the future."
|
|
678
|
+
);
|
|
566
679
|
}
|
|
680
|
+
|
|
567
681
|
const config = args.config as Config;
|
|
568
682
|
|
|
683
|
+
if (args.latest) {
|
|
684
|
+
console.warn(
|
|
685
|
+
"⚠️ 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"
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
|
|
569
689
|
// -- snip, extract --
|
|
570
690
|
if (!args.local) {
|
|
571
691
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
@@ -577,39 +697,34 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
577
697
|
if (!config.account_id) {
|
|
578
698
|
config.account_id = await getAccountId();
|
|
579
699
|
if (!config.account_id) {
|
|
580
|
-
|
|
581
|
-
return;
|
|
700
|
+
throw new Error("No account id found, quitting...");
|
|
582
701
|
}
|
|
583
702
|
}
|
|
584
703
|
}
|
|
585
704
|
|
|
586
705
|
// -- snip, end --
|
|
587
706
|
|
|
588
|
-
const polyfillNode = args["polyfill-node"] ?? config.polyfill_node;
|
|
589
|
-
if (polyfillNode) {
|
|
590
|
-
console.warn(
|
|
591
|
-
"Using polyfills for node builtin modules. These are not meant to be completely reliable, and have serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
|
|
592
|
-
);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
707
|
await publish({
|
|
596
708
|
config: args.config as Config,
|
|
597
709
|
name: args.name,
|
|
598
710
|
script: args.script,
|
|
599
711
|
env: args.env,
|
|
712
|
+
compatibilityDate: args.latest
|
|
713
|
+
? new Date().toISOString().substring(0, 10)
|
|
714
|
+
: args["compatibility-date"],
|
|
715
|
+
compatibilityFlags: args["compatibility-flags"] as string[],
|
|
600
716
|
triggers: args.triggers,
|
|
601
717
|
jsxFactory: args["jsx-factory"],
|
|
602
718
|
jsxFragment: args["jsx-fragment"],
|
|
603
|
-
polyfillNode: args["polyfill-node"],
|
|
604
719
|
routes: args.routes,
|
|
605
|
-
public: args
|
|
720
|
+
public: args["experimental-public"],
|
|
606
721
|
site: args.site,
|
|
607
722
|
});
|
|
608
723
|
}
|
|
609
724
|
);
|
|
610
725
|
|
|
611
726
|
// tail
|
|
612
|
-
|
|
727
|
+
wrangler.command(
|
|
613
728
|
"tail [name]",
|
|
614
729
|
"🦚 Starts a log tailing session for a deployed Worker.",
|
|
615
730
|
(yargs) => {
|
|
@@ -656,8 +771,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
656
771
|
const config = args.config as Config;
|
|
657
772
|
|
|
658
773
|
if (!(args.name || config.name)) {
|
|
659
|
-
|
|
660
|
-
return;
|
|
774
|
+
throw new Error("Missing script name");
|
|
661
775
|
}
|
|
662
776
|
const scriptName = `${args.name || config.name}${
|
|
663
777
|
args.env ? `-${args.env}` : ""
|
|
@@ -675,8 +789,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
675
789
|
if (!config.account_id) {
|
|
676
790
|
config.account_id = await getAccountId();
|
|
677
791
|
if (!config.account_id) {
|
|
678
|
-
|
|
679
|
-
return;
|
|
792
|
+
throw new Error("No account id found, quitting...");
|
|
680
793
|
}
|
|
681
794
|
}
|
|
682
795
|
}
|
|
@@ -700,9 +813,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
700
813
|
`successfully created tail, expires at ${expiration.toLocaleString()}`
|
|
701
814
|
);
|
|
702
815
|
|
|
703
|
-
onExit(() => {
|
|
816
|
+
onExit(async () => {
|
|
704
817
|
tail.terminate();
|
|
705
|
-
deleteTail();
|
|
818
|
+
await deleteTail();
|
|
706
819
|
});
|
|
707
820
|
|
|
708
821
|
tail.on("message", (data) => {
|
|
@@ -727,7 +840,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
727
840
|
);
|
|
728
841
|
|
|
729
842
|
// preview
|
|
730
|
-
|
|
843
|
+
wrangler.command(
|
|
731
844
|
"preview [method] [body]",
|
|
732
845
|
false,
|
|
733
846
|
(yargs) => {
|
|
@@ -753,20 +866,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
753
866
|
});
|
|
754
867
|
},
|
|
755
868
|
() => {
|
|
756
|
-
// "🔬 [DEPRECATED] Preview your code temporarily on cloudflareworkers.com"
|
|
757
|
-
|
|
869
|
+
// "🔬 [DEPRECATED] Preview your code temporarily on https://cloudflareworkers.com"
|
|
870
|
+
throw new DeprecationError(
|
|
758
871
|
"`wrangler preview` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
759
872
|
);
|
|
760
873
|
}
|
|
761
874
|
);
|
|
762
875
|
|
|
763
876
|
// route
|
|
764
|
-
|
|
877
|
+
wrangler.command(
|
|
765
878
|
"route",
|
|
766
879
|
false, // I think we want to hide this command
|
|
767
880
|
// "➡️ List or delete worker routes",
|
|
768
|
-
(
|
|
769
|
-
return
|
|
881
|
+
(routeYargs) => {
|
|
882
|
+
return routeYargs
|
|
770
883
|
.command(
|
|
771
884
|
"list",
|
|
772
885
|
"List a route associated with a zone",
|
|
@@ -790,11 +903,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
790
903
|
// TODO: use environment (current wrangler doesn't do so?)
|
|
791
904
|
const zone = args.zone || (args.config as Config).zone_id;
|
|
792
905
|
if (!zone) {
|
|
793
|
-
|
|
794
|
-
return;
|
|
906
|
+
throw new Error("missing zone id");
|
|
795
907
|
}
|
|
796
908
|
|
|
797
|
-
console.log(await
|
|
909
|
+
console.log(await fetchResult(`/zones/${zone}/workers/routes`));
|
|
798
910
|
}
|
|
799
911
|
)
|
|
800
912
|
.command(
|
|
@@ -824,7 +936,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
824
936
|
}
|
|
825
937
|
|
|
826
938
|
console.log(
|
|
827
|
-
await
|
|
939
|
+
await fetchResult(`/zones/${zone}/workers/routes/${args.id}`, {
|
|
828
940
|
method: "DELETE",
|
|
829
941
|
})
|
|
830
942
|
);
|
|
@@ -834,7 +946,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
834
946
|
);
|
|
835
947
|
|
|
836
948
|
// subdomain
|
|
837
|
-
|
|
949
|
+
wrangler.command(
|
|
838
950
|
"subdomain [name]",
|
|
839
951
|
false,
|
|
840
952
|
// "👷 Create or change your workers.dev subdomain.",
|
|
@@ -842,18 +954,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
842
954
|
return yargs.positional("name", { type: "string" });
|
|
843
955
|
},
|
|
844
956
|
() => {
|
|
845
|
-
|
|
957
|
+
throw new DeprecationError(
|
|
846
958
|
"`wrangler subdomain` has been deprecated, please refer to TODO://some/path for alternatives"
|
|
847
959
|
);
|
|
848
960
|
}
|
|
849
961
|
);
|
|
850
962
|
|
|
851
963
|
// secret
|
|
852
|
-
|
|
964
|
+
wrangler.command(
|
|
853
965
|
"secret",
|
|
854
966
|
"🤫 Generate a secret that can be referenced in the worker script",
|
|
855
|
-
(
|
|
856
|
-
return
|
|
967
|
+
(secretYargs) => {
|
|
968
|
+
return secretYargs
|
|
857
969
|
.command(
|
|
858
970
|
"put <key>",
|
|
859
971
|
"Create or update a secret variable for a script",
|
|
@@ -875,16 +987,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
875
987
|
},
|
|
876
988
|
async (args) => {
|
|
877
989
|
if (args.local) {
|
|
878
|
-
|
|
879
|
-
|
|
990
|
+
throw new NotImplementedError(
|
|
991
|
+
"--local not implemented for this command yet"
|
|
992
|
+
);
|
|
880
993
|
}
|
|
881
994
|
const config = args.config as Config;
|
|
882
995
|
|
|
883
996
|
// TODO: use environment (how does current wrangler do it?)
|
|
884
997
|
const scriptName = args.name || config.name;
|
|
885
998
|
if (!scriptName) {
|
|
886
|
-
|
|
887
|
-
return;
|
|
999
|
+
throw new Error("Missing script name");
|
|
888
1000
|
}
|
|
889
1001
|
|
|
890
1002
|
// -- snip, extract --
|
|
@@ -899,8 +1011,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
899
1011
|
if (!config.account_id) {
|
|
900
1012
|
config.account_id = await getAccountId();
|
|
901
1013
|
if (!config.account_id) {
|
|
902
|
-
|
|
903
|
-
return;
|
|
1014
|
+
throw new Error("No account id found, quitting...");
|
|
904
1015
|
}
|
|
905
1016
|
}
|
|
906
1017
|
}
|
|
@@ -912,7 +1023,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
912
1023
|
"password"
|
|
913
1024
|
);
|
|
914
1025
|
async function submitSecret() {
|
|
915
|
-
return await
|
|
1026
|
+
return await fetchResult(
|
|
916
1027
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/`,
|
|
917
1028
|
{
|
|
918
1029
|
method: "PUT",
|
|
@@ -931,7 +1042,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
931
1042
|
} catch (e) {
|
|
932
1043
|
if (e.code === 10007) {
|
|
933
1044
|
// upload a draft worker
|
|
934
|
-
await
|
|
1045
|
+
await fetchResult(
|
|
935
1046
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}`,
|
|
936
1047
|
{
|
|
937
1048
|
method: "PUT",
|
|
@@ -942,7 +1053,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
942
1053
|
content: `export default { fetch() {} }`,
|
|
943
1054
|
type: "esm",
|
|
944
1055
|
},
|
|
945
|
-
|
|
1056
|
+
bindings: {
|
|
1057
|
+
kv_namespaces: [],
|
|
1058
|
+
vars: {},
|
|
1059
|
+
durable_objects: { bindings: [] },
|
|
1060
|
+
},
|
|
946
1061
|
modules: [],
|
|
947
1062
|
}),
|
|
948
1063
|
}
|
|
@@ -976,8 +1091,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
976
1091
|
},
|
|
977
1092
|
async (args) => {
|
|
978
1093
|
if (args.local) {
|
|
979
|
-
|
|
980
|
-
|
|
1094
|
+
throw new NotImplementedError(
|
|
1095
|
+
"--local not implemented for this command yet"
|
|
1096
|
+
);
|
|
981
1097
|
}
|
|
982
1098
|
const config = args.config as Config;
|
|
983
1099
|
|
|
@@ -999,8 +1115,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
999
1115
|
if (!config.account_id) {
|
|
1000
1116
|
config.account_id = await getAccountId();
|
|
1001
1117
|
if (!config.account_id) {
|
|
1002
|
-
|
|
1003
|
-
return;
|
|
1118
|
+
throw new Error("No account id found, quitting...");
|
|
1004
1119
|
}
|
|
1005
1120
|
}
|
|
1006
1121
|
}
|
|
@@ -1013,7 +1128,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1013
1128
|
);
|
|
1014
1129
|
|
|
1015
1130
|
console.log(
|
|
1016
|
-
await
|
|
1131
|
+
await fetchResult(
|
|
1017
1132
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/${args.key}`,
|
|
1018
1133
|
{ method: "DELETE" }
|
|
1019
1134
|
)
|
|
@@ -1038,16 +1153,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1038
1153
|
},
|
|
1039
1154
|
async (args) => {
|
|
1040
1155
|
if (args.local) {
|
|
1041
|
-
|
|
1042
|
-
|
|
1156
|
+
throw new NotImplementedError(
|
|
1157
|
+
"--local not implemented for this command yet"
|
|
1158
|
+
);
|
|
1043
1159
|
}
|
|
1044
1160
|
const config = args.config as Config;
|
|
1045
1161
|
|
|
1046
1162
|
// TODO: use environment (how does current wrangler do it?)
|
|
1047
1163
|
const scriptName = args.name || config.name;
|
|
1048
1164
|
if (!scriptName) {
|
|
1049
|
-
|
|
1050
|
-
return;
|
|
1165
|
+
throw new Error("Missing script name");
|
|
1051
1166
|
}
|
|
1052
1167
|
|
|
1053
1168
|
// -- snip, extract --
|
|
@@ -1062,8 +1177,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1062
1177
|
if (!config.account_id) {
|
|
1063
1178
|
config.account_id = await getAccountId();
|
|
1064
1179
|
if (!config.account_id) {
|
|
1065
|
-
|
|
1066
|
-
return;
|
|
1180
|
+
throw new Error("No account id found, quitting...");
|
|
1067
1181
|
}
|
|
1068
1182
|
}
|
|
1069
1183
|
}
|
|
@@ -1071,7 +1185,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1071
1185
|
// -- snip, end --
|
|
1072
1186
|
|
|
1073
1187
|
console.log(
|
|
1074
|
-
await
|
|
1188
|
+
await fetchResult(
|
|
1075
1189
|
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1076
1190
|
)
|
|
1077
1191
|
);
|
|
@@ -1082,11 +1196,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1082
1196
|
|
|
1083
1197
|
// kv
|
|
1084
1198
|
// :namespace
|
|
1085
|
-
|
|
1199
|
+
wrangler.command(
|
|
1086
1200
|
"kv:namespace",
|
|
1087
1201
|
"🗂️ Interact with your Workers KV Namespaces",
|
|
1088
|
-
(
|
|
1089
|
-
return
|
|
1202
|
+
(namespaceYargs) => {
|
|
1203
|
+
return namespaceYargs
|
|
1090
1204
|
.command(
|
|
1091
1205
|
"create <namespace>",
|
|
1092
1206
|
"Create a new namespace",
|
|
@@ -1106,13 +1220,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1106
1220
|
});
|
|
1107
1221
|
},
|
|
1108
1222
|
async (args) => {
|
|
1109
|
-
if (args._.length
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
} ${args._.slice(2).join(" ")}"?`
|
|
1223
|
+
if (args._.length > 2) {
|
|
1224
|
+
const extraArgs = args._.slice(2).join(" ");
|
|
1225
|
+
throw new CommandLineArgsError(
|
|
1226
|
+
`Unexpected additional positional arguments "${extraArgs}".`
|
|
1114
1227
|
);
|
|
1115
1228
|
}
|
|
1229
|
+
|
|
1230
|
+
if (!isValidNamespaceBinding(args.namespace)) {
|
|
1231
|
+
throw new CommandLineArgsError(
|
|
1232
|
+
`The namespace binding name "${args.namespace}" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.`
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1116
1236
|
const config = args.config as Config;
|
|
1117
1237
|
if (!config.name) {
|
|
1118
1238
|
console.warn(
|
|
@@ -1120,13 +1240,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1120
1240
|
);
|
|
1121
1241
|
}
|
|
1122
1242
|
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
if (/[\W]+/.test(args.namespace)) {
|
|
1128
|
-
throw new Error("invalid binding name, needs to be js friendly");
|
|
1129
|
-
}
|
|
1243
|
+
const name = config.name || "worker";
|
|
1244
|
+
const environment = args.env ? `-${args.env}` : "";
|
|
1245
|
+
const preview = args.preview ? "_preview" : "";
|
|
1246
|
+
const title = `${name}${environment}-${args.namespace}${preview}`;
|
|
1130
1247
|
|
|
1131
1248
|
if (args.local) {
|
|
1132
1249
|
const { Miniflare } = await import("miniflare");
|
|
@@ -1135,7 +1252,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1135
1252
|
// TODO: these options shouldn't be required
|
|
1136
1253
|
script: ` `, // has to be a string with at least one char
|
|
1137
1254
|
});
|
|
1138
|
-
mf.getKVNamespace(title); // this should "create" the namespace
|
|
1255
|
+
await mf.getKVNamespace(title); // this should "create" the namespace
|
|
1139
1256
|
console.log(`✨ Success! Created KV namespace ${title}`);
|
|
1140
1257
|
return;
|
|
1141
1258
|
}
|
|
@@ -1152,8 +1269,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1152
1269
|
if (!config.account_id) {
|
|
1153
1270
|
config.account_id = await getAccountId();
|
|
1154
1271
|
if (!config.account_id) {
|
|
1155
|
-
|
|
1156
|
-
return;
|
|
1272
|
+
throw new Error("No account id found, quitting...");
|
|
1157
1273
|
}
|
|
1158
1274
|
}
|
|
1159
1275
|
}
|
|
@@ -1163,31 +1279,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1163
1279
|
// TODO: generate a binding name stripping non alphanumeric chars
|
|
1164
1280
|
|
|
1165
1281
|
console.log(`🌀 Creating namespace with title "${title}"`);
|
|
1166
|
-
|
|
1167
|
-
const response = await cfetch<{ id: string }>(
|
|
1168
|
-
`/accounts/${config.account_id}/storage/kv/namespaces`,
|
|
1169
|
-
{
|
|
1170
|
-
method: "POST",
|
|
1171
|
-
headers: {
|
|
1172
|
-
"Content-Type": "application/json",
|
|
1173
|
-
},
|
|
1174
|
-
body: JSON.stringify({
|
|
1175
|
-
title,
|
|
1176
|
-
}),
|
|
1177
|
-
}
|
|
1178
|
-
);
|
|
1282
|
+
const namespaceId = await createNamespace(config.account_id, title);
|
|
1179
1283
|
|
|
1180
1284
|
console.log("✨ Success!");
|
|
1285
|
+
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
1286
|
+
const previewString = args.preview ? "preview_" : "";
|
|
1181
1287
|
console.log(
|
|
1182
|
-
`Add the following to your configuration file in your kv_namespaces array${
|
|
1183
|
-
args.env ? ` under [env.${args.env}]` : ""
|
|
1184
|
-
}:`
|
|
1288
|
+
`Add the following to your configuration file in your kv_namespaces array${envString}:`
|
|
1185
1289
|
);
|
|
1186
1290
|
console.log(
|
|
1187
|
-
`{ binding = "${args.namespace}", ${
|
|
1188
|
-
args.preview ? "preview_" : ""
|
|
1189
|
-
}id = "${response.id}" }`
|
|
1291
|
+
`{ binding = "${args.namespace}", ${previewString}id = "${namespaceId}" }`
|
|
1190
1292
|
);
|
|
1293
|
+
|
|
1294
|
+
// TODO: automatically write this block to the wrangler.toml config file??
|
|
1191
1295
|
}
|
|
1192
1296
|
)
|
|
1193
1297
|
.command(
|
|
@@ -1196,8 +1300,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1196
1300
|
{},
|
|
1197
1301
|
async (args) => {
|
|
1198
1302
|
if (args.local) {
|
|
1199
|
-
|
|
1200
|
-
|
|
1303
|
+
throw new NotImplementedError(
|
|
1304
|
+
`local mode is not yet supported for this command`
|
|
1305
|
+
);
|
|
1201
1306
|
}
|
|
1202
1307
|
|
|
1203
1308
|
const config = args.config as Config;
|
|
@@ -1214,8 +1319,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1214
1319
|
if (!config.account_id) {
|
|
1215
1320
|
config.account_id = await getAccountId();
|
|
1216
1321
|
if (!config.account_id) {
|
|
1217
|
-
|
|
1218
|
-
return;
|
|
1322
|
+
throw new Error("No account id found, quitting...");
|
|
1219
1323
|
}
|
|
1220
1324
|
}
|
|
1221
1325
|
}
|
|
@@ -1258,21 +1362,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1258
1362
|
},
|
|
1259
1363
|
async (args) => {
|
|
1260
1364
|
if (args.local) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1365
|
+
throw new NotImplementedError(
|
|
1366
|
+
`local mode is not yet supported for this command`
|
|
1367
|
+
);
|
|
1263
1368
|
}
|
|
1264
1369
|
const config = args.config as Config;
|
|
1265
1370
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
(args
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
)[args.preview ? "preview_id" : "id"];
|
|
1274
|
-
if (!id) {
|
|
1275
|
-
throw new Error("Are you sure? id not found");
|
|
1371
|
+
let id;
|
|
1372
|
+
try {
|
|
1373
|
+
id = getNamespaceId(args);
|
|
1374
|
+
} catch (e) {
|
|
1375
|
+
throw new CommandLineArgsError(
|
|
1376
|
+
"Not able to delete namespace.\n" + e.message
|
|
1377
|
+
);
|
|
1276
1378
|
}
|
|
1277
1379
|
|
|
1278
1380
|
// -- snip, extract --
|
|
@@ -1288,15 +1390,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1288
1390
|
if (!config.account_id) {
|
|
1289
1391
|
config.account_id = await getAccountId();
|
|
1290
1392
|
if (!config.account_id) {
|
|
1291
|
-
|
|
1292
|
-
return;
|
|
1393
|
+
throw new Error("No account id found, quitting...");
|
|
1293
1394
|
}
|
|
1294
1395
|
}
|
|
1295
1396
|
}
|
|
1296
1397
|
|
|
1297
1398
|
// -- snip, end --
|
|
1298
1399
|
|
|
1299
|
-
await
|
|
1400
|
+
await fetchResult<{ id: string }>(
|
|
1300
1401
|
`/accounts/${config.account_id}/storage/kv/namespaces/${id}`,
|
|
1301
1402
|
{ method: "DELETE" }
|
|
1302
1403
|
);
|
|
@@ -1324,13 +1425,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1324
1425
|
);
|
|
1325
1426
|
|
|
1326
1427
|
// :key
|
|
1327
|
-
|
|
1428
|
+
wrangler.command(
|
|
1328
1429
|
"kv:key",
|
|
1329
1430
|
"🔑 Individually manage Workers KV key-value pairs",
|
|
1330
|
-
(
|
|
1331
|
-
return
|
|
1431
|
+
(kvKeyYargs) => {
|
|
1432
|
+
return kvKeyYargs
|
|
1332
1433
|
.command(
|
|
1333
|
-
"put <key>
|
|
1434
|
+
"put <key> [value]",
|
|
1334
1435
|
"Writes a single key/value pair to the given namespace.",
|
|
1335
1436
|
(yargs) => {
|
|
1336
1437
|
return yargs
|
|
@@ -1371,7 +1472,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1371
1472
|
.option("path", {
|
|
1372
1473
|
type: "string",
|
|
1373
1474
|
describe: "Read value from the file at a given path.",
|
|
1374
|
-
})
|
|
1475
|
+
})
|
|
1476
|
+
.check(demandOneOfOption("value", "path"));
|
|
1375
1477
|
},
|
|
1376
1478
|
async ({ key, ttl, expiration, ...args }) => {
|
|
1377
1479
|
const namespaceId = getNamespaceId(args);
|
|
@@ -1380,7 +1482,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1380
1482
|
: args.value;
|
|
1381
1483
|
const config = args.config as Config;
|
|
1382
1484
|
|
|
1383
|
-
|
|
1485
|
+
if (args.path) {
|
|
1486
|
+
console.log(
|
|
1487
|
+
`writing the contents of ${args.path} to the key "${key}" on namespace ${namespaceId}`
|
|
1488
|
+
);
|
|
1489
|
+
} else {
|
|
1490
|
+
console.log(
|
|
1491
|
+
`writing the value "${value}" to key "${key}" on namespace ${namespaceId}`
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1384
1495
|
if (args.local) {
|
|
1385
1496
|
const { Miniflare } = await import("miniflare");
|
|
1386
1497
|
const mf = new Miniflare({
|
|
@@ -1405,8 +1516,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1405
1516
|
if (!config.account_id) {
|
|
1406
1517
|
config.account_id = await getAccountId();
|
|
1407
1518
|
if (!config.account_id) {
|
|
1408
|
-
|
|
1409
|
-
return;
|
|
1519
|
+
throw new Error("No account id found, quitting...");
|
|
1410
1520
|
}
|
|
1411
1521
|
}
|
|
1412
1522
|
}
|
|
@@ -1437,6 +1547,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1437
1547
|
type: "string",
|
|
1438
1548
|
describe: "Perform on a specific environment",
|
|
1439
1549
|
})
|
|
1550
|
+
.option("preview", {
|
|
1551
|
+
type: "boolean",
|
|
1552
|
+
// In the case of listing keys we will default to non-preview mode
|
|
1553
|
+
default: false,
|
|
1554
|
+
describe: "Interact with a preview namespace",
|
|
1555
|
+
})
|
|
1440
1556
|
.option("prefix", {
|
|
1441
1557
|
type: "string",
|
|
1442
1558
|
describe: "A prefix to filter listed keys",
|
|
@@ -1474,8 +1590,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1474
1590
|
if (!config.account_id) {
|
|
1475
1591
|
config.account_id = await getAccountId();
|
|
1476
1592
|
if (!config.account_id) {
|
|
1477
|
-
|
|
1478
|
-
return;
|
|
1593
|
+
throw new Error("No account id found, quitting...");
|
|
1479
1594
|
}
|
|
1480
1595
|
}
|
|
1481
1596
|
}
|
|
@@ -1512,6 +1627,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1512
1627
|
.option("preview", {
|
|
1513
1628
|
type: "boolean",
|
|
1514
1629
|
describe: "Interact with a preview namespace",
|
|
1630
|
+
})
|
|
1631
|
+
.option("preview", {
|
|
1632
|
+
type: "boolean",
|
|
1633
|
+
// In the case of getting key values we will default to non-preview mode
|
|
1634
|
+
default: false,
|
|
1635
|
+
describe: "Interact with a preview namespace",
|
|
1515
1636
|
});
|
|
1516
1637
|
},
|
|
1517
1638
|
async ({ key, ...args }) => {
|
|
@@ -1543,20 +1664,15 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1543
1664
|
if (!config.account_id) {
|
|
1544
1665
|
config.account_id = await getAccountId();
|
|
1545
1666
|
if (!config.account_id) {
|
|
1546
|
-
|
|
1547
|
-
return;
|
|
1667
|
+
throw new Error("No account id found, quitting...");
|
|
1548
1668
|
}
|
|
1549
1669
|
}
|
|
1550
1670
|
}
|
|
1551
1671
|
|
|
1552
1672
|
// -- snip, end --
|
|
1553
1673
|
|
|
1554
|
-
// annoyingly, the API for this one doesn't return the
|
|
1555
|
-
// data in the 'standard' format. goddamit.
|
|
1556
|
-
// That's why we have the fallthrough response in cfetch.
|
|
1557
|
-
// Oh well.
|
|
1558
1674
|
console.log(
|
|
1559
|
-
await
|
|
1675
|
+
await fetchRaw(
|
|
1560
1676
|
`/accounts/${config.account_id}/storage/kv/namespaces/${namespaceId}/values/${key}`
|
|
1561
1677
|
)
|
|
1562
1678
|
);
|
|
@@ -1592,6 +1708,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1592
1708
|
async ({ key, ...args }) => {
|
|
1593
1709
|
const namespaceId = getNamespaceId(args);
|
|
1594
1710
|
|
|
1711
|
+
console.log(
|
|
1712
|
+
`deleting the key "${key}" on namespace ${namespaceId}`
|
|
1713
|
+
);
|
|
1714
|
+
|
|
1595
1715
|
if (args.local) {
|
|
1596
1716
|
const { Miniflare } = await import("miniflare");
|
|
1597
1717
|
const mf = new Miniflare({
|
|
@@ -1619,15 +1739,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1619
1739
|
if (!config.account_id) {
|
|
1620
1740
|
config.account_id = await getAccountId();
|
|
1621
1741
|
if (!config.account_id) {
|
|
1622
|
-
|
|
1623
|
-
return;
|
|
1742
|
+
throw new Error("No account id found, quitting...");
|
|
1624
1743
|
}
|
|
1625
1744
|
}
|
|
1626
1745
|
}
|
|
1627
1746
|
|
|
1628
1747
|
// -- snip, end --
|
|
1629
1748
|
|
|
1630
|
-
await
|
|
1749
|
+
await fetchResult(
|
|
1631
1750
|
`/accounts/${config.account_id}/storage/kv/namespaces/${namespaceId}/values/${key}`,
|
|
1632
1751
|
{ method: "DELETE" }
|
|
1633
1752
|
);
|
|
@@ -1637,11 +1756,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1637
1756
|
);
|
|
1638
1757
|
|
|
1639
1758
|
// :bulk
|
|
1640
|
-
|
|
1759
|
+
wrangler.command(
|
|
1641
1760
|
"kv:bulk",
|
|
1642
1761
|
"💪 Interact with multiple Workers KV key-value pairs at once",
|
|
1643
|
-
(
|
|
1644
|
-
return
|
|
1762
|
+
(kvBulkYargs) => {
|
|
1763
|
+
return kvBulkYargs
|
|
1645
1764
|
.command(
|
|
1646
1765
|
"put <filename>",
|
|
1647
1766
|
"Upload multiple key-value pairs to a namespace",
|
|
@@ -1681,8 +1800,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1681
1800
|
try {
|
|
1682
1801
|
parsedContent = JSON.parse(content);
|
|
1683
1802
|
} catch (err) {
|
|
1684
|
-
|
|
1685
|
-
|
|
1803
|
+
throw new Error(
|
|
1804
|
+
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1805
|
+
);
|
|
1686
1806
|
}
|
|
1687
1807
|
|
|
1688
1808
|
if (args.local) {
|
|
@@ -1721,8 +1841,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1721
1841
|
if (!config.account_id) {
|
|
1722
1842
|
config.account_id = await getAccountId();
|
|
1723
1843
|
if (!config.account_id) {
|
|
1724
|
-
|
|
1725
|
-
return;
|
|
1844
|
+
throw new Error("No account id found, quitting...");
|
|
1726
1845
|
}
|
|
1727
1846
|
}
|
|
1728
1847
|
}
|
|
@@ -1769,8 +1888,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1769
1888
|
try {
|
|
1770
1889
|
parsedContent = JSON.parse(content);
|
|
1771
1890
|
} catch (err) {
|
|
1772
|
-
|
|
1773
|
-
|
|
1891
|
+
throw new Error(
|
|
1892
|
+
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1893
|
+
);
|
|
1774
1894
|
}
|
|
1775
1895
|
|
|
1776
1896
|
if (args.local) {
|
|
@@ -1801,8 +1921,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1801
1921
|
if (!config.account_id) {
|
|
1802
1922
|
config.account_id = await getAccountId();
|
|
1803
1923
|
if (!config.account_id) {
|
|
1804
|
-
|
|
1805
|
-
return;
|
|
1924
|
+
throw new Error("No account id found, quitting...");
|
|
1806
1925
|
}
|
|
1807
1926
|
}
|
|
1808
1927
|
}
|
|
@@ -1817,10 +1936,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1817
1936
|
}
|
|
1818
1937
|
);
|
|
1819
1938
|
|
|
1820
|
-
|
|
1939
|
+
wrangler.command("pages", "⚡️ Configure Cloudflare Pages", pages);
|
|
1821
1940
|
|
|
1822
|
-
|
|
1941
|
+
wrangler
|
|
1823
1942
|
.option("config", {
|
|
1943
|
+
alias: "c",
|
|
1824
1944
|
describe: "Path to .toml configuration file",
|
|
1825
1945
|
type: "string",
|
|
1826
1946
|
async coerce(arg) {
|
|
@@ -1828,18 +1948,27 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1828
1948
|
},
|
|
1829
1949
|
})
|
|
1830
1950
|
.option("local", {
|
|
1951
|
+
alias: "l",
|
|
1831
1952
|
describe: "Run on my machine",
|
|
1832
1953
|
type: "boolean",
|
|
1833
1954
|
default: false, // I bet this will a point of contention. We'll revisit it.
|
|
1834
1955
|
});
|
|
1835
1956
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1957
|
+
wrangler.group(["config", "help", "version"], "Flags:");
|
|
1958
|
+
wrangler.help().alias("h", "help");
|
|
1959
|
+
wrangler.version(wranglerVersion).alias("v", "version");
|
|
1960
|
+
wrangler.exitProcess(false);
|
|
1961
|
+
|
|
1838
1962
|
await initialiseUserConfig();
|
|
1839
1963
|
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1964
|
+
try {
|
|
1965
|
+
await wrangler.parse();
|
|
1966
|
+
} catch (e) {
|
|
1967
|
+
if (e instanceof CommandLineArgsError) {
|
|
1968
|
+
wrangler.showHelp("error");
|
|
1969
|
+
console.error(""); // Just adds a bit of space
|
|
1843
1970
|
}
|
|
1844
|
-
|
|
1971
|
+
console.error(e.message);
|
|
1972
|
+
throw e;
|
|
1973
|
+
}
|
|
1845
1974
|
}
|