wrangler 0.0.0-e1c615f → 0.0.0-e3cab74
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/bin/wrangler.js +2 -2
- package/package.json +28 -13
- package/pages/functions/buildWorker.ts +6 -1
- package/pages/functions/filepath-routing.test.ts +112 -28
- package/pages/functions/filepath-routing.ts +88 -131
- package/pages/functions/routes.ts +11 -18
- package/pages/functions/template-worker.ts +21 -28
- package/src/__tests__/configuration.test.ts +2185 -0
- package/src/__tests__/dev.test.tsx +56 -9
- package/src/__tests__/guess-worker-format.test.ts +66 -0
- package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
- package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
- package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
- package/src/__tests__/helpers/mock-account-id.ts +30 -0
- package/src/__tests__/helpers/mock-bin.ts +36 -0
- package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +53 -17
- package/src/__tests__/helpers/mock-console.ts +62 -0
- package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
- package/src/__tests__/helpers/mock-kv.ts +40 -0
- package/src/__tests__/helpers/mock-user.ts +27 -0
- package/src/__tests__/helpers/mock-web-socket.ts +29 -0
- package/src/__tests__/helpers/run-in-tmp.ts +29 -0
- package/src/__tests__/helpers/run-wrangler.ts +16 -0
- package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
- package/src/__tests__/index.test.ts +655 -76
- package/src/__tests__/jest.setup.ts +37 -2
- package/src/__tests__/kv.test.ts +441 -398
- package/src/__tests__/logout.test.ts +50 -0
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +2406 -0
- package/src/__tests__/r2.test.ts +198 -0
- package/src/__tests__/secret.test.ts +326 -0
- package/src/__tests__/sentry.test.ts +146 -0
- package/src/__tests__/tail.test.ts +564 -0
- package/src/__tests__/whoami.test.tsx +86 -0
- package/src/api/form_data.ts +112 -26
- package/src/api/preview.ts +34 -15
- package/src/api/worker.ts +58 -27
- package/src/bundle.ts +133 -0
- package/src/cfetch/index.ts +21 -19
- package/src/cfetch/internal.ts +85 -21
- package/src/cli.ts +10 -0
- package/src/config/README.md +107 -0
- package/src/config/config.ts +265 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +305 -0
- package/src/config/index.ts +52 -0
- package/src/config/validation-helpers.ts +370 -0
- package/src/config/validation.ts +1017 -0
- package/src/dev.tsx +455 -368
- package/src/dialogs.tsx +2 -2
- package/src/entry.ts +57 -0
- package/src/environment-variables.ts +33 -0
- package/src/guess-worker-format.ts +68 -0
- package/src/index.tsx +1044 -646
- package/src/inspect.ts +609 -0
- package/src/kv.tsx +47 -39
- package/src/module-collection.ts +142 -36
- package/src/open-in-browser.ts +13 -0
- package/src/package-manager.ts +126 -0
- package/src/pages.tsx +139 -62
- package/src/parse.ts +183 -0
- package/src/paths.ts +26 -0
- package/src/proxy.ts +350 -77
- package/src/publish.ts +307 -289
- package/src/r2.ts +50 -0
- package/src/reporting.ts +115 -0
- package/src/sites.tsx +183 -56
- package/src/tail/filters.ts +279 -0
- package/src/tail/index.ts +299 -0
- package/src/tail/printing.ts +62 -0
- package/src/user.tsx +137 -110
- package/src/whoami.tsx +69 -0
- package/templates/new-worker.js +15 -0
- package/templates/new-worker.ts +15 -0
- package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
- package/templates/tsconfig.json +105 -0
- package/wrangler-dist/cli.js +127861 -111486
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/run-in-tmp.ts +0 -19
- package/src/__tests__/run-wrangler.ts +0 -32
- package/src/api/inspect.ts +0 -430
- package/src/config.ts +0 -131
- package/src/tail.tsx +0 -73
package/src/index.tsx
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { writeFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { setTimeout } from "node:timers/promises";
|
|
5
|
+
import TOML from "@iarna/toml";
|
|
6
|
+
import { findUp } from "find-up";
|
|
7
|
+
import getPort from "get-port";
|
|
2
8
|
import { render } from "ink";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
9
|
+
import React from "react";
|
|
10
|
+
import onExit from "signal-exit";
|
|
5
11
|
import makeCLI from "yargs";
|
|
6
|
-
import type Yargs from "yargs";
|
|
7
|
-
import { findUp } from "find-up";
|
|
8
|
-
import TOML from "@iarna/toml";
|
|
9
|
-
import type { Config } from "./config";
|
|
10
|
-
import { confirm, prompt } from "./dialogs";
|
|
11
12
|
import { version as wranglerVersion } from "../package.json";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
getAccountId,
|
|
19
|
-
} from "./user";
|
|
13
|
+
import { toFormData } from "./api/form_data";
|
|
14
|
+
import { fetchResult } from "./cfetch";
|
|
15
|
+
import { findWranglerToml, readConfig } from "./config";
|
|
16
|
+
import Dev from "./dev";
|
|
17
|
+
import { confirm, prompt } from "./dialogs";
|
|
18
|
+
import { getEntry } from "./entry";
|
|
20
19
|
import {
|
|
21
20
|
getNamespaceId,
|
|
22
21
|
listNamespaces,
|
|
@@ -26,92 +25,79 @@ import {
|
|
|
26
25
|
deleteBulkKeyValue,
|
|
27
26
|
createNamespace,
|
|
28
27
|
isValidNamespaceBinding,
|
|
28
|
+
getKeyValue,
|
|
29
29
|
} from "./kv";
|
|
30
|
-
|
|
30
|
+
import { getPackageManager } from "./package-manager";
|
|
31
31
|
import { pages } from "./pages";
|
|
32
|
-
|
|
33
|
-
import { fetchResult, fetchRaw } from "./cfetch";
|
|
34
|
-
|
|
32
|
+
import { formatMessage, ParseError, parseJSON, readFileSync } from "./parse";
|
|
35
33
|
import publish from "./publish";
|
|
36
|
-
import
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
34
|
+
import { createR2Bucket, deleteR2Bucket, listR2Buckets } from "./r2";
|
|
35
|
+
import { getAssetPaths } from "./sites";
|
|
36
|
+
import {
|
|
37
|
+
createTail,
|
|
38
|
+
jsonPrintLogs,
|
|
39
|
+
prettyPrintLogs,
|
|
40
|
+
translateCLICommandToFilterMessage,
|
|
41
|
+
} from "./tail";
|
|
42
|
+
import {
|
|
43
|
+
login,
|
|
44
|
+
logout,
|
|
45
|
+
listScopes,
|
|
46
|
+
initialise as initialiseUserConfig,
|
|
47
|
+
loginOrRefreshIfRequired,
|
|
48
|
+
getAccountId,
|
|
49
|
+
validateScopeKeys,
|
|
50
|
+
} from "./user";
|
|
51
|
+
import { whoami } from "./whoami";
|
|
39
52
|
|
|
40
|
-
import {
|
|
41
|
-
import
|
|
42
|
-
import {
|
|
43
|
-
import
|
|
44
|
-
import { execa } from "execa";
|
|
53
|
+
import type { Config } from "./config";
|
|
54
|
+
import type { TailCLIFilters } from "./tail";
|
|
55
|
+
import type { RawData } from "ws";
|
|
56
|
+
import type Yargs from "yargs";
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
const config: Config = {};
|
|
48
|
-
if (!configPath) {
|
|
49
|
-
configPath = await findUp("wrangler.toml");
|
|
50
|
-
// TODO - terminate this early instead of going all the way to the root
|
|
51
|
-
}
|
|
58
|
+
type ConfigPath = string | undefined;
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const parsed = TOML.parse(tml) as Config;
|
|
56
|
-
Object.assign(config, parsed);
|
|
57
|
-
}
|
|
60
|
+
const resetColor = "\x1b[0m";
|
|
61
|
+
const fgGreenColor = "\x1b[32m";
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"account_id",
|
|
62
|
-
"workers_dev",
|
|
63
|
-
"compatibility_date",
|
|
64
|
-
"compatibility_flags",
|
|
65
|
-
"zone_id",
|
|
66
|
-
"routes",
|
|
67
|
-
"route",
|
|
68
|
-
"jsx_factory",
|
|
69
|
-
"jsx_fragment",
|
|
70
|
-
"site",
|
|
71
|
-
"triggers",
|
|
72
|
-
"usage_model",
|
|
73
|
-
];
|
|
74
|
-
|
|
75
|
-
Object.keys(config.env || {}).forEach((env) => {
|
|
76
|
-
inheritedFields.forEach((field) => {
|
|
77
|
-
if (config[field] !== undefined && config.env[env][field] === undefined) {
|
|
78
|
-
config.env[env][field] = config[field]; // TODO: - shallow copy?
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
});
|
|
63
|
+
function getRules(config: Config): Config["rules"] {
|
|
64
|
+
const rules = config.rules ?? config.build?.upload?.rules ?? [];
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
];
|
|
89
|
-
Object.keys(config.env || {}).forEach((env) => {
|
|
90
|
-
mirroredFields.forEach((field) => {
|
|
91
|
-
// if it exists on top level, it should exist on env definitions
|
|
92
|
-
Object.keys(config[field] || {}).forEach((fieldKey) => {
|
|
93
|
-
if (!(fieldKey in config.env[env][field])) {
|
|
94
|
-
console.warn(
|
|
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}".`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
});
|
|
66
|
+
if (config.rules && config.build?.upload?.rules) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`You cannot configure both [rules] and [build.upload.rules] in your wrangler.toml. Delete the \`build.upload\` section.`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
101
71
|
|
|
102
|
-
if (
|
|
72
|
+
if (config.build?.upload?.rules) {
|
|
103
73
|
console.warn(
|
|
104
|
-
|
|
74
|
+
`Deprecation notice: The \`build.upload.rules\` config field is no longer used, the rules should be specified via the \`rules\` config field. Delete the \`build.upload\` field from the configuration file, and add this:
|
|
75
|
+
|
|
76
|
+
${TOML.stringify({ rules: config.build.upload.rules })}`
|
|
105
77
|
);
|
|
106
78
|
}
|
|
79
|
+
return rules;
|
|
80
|
+
}
|
|
107
81
|
|
|
108
|
-
|
|
109
|
-
|
|
82
|
+
function isLegacyEnv(args: unknown, config: Config): boolean {
|
|
83
|
+
return (
|
|
84
|
+
(args as { "legacy-env": boolean | undefined })["legacy-env"] ??
|
|
85
|
+
config.legacy_env
|
|
86
|
+
);
|
|
87
|
+
}
|
|
110
88
|
|
|
111
|
-
|
|
112
|
-
|
|
89
|
+
function getScriptName(
|
|
90
|
+
args: { name: string | undefined; env: string | undefined },
|
|
91
|
+
config: Config
|
|
92
|
+
): string | undefined {
|
|
93
|
+
const shortScriptName = args.name ?? config.name;
|
|
94
|
+
if (!shortScriptName) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
113
97
|
|
|
114
|
-
return config
|
|
98
|
+
return isLegacyEnv(args, config)
|
|
99
|
+
? `${shortScriptName}${args.env ? `-${args.env}` : ""}`
|
|
100
|
+
: shortScriptName;
|
|
115
101
|
}
|
|
116
102
|
|
|
117
103
|
// a helper to demand one of a set of options
|
|
@@ -140,8 +126,11 @@ function demandOneOfOption(...options: string[]) {
|
|
|
140
126
|
}
|
|
141
127
|
|
|
142
128
|
class CommandLineArgsError extends Error {}
|
|
143
|
-
class DeprecationError extends Error {
|
|
144
|
-
|
|
129
|
+
class DeprecationError extends Error {
|
|
130
|
+
constructor(message: string) {
|
|
131
|
+
super(`DEPRECATION WARNING:\n${message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
145
134
|
|
|
146
135
|
export async function main(argv: string[]): Promise<void> {
|
|
147
136
|
const wrangler = makeCLI(argv)
|
|
@@ -210,10 +199,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
210
199
|
"init [name]",
|
|
211
200
|
"📥 Create a wrangler.toml configuration file",
|
|
212
201
|
(yargs) => {
|
|
213
|
-
return yargs
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
202
|
+
return yargs
|
|
203
|
+
.positional("name", {
|
|
204
|
+
describe: "The name of your worker",
|
|
205
|
+
type: "string",
|
|
206
|
+
})
|
|
207
|
+
.option("yes", {
|
|
208
|
+
describe: 'Answer "yes" to any prompts for new projects',
|
|
209
|
+
type: "boolean",
|
|
210
|
+
alias: "y",
|
|
211
|
+
});
|
|
217
212
|
},
|
|
218
213
|
async (args) => {
|
|
219
214
|
if ("type" in args) {
|
|
@@ -226,94 +221,285 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
226
221
|
throw new CommandLineArgsError(message);
|
|
227
222
|
}
|
|
228
223
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
224
|
+
// TODO: make sure args.name is a valid identifier for a worker name
|
|
225
|
+
|
|
226
|
+
const creationDirectory = path.join(process.cwd(), args.name ?? "");
|
|
227
|
+
|
|
228
|
+
const packageManager = await getPackageManager(creationDirectory);
|
|
229
|
+
|
|
230
|
+
// TODO: ask which directory to make the worker in (defaults to args.name)
|
|
231
|
+
// TODO: if args.name isn't provided, ask what to name the worker
|
|
232
|
+
|
|
233
|
+
const wranglerTomlDestination = path.join(
|
|
234
|
+
creationDirectory,
|
|
235
|
+
"./wrangler.toml"
|
|
236
|
+
);
|
|
237
|
+
let justCreatedWranglerToml = false;
|
|
238
|
+
const workerName =
|
|
239
|
+
args.name || path.basename(path.resolve(process.cwd()));
|
|
240
|
+
if (fs.existsSync(wranglerTomlDestination)) {
|
|
241
|
+
console.warn(`${wranglerTomlDestination} file already exists!`);
|
|
242
|
+
const shouldContinue = await confirm(
|
|
233
243
|
"Do you want to continue initializing this project?"
|
|
234
244
|
);
|
|
235
|
-
if (!
|
|
245
|
+
if (!shouldContinue) {
|
|
236
246
|
return;
|
|
237
247
|
}
|
|
248
|
+
} else {
|
|
249
|
+
await mkdir(creationDirectory, { recursive: true });
|
|
250
|
+
const compatibilityDate = new Date().toISOString().substring(0, 10);
|
|
251
|
+
try {
|
|
252
|
+
await writeFile(
|
|
253
|
+
wranglerTomlDestination,
|
|
254
|
+
TOML.stringify({
|
|
255
|
+
name: workerName,
|
|
256
|
+
compatibility_date: compatibilityDate,
|
|
257
|
+
}) + "\n"
|
|
258
|
+
);
|
|
259
|
+
console.log(`✨ Successfully created wrangler.toml`);
|
|
260
|
+
justCreatedWranglerToml = true;
|
|
261
|
+
} catch (err) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`Failed to create wrangler.toml.\n${(err as Error).message ?? err}`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
238
266
|
}
|
|
239
267
|
|
|
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
|
-
|
|
254
|
-
// if no package.json, ask, and if yes, create one
|
|
255
268
|
let pathToPackageJson = await findUp("package.json");
|
|
256
|
-
|
|
269
|
+
let shouldCreatePackageJson = false;
|
|
270
|
+
const yesFlag = args.yes ?? false;
|
|
257
271
|
if (!pathToPackageJson) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
// If no package.json exists, ask to create one
|
|
273
|
+
shouldCreatePackageJson =
|
|
274
|
+
yesFlag ||
|
|
275
|
+
(await confirm(
|
|
276
|
+
"No package.json found. Would you like to create one?"
|
|
277
|
+
));
|
|
278
|
+
|
|
279
|
+
if (shouldCreatePackageJson) {
|
|
261
280
|
await writeFile(
|
|
262
|
-
path.join(
|
|
281
|
+
path.join(creationDirectory, "./package.json"),
|
|
263
282
|
JSON.stringify(
|
|
264
283
|
{
|
|
265
|
-
name:
|
|
266
|
-
version: "0.0.
|
|
284
|
+
name: workerName,
|
|
285
|
+
version: "0.0.0",
|
|
286
|
+
devDependencies: {
|
|
287
|
+
wrangler: wranglerVersion,
|
|
288
|
+
},
|
|
289
|
+
private: true,
|
|
267
290
|
},
|
|
268
291
|
null,
|
|
269
292
|
" "
|
|
270
293
|
) + "\n"
|
|
271
294
|
);
|
|
295
|
+
await packageManager.install();
|
|
272
296
|
console.log(`✨ Created package.json`);
|
|
273
|
-
pathToPackageJson = path.join(
|
|
297
|
+
pathToPackageJson = path.join(creationDirectory, "package.json");
|
|
274
298
|
} else {
|
|
275
299
|
return;
|
|
276
300
|
}
|
|
301
|
+
} else {
|
|
302
|
+
// If package.json exists and wrangler isn't installed,
|
|
303
|
+
// then ask to add wrangler to devDependencies
|
|
304
|
+
const packageJson = parseJSON(
|
|
305
|
+
readFileSync(pathToPackageJson),
|
|
306
|
+
pathToPackageJson
|
|
307
|
+
);
|
|
308
|
+
if (
|
|
309
|
+
!(
|
|
310
|
+
packageJson.devDependencies?.wrangler ||
|
|
311
|
+
packageJson.dependencies?.wrangler
|
|
312
|
+
)
|
|
313
|
+
) {
|
|
314
|
+
const shouldInstall =
|
|
315
|
+
yesFlag ||
|
|
316
|
+
(await confirm(
|
|
317
|
+
"Would you like to install wrangler into your package.json?"
|
|
318
|
+
));
|
|
319
|
+
if (shouldInstall) {
|
|
320
|
+
await packageManager.addDevDeps(`wrangler@${wranglerVersion}`);
|
|
321
|
+
console.log(`✨ Installed wrangler`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
277
324
|
}
|
|
278
325
|
|
|
279
|
-
|
|
280
|
-
// offer to install it
|
|
281
|
-
// and make a tsconfig?
|
|
326
|
+
let isTypescriptProject = false;
|
|
282
327
|
let pathToTSConfig = await findUp("tsconfig.json");
|
|
283
328
|
if (!pathToTSConfig) {
|
|
284
|
-
|
|
329
|
+
// If there's no tsconfig, offer to create one
|
|
330
|
+
// and install @cloudflare/workers-types
|
|
331
|
+
if (yesFlag || (await confirm("Would you like to use TypeScript?"))) {
|
|
332
|
+
isTypescriptProject = true;
|
|
285
333
|
await writeFile(
|
|
286
|
-
path.join(
|
|
334
|
+
path.join(creationDirectory, "./tsconfig.json"),
|
|
335
|
+
readFileSync(path.join(__dirname, "../templates/tsconfig.json"))
|
|
336
|
+
);
|
|
337
|
+
await packageManager.addDevDeps(
|
|
338
|
+
"@cloudflare/workers-types",
|
|
339
|
+
"typescript"
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
console.log(
|
|
343
|
+
`✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies`
|
|
344
|
+
);
|
|
345
|
+
pathToTSConfig = path.join(creationDirectory, "tsconfig.json");
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
isTypescriptProject = true;
|
|
349
|
+
// If there's a tsconfig, check if @cloudflare/workers-types
|
|
350
|
+
// is already installed, and offer to install it if not
|
|
351
|
+
const packageJson = parseJSON(
|
|
352
|
+
readFileSync(pathToPackageJson),
|
|
353
|
+
pathToPackageJson
|
|
354
|
+
);
|
|
355
|
+
if (
|
|
356
|
+
!(
|
|
357
|
+
packageJson.devDependencies?.["@cloudflare/workers-types"] ||
|
|
358
|
+
packageJson.dependencies?.["@cloudflare/workers-types"]
|
|
359
|
+
)
|
|
360
|
+
) {
|
|
361
|
+
const shouldInstall = await confirm(
|
|
362
|
+
"Would you like to install the type definitions for Workers into your package.json?"
|
|
363
|
+
);
|
|
364
|
+
if (shouldInstall) {
|
|
365
|
+
await packageManager.addDevDeps("@cloudflare/workers-types");
|
|
366
|
+
// We don't update the tsconfig.json because
|
|
367
|
+
// it could be complicated in existing projects
|
|
368
|
+
// and we don't want to break them. Instead, we simply
|
|
369
|
+
// tell the user that they need to update their tsconfig.json
|
|
370
|
+
console.log(
|
|
371
|
+
`✨ Installed @cloudflare/workers-types.\nPlease add "@cloudflare/workers-types" to compilerOptions.types in your tsconfig.json`
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const packageJsonContent = parseJSON(
|
|
378
|
+
readFileSync(pathToPackageJson),
|
|
379
|
+
pathToPackageJson
|
|
380
|
+
);
|
|
381
|
+
const shouldWritePackageJsonScripts =
|
|
382
|
+
!packageJsonContent.scripts?.start &&
|
|
383
|
+
!packageJsonContent.scripts?.publish &&
|
|
384
|
+
shouldCreatePackageJson;
|
|
385
|
+
|
|
386
|
+
async function writePackageJsonScriptsAndUpdateWranglerToml(
|
|
387
|
+
isWritingScripts: boolean,
|
|
388
|
+
isCreatingWranglerToml: boolean,
|
|
389
|
+
packagePath: string,
|
|
390
|
+
scriptPath: string
|
|
391
|
+
) {
|
|
392
|
+
if (isCreatingWranglerToml) {
|
|
393
|
+
// rewrite wrangler.toml with main = "path/to/script"
|
|
394
|
+
const parsedWranglerToml = TOML.parse(
|
|
395
|
+
readFileSync(wranglerTomlDestination)
|
|
396
|
+
);
|
|
397
|
+
fs.writeFileSync(
|
|
398
|
+
wranglerTomlDestination,
|
|
399
|
+
TOML.stringify({
|
|
400
|
+
name: parsedWranglerToml.name,
|
|
401
|
+
main: scriptPath,
|
|
402
|
+
compatibility_date: parsedWranglerToml.compatibility_date,
|
|
403
|
+
})
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
const isNamedWorker =
|
|
407
|
+
isCreatingWranglerToml && path.dirname(packagePath) !== process.cwd();
|
|
408
|
+
|
|
409
|
+
if (isWritingScripts) {
|
|
410
|
+
await writeFile(
|
|
411
|
+
packagePath,
|
|
287
412
|
JSON.stringify(
|
|
288
413
|
{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
lib: ["esnext"],
|
|
299
|
-
jsx: "react",
|
|
300
|
-
resolveJsonModule: true,
|
|
301
|
-
types: ["@cloudflare/workers-types"],
|
|
414
|
+
...packageJsonContent,
|
|
415
|
+
scripts: {
|
|
416
|
+
...packageJsonContent.scripts,
|
|
417
|
+
start: isCreatingWranglerToml
|
|
418
|
+
? `wrangler dev`
|
|
419
|
+
: `wrangler dev ${scriptPath}`,
|
|
420
|
+
publish: isCreatingWranglerToml
|
|
421
|
+
? `wrangler publish`
|
|
422
|
+
: `wrangler publish ${scriptPath}`,
|
|
302
423
|
},
|
|
303
424
|
},
|
|
304
425
|
null,
|
|
305
|
-
|
|
426
|
+
2
|
|
306
427
|
) + "\n"
|
|
307
428
|
);
|
|
308
|
-
await execa("npm", [
|
|
309
|
-
"install",
|
|
310
|
-
"@cloudflare/workers-types",
|
|
311
|
-
"--save-dev",
|
|
312
|
-
]);
|
|
313
429
|
console.log(
|
|
314
|
-
|
|
430
|
+
`\nTo start developing your Worker, run \`${
|
|
431
|
+
isNamedWorker ? `cd ${args.name} && ` : ""
|
|
432
|
+
}npm start\``
|
|
433
|
+
);
|
|
434
|
+
console.log(
|
|
435
|
+
`To publish your Worker to the Internet, run \`npm run publish\``
|
|
436
|
+
);
|
|
437
|
+
} else {
|
|
438
|
+
console.log(
|
|
439
|
+
`\nTo start developing your Worker, run \`npx wrangler dev\`${
|
|
440
|
+
isCreatingWranglerToml ? "" : ` ${scriptPath}`
|
|
441
|
+
}`
|
|
315
442
|
);
|
|
316
|
-
|
|
443
|
+
console.log(
|
|
444
|
+
`To publish your Worker to the Internet, run \`npx wrangler publish\`${
|
|
445
|
+
isCreatingWranglerToml ? "" : ` ${scriptPath}`
|
|
446
|
+
}`
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (isTypescriptProject) {
|
|
452
|
+
if (!fs.existsSync(path.join(creationDirectory, "./src/index.ts"))) {
|
|
453
|
+
let shouldCreateSource = false;
|
|
454
|
+
|
|
455
|
+
shouldCreateSource =
|
|
456
|
+
yesFlag ||
|
|
457
|
+
(await confirm(
|
|
458
|
+
`Would you like to create a Worker at src/index.ts?`
|
|
459
|
+
));
|
|
460
|
+
|
|
461
|
+
if (shouldCreateSource) {
|
|
462
|
+
await mkdir(path.join(creationDirectory, "./src"), {
|
|
463
|
+
recursive: true,
|
|
464
|
+
});
|
|
465
|
+
await writeFile(
|
|
466
|
+
path.join(creationDirectory, "./src/index.ts"),
|
|
467
|
+
readFileSync(path.join(__dirname, "../templates/new-worker.ts"))
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
console.log(`✨ Created src/index.ts`);
|
|
471
|
+
|
|
472
|
+
await writePackageJsonScriptsAndUpdateWranglerToml(
|
|
473
|
+
shouldWritePackageJsonScripts,
|
|
474
|
+
justCreatedWranglerToml,
|
|
475
|
+
pathToPackageJson,
|
|
476
|
+
"src/index.ts"
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
if (!fs.existsSync("./src/index.js")) {
|
|
482
|
+
const shouldCreateSource = await confirm(
|
|
483
|
+
`Would you like to create a Worker at src/index.js?`
|
|
484
|
+
);
|
|
485
|
+
if (shouldCreateSource) {
|
|
486
|
+
await mkdir(path.join(creationDirectory, "./src"), {
|
|
487
|
+
recursive: true,
|
|
488
|
+
});
|
|
489
|
+
await writeFile(
|
|
490
|
+
path.join(path.join(creationDirectory, "./src/index.js")),
|
|
491
|
+
readFileSync(path.join(__dirname, "../templates/new-worker.js"))
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
console.log(`✨ Created src/index.js`);
|
|
495
|
+
|
|
496
|
+
await writePackageJsonScriptsAndUpdateWranglerToml(
|
|
497
|
+
shouldWritePackageJsonScripts,
|
|
498
|
+
justCreatedWranglerToml,
|
|
499
|
+
pathToPackageJson,
|
|
500
|
+
"src/index.js"
|
|
501
|
+
);
|
|
502
|
+
}
|
|
317
503
|
}
|
|
318
504
|
}
|
|
319
505
|
}
|
|
@@ -347,10 +533,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
347
533
|
// I mean, this entire app does, but this too.
|
|
348
534
|
return yargs
|
|
349
535
|
.option("scopes-list", {
|
|
350
|
-
describe: "
|
|
536
|
+
describe: "List all the available OAuth scopes with descriptions",
|
|
351
537
|
})
|
|
352
538
|
.option("scopes", {
|
|
353
|
-
describe: "
|
|
539
|
+
describe: "Pick the set of applicable OAuth scopes when logging in",
|
|
354
540
|
array: true,
|
|
355
541
|
type: "string",
|
|
356
542
|
});
|
|
@@ -368,6 +554,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
368
554
|
listScopes();
|
|
369
555
|
return;
|
|
370
556
|
}
|
|
557
|
+
if (!validateScopeKeys(args.scopes)) {
|
|
558
|
+
throw new CommandLineArgsError(
|
|
559
|
+
`One of ${args.scopes} is not a valid authentication scope. Run "wrangler login --list-scopes" to see the valid scopes.`
|
|
560
|
+
);
|
|
561
|
+
}
|
|
371
562
|
await login({ scopes: args.scopes });
|
|
372
563
|
return;
|
|
373
564
|
}
|
|
@@ -394,11 +585,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
394
585
|
// whoami
|
|
395
586
|
wrangler.command(
|
|
396
587
|
"whoami",
|
|
397
|
-
|
|
398
|
-
// "🕵️ Retrieve your user info and test your auth config",
|
|
588
|
+
"🕵️ Retrieve your user info and test your auth config",
|
|
399
589
|
() => {},
|
|
400
|
-
(
|
|
401
|
-
|
|
590
|
+
async () => {
|
|
591
|
+
await whoami();
|
|
402
592
|
}
|
|
403
593
|
);
|
|
404
594
|
|
|
@@ -417,13 +607,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
417
607
|
|
|
418
608
|
// dev
|
|
419
609
|
wrangler.command(
|
|
420
|
-
"dev
|
|
610
|
+
"dev [script]",
|
|
421
611
|
"👂 Start a local server for developing your worker",
|
|
422
612
|
(yargs) => {
|
|
423
613
|
return yargs
|
|
424
|
-
.positional("
|
|
614
|
+
.positional("script", {
|
|
615
|
+
describe: "The path to an entry point for your worker",
|
|
616
|
+
type: "string",
|
|
617
|
+
})
|
|
425
618
|
.option("name", {
|
|
426
|
-
describe: "
|
|
619
|
+
describe: "Name of the worker",
|
|
427
620
|
type: "string",
|
|
428
621
|
})
|
|
429
622
|
.option("format", {
|
|
@@ -433,7 +626,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
433
626
|
.option("env", {
|
|
434
627
|
describe: "Perform on a specific environment",
|
|
435
628
|
type: "string",
|
|
436
|
-
|
|
629
|
+
})
|
|
630
|
+
.option("compatibility-date", {
|
|
631
|
+
describe: "Date to use for compatibility checks",
|
|
632
|
+
type: "string",
|
|
633
|
+
})
|
|
634
|
+
.option("compatibility-flags", {
|
|
635
|
+
describe: "Flags to use for compatibility checks",
|
|
636
|
+
type: "array",
|
|
637
|
+
alias: "compatibility-flag",
|
|
638
|
+
})
|
|
639
|
+
.option("latest", {
|
|
640
|
+
describe: "Use the latest version of the worker runtime",
|
|
641
|
+
type: "boolean",
|
|
642
|
+
default: true,
|
|
437
643
|
})
|
|
438
644
|
.option("ip", {
|
|
439
645
|
describe: "IP address to listen on",
|
|
@@ -441,9 +647,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
441
647
|
default: "127.0.0.1",
|
|
442
648
|
})
|
|
443
649
|
.option("port", {
|
|
444
|
-
describe: "Port to listen on
|
|
650
|
+
describe: "Port to listen on",
|
|
651
|
+
type: "number",
|
|
652
|
+
})
|
|
653
|
+
.option("inspector-port", {
|
|
654
|
+
describe: "Port for devtools to connect to",
|
|
445
655
|
type: "number",
|
|
446
|
-
default: 8787,
|
|
447
656
|
})
|
|
448
657
|
.option("host", {
|
|
449
658
|
type: "string",
|
|
@@ -463,6 +672,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
463
672
|
describe: "Root folder of static assets for Workers Sites",
|
|
464
673
|
type: "string",
|
|
465
674
|
})
|
|
675
|
+
.option("site-include", {
|
|
676
|
+
describe:
|
|
677
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.",
|
|
678
|
+
type: "string",
|
|
679
|
+
array: true,
|
|
680
|
+
})
|
|
681
|
+
.option("site-exclude", {
|
|
682
|
+
describe:
|
|
683
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded.",
|
|
684
|
+
type: "string",
|
|
685
|
+
array: true,
|
|
686
|
+
})
|
|
466
687
|
.option("upstream-protocol", {
|
|
467
688
|
default: "https",
|
|
468
689
|
describe:
|
|
@@ -476,11 +697,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
476
697
|
.option("jsx-fragment", {
|
|
477
698
|
describe: "The function that is called for each JSX fragment",
|
|
478
699
|
type: "string",
|
|
700
|
+
})
|
|
701
|
+
.option("local", {
|
|
702
|
+
alias: "l",
|
|
703
|
+
describe: "Run on my machine",
|
|
704
|
+
type: "boolean",
|
|
705
|
+
default: false, // I bet this will a point of contention. We'll revisit it.
|
|
706
|
+
})
|
|
707
|
+
.option("experimental-enable-local-persistence", {
|
|
708
|
+
describe: "Enable persistence for this session (only for local mode)",
|
|
709
|
+
type: "boolean",
|
|
479
710
|
});
|
|
480
711
|
},
|
|
481
712
|
async (args) => {
|
|
482
|
-
const
|
|
483
|
-
|
|
713
|
+
const config = readConfig(
|
|
714
|
+
(args.config as ConfigPath) ||
|
|
715
|
+
(args.script && findWranglerToml(path.dirname(args.script)))
|
|
716
|
+
);
|
|
717
|
+
const entry = getEntry(config, "dev", args.script);
|
|
484
718
|
|
|
485
719
|
if (args["experimental-public"]) {
|
|
486
720
|
console.warn(
|
|
@@ -494,54 +728,75 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
494
728
|
);
|
|
495
729
|
}
|
|
496
730
|
|
|
497
|
-
|
|
731
|
+
if (config.site?.["entry-point"]) {
|
|
732
|
+
console.warn(
|
|
733
|
+
"Deprecation notice: The `site.entry-point` config field is no longer used.\n" +
|
|
734
|
+
"The entry-point is specified via the command line (e.g. `wrangler dev path/to/script`).\n" +
|
|
735
|
+
"Please remove the `site.entry-point` field from the `wrangler.toml` file."
|
|
736
|
+
);
|
|
737
|
+
}
|
|
498
738
|
|
|
499
739
|
if (!args.local) {
|
|
740
|
+
// -- snip, extract --
|
|
500
741
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
501
742
|
if (!loggedIn) {
|
|
502
743
|
// didn't login, let's just quit
|
|
503
744
|
console.log("Did not login, quitting...");
|
|
504
745
|
return;
|
|
505
746
|
}
|
|
747
|
+
|
|
506
748
|
if (!config.account_id) {
|
|
507
749
|
config.account_id = await getAccountId();
|
|
508
750
|
if (!config.account_id) {
|
|
509
751
|
throw new Error("No account id found, quitting...");
|
|
510
752
|
}
|
|
511
753
|
}
|
|
754
|
+
// -- snip, end --
|
|
512
755
|
}
|
|
513
756
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const envRootObj = args.env ? config.env[args.env] || {} : config;
|
|
517
|
-
|
|
518
|
-
// TODO: this error shouldn't actually happen,
|
|
519
|
-
// but we haven't fixed it internally yet
|
|
520
|
-
if ("durable_objects" in envRootObj) {
|
|
521
|
-
if (!(args.name || config.name)) {
|
|
522
|
-
console.warn(
|
|
523
|
-
'A worker with durable objects need 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.'
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
// TODO: if not already published, publish a draft worker
|
|
527
|
-
}
|
|
757
|
+
const environments = config.env ?? {};
|
|
758
|
+
const envRootObj = args.env ? environments[args.env] || {} : config;
|
|
528
759
|
|
|
529
760
|
const { waitUntilExit } = render(
|
|
530
761
|
<Dev
|
|
531
|
-
name={args
|
|
532
|
-
entry={
|
|
762
|
+
name={getScriptName(args, config)}
|
|
763
|
+
entry={entry}
|
|
764
|
+
env={args.env}
|
|
765
|
+
zone={undefined}
|
|
766
|
+
rules={getRules(config)}
|
|
767
|
+
legacyEnv={isLegacyEnv(args, config)}
|
|
533
768
|
buildCommand={config.build || {}}
|
|
534
|
-
format={format}
|
|
769
|
+
format={args.format || config.build?.upload?.format}
|
|
535
770
|
initialMode={args.local ? "local" : "remote"}
|
|
536
771
|
jsxFactory={args["jsx-factory"] || envRootObj?.jsx_factory}
|
|
537
772
|
jsxFragment={args["jsx-fragment"] || envRootObj?.jsx_fragment}
|
|
773
|
+
enableLocalPersistence={
|
|
774
|
+
args["experimental-enable-local-persistence"] || false
|
|
775
|
+
}
|
|
538
776
|
accountId={config.account_id}
|
|
539
|
-
|
|
540
|
-
|
|
777
|
+
assetPaths={getAssetPaths(
|
|
778
|
+
config,
|
|
779
|
+
args.site,
|
|
780
|
+
args.siteInclude,
|
|
781
|
+
args.siteExclude
|
|
782
|
+
)}
|
|
783
|
+
port={
|
|
784
|
+
args.port || config.dev?.port || (await getPort({ port: 8787 }))
|
|
785
|
+
}
|
|
786
|
+
inspectorPort={
|
|
787
|
+
args["inspector-port"] ?? (await getPort({ port: 9229 }))
|
|
788
|
+
}
|
|
541
789
|
public={args["experimental-public"]}
|
|
542
|
-
compatibilityDate={
|
|
543
|
-
|
|
544
|
-
|
|
790
|
+
compatibilityDate={
|
|
791
|
+
args["compatibility-date"] ||
|
|
792
|
+
config.compatibility_date ||
|
|
793
|
+
new Date().toISOString().substring(0, 10)
|
|
794
|
+
}
|
|
795
|
+
compatibilityFlags={
|
|
796
|
+
(args["compatibility-flags"] as string[]) ||
|
|
797
|
+
config.compatibility_flags
|
|
798
|
+
}
|
|
799
|
+
usageModel={envRootObj.usage_model}
|
|
545
800
|
bindings={{
|
|
546
801
|
kv_namespaces: envRootObj.kv_namespaces?.map(
|
|
547
802
|
({ binding, preview_id, id: _id }) => {
|
|
@@ -565,8 +820,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
565
820
|
}
|
|
566
821
|
),
|
|
567
822
|
vars: envRootObj.vars,
|
|
823
|
+
wasm_modules: config.wasm_modules,
|
|
824
|
+
text_blobs: config.text_blobs,
|
|
568
825
|
durable_objects: envRootObj.durable_objects,
|
|
569
|
-
|
|
826
|
+
r2_buckets: envRootObj.r2_buckets,
|
|
827
|
+
unsafe: envRootObj.unsafe?.bindings,
|
|
570
828
|
}}
|
|
571
829
|
/>
|
|
572
830
|
);
|
|
@@ -585,13 +843,31 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
585
843
|
describe: "Perform on a specific environment",
|
|
586
844
|
})
|
|
587
845
|
.positional("script", {
|
|
588
|
-
describe: "
|
|
846
|
+
describe: "The path to an entry point for your worker",
|
|
589
847
|
type: "string",
|
|
590
848
|
})
|
|
591
849
|
.option("name", {
|
|
592
|
-
describe: "
|
|
850
|
+
describe: "Name of the worker",
|
|
851
|
+
type: "string",
|
|
852
|
+
})
|
|
853
|
+
.option("format", {
|
|
854
|
+
choices: ["modules", "service-worker"] as const,
|
|
855
|
+
describe: "Choose an entry type",
|
|
856
|
+
})
|
|
857
|
+
.option("compatibility-date", {
|
|
858
|
+
describe: "Date to use for compatibility checks",
|
|
593
859
|
type: "string",
|
|
594
860
|
})
|
|
861
|
+
.option("compatibility-flags", {
|
|
862
|
+
describe: "Flags to use for compatibility checks",
|
|
863
|
+
type: "array",
|
|
864
|
+
alias: "compatibility-flag",
|
|
865
|
+
})
|
|
866
|
+
.option("latest", {
|
|
867
|
+
describe: "Use the latest version of the worker runtime",
|
|
868
|
+
type: "boolean",
|
|
869
|
+
default: false,
|
|
870
|
+
})
|
|
595
871
|
.option("experimental-public", {
|
|
596
872
|
describe: "Static assets to be served",
|
|
597
873
|
type: "string",
|
|
@@ -600,22 +876,28 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
600
876
|
describe: "Root folder of static assets for Workers Sites",
|
|
601
877
|
type: "string",
|
|
602
878
|
})
|
|
879
|
+
.option("site-include", {
|
|
880
|
+
describe:
|
|
881
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.",
|
|
882
|
+
type: "string",
|
|
883
|
+
array: true,
|
|
884
|
+
})
|
|
885
|
+
.option("site-exclude", {
|
|
886
|
+
describe:
|
|
887
|
+
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded.",
|
|
888
|
+
type: "string",
|
|
889
|
+
array: true,
|
|
890
|
+
})
|
|
603
891
|
.option("triggers", {
|
|
604
892
|
describe: "cron schedules to attach",
|
|
605
893
|
alias: ["schedule", "schedules"],
|
|
606
894
|
type: "array",
|
|
607
895
|
})
|
|
608
896
|
.option("routes", {
|
|
609
|
-
describe: "
|
|
897
|
+
describe: "Routes to upload",
|
|
610
898
|
alias: "route",
|
|
611
899
|
type: "array",
|
|
612
900
|
})
|
|
613
|
-
.option("services", {
|
|
614
|
-
describe: "experimental support for services",
|
|
615
|
-
type: "boolean",
|
|
616
|
-
default: "false",
|
|
617
|
-
hidden: true,
|
|
618
|
-
})
|
|
619
901
|
.option("jsx-factory", {
|
|
620
902
|
describe: "The function that is called for each JSX element",
|
|
621
903
|
type: "string",
|
|
@@ -626,12 +908,6 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
626
908
|
});
|
|
627
909
|
},
|
|
628
910
|
async (args) => {
|
|
629
|
-
if (args.local) {
|
|
630
|
-
throw new NotImplementedError(
|
|
631
|
-
"🚫 Local publishing is not yet supported"
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
911
|
if (args["experimental-public"]) {
|
|
636
912
|
console.warn(
|
|
637
913
|
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
@@ -643,37 +919,58 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
643
919
|
);
|
|
644
920
|
}
|
|
645
921
|
|
|
646
|
-
const config =
|
|
922
|
+
const config = readConfig(
|
|
923
|
+
(args.config as ConfigPath) ||
|
|
924
|
+
(args.script && findWranglerToml(path.dirname(args.script)))
|
|
925
|
+
);
|
|
926
|
+
const entry = getEntry(config, "publish", args.script);
|
|
927
|
+
|
|
928
|
+
if (args.latest) {
|
|
929
|
+
console.warn(
|
|
930
|
+
"⚠️ 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"
|
|
931
|
+
);
|
|
932
|
+
}
|
|
647
933
|
|
|
648
934
|
// -- snip, extract --
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
935
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
936
|
+
if (!loggedIn) {
|
|
937
|
+
// didn't login, let's just quit
|
|
938
|
+
console.log("Did not login, quitting...");
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if (!config.account_id) {
|
|
943
|
+
config.account_id = await getAccountId();
|
|
656
944
|
if (!config.account_id) {
|
|
657
|
-
|
|
658
|
-
if (!config.account_id) {
|
|
659
|
-
throw new Error("No account id found, quitting...");
|
|
660
|
-
}
|
|
945
|
+
throw new Error("No account id found, quitting...");
|
|
661
946
|
}
|
|
662
947
|
}
|
|
663
|
-
|
|
664
948
|
// -- snip, end --
|
|
665
949
|
|
|
950
|
+
const assetPaths = getAssetPaths(
|
|
951
|
+
config,
|
|
952
|
+
args["experimental-public"] || args.site,
|
|
953
|
+
args.siteInclude,
|
|
954
|
+
args.siteExclude
|
|
955
|
+
);
|
|
666
956
|
await publish({
|
|
667
|
-
config
|
|
668
|
-
name: args
|
|
669
|
-
|
|
957
|
+
config,
|
|
958
|
+
name: getScriptName(args, config),
|
|
959
|
+
rules: getRules(config),
|
|
960
|
+
format: args.format || config.build?.upload?.format,
|
|
961
|
+
entry,
|
|
670
962
|
env: args.env,
|
|
963
|
+
compatibilityDate: args.latest
|
|
964
|
+
? new Date().toISOString().substring(0, 10)
|
|
965
|
+
: args["compatibility-date"],
|
|
966
|
+
compatibilityFlags: args["compatibility-flags"] as string[],
|
|
671
967
|
triggers: args.triggers,
|
|
672
968
|
jsxFactory: args["jsx-factory"],
|
|
673
969
|
jsxFragment: args["jsx-fragment"],
|
|
674
970
|
routes: args.routes,
|
|
675
|
-
|
|
676
|
-
|
|
971
|
+
assetPaths,
|
|
972
|
+
legacyEnv: isLegacyEnv(args, config),
|
|
973
|
+
experimentalPublic: args["experimental-public"] !== undefined,
|
|
677
974
|
});
|
|
678
975
|
}
|
|
679
976
|
);
|
|
@@ -681,12 +978,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
681
978
|
// tail
|
|
682
979
|
wrangler.command(
|
|
683
980
|
"tail [name]",
|
|
684
|
-
"🦚 Starts a log tailing session for a
|
|
981
|
+
"🦚 Starts a log tailing session for a published Worker.",
|
|
685
982
|
(yargs) => {
|
|
686
983
|
return (
|
|
687
984
|
yargs
|
|
688
985
|
.positional("name", {
|
|
689
|
-
describe: "
|
|
986
|
+
describe: "Name of the worker",
|
|
690
987
|
type: "string",
|
|
691
988
|
})
|
|
692
989
|
// TODO: auto-detect if this should be json or pretty based on atty
|
|
@@ -698,6 +995,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
698
995
|
.option("status", {
|
|
699
996
|
choices: ["ok", "error", "canceled"],
|
|
700
997
|
describe: "Filter by invocation status",
|
|
998
|
+
array: true,
|
|
701
999
|
})
|
|
702
1000
|
.option("header", {
|
|
703
1001
|
type: "string",
|
|
@@ -706,6 +1004,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
706
1004
|
.option("method", {
|
|
707
1005
|
type: "string",
|
|
708
1006
|
describe: "Filter by HTTP method",
|
|
1007
|
+
array: true,
|
|
709
1008
|
})
|
|
710
1009
|
.option("sampling-rate", {
|
|
711
1010
|
type: "number",
|
|
@@ -715,54 +1014,76 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
715
1014
|
type: "string",
|
|
716
1015
|
describe: "Filter by a text match in console.log messages",
|
|
717
1016
|
})
|
|
1017
|
+
.option("ip", {
|
|
1018
|
+
type: "string",
|
|
1019
|
+
describe:
|
|
1020
|
+
'Filter by the IP address the request originates from. Use "self" to filter for your own IP',
|
|
1021
|
+
array: true,
|
|
1022
|
+
})
|
|
718
1023
|
.option("env", {
|
|
719
1024
|
type: "string",
|
|
720
1025
|
describe: "Perform on a specific environment",
|
|
721
1026
|
})
|
|
1027
|
+
.option("debug", {
|
|
1028
|
+
type: "boolean",
|
|
1029
|
+
hidden: true,
|
|
1030
|
+
default: false,
|
|
1031
|
+
describe:
|
|
1032
|
+
"If a log would have been filtered out, send it through anyway alongside the filter which would have blocked it.",
|
|
1033
|
+
})
|
|
722
1034
|
);
|
|
723
|
-
// TODO: filter by client ip, which can be 'self' or an ip address
|
|
724
1035
|
},
|
|
725
1036
|
async (args) => {
|
|
726
|
-
const config = args.config as
|
|
1037
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1038
|
+
|
|
1039
|
+
const scriptName = getScriptName(args, config);
|
|
727
1040
|
|
|
728
|
-
if (!
|
|
1041
|
+
if (!scriptName) {
|
|
729
1042
|
throw new Error("Missing script name");
|
|
730
1043
|
}
|
|
731
|
-
const scriptName = `${args.name || config.name}${
|
|
732
|
-
args.env ? `-${args.env}` : ""
|
|
733
|
-
}`;
|
|
734
1044
|
|
|
735
1045
|
// -- snip, extract --
|
|
1046
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1047
|
+
if (!loggedIn) {
|
|
1048
|
+
// didn't login, let's just quit
|
|
1049
|
+
console.log("Did not login, quitting...");
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
736
1052
|
|
|
737
|
-
if (!
|
|
738
|
-
|
|
739
|
-
if (!loggedIn) {
|
|
740
|
-
// didn't login, let's just quit
|
|
741
|
-
console.log("Did not login, quitting...");
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
1053
|
+
if (!config.account_id) {
|
|
1054
|
+
config.account_id = await getAccountId();
|
|
744
1055
|
if (!config.account_id) {
|
|
745
|
-
|
|
746
|
-
if (!config.account_id) {
|
|
747
|
-
throw new Error("No account id found, quitting...");
|
|
748
|
-
}
|
|
1056
|
+
throw new Error("No account id found, quitting...");
|
|
749
1057
|
}
|
|
750
1058
|
}
|
|
751
|
-
|
|
752
1059
|
// -- snip, end --
|
|
753
1060
|
|
|
754
1061
|
const accountId = config.account_id;
|
|
755
1062
|
|
|
756
|
-
const
|
|
757
|
-
status: args.status as "ok" | "error" | "canceled",
|
|
1063
|
+
const cliFilters: TailCLIFilters = {
|
|
1064
|
+
status: args.status as ("ok" | "error" | "canceled")[],
|
|
758
1065
|
header: args.header,
|
|
759
1066
|
method: args.method,
|
|
760
|
-
|
|
1067
|
+
samplingRate: args["sampling-rate"],
|
|
761
1068
|
search: args.search,
|
|
1069
|
+
clientIp: args.ip,
|
|
762
1070
|
};
|
|
763
1071
|
|
|
764
|
-
const
|
|
765
|
-
|
|
1072
|
+
const filters = translateCLICommandToFilterMessage(
|
|
1073
|
+
cliFilters,
|
|
1074
|
+
args.debug
|
|
1075
|
+
);
|
|
1076
|
+
|
|
1077
|
+
const { tail, expiration, deleteTail } = await createTail(
|
|
1078
|
+
accountId,
|
|
1079
|
+
scriptName,
|
|
1080
|
+
filters,
|
|
1081
|
+
!isLegacyEnv(args, config) ? args.env : undefined
|
|
1082
|
+
);
|
|
1083
|
+
|
|
1084
|
+
const scriptDisplayName = `${scriptName}${
|
|
1085
|
+
args.env && !isLegacyEnv(args, config) ? ` (${args.env})` : ""
|
|
1086
|
+
}`;
|
|
766
1087
|
|
|
767
1088
|
console.log(
|
|
768
1089
|
`successfully created tail, expires at ${expiration.toLocaleString()}`
|
|
@@ -773,24 +1094,32 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
773
1094
|
await deleteTail();
|
|
774
1095
|
});
|
|
775
1096
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1097
|
+
const printLog: (data: RawData) => void =
|
|
1098
|
+
args.format === "pretty" ? prettyPrintLogs : jsonPrintLogs;
|
|
1099
|
+
|
|
1100
|
+
tail.on("message", printLog);
|
|
779
1101
|
|
|
780
1102
|
while (tail.readyState !== tail.OPEN) {
|
|
781
1103
|
switch (tail.readyState) {
|
|
782
1104
|
case tail.CONNECTING:
|
|
783
|
-
await setTimeout(
|
|
1105
|
+
await setTimeout(100);
|
|
784
1106
|
break;
|
|
785
1107
|
case tail.CLOSING:
|
|
786
|
-
await setTimeout(
|
|
1108
|
+
await setTimeout(100);
|
|
787
1109
|
break;
|
|
788
1110
|
case tail.CLOSED:
|
|
789
|
-
|
|
1111
|
+
throw new Error(
|
|
1112
|
+
`Connection to ${scriptDisplayName} closed unexpectedly.`
|
|
1113
|
+
);
|
|
790
1114
|
}
|
|
791
1115
|
}
|
|
792
1116
|
|
|
793
|
-
console.log(`Connected to ${
|
|
1117
|
+
console.log(`Connected to ${scriptDisplayName}, waiting for logs...`);
|
|
1118
|
+
|
|
1119
|
+
tail.on("close", async () => {
|
|
1120
|
+
tail.terminate();
|
|
1121
|
+
await deleteTail();
|
|
1122
|
+
});
|
|
794
1123
|
}
|
|
795
1124
|
);
|
|
796
1125
|
|
|
@@ -801,14 +1130,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
801
1130
|
(yargs) => {
|
|
802
1131
|
return yargs
|
|
803
1132
|
.positional("method", {
|
|
1133
|
+
type: "string",
|
|
804
1134
|
describe: "Type of request to preview your worker",
|
|
805
|
-
choices: ["GET", "POST"],
|
|
806
|
-
default: ["GET"],
|
|
807
1135
|
})
|
|
808
1136
|
.positional("body", {
|
|
809
1137
|
type: "string",
|
|
810
1138
|
describe: "Body string to post to your preview worker request.",
|
|
811
|
-
default: "Null",
|
|
812
1139
|
})
|
|
813
1140
|
.option("env", {
|
|
814
1141
|
type: "string",
|
|
@@ -820,11 +1147,104 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
820
1147
|
type: "boolean",
|
|
821
1148
|
});
|
|
822
1149
|
},
|
|
823
|
-
() => {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1150
|
+
async (args) => {
|
|
1151
|
+
if (args.method || args.body) {
|
|
1152
|
+
throw new DeprecationError(
|
|
1153
|
+
"The `wrangler preview` command has been deprecated.\n" +
|
|
1154
|
+
"Try using `wrangler dev` to to try out a worker during development.\n"
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// Delegate to `wrangler dev`
|
|
1159
|
+
console.warn(
|
|
1160
|
+
"***************************************************\n" +
|
|
1161
|
+
"The `wrangler preview` command has been deprecated.\n" +
|
|
1162
|
+
"Attempting to run `wrangler dev` instead.\n" +
|
|
1163
|
+
"***************************************************\n"
|
|
827
1164
|
);
|
|
1165
|
+
|
|
1166
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1167
|
+
const entry = getEntry(config, "dev");
|
|
1168
|
+
|
|
1169
|
+
// -- snip, extract --
|
|
1170
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1171
|
+
if (!loggedIn) {
|
|
1172
|
+
// didn't login, let's just quit
|
|
1173
|
+
console.log("Did not login, quitting...");
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if (!config.account_id) {
|
|
1178
|
+
config.account_id = await getAccountId();
|
|
1179
|
+
if (!config.account_id) {
|
|
1180
|
+
throw new Error("No account id found, quitting...");
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
// -- snip, end --
|
|
1184
|
+
|
|
1185
|
+
const environments = config.env ?? {};
|
|
1186
|
+
const envRootObj = args.env ? environments[args.env] || {} : config;
|
|
1187
|
+
|
|
1188
|
+
const { waitUntilExit } = render(
|
|
1189
|
+
<Dev
|
|
1190
|
+
name={config.name}
|
|
1191
|
+
entry={entry}
|
|
1192
|
+
rules={getRules(config)}
|
|
1193
|
+
env={args.env}
|
|
1194
|
+
zone={undefined}
|
|
1195
|
+
legacyEnv={isLegacyEnv(args, config)}
|
|
1196
|
+
buildCommand={config.build || {}}
|
|
1197
|
+
format={config.build?.upload?.format}
|
|
1198
|
+
initialMode={args.local ? "local" : "remote"}
|
|
1199
|
+
jsxFactory={envRootObj?.jsx_factory}
|
|
1200
|
+
jsxFragment={envRootObj?.jsx_fragment}
|
|
1201
|
+
enableLocalPersistence={false}
|
|
1202
|
+
accountId={config.account_id}
|
|
1203
|
+
assetPaths={undefined}
|
|
1204
|
+
port={config.dev?.port}
|
|
1205
|
+
public={undefined}
|
|
1206
|
+
compatibilityDate={
|
|
1207
|
+
config.compatibility_date ||
|
|
1208
|
+
new Date().toISOString().substring(0, 10)
|
|
1209
|
+
}
|
|
1210
|
+
compatibilityFlags={
|
|
1211
|
+
(args["compatibility-flags"] as string[]) ||
|
|
1212
|
+
config.compatibility_flags
|
|
1213
|
+
}
|
|
1214
|
+
usageModel={config.usage_model}
|
|
1215
|
+
bindings={{
|
|
1216
|
+
kv_namespaces: envRootObj.kv_namespaces?.map(
|
|
1217
|
+
({ binding, preview_id, id: _id }) => {
|
|
1218
|
+
// In `dev`, we make folks use a separate kv namespace called
|
|
1219
|
+
// `preview_id` instead of `id` so that they don't
|
|
1220
|
+
// break production data. So here we check that a `preview_id`
|
|
1221
|
+
// has actually been configured.
|
|
1222
|
+
// This whole block of code will be obsoleted in the future
|
|
1223
|
+
// when we have copy-on-write for previews on edge workers.
|
|
1224
|
+
if (!preview_id) {
|
|
1225
|
+
// TODO: This error has to be a _lot_ better, ideally just asking
|
|
1226
|
+
// to create a preview namespace for the user automatically
|
|
1227
|
+
throw new Error(
|
|
1228
|
+
`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`
|
|
1229
|
+
); // Ugh, I really don't like this message very much
|
|
1230
|
+
}
|
|
1231
|
+
return {
|
|
1232
|
+
binding,
|
|
1233
|
+
id: preview_id,
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
),
|
|
1237
|
+
vars: envRootObj.vars,
|
|
1238
|
+
wasm_modules: config.wasm_modules,
|
|
1239
|
+
text_blobs: config.text_blobs,
|
|
1240
|
+
durable_objects: envRootObj.durable_objects,
|
|
1241
|
+
r2_buckets: envRootObj.r2_buckets,
|
|
1242
|
+
unsafe: envRootObj.unsafe?.bindings,
|
|
1243
|
+
}}
|
|
1244
|
+
inspectorPort={await getPort({ port: 9229 })}
|
|
1245
|
+
/>
|
|
1246
|
+
);
|
|
1247
|
+
await waitUntilExit();
|
|
828
1248
|
}
|
|
829
1249
|
);
|
|
830
1250
|
|
|
@@ -837,7 +1257,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
837
1257
|
return routeYargs
|
|
838
1258
|
.command(
|
|
839
1259
|
"list",
|
|
840
|
-
"List
|
|
1260
|
+
"List the routes associated with a zone",
|
|
841
1261
|
(yargs) => {
|
|
842
1262
|
return yargs
|
|
843
1263
|
.option("env", {
|
|
@@ -846,17 +1266,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
846
1266
|
})
|
|
847
1267
|
.option("zone", {
|
|
848
1268
|
type: "string",
|
|
849
|
-
describe: "
|
|
1269
|
+
describe: "Zone id",
|
|
850
1270
|
})
|
|
851
1271
|
.positional("zone", {
|
|
852
|
-
describe: "
|
|
1272
|
+
describe: "Zone id",
|
|
853
1273
|
type: "string",
|
|
854
1274
|
});
|
|
855
1275
|
},
|
|
856
1276
|
async (args) => {
|
|
857
1277
|
console.log(":route list", args);
|
|
858
1278
|
// TODO: use environment (current wrangler doesn't do so?)
|
|
859
|
-
|
|
1279
|
+
// TODO: don't get `zone_id` from config at all and require the command line arg `--zone`.
|
|
1280
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1281
|
+
const zone = args.zone || config.zone_id;
|
|
860
1282
|
if (!zone) {
|
|
861
1283
|
throw new Error("missing zone id");
|
|
862
1284
|
}
|
|
@@ -885,7 +1307,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
885
1307
|
async (args) => {
|
|
886
1308
|
console.log(":route delete", args);
|
|
887
1309
|
// TODO: use environment (current wrangler doesn't do so?)
|
|
888
|
-
const
|
|
1310
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1311
|
+
const zone = args.zone || config.zone_id;
|
|
889
1312
|
if (!zone) {
|
|
890
1313
|
throw new Error("missing zone id");
|
|
891
1314
|
}
|
|
@@ -927,82 +1350,86 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
927
1350
|
(yargs) => {
|
|
928
1351
|
return yargs
|
|
929
1352
|
.positional("key", {
|
|
930
|
-
describe: "The variable name to be accessible in the script
|
|
1353
|
+
describe: "The variable name to be accessible in the script",
|
|
931
1354
|
type: "string",
|
|
932
1355
|
})
|
|
933
1356
|
.option("name", {
|
|
934
|
-
describe: "
|
|
1357
|
+
describe: "Name of the worker",
|
|
935
1358
|
type: "string",
|
|
936
1359
|
})
|
|
937
1360
|
.option("env", {
|
|
938
1361
|
type: "string",
|
|
939
1362
|
describe:
|
|
940
|
-
"Binds the secret to the
|
|
1363
|
+
"Binds the secret to the Worker of the specific environment",
|
|
941
1364
|
});
|
|
942
1365
|
},
|
|
943
1366
|
async (args) => {
|
|
944
|
-
|
|
945
|
-
throw new NotImplementedError(
|
|
946
|
-
"--local not implemented for this command yet"
|
|
947
|
-
);
|
|
948
|
-
}
|
|
949
|
-
const config = args.config as Config;
|
|
1367
|
+
const config = readConfig(args.config as ConfigPath);
|
|
950
1368
|
|
|
951
|
-
|
|
952
|
-
const scriptName = args.name || config.name;
|
|
1369
|
+
const scriptName = getScriptName(args, config);
|
|
953
1370
|
if (!scriptName) {
|
|
954
1371
|
throw new Error("Missing script name");
|
|
955
1372
|
}
|
|
956
1373
|
|
|
957
1374
|
// -- snip, extract --
|
|
1375
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1376
|
+
if (!loggedIn) {
|
|
1377
|
+
// didn't login, let's just quit
|
|
1378
|
+
console.log("Did not login, quitting...");
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
958
1381
|
|
|
959
|
-
if (!
|
|
960
|
-
|
|
961
|
-
if (!loggedIn) {
|
|
962
|
-
// didn't login, let's just quit
|
|
963
|
-
console.log("Did not login, quitting...");
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
1382
|
+
if (!config.account_id) {
|
|
1383
|
+
config.account_id = await getAccountId();
|
|
966
1384
|
if (!config.account_id) {
|
|
967
|
-
|
|
968
|
-
if (!config.account_id) {
|
|
969
|
-
throw new Error("No account id found, quitting...");
|
|
970
|
-
}
|
|
1385
|
+
throw new Error("No account id found, quitting...");
|
|
971
1386
|
}
|
|
972
1387
|
}
|
|
973
|
-
|
|
974
1388
|
// -- snip, end --
|
|
975
1389
|
|
|
976
1390
|
const secretValue = await prompt(
|
|
977
1391
|
"Enter a secret value:",
|
|
978
1392
|
"password"
|
|
979
1393
|
);
|
|
1394
|
+
|
|
1395
|
+
console.log(
|
|
1396
|
+
`🌀 Creating the secret for script ${scriptName} ${
|
|
1397
|
+
args.env && !isLegacyEnv(args, config) ? `(${args.env})` : ""
|
|
1398
|
+
}`
|
|
1399
|
+
);
|
|
1400
|
+
|
|
980
1401
|
async function submitSecret() {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1402
|
+
const url =
|
|
1403
|
+
!args.env || isLegacyEnv(args, config)
|
|
1404
|
+
? `/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1405
|
+
: `/accounts/${config.account_id}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1406
|
+
|
|
1407
|
+
return await fetchResult(url, {
|
|
1408
|
+
method: "PUT",
|
|
1409
|
+
headers: { "Content-Type": "application/json" },
|
|
1410
|
+
body: JSON.stringify({
|
|
1411
|
+
name: args.key,
|
|
1412
|
+
text: secretValue,
|
|
1413
|
+
type: "secret_text",
|
|
1414
|
+
}),
|
|
1415
|
+
});
|
|
993
1416
|
}
|
|
994
1417
|
|
|
995
1418
|
try {
|
|
996
|
-
|
|
1419
|
+
await submitSecret();
|
|
997
1420
|
} catch (e) {
|
|
1421
|
+
// @ts-expect-error non-standard property on Error
|
|
998
1422
|
if (e.code === 10007) {
|
|
999
1423
|
// upload a draft worker
|
|
1424
|
+
// TODO: log a warning
|
|
1000
1425
|
await fetchResult(
|
|
1001
|
-
|
|
1426
|
+
!args["legacy-env"] && args.env
|
|
1427
|
+
? `/accounts/${config.account_id}/workers/services/${scriptName}/environments/${args.env}`
|
|
1428
|
+
: `/accounts/${config.account_id}/workers/scripts/${scriptName}`,
|
|
1002
1429
|
{
|
|
1003
1430
|
method: "PUT",
|
|
1004
|
-
// @ts-expect-error TODO: fix this error!
|
|
1005
1431
|
body: toFormData({
|
|
1432
|
+
name: scriptName,
|
|
1006
1433
|
main: {
|
|
1007
1434
|
name: scriptName,
|
|
1008
1435
|
content: `export default { fetch() {} }`,
|
|
@@ -1012,17 +1439,26 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1012
1439
|
kv_namespaces: [],
|
|
1013
1440
|
vars: {},
|
|
1014
1441
|
durable_objects: { bindings: [] },
|
|
1442
|
+
r2_buckets: [],
|
|
1443
|
+
wasm_modules: {},
|
|
1444
|
+
text_blobs: {},
|
|
1445
|
+
unsafe: [],
|
|
1015
1446
|
},
|
|
1016
1447
|
modules: [],
|
|
1448
|
+
migrations: undefined,
|
|
1449
|
+
compatibility_date: undefined,
|
|
1450
|
+
compatibility_flags: undefined,
|
|
1451
|
+
usage_model: undefined,
|
|
1017
1452
|
}),
|
|
1018
1453
|
}
|
|
1019
1454
|
);
|
|
1020
1455
|
|
|
1021
1456
|
// and then try again
|
|
1022
|
-
|
|
1457
|
+
await submitSecret();
|
|
1023
1458
|
// TODO: delete the draft worker if this failed too?
|
|
1024
1459
|
}
|
|
1025
1460
|
}
|
|
1461
|
+
console.log(`✨ Success! Uploaded secret ${args.key}`);
|
|
1026
1462
|
}
|
|
1027
1463
|
)
|
|
1028
1464
|
.command(
|
|
@@ -1031,63 +1467,65 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1031
1467
|
(yargs) => {
|
|
1032
1468
|
return yargs
|
|
1033
1469
|
.positional("key", {
|
|
1034
|
-
describe: "The variable name to be accessible in the script
|
|
1470
|
+
describe: "The variable name to be accessible in the script",
|
|
1035
1471
|
type: "string",
|
|
1036
1472
|
})
|
|
1037
1473
|
.option("name", {
|
|
1038
|
-
describe: "
|
|
1474
|
+
describe: "Name of the worker",
|
|
1039
1475
|
type: "string",
|
|
1040
1476
|
})
|
|
1041
1477
|
.option("env", {
|
|
1042
1478
|
type: "string",
|
|
1043
1479
|
describe:
|
|
1044
|
-
"Binds the secret to the
|
|
1480
|
+
"Binds the secret to the Worker of the specific environment",
|
|
1045
1481
|
});
|
|
1046
1482
|
},
|
|
1047
1483
|
async (args) => {
|
|
1048
|
-
|
|
1049
|
-
throw new NotImplementedError(
|
|
1050
|
-
"--local not implemented for this command yet"
|
|
1051
|
-
);
|
|
1052
|
-
}
|
|
1053
|
-
const config = args.config as Config;
|
|
1484
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1054
1485
|
|
|
1055
|
-
|
|
1056
|
-
const scriptName = args.name || config.name;
|
|
1486
|
+
const scriptName = getScriptName(args, config);
|
|
1057
1487
|
if (!scriptName) {
|
|
1058
1488
|
throw new Error("Missing script name");
|
|
1059
1489
|
}
|
|
1060
1490
|
|
|
1061
1491
|
// -- snip, extract --
|
|
1492
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1493
|
+
if (!loggedIn) {
|
|
1494
|
+
// didn't login, let's just quit
|
|
1495
|
+
console.log("Did not login, quitting...");
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1062
1498
|
|
|
1063
|
-
if (!
|
|
1064
|
-
|
|
1065
|
-
if (!loggedIn) {
|
|
1066
|
-
// didn't login, let's just quit
|
|
1067
|
-
console.log("Did not login, quitting...");
|
|
1068
|
-
return;
|
|
1069
|
-
}
|
|
1499
|
+
if (!config.account_id) {
|
|
1500
|
+
config.account_id = await getAccountId();
|
|
1070
1501
|
if (!config.account_id) {
|
|
1071
|
-
|
|
1072
|
-
if (!config.account_id) {
|
|
1073
|
-
throw new Error("No account id found, quitting...");
|
|
1074
|
-
}
|
|
1502
|
+
throw new Error("No account id found, quitting...");
|
|
1075
1503
|
}
|
|
1076
1504
|
}
|
|
1077
|
-
|
|
1078
1505
|
// -- snip, end --
|
|
1079
1506
|
|
|
1080
|
-
if (
|
|
1507
|
+
if (
|
|
1508
|
+
await confirm(
|
|
1509
|
+
`Are you sure you want to permanently delete the variable ${
|
|
1510
|
+
args.key
|
|
1511
|
+
} on the script ${scriptName}${
|
|
1512
|
+
args.env && !isLegacyEnv(args, config) ? ` (${args.env})` : ""
|
|
1513
|
+
}?`
|
|
1514
|
+
)
|
|
1515
|
+
) {
|
|
1081
1516
|
console.log(
|
|
1082
|
-
|
|
1517
|
+
`🌀 Deleting the secret ${args.key} on script ${scriptName}${
|
|
1518
|
+
args.env && !isLegacyEnv(args, config) ? ` (${args.env})` : ""
|
|
1519
|
+
}`
|
|
1083
1520
|
);
|
|
1084
1521
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
);
|
|
1522
|
+
const url =
|
|
1523
|
+
!args.env || isLegacyEnv(args, config)
|
|
1524
|
+
? `/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1525
|
+
: `/accounts/${config.account_id}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1526
|
+
|
|
1527
|
+
await fetchResult(`${url}/${args.key}`, { method: "DELETE" });
|
|
1528
|
+
console.log(`✨ Success! Deleted secret ${args.key}`);
|
|
1091
1529
|
}
|
|
1092
1530
|
}
|
|
1093
1531
|
)
|
|
@@ -1097,53 +1535,45 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1097
1535
|
(yargs) => {
|
|
1098
1536
|
return yargs
|
|
1099
1537
|
.option("name", {
|
|
1100
|
-
describe: "
|
|
1538
|
+
describe: "Name of the worker",
|
|
1101
1539
|
type: "string",
|
|
1102
1540
|
})
|
|
1103
1541
|
.option("env", {
|
|
1104
1542
|
type: "string",
|
|
1105
1543
|
describe:
|
|
1106
|
-
"Binds the secret to the
|
|
1544
|
+
"Binds the secret to the Worker of the specific environment.",
|
|
1107
1545
|
});
|
|
1108
1546
|
},
|
|
1109
1547
|
async (args) => {
|
|
1110
|
-
|
|
1111
|
-
throw new NotImplementedError(
|
|
1112
|
-
"--local not implemented for this command yet"
|
|
1113
|
-
);
|
|
1114
|
-
}
|
|
1115
|
-
const config = args.config as Config;
|
|
1548
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1116
1549
|
|
|
1117
|
-
|
|
1118
|
-
const scriptName = args.name || config.name;
|
|
1550
|
+
const scriptName = getScriptName(args, config);
|
|
1119
1551
|
if (!scriptName) {
|
|
1120
1552
|
throw new Error("Missing script name");
|
|
1121
1553
|
}
|
|
1122
1554
|
|
|
1123
1555
|
// -- snip, extract --
|
|
1556
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1557
|
+
if (!loggedIn) {
|
|
1558
|
+
// didn't login, let's just quit
|
|
1559
|
+
console.log("Did not login, quitting...");
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1124
1562
|
|
|
1125
|
-
if (!
|
|
1126
|
-
|
|
1127
|
-
if (!loggedIn) {
|
|
1128
|
-
// didn't login, let's just quit
|
|
1129
|
-
console.log("Did not login, quitting...");
|
|
1130
|
-
return;
|
|
1131
|
-
}
|
|
1563
|
+
if (!config.account_id) {
|
|
1564
|
+
config.account_id = await getAccountId();
|
|
1132
1565
|
if (!config.account_id) {
|
|
1133
|
-
|
|
1134
|
-
if (!config.account_id) {
|
|
1135
|
-
throw new Error("No account id found, quitting...");
|
|
1136
|
-
}
|
|
1566
|
+
throw new Error("No account id found, quitting...");
|
|
1137
1567
|
}
|
|
1138
1568
|
}
|
|
1139
|
-
|
|
1140
1569
|
// -- snip, end --
|
|
1141
1570
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1145
|
-
|
|
1146
|
-
|
|
1571
|
+
const url =
|
|
1572
|
+
!args.env || isLegacyEnv(args, config)
|
|
1573
|
+
? `/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
|
|
1574
|
+
: `/accounts/${config.account_id}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1575
|
+
|
|
1576
|
+
console.log(JSON.stringify(await fetchResult(url), null, " "));
|
|
1147
1577
|
}
|
|
1148
1578
|
);
|
|
1149
1579
|
}
|
|
@@ -1164,6 +1594,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1164
1594
|
.positional("namespace", {
|
|
1165
1595
|
describe: "The name of the new namespace",
|
|
1166
1596
|
type: "string",
|
|
1597
|
+
demandOption: true,
|
|
1167
1598
|
})
|
|
1168
1599
|
.option("env", {
|
|
1169
1600
|
type: "string",
|
|
@@ -1188,7 +1619,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1188
1619
|
);
|
|
1189
1620
|
}
|
|
1190
1621
|
|
|
1191
|
-
const config = args.config as
|
|
1622
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1192
1623
|
if (!config.name) {
|
|
1193
1624
|
console.warn(
|
|
1194
1625
|
"No configured name present, using `worker` as a prefix for the title"
|
|
@@ -1200,35 +1631,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1200
1631
|
const preview = args.preview ? "_preview" : "";
|
|
1201
1632
|
const title = `${name}${environment}-${args.namespace}${preview}`;
|
|
1202
1633
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
script: ` `, // has to be a string with at least one char
|
|
1209
|
-
});
|
|
1210
|
-
await mf.getKVNamespace(title); // this should "create" the namespace
|
|
1211
|
-
console.log(`✨ Success! Created KV namespace ${title}`);
|
|
1634
|
+
// -- snip, extract --
|
|
1635
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1636
|
+
if (!loggedIn) {
|
|
1637
|
+
// didn't login, let's just quit
|
|
1638
|
+
console.log("Did not login, quitting...");
|
|
1212
1639
|
return;
|
|
1213
1640
|
}
|
|
1214
1641
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
if (!args.local) {
|
|
1218
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1219
|
-
if (!loggedIn) {
|
|
1220
|
-
// didn't login, let's just quit
|
|
1221
|
-
console.log("Did not login, quitting...");
|
|
1222
|
-
return;
|
|
1223
|
-
}
|
|
1642
|
+
if (!config.account_id) {
|
|
1643
|
+
config.account_id = await getAccountId();
|
|
1224
1644
|
if (!config.account_id) {
|
|
1225
|
-
|
|
1226
|
-
if (!config.account_id) {
|
|
1227
|
-
throw new Error("No account id found, quitting...");
|
|
1228
|
-
}
|
|
1645
|
+
throw new Error("No account id found, quitting...");
|
|
1229
1646
|
}
|
|
1230
1647
|
}
|
|
1231
|
-
|
|
1232
1648
|
// -- snip, end --
|
|
1233
1649
|
|
|
1234
1650
|
// TODO: generate a binding name stripping non alphanumeric chars
|
|
@@ -1254,31 +1670,22 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1254
1670
|
"Outputs a list of all KV namespaces associated with your account id.",
|
|
1255
1671
|
{},
|
|
1256
1672
|
async (args) => {
|
|
1257
|
-
|
|
1258
|
-
throw new NotImplementedError(
|
|
1259
|
-
`local mode is not yet supported for this command`
|
|
1260
|
-
);
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
const config = args.config as Config;
|
|
1673
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1264
1674
|
|
|
1265
1675
|
// -- snip, extract --
|
|
1676
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1677
|
+
if (!loggedIn) {
|
|
1678
|
+
// didn't login, let's just quit
|
|
1679
|
+
console.log("Did not login, quitting...");
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1266
1682
|
|
|
1267
|
-
if (!
|
|
1268
|
-
|
|
1269
|
-
if (!loggedIn) {
|
|
1270
|
-
// didn't login, let's just quit
|
|
1271
|
-
console.log("Did not login, quitting...");
|
|
1272
|
-
return;
|
|
1273
|
-
}
|
|
1683
|
+
if (!config.account_id) {
|
|
1684
|
+
config.account_id = await getAccountId();
|
|
1274
1685
|
if (!config.account_id) {
|
|
1275
|
-
|
|
1276
|
-
if (!config.account_id) {
|
|
1277
|
-
throw new Error("No account id found, quitting...");
|
|
1278
|
-
}
|
|
1686
|
+
throw new Error("No account id found, quitting...");
|
|
1279
1687
|
}
|
|
1280
1688
|
}
|
|
1281
|
-
|
|
1282
1689
|
// -- snip, end --
|
|
1283
1690
|
|
|
1284
1691
|
// TODO: we should show bindings if they exist for given ids
|
|
@@ -1316,40 +1723,31 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1316
1723
|
});
|
|
1317
1724
|
},
|
|
1318
1725
|
async (args) => {
|
|
1319
|
-
|
|
1320
|
-
throw new NotImplementedError(
|
|
1321
|
-
`local mode is not yet supported for this command`
|
|
1322
|
-
);
|
|
1323
|
-
}
|
|
1324
|
-
const config = args.config as Config;
|
|
1726
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1325
1727
|
|
|
1326
1728
|
let id;
|
|
1327
1729
|
try {
|
|
1328
|
-
id = getNamespaceId(args);
|
|
1730
|
+
id = getNamespaceId(args, config);
|
|
1329
1731
|
} catch (e) {
|
|
1330
1732
|
throw new CommandLineArgsError(
|
|
1331
|
-
"Not able to delete namespace.\n" + e.message
|
|
1733
|
+
"Not able to delete namespace.\n" + ((e as Error).message ?? e)
|
|
1332
1734
|
);
|
|
1333
1735
|
}
|
|
1334
1736
|
|
|
1335
1737
|
// -- snip, extract --
|
|
1738
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1739
|
+
if (!loggedIn) {
|
|
1740
|
+
// didn't login, let's just quit
|
|
1741
|
+
console.log("Did not login, quitting...");
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1336
1744
|
|
|
1337
|
-
if (!
|
|
1338
|
-
|
|
1339
|
-
if (!loggedIn) {
|
|
1340
|
-
// didn't login, let's just quit
|
|
1341
|
-
console.log("Did not login, quitting...");
|
|
1342
|
-
return;
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1745
|
+
if (!config.account_id) {
|
|
1746
|
+
config.account_id = await getAccountId();
|
|
1345
1747
|
if (!config.account_id) {
|
|
1346
|
-
|
|
1347
|
-
if (!config.account_id) {
|
|
1348
|
-
throw new Error("No account id found, quitting...");
|
|
1349
|
-
}
|
|
1748
|
+
throw new Error("No account id found, quitting...");
|
|
1350
1749
|
}
|
|
1351
1750
|
}
|
|
1352
|
-
|
|
1353
1751
|
// -- snip, end --
|
|
1354
1752
|
|
|
1355
1753
|
await fetchResult<{ id: string }>(
|
|
@@ -1392,19 +1790,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1392
1790
|
return yargs
|
|
1393
1791
|
.positional("key", {
|
|
1394
1792
|
type: "string",
|
|
1395
|
-
describe: "The key to write to
|
|
1793
|
+
describe: "The key to write to",
|
|
1794
|
+
demandOption: true,
|
|
1396
1795
|
})
|
|
1397
1796
|
.positional("value", {
|
|
1398
1797
|
type: "string",
|
|
1399
|
-
describe: "The value to write
|
|
1798
|
+
describe: "The value to write",
|
|
1400
1799
|
})
|
|
1401
1800
|
.option("binding", {
|
|
1402
1801
|
type: "string",
|
|
1403
|
-
describe: "The binding of the namespace to write to
|
|
1802
|
+
describe: "The binding of the namespace to write to",
|
|
1404
1803
|
})
|
|
1405
1804
|
.option("namespace-id", {
|
|
1406
1805
|
type: "string",
|
|
1407
|
-
describe: "The id of the namespace to write to
|
|
1806
|
+
describe: "The id of the namespace to write to",
|
|
1408
1807
|
})
|
|
1409
1808
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1410
1809
|
.option("env", {
|
|
@@ -1417,7 +1816,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1417
1816
|
})
|
|
1418
1817
|
.option("ttl", {
|
|
1419
1818
|
type: "number",
|
|
1420
|
-
describe: "Time for which the entries should be visible
|
|
1819
|
+
describe: "Time for which the entries should be visible",
|
|
1421
1820
|
})
|
|
1422
1821
|
.option("expiration", {
|
|
1423
1822
|
type: "number",
|
|
@@ -1426,16 +1825,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1426
1825
|
})
|
|
1427
1826
|
.option("path", {
|
|
1428
1827
|
type: "string",
|
|
1429
|
-
describe: "Read value from the file at a given path
|
|
1828
|
+
describe: "Read value from the file at a given path",
|
|
1430
1829
|
})
|
|
1431
1830
|
.check(demandOneOfOption("value", "path"));
|
|
1432
1831
|
},
|
|
1433
1832
|
async ({ key, ttl, expiration, ...args }) => {
|
|
1434
|
-
const
|
|
1833
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1834
|
+
const namespaceId = getNamespaceId(args, config);
|
|
1835
|
+
// One of `args.path` and `args.value` must be defined
|
|
1435
1836
|
const value = args.path
|
|
1436
|
-
?
|
|
1437
|
-
:
|
|
1438
|
-
|
|
1837
|
+
? readFileSync(args.path)
|
|
1838
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1839
|
+
args.value!;
|
|
1439
1840
|
|
|
1440
1841
|
if (args.path) {
|
|
1441
1842
|
console.log(
|
|
@@ -1447,35 +1848,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1447
1848
|
);
|
|
1448
1849
|
}
|
|
1449
1850
|
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
script: ` `, // has to be a string with at least one char
|
|
1456
|
-
});
|
|
1457
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1458
|
-
await ns.put(key, value, { expiration, expirationTtl: ttl });
|
|
1851
|
+
// -- snip, extract --
|
|
1852
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1853
|
+
if (!loggedIn) {
|
|
1854
|
+
// didn't login, let's just quit
|
|
1855
|
+
console.log("Did not login, quitting...");
|
|
1459
1856
|
return;
|
|
1460
1857
|
}
|
|
1461
|
-
// -- snip, extract --
|
|
1462
|
-
|
|
1463
|
-
if (!args.local) {
|
|
1464
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1465
|
-
if (!loggedIn) {
|
|
1466
|
-
// didn't login, let's just quit
|
|
1467
|
-
console.log("Did not login, quitting...");
|
|
1468
|
-
return;
|
|
1469
|
-
}
|
|
1470
1858
|
|
|
1859
|
+
if (!config.account_id) {
|
|
1860
|
+
config.account_id = await getAccountId();
|
|
1471
1861
|
if (!config.account_id) {
|
|
1472
|
-
|
|
1473
|
-
if (!config.account_id) {
|
|
1474
|
-
throw new Error("No account id found, quitting...");
|
|
1475
|
-
}
|
|
1862
|
+
throw new Error("No account id found, quitting...");
|
|
1476
1863
|
}
|
|
1477
1864
|
}
|
|
1478
|
-
|
|
1479
1865
|
// -- snip, end --
|
|
1480
1866
|
|
|
1481
1867
|
await putKeyValue(config.account_id, namespaceId, key, value, {
|
|
@@ -1515,46 +1901,31 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1515
1901
|
},
|
|
1516
1902
|
async ({ prefix, ...args }) => {
|
|
1517
1903
|
// TODO: support for limit+cursor (pagination)
|
|
1904
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1905
|
+
const namespaceId = getNamespaceId(args, config);
|
|
1518
1906
|
|
|
1519
|
-
|
|
1520
|
-
const
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
const mf = new Miniflare({
|
|
1525
|
-
kvPersist: (args.kvPersist as string) || true,
|
|
1526
|
-
// TODO: these options shouldn't be required
|
|
1527
|
-
script: ` `, // has to be a string with at least one char
|
|
1528
|
-
});
|
|
1529
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1530
|
-
const listResponse = await ns.list({ prefix });
|
|
1531
|
-
console.log(JSON.stringify(listResponse.keys, null, " ")); // TODO: paginate, collate
|
|
1907
|
+
// -- snip, extract --
|
|
1908
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1909
|
+
if (!loggedIn) {
|
|
1910
|
+
// didn't login, let's just quit
|
|
1911
|
+
console.log("Did not login, quitting...");
|
|
1532
1912
|
return;
|
|
1533
1913
|
}
|
|
1534
1914
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
if (!args.local) {
|
|
1538
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1539
|
-
if (!loggedIn) {
|
|
1540
|
-
// didn't login, let's just quit
|
|
1541
|
-
console.log("Did not login, quitting...");
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1915
|
+
if (!config.account_id) {
|
|
1916
|
+
config.account_id = await getAccountId();
|
|
1545
1917
|
if (!config.account_id) {
|
|
1546
|
-
|
|
1547
|
-
if (!config.account_id) {
|
|
1548
|
-
throw new Error("No account id found, quitting...");
|
|
1549
|
-
}
|
|
1918
|
+
throw new Error("No account id found, quitting...");
|
|
1550
1919
|
}
|
|
1551
1920
|
}
|
|
1552
|
-
|
|
1553
1921
|
// -- snip, end --
|
|
1554
1922
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1923
|
+
const results = await listNamespaceKeys(
|
|
1924
|
+
config.account_id,
|
|
1925
|
+
namespaceId,
|
|
1926
|
+
prefix
|
|
1557
1927
|
);
|
|
1928
|
+
console.log(JSON.stringify(results, undefined, 2));
|
|
1558
1929
|
}
|
|
1559
1930
|
)
|
|
1560
1931
|
.command(
|
|
@@ -1565,6 +1936,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1565
1936
|
.positional("key", {
|
|
1566
1937
|
describe: "The key value to get.",
|
|
1567
1938
|
type: "string",
|
|
1939
|
+
demandOption: true,
|
|
1568
1940
|
})
|
|
1569
1941
|
.option("binding", {
|
|
1570
1942
|
type: "string",
|
|
@@ -1591,46 +1963,26 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1591
1963
|
});
|
|
1592
1964
|
},
|
|
1593
1965
|
async ({ key, ...args }) => {
|
|
1594
|
-
const
|
|
1595
|
-
const
|
|
1596
|
-
|
|
1597
|
-
if (args.local) {
|
|
1598
|
-
const { Miniflare } = await import("miniflare");
|
|
1599
|
-
const mf = new Miniflare({
|
|
1600
|
-
kvPersist: (args.kvPersist as string) || true,
|
|
1601
|
-
// TODO: these options shouldn't be required
|
|
1602
|
-
script: ` `, // has to be a string with at least one char
|
|
1603
|
-
});
|
|
1604
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1605
|
-
console.log(await ns.get(key));
|
|
1606
|
-
return;
|
|
1607
|
-
}
|
|
1966
|
+
const config = readConfig(args.config as ConfigPath);
|
|
1967
|
+
const namespaceId = getNamespaceId(args, config);
|
|
1608
1968
|
|
|
1609
1969
|
// -- snip, extract --
|
|
1970
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
1971
|
+
if (!loggedIn) {
|
|
1972
|
+
// didn't login, let's just quit
|
|
1973
|
+
console.log("Did not login, quitting...");
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1610
1976
|
|
|
1611
|
-
if (!
|
|
1612
|
-
|
|
1613
|
-
if (!loggedIn) {
|
|
1614
|
-
// didn't login, let's just quit
|
|
1615
|
-
console.log("Did not login, quitting...");
|
|
1616
|
-
return;
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1977
|
+
if (!config.account_id) {
|
|
1978
|
+
config.account_id = await getAccountId();
|
|
1619
1979
|
if (!config.account_id) {
|
|
1620
|
-
|
|
1621
|
-
if (!config.account_id) {
|
|
1622
|
-
throw new Error("No account id found, quitting...");
|
|
1623
|
-
}
|
|
1980
|
+
throw new Error("No account id found, quitting...");
|
|
1624
1981
|
}
|
|
1625
1982
|
}
|
|
1626
|
-
|
|
1627
1983
|
// -- snip, end --
|
|
1628
1984
|
|
|
1629
|
-
console.log(
|
|
1630
|
-
await fetchRaw(
|
|
1631
|
-
`/accounts/${config.account_id}/storage/kv/namespaces/${namespaceId}/values/${key}`
|
|
1632
|
-
)
|
|
1633
|
-
);
|
|
1985
|
+
console.log(await getKeyValue(config.account_id, namespaceId, key));
|
|
1634
1986
|
}
|
|
1635
1987
|
)
|
|
1636
1988
|
.command(
|
|
@@ -1641,6 +1993,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1641
1993
|
.positional("key", {
|
|
1642
1994
|
describe: "The key value to delete",
|
|
1643
1995
|
type: "string",
|
|
1996
|
+
demandOption: true,
|
|
1644
1997
|
})
|
|
1645
1998
|
.option("binding", {
|
|
1646
1999
|
type: "string",
|
|
@@ -1661,44 +2014,27 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1661
2014
|
});
|
|
1662
2015
|
},
|
|
1663
2016
|
async ({ key, ...args }) => {
|
|
1664
|
-
const
|
|
2017
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2018
|
+
const namespaceId = getNamespaceId(args, config);
|
|
1665
2019
|
|
|
1666
2020
|
console.log(
|
|
1667
2021
|
`deleting the key "${key}" on namespace ${namespaceId}`
|
|
1668
2022
|
);
|
|
1669
2023
|
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
script: ` `, // has to be a string with at least one char
|
|
1676
|
-
});
|
|
1677
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1678
|
-
console.log(await ns.delete(key));
|
|
2024
|
+
// -- snip, extract --
|
|
2025
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2026
|
+
if (!loggedIn) {
|
|
2027
|
+
// didn't login, let's just quit
|
|
2028
|
+
console.log("Did not login, quitting...");
|
|
1679
2029
|
return;
|
|
1680
2030
|
}
|
|
1681
2031
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
// -- snip, extract --
|
|
1685
|
-
|
|
1686
|
-
if (!args.local) {
|
|
1687
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1688
|
-
if (!loggedIn) {
|
|
1689
|
-
// didn't login, let's just quit
|
|
1690
|
-
console.log("Did not login, quitting...");
|
|
1691
|
-
return;
|
|
1692
|
-
}
|
|
1693
|
-
|
|
2032
|
+
if (!config.account_id) {
|
|
2033
|
+
config.account_id = await getAccountId();
|
|
1694
2034
|
if (!config.account_id) {
|
|
1695
|
-
|
|
1696
|
-
if (!config.account_id) {
|
|
1697
|
-
throw new Error("No account id found, quitting...");
|
|
1698
|
-
}
|
|
2035
|
+
throw new Error("No account id found, quitting...");
|
|
1699
2036
|
}
|
|
1700
2037
|
}
|
|
1701
|
-
|
|
1702
2038
|
// -- snip, end --
|
|
1703
2039
|
|
|
1704
2040
|
await fetchResult(
|
|
@@ -1724,14 +2060,15 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1724
2060
|
.positional("filename", {
|
|
1725
2061
|
describe: `The JSON file of key-value pairs to upload, in form [{"key":..., "value":...}"...]`,
|
|
1726
2062
|
type: "string",
|
|
2063
|
+
demandOption: true,
|
|
1727
2064
|
})
|
|
1728
2065
|
.option("binding", {
|
|
1729
2066
|
type: "string",
|
|
1730
|
-
describe: "The name of the namespace to
|
|
2067
|
+
describe: "The name of the namespace to insert values into",
|
|
1731
2068
|
})
|
|
1732
2069
|
.option("namespace-id", {
|
|
1733
2070
|
type: "string",
|
|
1734
|
-
describe: "The id of the namespace to
|
|
2071
|
+
describe: "The id of the namespace to insert values into",
|
|
1735
2072
|
})
|
|
1736
2073
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1737
2074
|
.option("env", {
|
|
@@ -1748,59 +2085,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1748
2085
|
// This could be made more efficient with a streaming parser/uploader
|
|
1749
2086
|
// but we'll do that in the future if needed.
|
|
1750
2087
|
|
|
1751
|
-
const
|
|
1752
|
-
const
|
|
1753
|
-
const content =
|
|
1754
|
-
let parsedContent;
|
|
1755
|
-
try {
|
|
1756
|
-
parsedContent = JSON.parse(content);
|
|
1757
|
-
} catch (err) {
|
|
1758
|
-
throw new Error(
|
|
1759
|
-
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1760
|
-
);
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
if (args.local) {
|
|
1764
|
-
const { Miniflare } = await import("miniflare");
|
|
1765
|
-
const mf = new Miniflare({
|
|
1766
|
-
kvPersist: (args.kvPersist as string) || true,
|
|
1767
|
-
// TODO: these options shouldn't be required
|
|
1768
|
-
script: ` `, // has to be a string with at least one char
|
|
1769
|
-
});
|
|
1770
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1771
|
-
for (const {
|
|
1772
|
-
key,
|
|
1773
|
-
value,
|
|
1774
|
-
expiration,
|
|
1775
|
-
expiration_ttl,
|
|
1776
|
-
} of parsedContent) {
|
|
1777
|
-
await ns.put(key, value, {
|
|
1778
|
-
expiration,
|
|
1779
|
-
expirationTtl: expiration_ttl,
|
|
1780
|
-
});
|
|
1781
|
-
}
|
|
2088
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2089
|
+
const namespaceId = getNamespaceId(args, config);
|
|
2090
|
+
const content = parseJSON(readFileSync(filename), filename);
|
|
1782
2091
|
|
|
2092
|
+
// -- snip, extract --
|
|
2093
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2094
|
+
if (!loggedIn) {
|
|
2095
|
+
// didn't login, let's just quit
|
|
2096
|
+
console.log("Did not login, quitting...");
|
|
1783
2097
|
return;
|
|
1784
2098
|
}
|
|
1785
2099
|
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
if (!args.local) {
|
|
1789
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1790
|
-
if (!loggedIn) {
|
|
1791
|
-
// didn't login, let's just quit
|
|
1792
|
-
console.log("Did not login, quitting...");
|
|
1793
|
-
return;
|
|
1794
|
-
}
|
|
1795
|
-
|
|
2100
|
+
if (!config.account_id) {
|
|
2101
|
+
config.account_id = await getAccountId();
|
|
1796
2102
|
if (!config.account_id) {
|
|
1797
|
-
|
|
1798
|
-
if (!config.account_id) {
|
|
1799
|
-
throw new Error("No account id found, quitting...");
|
|
1800
|
-
}
|
|
2103
|
+
throw new Error("No account id found, quitting...");
|
|
1801
2104
|
}
|
|
1802
2105
|
}
|
|
1803
|
-
|
|
1804
2106
|
// -- snip, end --
|
|
1805
2107
|
|
|
1806
2108
|
console.log(
|
|
@@ -1810,12 +2112,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1810
2112
|
)
|
|
1811
2113
|
.command(
|
|
1812
2114
|
"delete <filename>",
|
|
1813
|
-
"
|
|
2115
|
+
"Delete multiple key-value pairs from a namespace",
|
|
1814
2116
|
(yargs) => {
|
|
1815
2117
|
return yargs
|
|
1816
2118
|
.positional("filename", {
|
|
1817
|
-
describe: `The JSON file of
|
|
2119
|
+
describe: `The JSON file of keys to delete, in the form ["key1", "key2", ...]`,
|
|
1818
2120
|
type: "string",
|
|
2121
|
+
demandOption: true,
|
|
1819
2122
|
})
|
|
1820
2123
|
.option("binding", {
|
|
1821
2124
|
type: "string",
|
|
@@ -1836,51 +2139,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1836
2139
|
});
|
|
1837
2140
|
},
|
|
1838
2141
|
async ({ filename, ...args }) => {
|
|
1839
|
-
const
|
|
1840
|
-
const
|
|
1841
|
-
const content =
|
|
1842
|
-
let parsedContent;
|
|
1843
|
-
try {
|
|
1844
|
-
parsedContent = JSON.parse(content);
|
|
1845
|
-
} catch (err) {
|
|
1846
|
-
throw new Error(
|
|
1847
|
-
`Could not parse json from ${filename}.\n${err.message ?? err}`
|
|
1848
|
-
);
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
if (args.local) {
|
|
1852
|
-
const { Miniflare } = await import("miniflare");
|
|
1853
|
-
const mf = new Miniflare({
|
|
1854
|
-
kvPersist: (args.kvPersist as string) || true,
|
|
1855
|
-
// TODO: these options shouldn't be required
|
|
1856
|
-
script: ` `, // has to be a string with at least one char
|
|
1857
|
-
});
|
|
1858
|
-
const ns = await mf.getKVNamespace(namespaceId);
|
|
1859
|
-
for (const key of parsedContent) {
|
|
1860
|
-
await ns.delete(key);
|
|
1861
|
-
}
|
|
2142
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2143
|
+
const namespaceId = getNamespaceId(args, config);
|
|
2144
|
+
const content = parseJSON(readFileSync(filename), filename);
|
|
1862
2145
|
|
|
2146
|
+
// -- snip, extract --
|
|
2147
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2148
|
+
if (!loggedIn) {
|
|
2149
|
+
// didn't login, let's just quit
|
|
2150
|
+
console.log("Did not login, quitting...");
|
|
1863
2151
|
return;
|
|
1864
2152
|
}
|
|
1865
2153
|
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
if (!args.local) {
|
|
1869
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1870
|
-
if (!loggedIn) {
|
|
1871
|
-
// didn't login, let's just quit
|
|
1872
|
-
console.log("Did not login, quitting...");
|
|
1873
|
-
return;
|
|
1874
|
-
}
|
|
1875
|
-
|
|
2154
|
+
if (!config.account_id) {
|
|
2155
|
+
config.account_id = await getAccountId();
|
|
1876
2156
|
if (!config.account_id) {
|
|
1877
|
-
|
|
1878
|
-
if (!config.account_id) {
|
|
1879
|
-
throw new Error("No account id found, quitting...");
|
|
1880
|
-
}
|
|
2157
|
+
throw new Error("No account id found, quitting...");
|
|
1881
2158
|
}
|
|
1882
2159
|
}
|
|
1883
|
-
|
|
1884
2160
|
// -- snip, end --
|
|
1885
2161
|
|
|
1886
2162
|
console.log(
|
|
@@ -1893,37 +2169,159 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1893
2169
|
|
|
1894
2170
|
wrangler.command("pages", "⚡️ Configure Cloudflare Pages", pages);
|
|
1895
2171
|
|
|
2172
|
+
wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
|
|
2173
|
+
return r2Yargs.command("bucket", "Manage R2 buckets", (r2BucketYargs) => {
|
|
2174
|
+
r2BucketYargs.command(
|
|
2175
|
+
"create <name>",
|
|
2176
|
+
"Create a new R2 bucket",
|
|
2177
|
+
(yargs) => {
|
|
2178
|
+
return yargs.positional("name", {
|
|
2179
|
+
describe: "The name of the new bucket",
|
|
2180
|
+
type: "string",
|
|
2181
|
+
demandOption: true,
|
|
2182
|
+
});
|
|
2183
|
+
},
|
|
2184
|
+
async (args) => {
|
|
2185
|
+
// We expect three values in `_`: `r2`, `bucket`, `create`.
|
|
2186
|
+
if (args._.length > 3) {
|
|
2187
|
+
const extraArgs = args._.slice(3).join(" ");
|
|
2188
|
+
throw new CommandLineArgsError(
|
|
2189
|
+
`Unexpected additional positional arguments "${extraArgs}".`
|
|
2190
|
+
);
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2194
|
+
|
|
2195
|
+
// -- snip, extract --
|
|
2196
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2197
|
+
if (!loggedIn) {
|
|
2198
|
+
// didn't login, let's just quit
|
|
2199
|
+
console.log("Did not login, quitting...");
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
if (!config.account_id) {
|
|
2204
|
+
config.account_id = await getAccountId();
|
|
2205
|
+
if (!config.account_id) {
|
|
2206
|
+
throw new Error("No account id found, quitting...");
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
// -- snip, end --
|
|
2210
|
+
|
|
2211
|
+
console.log(`Creating bucket ${args.name}.`);
|
|
2212
|
+
await createR2Bucket(config.account_id, args.name);
|
|
2213
|
+
console.log(`Created bucket ${args.name}.`);
|
|
2214
|
+
}
|
|
2215
|
+
);
|
|
2216
|
+
|
|
2217
|
+
r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
|
|
2218
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2219
|
+
|
|
2220
|
+
// -- snip, extract --
|
|
2221
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2222
|
+
if (!loggedIn) {
|
|
2223
|
+
// didn't login, let's just quit
|
|
2224
|
+
console.log("Did not login, quitting...");
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
if (!config.account_id) {
|
|
2229
|
+
config.account_id = await getAccountId();
|
|
2230
|
+
if (!config.account_id) {
|
|
2231
|
+
throw new Error("No account id found, quitting...");
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
// -- snip, end --
|
|
2235
|
+
|
|
2236
|
+
console.log(
|
|
2237
|
+
JSON.stringify(await listR2Buckets(config.account_id), null, 2)
|
|
2238
|
+
);
|
|
2239
|
+
});
|
|
2240
|
+
|
|
2241
|
+
r2BucketYargs.command(
|
|
2242
|
+
"delete <name>",
|
|
2243
|
+
"Delete an R2 bucket",
|
|
2244
|
+
(yargs) => {
|
|
2245
|
+
return yargs.positional("name", {
|
|
2246
|
+
describe: "The name of the bucket to delete",
|
|
2247
|
+
type: "string",
|
|
2248
|
+
demandOption: true,
|
|
2249
|
+
});
|
|
2250
|
+
},
|
|
2251
|
+
async (args) => {
|
|
2252
|
+
// We expect three values in `_`: `r2`, `bucket`, `delete`.
|
|
2253
|
+
if (args._.length > 3) {
|
|
2254
|
+
const extraArgs = args._.slice(3).join(" ");
|
|
2255
|
+
throw new CommandLineArgsError(
|
|
2256
|
+
`Unexpected additional positional arguments "${extraArgs}".`
|
|
2257
|
+
);
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
const config = readConfig(args.config as ConfigPath);
|
|
2261
|
+
|
|
2262
|
+
// -- snip, extract --
|
|
2263
|
+
const loggedIn = await loginOrRefreshIfRequired();
|
|
2264
|
+
if (!loggedIn) {
|
|
2265
|
+
// didn't login, let's just quit
|
|
2266
|
+
console.log("Did not login, quitting...");
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
if (!config.account_id) {
|
|
2271
|
+
config.account_id = await getAccountId();
|
|
2272
|
+
if (!config.account_id) {
|
|
2273
|
+
throw new Error("No account id found, quitting...");
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
// -- snip, end --
|
|
2277
|
+
|
|
2278
|
+
console.log(`Deleting bucket ${args.name}.`);
|
|
2279
|
+
await deleteR2Bucket(config.account_id, args.name);
|
|
2280
|
+
console.log(`Deleted bucket ${args.name}.`);
|
|
2281
|
+
}
|
|
2282
|
+
);
|
|
2283
|
+
return r2BucketYargs;
|
|
2284
|
+
});
|
|
2285
|
+
});
|
|
2286
|
+
|
|
1896
2287
|
wrangler
|
|
2288
|
+
.option("legacy-env", {
|
|
2289
|
+
type: "boolean",
|
|
2290
|
+
describe: "Use legacy environments",
|
|
2291
|
+
})
|
|
1897
2292
|
.option("config", {
|
|
1898
2293
|
alias: "c",
|
|
1899
2294
|
describe: "Path to .toml configuration file",
|
|
1900
2295
|
type: "string",
|
|
1901
|
-
async coerce(arg) {
|
|
1902
|
-
return await readConfig(arg);
|
|
1903
|
-
},
|
|
1904
|
-
})
|
|
1905
|
-
.option("local", {
|
|
1906
|
-
alias: "l",
|
|
1907
|
-
describe: "Run on my machine",
|
|
1908
|
-
type: "boolean",
|
|
1909
|
-
default: false, // I bet this will a point of contention. We'll revisit it.
|
|
1910
2296
|
});
|
|
1911
2297
|
|
|
1912
|
-
wrangler.group(["config", "help", "version"], "Flags:");
|
|
2298
|
+
wrangler.group(["config", "help", "version", "legacy-env"], "Flags:");
|
|
1913
2299
|
wrangler.help().alias("h", "help");
|
|
1914
2300
|
wrangler.version(wranglerVersion).alias("v", "version");
|
|
1915
2301
|
wrangler.exitProcess(false);
|
|
1916
2302
|
|
|
1917
|
-
await initialiseUserConfig();
|
|
1918
|
-
|
|
1919
2303
|
try {
|
|
2304
|
+
await initialiseUserConfig();
|
|
1920
2305
|
await wrangler.parse();
|
|
1921
2306
|
} catch (e) {
|
|
1922
2307
|
if (e instanceof CommandLineArgsError) {
|
|
1923
2308
|
wrangler.showHelp("error");
|
|
1924
2309
|
console.error(""); // Just adds a bit of space
|
|
2310
|
+
console.error(e.message);
|
|
2311
|
+
} else if (e instanceof ParseError) {
|
|
2312
|
+
console.error("");
|
|
2313
|
+
e.notes.push({
|
|
2314
|
+
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new",
|
|
2315
|
+
});
|
|
2316
|
+
console.error(formatMessage(e));
|
|
2317
|
+
} else {
|
|
2318
|
+
console.error(e instanceof Error ? e.message : e);
|
|
2319
|
+
console.error(""); // Just adds a bit of space
|
|
2320
|
+
console.error(
|
|
2321
|
+
`${fgGreenColor}%s${resetColor}`,
|
|
2322
|
+
"If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
2323
|
+
);
|
|
1925
2324
|
}
|
|
1926
|
-
console.error(e.message);
|
|
1927
2325
|
throw e;
|
|
1928
2326
|
}
|
|
1929
2327
|
}
|