wrangler 0.0.0-e178d6fb → 0.0.0-e1c2f5b9
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/README.md +16 -2
- package/bin/wrangler.js +31 -11
- package/miniflare-dist/index.mjs +1340 -330
- package/package.json +40 -13
- package/src/__tests__/access.test.ts +25 -0
- package/src/__tests__/api-dev.test.ts +238 -0
- package/src/__tests__/api-devregistry.test.js +64 -0
- package/src/__tests__/api.test.ts +80 -0
- package/src/__tests__/configuration.test.ts +683 -470
- package/src/__tests__/d1.test.ts +123 -0
- package/src/__tests__/delete.test.ts +263 -0
- package/src/__tests__/deployments.test.ts +105 -0
- package/src/__tests__/dev.test.tsx +453 -70
- package/src/__tests__/dialogs.test.tsx +40 -0
- package/src/__tests__/generate.test.ts +235 -0
- package/src/__tests__/get-host-from-url.test.ts +16 -0
- package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-cfetch.ts +92 -26
- package/src/__tests__/helpers/mock-console.ts +11 -2
- package/src/__tests__/helpers/mock-dialogs.ts +1 -1
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
- package/src/__tests__/helpers/mock-known-routes.ts +7 -0
- package/src/__tests__/helpers/mock-kv.ts +1 -1
- package/src/__tests__/helpers/mock-oauth-flow.ts +74 -53
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +59 -0
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
- package/src/__tests__/helpers/msw/handlers/oauth.ts +31 -0
- package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
- package/src/__tests__/helpers/msw/handlers/script.ts +75 -0
- package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
- package/src/__tests__/helpers/msw/handlers/zones.ts +22 -0
- package/src/__tests__/helpers/msw/index.ts +21 -0
- package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
- package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
- package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
- package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
- package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
- package/src/__tests__/index.test.ts +103 -97
- package/src/__tests__/init.test.ts +1484 -382
- package/src/__tests__/jest.setup.ts +88 -5
- package/src/__tests__/kv.test.ts +655 -540
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +95 -45
- package/src/__tests__/middleware.scheduled.test.ts +145 -0
- package/src/__tests__/middleware.test.ts +750 -0
- package/src/__tests__/pages-deployment-tail.test.ts +884 -0
- package/src/__tests__/pages.test.ts +1301 -119
- package/src/__tests__/paths.test.ts +39 -0
- package/src/__tests__/publish.test.ts +2266 -1180
- package/src/__tests__/pubsub.test.ts +211 -88
- package/src/__tests__/queues.test.ts +522 -0
- package/src/__tests__/r2.test.ts +363 -203
- package/src/__tests__/secret.test.ts +261 -59
- package/src/__tests__/tail.test.ts +352 -151
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/type-generation.test.ts +233 -0
- package/src/__tests__/user.test.ts +59 -73
- package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
- package/src/__tests__/validate-dev-props.test.ts +56 -0
- package/src/__tests__/whoami.test.tsx +114 -66
- package/src/__tests__/worker-namespace.test.ts +154 -155
- package/src/api/dev.ts +170 -38
- package/src/api/index.ts +1 -0
- package/src/bundle-reporter.tsx +41 -2
- package/src/bundle.ts +668 -81
- package/src/cfetch/index.ts +40 -3
- package/src/cfetch/internal.ts +144 -32
- package/src/cli.ts +4 -3
- package/src/config/config.ts +27 -3
- package/src/config/environment.ts +131 -7
- package/src/config/index.ts +128 -8
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +411 -14
- package/src/config-cache.ts +3 -2
- package/src/create-worker-preview.ts +31 -6
- package/src/create-worker-upload-form.ts +84 -22
- package/src/d1/backups.tsx +223 -0
- package/src/d1/constants.ts +2 -0
- package/src/d1/create.tsx +63 -0
- package/src/d1/delete.tsx +56 -0
- package/src/d1/execute.tsx +352 -0
- package/src/d1/formatTimeAgo.ts +14 -0
- package/src/d1/index.ts +101 -0
- package/src/d1/list.tsx +48 -0
- package/src/d1/migrations/apply.tsx +196 -0
- package/src/d1/migrations/create.tsx +77 -0
- package/src/d1/migrations/helpers.ts +147 -0
- package/src/d1/migrations/index.tsx +3 -0
- package/src/d1/migrations/list.tsx +79 -0
- package/src/d1/migrations/options.ts +18 -0
- package/src/d1/options.ts +22 -0
- package/src/d1/types.tsx +24 -0
- package/src/d1/utils.ts +48 -0
- package/src/delete.ts +108 -0
- package/src/deployments.ts +83 -0
- package/src/deprecated/index.ts +145 -0
- package/src/dev/dev-vars.ts +11 -8
- package/src/dev/dev.tsx +220 -58
- package/src/dev/get-local-persistence-path.tsx +31 -0
- package/src/dev/local.tsx +740 -181
- package/src/dev/remote.tsx +340 -123
- package/src/dev/start-server.ts +543 -0
- package/src/dev/use-esbuild.ts +61 -7
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +201 -0
- package/src/dev.tsx +614 -258
- package/src/dialogs.tsx +41 -8
- package/src/{worker-namespace.ts → dispatch-namespace.ts} +23 -22
- package/src/docs/index.ts +97 -0
- package/src/entry.ts +3 -2
- package/src/environment-variables/factory.ts +88 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +300 -0
- package/src/git-client.ts +100 -7
- package/src/index.tsx +249 -1560
- package/src/init.ts +626 -150
- package/src/inspect.ts +137 -32
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/is-interactive.ts +4 -0
- package/src/jest.d.ts +4 -0
- package/src/{kv.ts → kv/helpers.ts} +3 -3
- package/src/kv/index.ts +596 -0
- package/src/logger.ts +27 -8
- package/src/metrics/index.ts +1 -0
- package/src/metrics/metrics-config.ts +4 -4
- package/src/metrics/metrics-dispatcher.ts +1 -0
- package/src/metrics/metrics-usage-headers.ts +24 -0
- package/src/metrics/send-event.ts +13 -8
- package/src/miniflare-cli/assets.ts +172 -465
- package/src/miniflare-cli/index.ts +149 -24
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/module-collection.ts +12 -3
- package/src/pages/build.tsx +108 -42
- package/src/pages/constants.ts +11 -0
- package/src/pages/deployment-tails.tsx +284 -0
- package/src/pages/deployments.tsx +9 -31
- package/src/pages/dev.tsx +417 -108
- package/src/pages/errors.ts +66 -0
- package/src/pages/functions/buildPlugin.ts +86 -84
- package/src/pages/functions/buildWorker.ts +121 -106
- package/src/pages/functions/routes-consolidation.test.ts +250 -0
- package/src/pages/functions/routes-consolidation.ts +73 -0
- package/src/pages/functions/routes-transformation.test.ts +282 -0
- package/src/pages/functions/routes-transformation.ts +115 -0
- package/src/pages/functions/routes-validation.test.ts +403 -0
- package/src/pages/functions/routes-validation.ts +202 -0
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/functions.tsx +82 -0
- package/src/pages/hash.tsx +13 -0
- package/src/pages/index.tsx +73 -55
- package/src/pages/projects.tsx +9 -3
- package/src/pages/prompt-select-project.tsx +31 -0
- package/src/pages/publish.tsx +183 -60
- package/src/pages/types.ts +1 -0
- package/src/pages/upload.tsx +107 -56
- package/src/pages/utils.ts +13 -2
- package/src/paths.ts +49 -4
- package/src/proxy.ts +375 -157
- package/src/publish/index.ts +270 -0
- package/src/{publish.ts → publish/publish.ts} +431 -188
- package/src/pubsub/pubsub-commands.tsx +4 -3
- package/src/queues/cli/commands/consumer/add.ts +71 -0
- package/src/queues/cli/commands/consumer/index.ts +22 -0
- package/src/queues/cli/commands/consumer/remove.ts +38 -0
- package/src/queues/cli/commands/create.ts +25 -0
- package/src/queues/cli/commands/delete.ts +26 -0
- package/src/queues/cli/commands/index.ts +36 -0
- package/src/queues/cli/commands/list.ts +25 -0
- package/src/queues/client.ts +135 -0
- package/src/queues/utils.ts +18 -0
- package/src/r2/constants.ts +4 -0
- package/src/r2/helpers.ts +131 -0
- package/src/r2/index.ts +289 -0
- package/src/routes.ts +140 -0
- package/src/secret/index.ts +379 -0
- package/src/sites.tsx +3 -3
- package/src/tail/createTail.ts +379 -0
- package/src/tail/filters.ts +4 -6
- package/src/tail/index.ts +199 -284
- package/src/tail/printing.ts +43 -3
- package/src/tsconfig-sanity.ts +16 -0
- package/src/type-generation.ts +181 -0
- package/src/user/access.ts +68 -0
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -1
- package/src/user/index.ts +0 -1
- package/src/user/user.tsx +116 -49
- package/src/utils/collectKeyValues.ts +14 -0
- package/src/whoami.tsx +80 -2
- package/src/worker.ts +69 -9
- package/src/yargs-types.ts +24 -0
- package/src/zones.ts +124 -9
- package/templates/__tests__/pages-dev-util.test.ts +128 -0
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/d1-beta-facade.js +205 -0
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +19 -0
- package/templates/format-dev-errors.ts +33 -0
- package/templates/init-tests/test-jest-new-worker.js +23 -0
- package/templates/init-tests/test-vitest-new-worker.js +24 -0
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/common.ts +62 -0
- package/templates/middleware/loader-modules.ts +82 -0
- package/templates/middleware/loader-sw.ts +233 -0
- package/templates/middleware/middleware-miniflare3-json-error.ts +20 -0
- package/templates/middleware/middleware-pretty-error.ts +40 -0
- package/templates/middleware/middleware-scheduled.ts +15 -0
- package/templates/new-worker.js +1 -1
- package/templates/pages-dev-pipeline.ts +31 -0
- package/templates/pages-dev-util.ts +52 -0
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +21 -5
- package/templates/pages-template-worker.ts +37 -9
- package/templates/{static-asset-facade.js → serve-static-assets.ts} +23 -7
- package/templates/service-bindings-module-facade.js +54 -0
- package/templates/service-bindings-sw-facade.js +42 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +106 -0
- package/templates/tsconfig.json +5 -102
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +621 -42
- package/wrangler-dist/cli.js +144441 -102606
- package/src/environment-variables.ts +0 -35
- package/src/faye-websocket.d.ts +0 -6
- package/src/generate.ts +0 -33
- package/src/miniflare-cli/enum-keys.ts +0 -17
- package/src/preview.ts +0 -31
- package/src/r2.ts +0 -50
- package/src/user/env-vars.ts +0 -46
package/src/index.tsx
CHANGED
|
@@ -1,74 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { StringDecoder } from "node:string_decoder";
|
|
3
|
-
import { setTimeout } from "node:timers/promises";
|
|
1
|
+
import os from "node:os";
|
|
4
2
|
import TOML from "@iarna/toml";
|
|
5
3
|
import chalk from "chalk";
|
|
6
|
-
import onExit from "signal-exit";
|
|
7
4
|
import supportsColor from "supports-color";
|
|
8
|
-
import {
|
|
5
|
+
import { ProxyAgent, setGlobalDispatcher } from "undici";
|
|
9
6
|
import makeCLI from "yargs";
|
|
10
7
|
import { version as wranglerVersion } from "../package.json";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
8
|
+
import { isBuildFailure } from "./bundle";
|
|
9
|
+
import { loadDotEnv, readConfig } from "./config";
|
|
10
|
+
import { d1 } from "./d1";
|
|
11
|
+
import { deleteHandler, deleteOptions } from "./delete";
|
|
12
|
+
import { deployments } from "./deployments";
|
|
13
|
+
import {
|
|
14
|
+
buildHandler,
|
|
15
|
+
buildOptions,
|
|
16
|
+
configHandler,
|
|
17
|
+
noOpOptions,
|
|
18
|
+
previewHandler,
|
|
19
|
+
previewOptions,
|
|
20
|
+
route,
|
|
21
|
+
routeHandler,
|
|
22
|
+
subdomainHandler,
|
|
23
|
+
subdomainOptions,
|
|
24
|
+
} from "./deprecated";
|
|
14
25
|
import { devHandler, devOptions } from "./dev";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { DeprecationError } from "./errors";
|
|
26
|
+
import { workerNamespaceCommands } from "./dispatch-namespace";
|
|
27
|
+
import { docsHandler, docsOptions } from "./docs";
|
|
18
28
|
import { generateHandler, generateOptions } from "./generate";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
listKVNamespaces,
|
|
23
|
-
listKVNamespaceKeys,
|
|
24
|
-
putKVKeyValue,
|
|
25
|
-
putKVBulkKeyValue,
|
|
26
|
-
deleteKVBulkKeyValue,
|
|
27
|
-
createKVNamespace,
|
|
28
|
-
isValidKVNamespaceBinding,
|
|
29
|
-
getKVKeyValue,
|
|
30
|
-
isKVKeyValue,
|
|
31
|
-
unexpectedKVKeyValueProps,
|
|
32
|
-
deleteKVNamespace,
|
|
33
|
-
deleteKVKeyValue,
|
|
34
|
-
} from "./kv";
|
|
35
|
-
import { logger } from "./logger";
|
|
29
|
+
import { initHandler, initOptions } from "./init";
|
|
30
|
+
import { kvNamespace, kvKey, kvBulk } from "./kv";
|
|
31
|
+
import { logBuildFailure, logger } from "./logger";
|
|
36
32
|
import * as metrics from "./metrics";
|
|
37
33
|
import { pages } from "./pages";
|
|
38
|
-
import {
|
|
39
|
-
|
|
40
|
-
ParseError,
|
|
41
|
-
parseJSON,
|
|
42
|
-
readFileSync,
|
|
43
|
-
readFileSyncToBuffer,
|
|
44
|
-
} from "./parse";
|
|
45
|
-
import { previewHandler, previewOptions } from "./preview";
|
|
46
|
-
import publish from "./publish";
|
|
34
|
+
import { formatMessage, ParseError } from "./parse";
|
|
35
|
+
import { publishOptions, publishHandler } from "./publish";
|
|
47
36
|
import { pubSubCommands } from "./pubsub/pubsub-commands";
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
prettyPrintLogs,
|
|
54
|
-
translateCLICommandToFilterMessage,
|
|
55
|
-
} from "./tail";
|
|
37
|
+
import { queues } from "./queues/cli/commands";
|
|
38
|
+
import { r2 } from "./r2";
|
|
39
|
+
import { secret, secretBulkHandler, secretBulkOptions } from "./secret";
|
|
40
|
+
import { tailOptions, tailHandler } from "./tail";
|
|
41
|
+
import { generateTypes } from "./type-generation";
|
|
56
42
|
import { updateCheck } from "./update-check";
|
|
57
43
|
import {
|
|
44
|
+
listScopes,
|
|
58
45
|
login,
|
|
59
46
|
logout,
|
|
60
|
-
listScopes,
|
|
61
|
-
validateScopeKeys,
|
|
62
47
|
requireAuth,
|
|
48
|
+
validateScopeKeys,
|
|
63
49
|
} from "./user";
|
|
64
50
|
import { whoami } from "./whoami";
|
|
65
51
|
|
|
66
|
-
import { workerNamespaceCommands } from "./worker-namespace";
|
|
67
52
|
import type { Config } from "./config";
|
|
68
|
-
import type {
|
|
69
|
-
import type {
|
|
70
|
-
import type { RawData } from "ws";
|
|
71
|
-
import type { CommandModule } from "yargs";
|
|
53
|
+
import type { CommonYargsOptions } from "./yargs-types";
|
|
54
|
+
import type { ArgumentsCamelCase } from "yargs";
|
|
72
55
|
import type Yargs from "yargs";
|
|
73
56
|
|
|
74
57
|
export type ConfigPath = string | undefined;
|
|
@@ -76,6 +59,7 @@ export type ConfigPath = string | undefined;
|
|
|
76
59
|
const resetColor = "\x1b[0m";
|
|
77
60
|
const fgGreenColor = "\x1b[32m";
|
|
78
61
|
export const DEFAULT_LOCAL_PORT = 8787;
|
|
62
|
+
export const DEFAULT_INSPECTOR_PORT = 9229;
|
|
79
63
|
|
|
80
64
|
const proxy =
|
|
81
65
|
process.env.https_proxy ||
|
|
@@ -86,6 +70,9 @@ const proxy =
|
|
|
86
70
|
|
|
87
71
|
if (proxy) {
|
|
88
72
|
setGlobalDispatcher(new ProxyAgent(proxy));
|
|
73
|
+
logger.log(
|
|
74
|
+
`Proxy environment variables detected. We'll use your proxy for fetch requests.`
|
|
75
|
+
);
|
|
89
76
|
}
|
|
90
77
|
|
|
91
78
|
export function getRules(config: Config): Config["rules"] {
|
|
@@ -150,7 +137,7 @@ export function getScriptName(
|
|
|
150
137
|
/**
|
|
151
138
|
* Alternative to the getScriptName() because special Legacy cases allowed "name", and "env" together in Wrangler1
|
|
152
139
|
*/
|
|
153
|
-
function getLegacyScriptName(
|
|
140
|
+
export function getLegacyScriptName(
|
|
154
141
|
args: { name: string | undefined; env: string | undefined },
|
|
155
142
|
config: Config
|
|
156
143
|
) {
|
|
@@ -159,42 +146,9 @@ function getLegacyScriptName(
|
|
|
159
146
|
: args.name ?? config.name;
|
|
160
147
|
}
|
|
161
148
|
|
|
162
|
-
/**
|
|
163
|
-
* Get a promise to the streamed input from stdin.
|
|
164
|
-
*
|
|
165
|
-
* This function can be used to grab the incoming stream of data from, say,
|
|
166
|
-
* piping the output of another process into the wrangler process.
|
|
167
|
-
*/
|
|
168
|
-
function readFromStdin(): Promise<string> {
|
|
169
|
-
return new Promise((resolve, reject) => {
|
|
170
|
-
const stdin = process.stdin;
|
|
171
|
-
const chunks: string[] = [];
|
|
172
|
-
|
|
173
|
-
// When there is data ready to be read, the `readable` event will be triggered.
|
|
174
|
-
// In the handler for `readable` we call `read()` over and over until all the available data has been read.
|
|
175
|
-
stdin.on("readable", () => {
|
|
176
|
-
let chunk;
|
|
177
|
-
while (null !== (chunk = stdin.read())) {
|
|
178
|
-
chunks.push(chunk);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// When the streamed data is complete the `end` event will be triggered.
|
|
183
|
-
// In the handler for `end` we join the chunks together and resolve the promise.
|
|
184
|
-
stdin.on("end", () => {
|
|
185
|
-
resolve(chunks.join(""));
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// If there is an `error` event then the handler will reject the promise.
|
|
189
|
-
stdin.on("error", (err) => {
|
|
190
|
-
reject(err);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
149
|
// a helper to demand one of a set of options
|
|
196
150
|
// via https://github.com/yargs/yargs/issues/1093#issuecomment-491299261
|
|
197
|
-
function demandOneOfOption(...options: string[]) {
|
|
151
|
+
export function demandOneOfOption(...options: string[]) {
|
|
198
152
|
return function (argv: Yargs.Arguments) {
|
|
199
153
|
const count = options.filter((option) => argv[option]).length;
|
|
200
154
|
const lastOption = options.pop();
|
|
@@ -217,18 +171,12 @@ function demandOneOfOption(...options: string[]) {
|
|
|
217
171
|
};
|
|
218
172
|
}
|
|
219
173
|
|
|
220
|
-
/**
|
|
221
|
-
* Remove trailing white space from inputs.
|
|
222
|
-
* Matching Wrangler legacy behavior with handling inputs
|
|
223
|
-
*/
|
|
224
|
-
function trimTrailingWhitespace(str: string) {
|
|
225
|
-
return str.trimEnd();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
174
|
export class CommandLineArgsError extends Error {}
|
|
229
175
|
|
|
230
|
-
function createCLIParser(argv: string[]) {
|
|
231
|
-
|
|
176
|
+
export function createCLIParser(argv: string[]) {
|
|
177
|
+
// Type check result against CommonYargsOptions to make sure we've included
|
|
178
|
+
// all common options
|
|
179
|
+
const wrangler: Yargs.Argv<CommonYargsOptions> = makeCLI(argv)
|
|
232
180
|
.strict()
|
|
233
181
|
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
234
182
|
// If you want the "help info" to be displayed then throw an instance of `CommandLineArgsError`.
|
|
@@ -243,10 +191,41 @@ function createCLIParser(argv: string[]) {
|
|
|
243
191
|
throw error;
|
|
244
192
|
})
|
|
245
193
|
.scriptName("wrangler")
|
|
246
|
-
.wrap(null)
|
|
194
|
+
.wrap(null)
|
|
195
|
+
// Define global options here, so they get included in the `Argv` type of
|
|
196
|
+
// the `wrangler` variable
|
|
197
|
+
.version(false)
|
|
198
|
+
.option("v", {
|
|
199
|
+
describe: "Show version number",
|
|
200
|
+
alias: "version",
|
|
201
|
+
type: "boolean",
|
|
202
|
+
})
|
|
203
|
+
.option("config", {
|
|
204
|
+
alias: "c",
|
|
205
|
+
describe: "Path to .toml configuration file",
|
|
206
|
+
type: "string",
|
|
207
|
+
requiresArg: true,
|
|
208
|
+
})
|
|
209
|
+
.option("env", {
|
|
210
|
+
alias: "e",
|
|
211
|
+
describe: "Environment to use for operations and .env files",
|
|
212
|
+
type: "string",
|
|
213
|
+
requiresArg: true,
|
|
214
|
+
})
|
|
215
|
+
.check((args) => {
|
|
216
|
+
// Grab locally specified env params from `.env` file
|
|
217
|
+
const loaded = loadDotEnv(".env", args.env);
|
|
218
|
+
for (const [key, value] of Object.entries(loaded?.parsed ?? {})) {
|
|
219
|
+
if (!(key in process.env)) process.env[key] = value;
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
wrangler.group(["config", "env", "help", "version"], "Flags:");
|
|
225
|
+
wrangler.help().alias("h", "help");
|
|
247
226
|
|
|
248
227
|
// Default help command that supports the subcommands
|
|
249
|
-
const subHelp: CommandModule = {
|
|
228
|
+
const subHelp: Yargs.CommandModule<CommonYargsOptions, CommonYargsOptions> = {
|
|
250
229
|
command: ["*"],
|
|
251
230
|
handler: async (args) => {
|
|
252
231
|
setImmediate(() =>
|
|
@@ -285,74 +264,35 @@ function createCLIParser(argv: string[]) {
|
|
|
285
264
|
// I wish we could enforce this pattern, but this comment will have to do for now.
|
|
286
265
|
// (It's also annoying that choices[] doesn't get inferred as an enum. 🤷♂.)
|
|
287
266
|
|
|
288
|
-
//
|
|
267
|
+
// docs
|
|
289
268
|
wrangler.command(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
generateOptions,
|
|
295
|
-
generateHandler
|
|
269
|
+
"docs [command]",
|
|
270
|
+
"📚 Open wrangler's docs in your browser",
|
|
271
|
+
docsOptions,
|
|
272
|
+
docsHandler
|
|
296
273
|
);
|
|
297
274
|
|
|
298
275
|
// init
|
|
299
276
|
wrangler.command(
|
|
300
277
|
"init [name]",
|
|
301
|
-
"📥
|
|
278
|
+
"📥 Initialize a basic Worker project, including a wrangler.toml file",
|
|
302
279
|
initOptions,
|
|
303
280
|
initHandler
|
|
304
281
|
);
|
|
305
282
|
|
|
306
|
-
//
|
|
283
|
+
// generate
|
|
307
284
|
wrangler.command(
|
|
308
|
-
"
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
describe: "Perform on a specific environment",
|
|
313
|
-
type: "string",
|
|
314
|
-
});
|
|
315
|
-
},
|
|
316
|
-
async (buildArgs) => {
|
|
317
|
-
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
318
|
-
|
|
319
|
-
const envFlag = buildArgs.env ? ` --env=${buildArgs.env}` : "";
|
|
320
|
-
logger.log(
|
|
321
|
-
formatMessage({
|
|
322
|
-
kind: "warning",
|
|
323
|
-
text: "Deprecation: `wrangler build` has been deprecated.",
|
|
324
|
-
notes: [
|
|
325
|
-
{
|
|
326
|
-
text: "Please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#build for more information.",
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
text: `Attempting to run \`wrangler publish --dry-run --outdir=dist${envFlag}\` for you instead:`,
|
|
330
|
-
},
|
|
331
|
-
],
|
|
332
|
-
})
|
|
333
|
-
);
|
|
334
|
-
|
|
335
|
-
await createCLIParser([
|
|
336
|
-
"publish",
|
|
337
|
-
"--dry-run",
|
|
338
|
-
"--outdir=dist",
|
|
339
|
-
...(buildArgs.env ? ["--env", buildArgs.env] : []),
|
|
340
|
-
]).parse();
|
|
341
|
-
}
|
|
285
|
+
"generate [name] [template]",
|
|
286
|
+
"✨ Generate a new Worker project from an existing Worker template. See https://github.com/cloudflare/templates",
|
|
287
|
+
generateOptions,
|
|
288
|
+
generateHandler
|
|
342
289
|
);
|
|
343
290
|
|
|
344
|
-
//
|
|
345
|
-
wrangler.command(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
() => {
|
|
350
|
-
// "🕵️ Authenticate Wrangler with a Cloudflare API Token",
|
|
351
|
-
throw new DeprecationError(
|
|
352
|
-
"`wrangler config` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#config for alternatives"
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
);
|
|
291
|
+
// [DEPRECATED] build
|
|
292
|
+
wrangler.command("build", false, buildOptions, buildHandler);
|
|
293
|
+
|
|
294
|
+
// [DEPRECATED] config
|
|
295
|
+
wrangler.command("config", false, noOpOptions, configHandler);
|
|
356
296
|
|
|
357
297
|
// dev
|
|
358
298
|
wrangler.command(
|
|
@@ -366,386 +306,27 @@ function createCLIParser(argv: string[]) {
|
|
|
366
306
|
wrangler.command(
|
|
367
307
|
"publish [script]",
|
|
368
308
|
"🆙 Publish your Worker to Cloudflare.",
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
.option("env", {
|
|
373
|
-
type: "string",
|
|
374
|
-
requiresArg: true,
|
|
375
|
-
describe: "Perform on a specific environment",
|
|
376
|
-
alias: "e",
|
|
377
|
-
})
|
|
378
|
-
.positional("script", {
|
|
379
|
-
describe: "The path to an entry point for your worker",
|
|
380
|
-
type: "string",
|
|
381
|
-
requiresArg: true,
|
|
382
|
-
})
|
|
383
|
-
.option("name", {
|
|
384
|
-
describe: "Name of the worker",
|
|
385
|
-
type: "string",
|
|
386
|
-
requiresArg: true,
|
|
387
|
-
})
|
|
388
|
-
// We want to have a --no-bundle flag, but yargs requires that
|
|
389
|
-
// we also have a --bundle flag (that it adds the --no to by itself)
|
|
390
|
-
// So we make a --bundle flag, but hide it, and then add a --no-bundle flag
|
|
391
|
-
// that's visible to the user but doesn't "do" anything.
|
|
392
|
-
.option("bundle", {
|
|
393
|
-
describe: "Run wrangler's compilation step before publishing",
|
|
394
|
-
type: "boolean",
|
|
395
|
-
hidden: true,
|
|
396
|
-
})
|
|
397
|
-
.option("no-bundle", {
|
|
398
|
-
describe: "Skip internal build steps and directly publish Worker",
|
|
399
|
-
type: "boolean",
|
|
400
|
-
default: false,
|
|
401
|
-
})
|
|
402
|
-
.option("outdir", {
|
|
403
|
-
describe: "Output directory for the bundled worker",
|
|
404
|
-
type: "string",
|
|
405
|
-
requiresArg: true,
|
|
406
|
-
})
|
|
407
|
-
.option("format", {
|
|
408
|
-
choices: ["modules", "service-worker"] as const,
|
|
409
|
-
describe: "Choose an entry type",
|
|
410
|
-
deprecated: true,
|
|
411
|
-
})
|
|
412
|
-
.option("compatibility-date", {
|
|
413
|
-
describe: "Date to use for compatibility checks",
|
|
414
|
-
type: "string",
|
|
415
|
-
requiresArg: true,
|
|
416
|
-
})
|
|
417
|
-
.option("compatibility-flags", {
|
|
418
|
-
describe: "Flags to use for compatibility checks",
|
|
419
|
-
alias: "compatibility-flag",
|
|
420
|
-
type: "string",
|
|
421
|
-
requiresArg: true,
|
|
422
|
-
array: true,
|
|
423
|
-
})
|
|
424
|
-
.option("latest", {
|
|
425
|
-
describe: "Use the latest version of the worker runtime",
|
|
426
|
-
type: "boolean",
|
|
427
|
-
default: false,
|
|
428
|
-
})
|
|
429
|
-
.option("experimental-public", {
|
|
430
|
-
describe: "Static assets to be served",
|
|
431
|
-
type: "string",
|
|
432
|
-
requiresArg: true,
|
|
433
|
-
deprecated: true,
|
|
434
|
-
hidden: true,
|
|
435
|
-
})
|
|
436
|
-
.option("assets", {
|
|
437
|
-
describe: "Static assets to be served",
|
|
438
|
-
type: "string",
|
|
439
|
-
requiresArg: true,
|
|
440
|
-
})
|
|
441
|
-
.option("site", {
|
|
442
|
-
describe: "Root folder of static assets for Workers Sites",
|
|
443
|
-
type: "string",
|
|
444
|
-
requiresArg: true,
|
|
445
|
-
})
|
|
446
|
-
.option("site-include", {
|
|
447
|
-
describe:
|
|
448
|
-
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.",
|
|
449
|
-
type: "string",
|
|
450
|
-
requiresArg: true,
|
|
451
|
-
array: true,
|
|
452
|
-
})
|
|
453
|
-
.option("site-exclude", {
|
|
454
|
-
describe:
|
|
455
|
-
"Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded.",
|
|
456
|
-
type: "string",
|
|
457
|
-
requiresArg: true,
|
|
458
|
-
array: true,
|
|
459
|
-
})
|
|
460
|
-
.option("triggers", {
|
|
461
|
-
describe: "cron schedules to attach",
|
|
462
|
-
alias: ["schedule", "schedules"],
|
|
463
|
-
type: "string",
|
|
464
|
-
requiresArg: true,
|
|
465
|
-
array: true,
|
|
466
|
-
})
|
|
467
|
-
.option("routes", {
|
|
468
|
-
describe: "Routes to upload",
|
|
469
|
-
alias: "route",
|
|
470
|
-
type: "string",
|
|
471
|
-
requiresArg: true,
|
|
472
|
-
array: true,
|
|
473
|
-
})
|
|
474
|
-
.option("jsx-factory", {
|
|
475
|
-
describe: "The function that is called for each JSX element",
|
|
476
|
-
type: "string",
|
|
477
|
-
requiresArg: true,
|
|
478
|
-
})
|
|
479
|
-
.option("jsx-fragment", {
|
|
480
|
-
describe: "The function that is called for each JSX fragment",
|
|
481
|
-
type: "string",
|
|
482
|
-
requiresArg: true,
|
|
483
|
-
})
|
|
484
|
-
.option("tsconfig", {
|
|
485
|
-
describe: "Path to a custom tsconfig.json file",
|
|
486
|
-
type: "string",
|
|
487
|
-
requiresArg: true,
|
|
488
|
-
})
|
|
489
|
-
.option("minify", {
|
|
490
|
-
describe: "Minify the Worker",
|
|
491
|
-
type: "boolean",
|
|
492
|
-
})
|
|
493
|
-
.option("node-compat", {
|
|
494
|
-
describe: "Enable node.js compatibility",
|
|
495
|
-
type: "boolean",
|
|
496
|
-
})
|
|
497
|
-
.option("dry-run", {
|
|
498
|
-
describe: "Don't actually publish",
|
|
499
|
-
type: "boolean",
|
|
500
|
-
})
|
|
501
|
-
.option("legacy-env", {
|
|
502
|
-
type: "boolean",
|
|
503
|
-
describe: "Use legacy environments",
|
|
504
|
-
hidden: true,
|
|
505
|
-
})
|
|
506
|
-
);
|
|
507
|
-
},
|
|
508
|
-
async (args) => {
|
|
509
|
-
await printWranglerBanner();
|
|
510
|
-
|
|
511
|
-
const configPath =
|
|
512
|
-
(args.config as ConfigPath) ||
|
|
513
|
-
(args.script && findWranglerToml(path.dirname(args.script)));
|
|
514
|
-
const config = readConfig(configPath, args);
|
|
515
|
-
await metrics.sendMetricsEvent("deploy worker script", {
|
|
516
|
-
sendMetrics: config.send_metrics,
|
|
517
|
-
});
|
|
518
|
-
const entry = await getEntry(args, config, "publish");
|
|
519
|
-
|
|
520
|
-
if (args.public) {
|
|
521
|
-
throw new Error("The --public field has been renamed to --assets");
|
|
522
|
-
}
|
|
523
|
-
if (args["experimental-public"]) {
|
|
524
|
-
throw new Error(
|
|
525
|
-
"The --experimental-public field has been renamed to --assets"
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if ((args.assets || config.assets) && (args.site || config.site)) {
|
|
530
|
-
throw new Error(
|
|
531
|
-
"Cannot use Assets and Workers Sites in the same Worker."
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
if (args.assets) {
|
|
536
|
-
logger.warn(
|
|
537
|
-
"The --assets argument is experimental and may change or break at any time"
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
if (args.latest) {
|
|
542
|
-
logger.warn(
|
|
543
|
-
"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"
|
|
544
|
-
);
|
|
545
|
-
}
|
|
309
|
+
publishOptions,
|
|
310
|
+
publishHandler
|
|
311
|
+
);
|
|
546
312
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
config,
|
|
554
|
-
args.site,
|
|
555
|
-
args.siteInclude,
|
|
556
|
-
args.siteExclude
|
|
557
|
-
);
|
|
558
|
-
|
|
559
|
-
await publish({
|
|
560
|
-
config,
|
|
561
|
-
accountId,
|
|
562
|
-
name: getScriptName(args, config),
|
|
563
|
-
rules: getRules(config),
|
|
564
|
-
entry,
|
|
565
|
-
env: args.env,
|
|
566
|
-
compatibilityDate: args.latest
|
|
567
|
-
? new Date().toISOString().substring(0, 10)
|
|
568
|
-
: args["compatibility-date"],
|
|
569
|
-
compatibilityFlags: args["compatibility-flags"],
|
|
570
|
-
triggers: args.triggers,
|
|
571
|
-
jsxFactory: args["jsx-factory"],
|
|
572
|
-
jsxFragment: args["jsx-fragment"],
|
|
573
|
-
tsconfig: args.tsconfig,
|
|
574
|
-
routes: args.routes,
|
|
575
|
-
assetPaths,
|
|
576
|
-
legacyEnv: isLegacyEnv(config),
|
|
577
|
-
minify: args.minify,
|
|
578
|
-
nodeCompat: args.nodeCompat,
|
|
579
|
-
isWorkersSite: Boolean(args.site || config.site),
|
|
580
|
-
outDir: args.outdir,
|
|
581
|
-
dryRun: args.dryRun,
|
|
582
|
-
noBundle: !(args.bundle ?? !config.no_bundle),
|
|
583
|
-
});
|
|
584
|
-
}
|
|
313
|
+
// delete
|
|
314
|
+
wrangler.command(
|
|
315
|
+
"delete [script]",
|
|
316
|
+
"🗑 Delete your Worker from Cloudflare.",
|
|
317
|
+
deleteOptions,
|
|
318
|
+
deleteHandler
|
|
585
319
|
);
|
|
586
320
|
|
|
587
321
|
// tail
|
|
588
322
|
wrangler.command(
|
|
589
|
-
"tail [
|
|
323
|
+
"tail [worker]",
|
|
590
324
|
"🦚 Starts a log tailing session for a published Worker.",
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
.positional("name", {
|
|
594
|
-
describe: "Name of the worker",
|
|
595
|
-
type: "string",
|
|
596
|
-
})
|
|
597
|
-
.option("format", {
|
|
598
|
-
default: process.stdout.isTTY ? "pretty" : "json",
|
|
599
|
-
choices: ["json", "pretty"],
|
|
600
|
-
describe: "The format of log entries",
|
|
601
|
-
})
|
|
602
|
-
.option("status", {
|
|
603
|
-
choices: ["ok", "error", "canceled"],
|
|
604
|
-
describe: "Filter by invocation status",
|
|
605
|
-
array: true,
|
|
606
|
-
})
|
|
607
|
-
.option("header", {
|
|
608
|
-
type: "string",
|
|
609
|
-
requiresArg: true,
|
|
610
|
-
describe: "Filter by HTTP header",
|
|
611
|
-
})
|
|
612
|
-
.option("method", {
|
|
613
|
-
type: "string",
|
|
614
|
-
requiresArg: true,
|
|
615
|
-
describe: "Filter by HTTP method",
|
|
616
|
-
array: true,
|
|
617
|
-
})
|
|
618
|
-
.option("sampling-rate", {
|
|
619
|
-
type: "number",
|
|
620
|
-
describe: "Adds a percentage of requests to log sampling rate",
|
|
621
|
-
})
|
|
622
|
-
.option("search", {
|
|
623
|
-
type: "string",
|
|
624
|
-
requiresArg: true,
|
|
625
|
-
describe: "Filter by a text match in console.log messages",
|
|
626
|
-
})
|
|
627
|
-
.option("ip", {
|
|
628
|
-
type: "string",
|
|
629
|
-
requiresArg: true,
|
|
630
|
-
describe:
|
|
631
|
-
'Filter by the IP address the request originates from. Use "self" to filter for your own IP',
|
|
632
|
-
array: true,
|
|
633
|
-
})
|
|
634
|
-
.option("env", {
|
|
635
|
-
type: "string",
|
|
636
|
-
requiresArg: true,
|
|
637
|
-
describe: "Perform on a specific environment",
|
|
638
|
-
alias: "e",
|
|
639
|
-
})
|
|
640
|
-
.option("debug", {
|
|
641
|
-
type: "boolean",
|
|
642
|
-
hidden: true,
|
|
643
|
-
default: false,
|
|
644
|
-
describe:
|
|
645
|
-
"If a log would have been filtered out, send it through anyway alongside the filter which would have blocked it.",
|
|
646
|
-
})
|
|
647
|
-
.option("legacy-env", {
|
|
648
|
-
type: "boolean",
|
|
649
|
-
describe: "Use legacy environments",
|
|
650
|
-
hidden: true,
|
|
651
|
-
});
|
|
652
|
-
},
|
|
653
|
-
async (args) => {
|
|
654
|
-
if (args.format === "pretty") {
|
|
655
|
-
await printWranglerBanner();
|
|
656
|
-
}
|
|
657
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
658
|
-
await metrics.sendMetricsEvent("begin log stream", {
|
|
659
|
-
sendMetrics: config.send_metrics,
|
|
660
|
-
});
|
|
661
|
-
|
|
662
|
-
const scriptName = getLegacyScriptName(args, config);
|
|
663
|
-
|
|
664
|
-
if (!scriptName) {
|
|
665
|
-
throw new Error(
|
|
666
|
-
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `wrangler tail <worker-name>`"
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
const accountId = await requireAuth(config);
|
|
671
|
-
|
|
672
|
-
const cliFilters: TailCLIFilters = {
|
|
673
|
-
status: args.status as ("ok" | "error" | "canceled")[] | undefined,
|
|
674
|
-
header: args.header,
|
|
675
|
-
method: args.method,
|
|
676
|
-
samplingRate: args["sampling-rate"],
|
|
677
|
-
search: args.search,
|
|
678
|
-
clientIp: args.ip,
|
|
679
|
-
};
|
|
680
|
-
|
|
681
|
-
const filters = translateCLICommandToFilterMessage(
|
|
682
|
-
cliFilters,
|
|
683
|
-
args.debug
|
|
684
|
-
);
|
|
685
|
-
|
|
686
|
-
const { tail, expiration, deleteTail } = await createTail(
|
|
687
|
-
accountId,
|
|
688
|
-
scriptName,
|
|
689
|
-
filters,
|
|
690
|
-
!isLegacyEnv(config) ? args.env : undefined
|
|
691
|
-
);
|
|
692
|
-
|
|
693
|
-
const scriptDisplayName = `${scriptName}${
|
|
694
|
-
args.env && !isLegacyEnv(config) ? ` (${args.env})` : ""
|
|
695
|
-
}`;
|
|
696
|
-
|
|
697
|
-
if (args.format === "pretty") {
|
|
698
|
-
logger.log(
|
|
699
|
-
`Successfully created tail, expires at ${expiration.toLocaleString()}`
|
|
700
|
-
);
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
onExit(async () => {
|
|
704
|
-
tail.terminate();
|
|
705
|
-
await deleteTail();
|
|
706
|
-
await metrics.sendMetricsEvent("end log stream", {
|
|
707
|
-
sendMetrics: config.send_metrics,
|
|
708
|
-
});
|
|
709
|
-
});
|
|
710
|
-
|
|
711
|
-
const printLog: (data: RawData) => void =
|
|
712
|
-
args.format === "pretty" ? prettyPrintLogs : jsonPrintLogs;
|
|
713
|
-
|
|
714
|
-
tail.on("message", printLog);
|
|
715
|
-
|
|
716
|
-
while (tail.readyState !== tail.OPEN) {
|
|
717
|
-
switch (tail.readyState) {
|
|
718
|
-
case tail.CONNECTING:
|
|
719
|
-
await setTimeout(100);
|
|
720
|
-
break;
|
|
721
|
-
case tail.CLOSING:
|
|
722
|
-
await setTimeout(100);
|
|
723
|
-
break;
|
|
724
|
-
case tail.CLOSED:
|
|
725
|
-
await metrics.sendMetricsEvent("end log stream", {
|
|
726
|
-
sendMetrics: config.send_metrics,
|
|
727
|
-
});
|
|
728
|
-
throw new Error(
|
|
729
|
-
`Connection to ${scriptDisplayName} closed unexpectedly.`
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
if (args.format === "pretty") {
|
|
735
|
-
logger.log(`Connected to ${scriptDisplayName}, waiting for logs...`);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
tail.on("close", async () => {
|
|
739
|
-
tail.terminate();
|
|
740
|
-
await deleteTail();
|
|
741
|
-
await metrics.sendMetricsEvent("end log stream", {
|
|
742
|
-
sendMetrics: config.send_metrics,
|
|
743
|
-
});
|
|
744
|
-
});
|
|
745
|
-
}
|
|
325
|
+
tailOptions,
|
|
326
|
+
tailHandler
|
|
746
327
|
);
|
|
747
328
|
|
|
748
|
-
// preview
|
|
329
|
+
// [DEPRECATED] preview
|
|
749
330
|
wrangler.command(
|
|
750
331
|
"preview [method] [body]",
|
|
751
332
|
false,
|
|
@@ -759,92 +340,18 @@ function createCLIParser(argv: string[]) {
|
|
|
759
340
|
false, // I think we want to hide this command
|
|
760
341
|
// "➡️ List or delete worker routes",
|
|
761
342
|
(routeYargs) => {
|
|
762
|
-
return routeYargs
|
|
763
|
-
.command(
|
|
764
|
-
"list",
|
|
765
|
-
"List the routes associated with a zone",
|
|
766
|
-
(yargs) => {
|
|
767
|
-
return yargs
|
|
768
|
-
.option("env", {
|
|
769
|
-
type: "string",
|
|
770
|
-
requiresArg: true,
|
|
771
|
-
describe: "Perform on a specific environment",
|
|
772
|
-
})
|
|
773
|
-
.option("zone", {
|
|
774
|
-
type: "string",
|
|
775
|
-
requiresArg: true,
|
|
776
|
-
describe: "Zone id",
|
|
777
|
-
})
|
|
778
|
-
.positional("zone", {
|
|
779
|
-
describe: "Zone id",
|
|
780
|
-
type: "string",
|
|
781
|
-
});
|
|
782
|
-
},
|
|
783
|
-
() => {
|
|
784
|
-
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
785
|
-
const deprecationNotice =
|
|
786
|
-
"`wrangler route list` has been deprecated.";
|
|
787
|
-
const futureRoutes =
|
|
788
|
-
"Refer to wrangler.toml for a list of routes the worker will be deployed to upon publishing.";
|
|
789
|
-
const presentRoutes =
|
|
790
|
-
"Refer to the Cloudflare Dashboard to see the routes this worker is currently running on.";
|
|
791
|
-
throw new DeprecationError(
|
|
792
|
-
`${deprecationNotice}\n${futureRoutes}\n${presentRoutes}`
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
)
|
|
796
|
-
.command(
|
|
797
|
-
"delete [id]",
|
|
798
|
-
"Delete a route associated with a zone",
|
|
799
|
-
(yargs) => {
|
|
800
|
-
return yargs
|
|
801
|
-
.positional("id", {
|
|
802
|
-
describe: "The hash of the route ID to delete.",
|
|
803
|
-
type: "string",
|
|
804
|
-
})
|
|
805
|
-
.option("zone", {
|
|
806
|
-
type: "string",
|
|
807
|
-
requiresArg: true,
|
|
808
|
-
describe: "zone id",
|
|
809
|
-
})
|
|
810
|
-
.option("env", {
|
|
811
|
-
type: "string",
|
|
812
|
-
requiresArg: true,
|
|
813
|
-
describe: "Perform on a specific environment",
|
|
814
|
-
});
|
|
815
|
-
},
|
|
816
|
-
() => {
|
|
817
|
-
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
818
|
-
const deprecationNotice =
|
|
819
|
-
"`wrangler route delete` has been deprecated.";
|
|
820
|
-
const shouldDo =
|
|
821
|
-
"Remove the unwanted route(s) from wrangler.toml and run `wrangler publish` to remove your worker from those routes.";
|
|
822
|
-
throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
|
|
823
|
-
}
|
|
824
|
-
);
|
|
343
|
+
return route(routeYargs);
|
|
825
344
|
},
|
|
826
|
-
|
|
827
|
-
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
828
|
-
const deprecationNotice = "`wrangler route` has been deprecated.";
|
|
829
|
-
const shouldDo =
|
|
830
|
-
"Please use wrangler.toml and/or `wrangler publish --routes` to modify routes";
|
|
831
|
-
throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
|
|
832
|
-
}
|
|
345
|
+
routeHandler
|
|
833
346
|
);
|
|
834
347
|
|
|
835
|
-
// subdomain
|
|
348
|
+
// [DEPRECATED] subdomain
|
|
836
349
|
wrangler.command(
|
|
837
350
|
"subdomain [name]",
|
|
838
351
|
false,
|
|
839
352
|
// "👷 Create or change your workers.dev subdomain.",
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
},
|
|
843
|
-
() => {
|
|
844
|
-
throw new DeprecationError(
|
|
845
|
-
"`wrangler subdomain` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#subdomain for alternatives"
|
|
846
|
-
);
|
|
847
|
-
}
|
|
353
|
+
subdomainOptions,
|
|
354
|
+
subdomainHandler
|
|
848
355
|
);
|
|
849
356
|
|
|
850
357
|
// secret
|
|
@@ -852,974 +359,74 @@ function createCLIParser(argv: string[]) {
|
|
|
852
359
|
"secret",
|
|
853
360
|
"🤫 Generate a secret that can be referenced in a Worker",
|
|
854
361
|
(secretYargs) => {
|
|
855
|
-
return secretYargs
|
|
856
|
-
.command(subHelp)
|
|
857
|
-
.option("legacy-env", {
|
|
858
|
-
type: "boolean",
|
|
859
|
-
describe: "Use legacy environments",
|
|
860
|
-
hidden: true,
|
|
861
|
-
})
|
|
862
|
-
.command(
|
|
863
|
-
"put <key>",
|
|
864
|
-
"Create or update a secret variable for a Worker",
|
|
865
|
-
(yargs) => {
|
|
866
|
-
return yargs
|
|
867
|
-
.positional("key", {
|
|
868
|
-
describe: "The variable name to be accessible in the Worker",
|
|
869
|
-
type: "string",
|
|
870
|
-
})
|
|
871
|
-
.option("name", {
|
|
872
|
-
describe: "Name of the Worker",
|
|
873
|
-
type: "string",
|
|
874
|
-
requiresArg: true,
|
|
875
|
-
})
|
|
876
|
-
.option("env", {
|
|
877
|
-
type: "string",
|
|
878
|
-
requiresArg: true,
|
|
879
|
-
describe:
|
|
880
|
-
"Binds the secret to the Worker of the specific environment",
|
|
881
|
-
alias: "e",
|
|
882
|
-
});
|
|
883
|
-
},
|
|
884
|
-
async (args) => {
|
|
885
|
-
await printWranglerBanner();
|
|
886
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
887
|
-
|
|
888
|
-
const scriptName = getLegacyScriptName(args, config);
|
|
889
|
-
if (!scriptName) {
|
|
890
|
-
throw new Error(
|
|
891
|
-
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
const accountId = await requireAuth(config);
|
|
896
|
-
|
|
897
|
-
const isInteractive = process.stdin.isTTY;
|
|
898
|
-
const secretValue = trimTrailingWhitespace(
|
|
899
|
-
isInteractive
|
|
900
|
-
? await prompt("Enter a secret value:", "password")
|
|
901
|
-
: await readFromStdin()
|
|
902
|
-
);
|
|
903
|
-
|
|
904
|
-
logger.log(
|
|
905
|
-
`🌀 Creating the secret for the Worker "${scriptName}" ${
|
|
906
|
-
args.env && !isLegacyEnv(config) ? `(${args.env})` : ""
|
|
907
|
-
}`
|
|
908
|
-
);
|
|
909
|
-
|
|
910
|
-
async function submitSecret() {
|
|
911
|
-
const url =
|
|
912
|
-
!args.env || isLegacyEnv(config)
|
|
913
|
-
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
914
|
-
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
915
|
-
|
|
916
|
-
return await fetchResult(url, {
|
|
917
|
-
method: "PUT",
|
|
918
|
-
headers: { "Content-Type": "application/json" },
|
|
919
|
-
body: JSON.stringify({
|
|
920
|
-
name: args.key,
|
|
921
|
-
text: secretValue,
|
|
922
|
-
type: "secret_text",
|
|
923
|
-
}),
|
|
924
|
-
});
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
const createDraftWorker = async () => {
|
|
928
|
-
// TODO: log a warning
|
|
929
|
-
await fetchResult(
|
|
930
|
-
!isLegacyEnv(config) && args.env
|
|
931
|
-
? `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}`
|
|
932
|
-
: `/accounts/${accountId}/workers/scripts/${scriptName}`,
|
|
933
|
-
{
|
|
934
|
-
method: "PUT",
|
|
935
|
-
body: createWorkerUploadForm({
|
|
936
|
-
name: scriptName,
|
|
937
|
-
main: {
|
|
938
|
-
name: scriptName,
|
|
939
|
-
content: `export default { fetch() {} }`,
|
|
940
|
-
type: "esm",
|
|
941
|
-
},
|
|
942
|
-
bindings: {
|
|
943
|
-
kv_namespaces: [],
|
|
944
|
-
vars: {},
|
|
945
|
-
durable_objects: { bindings: [] },
|
|
946
|
-
r2_buckets: [],
|
|
947
|
-
services: [],
|
|
948
|
-
wasm_modules: {},
|
|
949
|
-
text_blobs: {},
|
|
950
|
-
data_blobs: {},
|
|
951
|
-
worker_namespaces: [],
|
|
952
|
-
unsafe: [],
|
|
953
|
-
},
|
|
954
|
-
modules: [],
|
|
955
|
-
migrations: undefined,
|
|
956
|
-
compatibility_date: undefined,
|
|
957
|
-
compatibility_flags: undefined,
|
|
958
|
-
usage_model: undefined,
|
|
959
|
-
}),
|
|
960
|
-
}
|
|
961
|
-
);
|
|
962
|
-
};
|
|
963
|
-
|
|
964
|
-
function isMissingWorkerError(e: unknown): e is { code: 10007 } {
|
|
965
|
-
return (
|
|
966
|
-
typeof e === "object" &&
|
|
967
|
-
e !== null &&
|
|
968
|
-
(e as { code: number }).code === 10007
|
|
969
|
-
);
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
try {
|
|
973
|
-
await submitSecret();
|
|
974
|
-
await metrics.sendMetricsEvent("create encrypted variable", {
|
|
975
|
-
sendMetrics: config.send_metrics,
|
|
976
|
-
});
|
|
977
|
-
} catch (e) {
|
|
978
|
-
if (isMissingWorkerError(e)) {
|
|
979
|
-
// create a draft worker and try again
|
|
980
|
-
await createDraftWorker();
|
|
981
|
-
await submitSecret();
|
|
982
|
-
// TODO: delete the draft worker if this failed too?
|
|
983
|
-
} else {
|
|
984
|
-
throw e;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
logger.log(`✨ Success! Uploaded secret ${args.key}`);
|
|
989
|
-
}
|
|
990
|
-
)
|
|
991
|
-
.command(
|
|
992
|
-
"delete <key>",
|
|
993
|
-
"Delete a secret variable from a Worker",
|
|
994
|
-
async (yargs) => {
|
|
995
|
-
await printWranglerBanner();
|
|
996
|
-
return yargs
|
|
997
|
-
.positional("key", {
|
|
998
|
-
describe: "The variable name to be accessible in the Worker",
|
|
999
|
-
type: "string",
|
|
1000
|
-
})
|
|
1001
|
-
.option("name", {
|
|
1002
|
-
describe: "Name of the Worker",
|
|
1003
|
-
type: "string",
|
|
1004
|
-
requiresArg: true,
|
|
1005
|
-
})
|
|
1006
|
-
.option("env", {
|
|
1007
|
-
type: "string",
|
|
1008
|
-
requiresArg: true,
|
|
1009
|
-
describe:
|
|
1010
|
-
"Binds the secret to the Worker of the specific environment",
|
|
1011
|
-
alias: "e",
|
|
1012
|
-
});
|
|
1013
|
-
},
|
|
1014
|
-
async (args) => {
|
|
1015
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1016
|
-
|
|
1017
|
-
const scriptName = getLegacyScriptName(args, config);
|
|
1018
|
-
if (!scriptName) {
|
|
1019
|
-
throw new Error(
|
|
1020
|
-
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
1021
|
-
);
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
const accountId = await requireAuth(config);
|
|
1025
|
-
|
|
1026
|
-
if (
|
|
1027
|
-
await confirm(
|
|
1028
|
-
`Are you sure you want to permanently delete the secret ${
|
|
1029
|
-
args.key
|
|
1030
|
-
} on the Worker ${scriptName}${
|
|
1031
|
-
args.env && !isLegacyEnv(config) ? ` (${args.env})` : ""
|
|
1032
|
-
}?`
|
|
1033
|
-
)
|
|
1034
|
-
) {
|
|
1035
|
-
logger.log(
|
|
1036
|
-
`🌀 Deleting the secret ${
|
|
1037
|
-
args.key
|
|
1038
|
-
} on the Worker ${scriptName}${
|
|
1039
|
-
args.env && !isLegacyEnv(config) ? ` (${args.env})` : ""
|
|
1040
|
-
}`
|
|
1041
|
-
);
|
|
1042
|
-
|
|
1043
|
-
const url =
|
|
1044
|
-
!args.env || isLegacyEnv(config)
|
|
1045
|
-
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
1046
|
-
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1047
|
-
|
|
1048
|
-
await fetchResult(`${url}/${args.key}`, { method: "DELETE" });
|
|
1049
|
-
await metrics.sendMetricsEvent("delete encrypted variable", {
|
|
1050
|
-
sendMetrics: config.send_metrics,
|
|
1051
|
-
});
|
|
1052
|
-
logger.log(`✨ Success! Deleted secret ${args.key}`);
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
)
|
|
1056
|
-
.command(
|
|
1057
|
-
"list",
|
|
1058
|
-
"List all secrets for a Worker",
|
|
1059
|
-
(yargs) => {
|
|
1060
|
-
return yargs
|
|
1061
|
-
.option("name", {
|
|
1062
|
-
describe: "Name of the Worker",
|
|
1063
|
-
type: "string",
|
|
1064
|
-
requiresArg: true,
|
|
1065
|
-
})
|
|
1066
|
-
.option("env", {
|
|
1067
|
-
type: "string",
|
|
1068
|
-
requiresArg: true,
|
|
1069
|
-
describe:
|
|
1070
|
-
"Binds the secret to the Worker of the specific environment.",
|
|
1071
|
-
alias: "e",
|
|
1072
|
-
});
|
|
1073
|
-
},
|
|
1074
|
-
async (args) => {
|
|
1075
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1076
|
-
|
|
1077
|
-
const scriptName = getLegacyScriptName(args, config);
|
|
1078
|
-
if (!scriptName) {
|
|
1079
|
-
throw new Error(
|
|
1080
|
-
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
const accountId = await requireAuth(config);
|
|
1085
|
-
|
|
1086
|
-
const url =
|
|
1087
|
-
!args.env || isLegacyEnv(config)
|
|
1088
|
-
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
1089
|
-
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1090
|
-
|
|
1091
|
-
logger.log(JSON.stringify(await fetchResult(url), null, " "));
|
|
1092
|
-
await metrics.sendMetricsEvent("list encrypted variables", {
|
|
1093
|
-
sendMetrics: config.send_metrics,
|
|
1094
|
-
});
|
|
1095
|
-
}
|
|
1096
|
-
);
|
|
362
|
+
return secret(secretYargs.command(subHelp));
|
|
1097
363
|
}
|
|
1098
364
|
);
|
|
1099
365
|
|
|
1100
|
-
|
|
1101
|
-
|
|
366
|
+
wrangler.command(
|
|
367
|
+
"secret:bulk <json>",
|
|
368
|
+
"🗄️ Bulk upload secrets for a Worker",
|
|
369
|
+
secretBulkOptions,
|
|
370
|
+
secretBulkHandler
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
// kv namespace
|
|
1102
374
|
wrangler.command(
|
|
1103
375
|
"kv:namespace",
|
|
1104
376
|
"🗂️ Interact with your Workers KV Namespaces",
|
|
1105
377
|
(namespaceYargs) => {
|
|
1106
|
-
return namespaceYargs
|
|
1107
|
-
.command(subHelp)
|
|
1108
|
-
.command(
|
|
1109
|
-
"create <namespace>",
|
|
1110
|
-
"Create a new namespace",
|
|
1111
|
-
(yargs) => {
|
|
1112
|
-
return yargs
|
|
1113
|
-
.positional("namespace", {
|
|
1114
|
-
describe: "The name of the new namespace",
|
|
1115
|
-
type: "string",
|
|
1116
|
-
demandOption: true,
|
|
1117
|
-
})
|
|
1118
|
-
.option("env", {
|
|
1119
|
-
type: "string",
|
|
1120
|
-
requiresArg: true,
|
|
1121
|
-
describe: "Perform on a specific environment",
|
|
1122
|
-
alias: "e",
|
|
1123
|
-
})
|
|
1124
|
-
.option("preview", {
|
|
1125
|
-
type: "boolean",
|
|
1126
|
-
describe: "Interact with a preview namespace",
|
|
1127
|
-
});
|
|
1128
|
-
},
|
|
1129
|
-
async (args) => {
|
|
1130
|
-
await printWranglerBanner();
|
|
1131
|
-
|
|
1132
|
-
if (!isValidKVNamespaceBinding(args.namespace)) {
|
|
1133
|
-
throw new CommandLineArgsError(
|
|
1134
|
-
`The namespace binding name "${args.namespace}" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.`
|
|
1135
|
-
);
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1139
|
-
if (!config.name) {
|
|
1140
|
-
logger.warn(
|
|
1141
|
-
"No configured name present, using `worker` as a prefix for the title"
|
|
1142
|
-
);
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
const name = config.name || "worker";
|
|
1146
|
-
const environment = args.env ? `-${args.env}` : "";
|
|
1147
|
-
const preview = args.preview ? "_preview" : "";
|
|
1148
|
-
const title = `${name}${environment}-${args.namespace}${preview}`;
|
|
1149
|
-
|
|
1150
|
-
const accountId = await requireAuth(config);
|
|
1151
|
-
|
|
1152
|
-
// TODO: generate a binding name stripping non alphanumeric chars
|
|
1153
|
-
|
|
1154
|
-
logger.log(`🌀 Creating namespace with title "${title}"`);
|
|
1155
|
-
const namespaceId = await createKVNamespace(accountId, title);
|
|
1156
|
-
await metrics.sendMetricsEvent("create kv namespace", {
|
|
1157
|
-
sendMetrics: config.send_metrics,
|
|
1158
|
-
});
|
|
1159
|
-
|
|
1160
|
-
logger.log("✨ Success!");
|
|
1161
|
-
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
1162
|
-
const previewString = args.preview ? "preview_" : "";
|
|
1163
|
-
logger.log(
|
|
1164
|
-
`Add the following to your configuration file in your kv_namespaces array${envString}:`
|
|
1165
|
-
);
|
|
1166
|
-
logger.log(
|
|
1167
|
-
`{ binding = "${args.namespace}", ${previewString}id = "${namespaceId}" }`
|
|
1168
|
-
);
|
|
1169
|
-
|
|
1170
|
-
// TODO: automatically write this block to the wrangler.toml config file??
|
|
1171
|
-
}
|
|
1172
|
-
)
|
|
1173
|
-
.command(
|
|
1174
|
-
"list",
|
|
1175
|
-
"Outputs a list of all KV namespaces associated with your account id.",
|
|
1176
|
-
{},
|
|
1177
|
-
async (args) => {
|
|
1178
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1179
|
-
|
|
1180
|
-
const accountId = await requireAuth(config);
|
|
1181
|
-
|
|
1182
|
-
// TODO: we should show bindings if they exist for given ids
|
|
1183
|
-
|
|
1184
|
-
logger.log(
|
|
1185
|
-
JSON.stringify(await listKVNamespaces(accountId), null, " ")
|
|
1186
|
-
);
|
|
1187
|
-
await metrics.sendMetricsEvent("list kv namespaces", {
|
|
1188
|
-
sendMetrics: config.send_metrics,
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
)
|
|
1192
|
-
.command(
|
|
1193
|
-
"delete",
|
|
1194
|
-
"Deletes a given namespace.",
|
|
1195
|
-
(yargs) => {
|
|
1196
|
-
return yargs
|
|
1197
|
-
.option("binding", {
|
|
1198
|
-
type: "string",
|
|
1199
|
-
requiresArg: true,
|
|
1200
|
-
describe: "The name of the namespace to delete",
|
|
1201
|
-
})
|
|
1202
|
-
.option("namespace-id", {
|
|
1203
|
-
type: "string",
|
|
1204
|
-
requiresArg: true,
|
|
1205
|
-
describe: "The id of the namespace to delete",
|
|
1206
|
-
})
|
|
1207
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1208
|
-
.option("env", {
|
|
1209
|
-
type: "string",
|
|
1210
|
-
requiresArg: true,
|
|
1211
|
-
describe: "Perform on a specific environment",
|
|
1212
|
-
alias: "e",
|
|
1213
|
-
})
|
|
1214
|
-
.option("preview", {
|
|
1215
|
-
type: "boolean",
|
|
1216
|
-
describe: "Interact with a preview namespace",
|
|
1217
|
-
});
|
|
1218
|
-
},
|
|
1219
|
-
async (args) => {
|
|
1220
|
-
await printWranglerBanner();
|
|
1221
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1222
|
-
|
|
1223
|
-
let id;
|
|
1224
|
-
try {
|
|
1225
|
-
id = getKVNamespaceId(args, config);
|
|
1226
|
-
} catch (e) {
|
|
1227
|
-
throw new CommandLineArgsError(
|
|
1228
|
-
"Not able to delete namespace.\n" + ((e as Error).message ?? e)
|
|
1229
|
-
);
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
const accountId = await requireAuth(config);
|
|
1233
|
-
|
|
1234
|
-
logger.log(`Deleting KV namespace ${id}.`);
|
|
1235
|
-
await deleteKVNamespace(accountId, id);
|
|
1236
|
-
logger.log(`Deleted KV namespace ${id}.`);
|
|
1237
|
-
await metrics.sendMetricsEvent("delete kv namespace", {
|
|
1238
|
-
sendMetrics: config.send_metrics,
|
|
1239
|
-
});
|
|
1240
|
-
|
|
1241
|
-
// TODO: recommend they remove it from wrangler.toml
|
|
1242
|
-
|
|
1243
|
-
// test-mf wrangler kv:namespace delete --namespace-id 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1244
|
-
// Are you sure you want to delete namespace 2a7d3d8b23fc4159b5afa489d6cfd388? [y/n]
|
|
1245
|
-
// n
|
|
1246
|
-
// 💁 Not deleting namespace 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1247
|
-
// ➜ test-mf wrangler kv:namespace delete --namespace-id 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1248
|
-
// Are you sure you want to delete namespace 2a7d3d8b23fc4159b5afa489d6cfd388? [y/n]
|
|
1249
|
-
// y
|
|
1250
|
-
// 🌀 Deleting namespace 2a7d3d8b23fc4159b5afa489d6cfd388
|
|
1251
|
-
// ✨ Success
|
|
1252
|
-
// ⚠️ Make sure to remove this "kv-namespace" entry from your configuration file!
|
|
1253
|
-
// ➜ test-mf
|
|
1254
|
-
|
|
1255
|
-
// TODO: do it automatically
|
|
1256
|
-
|
|
1257
|
-
// TODO: delete the preview namespace as well?
|
|
1258
|
-
}
|
|
1259
|
-
);
|
|
378
|
+
return kvNamespace(namespaceYargs.command(subHelp));
|
|
1260
379
|
}
|
|
1261
380
|
);
|
|
1262
381
|
|
|
1263
|
-
//
|
|
382
|
+
// kv key
|
|
1264
383
|
wrangler.command(
|
|
1265
384
|
"kv:key",
|
|
1266
385
|
"🔑 Individually manage Workers KV key-value pairs",
|
|
1267
|
-
(
|
|
1268
|
-
return
|
|
1269
|
-
.command(subHelp)
|
|
1270
|
-
.command(
|
|
1271
|
-
"put <key> [value]",
|
|
1272
|
-
"Writes a single key/value pair to the given namespace.",
|
|
1273
|
-
(yargs) => {
|
|
1274
|
-
return yargs
|
|
1275
|
-
.positional("key", {
|
|
1276
|
-
type: "string",
|
|
1277
|
-
describe: "The key to write to",
|
|
1278
|
-
demandOption: true,
|
|
1279
|
-
})
|
|
1280
|
-
.positional("value", {
|
|
1281
|
-
type: "string",
|
|
1282
|
-
describe: "The value to write",
|
|
1283
|
-
})
|
|
1284
|
-
.option("binding", {
|
|
1285
|
-
type: "string",
|
|
1286
|
-
requiresArg: true,
|
|
1287
|
-
describe: "The binding of the namespace to write to",
|
|
1288
|
-
})
|
|
1289
|
-
.option("namespace-id", {
|
|
1290
|
-
type: "string",
|
|
1291
|
-
requiresArg: true,
|
|
1292
|
-
describe: "The id of the namespace to write to",
|
|
1293
|
-
})
|
|
1294
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1295
|
-
.option("env", {
|
|
1296
|
-
type: "string",
|
|
1297
|
-
requiresArg: true,
|
|
1298
|
-
describe: "Perform on a specific environment",
|
|
1299
|
-
alias: "e",
|
|
1300
|
-
})
|
|
1301
|
-
.option("preview", {
|
|
1302
|
-
type: "boolean",
|
|
1303
|
-
describe: "Interact with a preview namespace",
|
|
1304
|
-
})
|
|
1305
|
-
.option("ttl", {
|
|
1306
|
-
type: "number",
|
|
1307
|
-
describe: "Time for which the entries should be visible",
|
|
1308
|
-
})
|
|
1309
|
-
.option("expiration", {
|
|
1310
|
-
type: "number",
|
|
1311
|
-
describe:
|
|
1312
|
-
"Time since the UNIX epoch after which the entry expires",
|
|
1313
|
-
})
|
|
1314
|
-
.option("metadata", {
|
|
1315
|
-
type: "string",
|
|
1316
|
-
describe: "Arbitrary JSON that is associated with a key",
|
|
1317
|
-
coerce: (jsonStr: string): KeyValue["metadata"] => {
|
|
1318
|
-
try {
|
|
1319
|
-
return JSON.parse(jsonStr);
|
|
1320
|
-
} catch (_) {}
|
|
1321
|
-
},
|
|
1322
|
-
})
|
|
1323
|
-
.option("path", {
|
|
1324
|
-
type: "string",
|
|
1325
|
-
requiresArg: true,
|
|
1326
|
-
describe: "Read value from the file at a given path",
|
|
1327
|
-
})
|
|
1328
|
-
.check(demandOneOfOption("value", "path"));
|
|
1329
|
-
},
|
|
1330
|
-
async ({ key, ttl, expiration, metadata, ...args }) => {
|
|
1331
|
-
await printWranglerBanner();
|
|
1332
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1333
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1334
|
-
// One of `args.path` and `args.value` must be defined
|
|
1335
|
-
const value = args.path
|
|
1336
|
-
? readFileSyncToBuffer(args.path)
|
|
1337
|
-
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1338
|
-
args.value!;
|
|
1339
|
-
|
|
1340
|
-
const metadataLog = metadata
|
|
1341
|
-
? ` with metadata "${JSON.stringify(metadata)}"`
|
|
1342
|
-
: "";
|
|
1343
|
-
|
|
1344
|
-
if (args.path) {
|
|
1345
|
-
logger.log(
|
|
1346
|
-
`Writing the contents of ${args.path} to the key "${key}" on namespace ${namespaceId}${metadataLog}.`
|
|
1347
|
-
);
|
|
1348
|
-
} else {
|
|
1349
|
-
logger.log(
|
|
1350
|
-
`Writing the value "${value}" to key "${key}" on namespace ${namespaceId}${metadataLog}.`
|
|
1351
|
-
);
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
const accountId = await requireAuth(config);
|
|
1355
|
-
|
|
1356
|
-
await putKVKeyValue(accountId, namespaceId, {
|
|
1357
|
-
key,
|
|
1358
|
-
value,
|
|
1359
|
-
expiration,
|
|
1360
|
-
expiration_ttl: ttl,
|
|
1361
|
-
metadata: metadata as KeyValue["metadata"],
|
|
1362
|
-
});
|
|
1363
|
-
await metrics.sendMetricsEvent("write kv key-value", {
|
|
1364
|
-
sendMetrics: config.send_metrics,
|
|
1365
|
-
});
|
|
1366
|
-
}
|
|
1367
|
-
)
|
|
1368
|
-
.command(
|
|
1369
|
-
"list",
|
|
1370
|
-
"Outputs a list of all keys in a given namespace.",
|
|
1371
|
-
(yargs) => {
|
|
1372
|
-
return yargs
|
|
1373
|
-
.option("binding", {
|
|
1374
|
-
type: "string",
|
|
1375
|
-
requiresArg: true,
|
|
1376
|
-
describe: "The name of the namespace to list",
|
|
1377
|
-
})
|
|
1378
|
-
.option("namespace-id", {
|
|
1379
|
-
type: "string",
|
|
1380
|
-
requiresArg: true,
|
|
1381
|
-
describe: "The id of the namespace to list",
|
|
1382
|
-
})
|
|
1383
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1384
|
-
.option("env", {
|
|
1385
|
-
type: "string",
|
|
1386
|
-
requiresArg: true,
|
|
1387
|
-
describe: "Perform on a specific environment",
|
|
1388
|
-
alias: "e",
|
|
1389
|
-
})
|
|
1390
|
-
.option("preview", {
|
|
1391
|
-
type: "boolean",
|
|
1392
|
-
// In the case of listing keys we will default to non-preview mode
|
|
1393
|
-
default: false,
|
|
1394
|
-
describe: "Interact with a preview namespace",
|
|
1395
|
-
})
|
|
1396
|
-
.option("prefix", {
|
|
1397
|
-
type: "string",
|
|
1398
|
-
requiresArg: true,
|
|
1399
|
-
describe: "A prefix to filter listed keys",
|
|
1400
|
-
});
|
|
1401
|
-
},
|
|
1402
|
-
async ({ prefix, ...args }) => {
|
|
1403
|
-
// TODO: support for limit+cursor (pagination)
|
|
1404
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1405
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1406
|
-
|
|
1407
|
-
const accountId = await requireAuth(config);
|
|
1408
|
-
|
|
1409
|
-
const results = await listKVNamespaceKeys(
|
|
1410
|
-
accountId,
|
|
1411
|
-
namespaceId,
|
|
1412
|
-
prefix
|
|
1413
|
-
);
|
|
1414
|
-
logger.log(JSON.stringify(results, undefined, 2));
|
|
1415
|
-
await metrics.sendMetricsEvent("list kv keys", {
|
|
1416
|
-
sendMetrics: config.send_metrics,
|
|
1417
|
-
});
|
|
1418
|
-
}
|
|
1419
|
-
)
|
|
1420
|
-
.command(
|
|
1421
|
-
"get <key>",
|
|
1422
|
-
"Reads a single value by key from the given namespace.",
|
|
1423
|
-
(yargs) => {
|
|
1424
|
-
return yargs
|
|
1425
|
-
.positional("key", {
|
|
1426
|
-
describe: "The key value to get.",
|
|
1427
|
-
type: "string",
|
|
1428
|
-
demandOption: true,
|
|
1429
|
-
})
|
|
1430
|
-
.option("binding", {
|
|
1431
|
-
type: "string",
|
|
1432
|
-
requiresArg: true,
|
|
1433
|
-
describe: "The name of the namespace to get from",
|
|
1434
|
-
})
|
|
1435
|
-
.option("namespace-id", {
|
|
1436
|
-
type: "string",
|
|
1437
|
-
requiresArg: true,
|
|
1438
|
-
describe: "The id of the namespace to get from",
|
|
1439
|
-
})
|
|
1440
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1441
|
-
.option("env", {
|
|
1442
|
-
type: "string",
|
|
1443
|
-
requiresArg: true,
|
|
1444
|
-
describe: "Perform on a specific environment",
|
|
1445
|
-
alias: "e",
|
|
1446
|
-
})
|
|
1447
|
-
.option("preview", {
|
|
1448
|
-
type: "boolean",
|
|
1449
|
-
describe: "Interact with a preview namespace",
|
|
1450
|
-
})
|
|
1451
|
-
.option("preview", {
|
|
1452
|
-
type: "boolean",
|
|
1453
|
-
// In the case of getting key values we will default to non-preview mode
|
|
1454
|
-
default: false,
|
|
1455
|
-
describe: "Interact with a preview namespace",
|
|
1456
|
-
})
|
|
1457
|
-
.option("text", {
|
|
1458
|
-
type: "boolean",
|
|
1459
|
-
default: false,
|
|
1460
|
-
describe: "Decode the returned value as a utf8 string",
|
|
1461
|
-
});
|
|
1462
|
-
},
|
|
1463
|
-
async ({ key, ...args }) => {
|
|
1464
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1465
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1466
|
-
|
|
1467
|
-
const accountId = await requireAuth(config);
|
|
1468
|
-
const bufferKVValue = Buffer.from(
|
|
1469
|
-
await getKVKeyValue(accountId, namespaceId, key)
|
|
1470
|
-
);
|
|
1471
|
-
|
|
1472
|
-
if (args.text) {
|
|
1473
|
-
const decoder = new StringDecoder("utf8");
|
|
1474
|
-
logger.log(decoder.write(bufferKVValue));
|
|
1475
|
-
} else {
|
|
1476
|
-
process.stdout.write(bufferKVValue);
|
|
1477
|
-
}
|
|
1478
|
-
await metrics.sendMetricsEvent("read kv value", {
|
|
1479
|
-
sendMetrics: config.send_metrics,
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
|
-
)
|
|
1483
|
-
.command(
|
|
1484
|
-
"delete <key>",
|
|
1485
|
-
"Removes a single key value pair from the given namespace.",
|
|
1486
|
-
(yargs) => {
|
|
1487
|
-
return yargs
|
|
1488
|
-
.positional("key", {
|
|
1489
|
-
describe: "The key value to delete",
|
|
1490
|
-
type: "string",
|
|
1491
|
-
demandOption: true,
|
|
1492
|
-
})
|
|
1493
|
-
.option("binding", {
|
|
1494
|
-
type: "string",
|
|
1495
|
-
requiresArg: true,
|
|
1496
|
-
describe: "The name of the namespace to delete from",
|
|
1497
|
-
})
|
|
1498
|
-
.option("namespace-id", {
|
|
1499
|
-
type: "string",
|
|
1500
|
-
requiresArg: true,
|
|
1501
|
-
describe: "The id of the namespace to delete from",
|
|
1502
|
-
})
|
|
1503
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1504
|
-
.option("env", {
|
|
1505
|
-
type: "string",
|
|
1506
|
-
requiresArg: true,
|
|
1507
|
-
describe: "Perform on a specific environment",
|
|
1508
|
-
alias: "e",
|
|
1509
|
-
})
|
|
1510
|
-
.option("preview", {
|
|
1511
|
-
type: "boolean",
|
|
1512
|
-
describe: "Interact with a preview namespace",
|
|
1513
|
-
});
|
|
1514
|
-
},
|
|
1515
|
-
async ({ key, ...args }) => {
|
|
1516
|
-
await printWranglerBanner();
|
|
1517
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1518
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1519
|
-
|
|
1520
|
-
logger.log(
|
|
1521
|
-
`Deleting the key "${key}" on namespace ${namespaceId}.`
|
|
1522
|
-
);
|
|
1523
|
-
|
|
1524
|
-
const accountId = await requireAuth(config);
|
|
1525
|
-
|
|
1526
|
-
await deleteKVKeyValue(accountId, namespaceId, key);
|
|
1527
|
-
await metrics.sendMetricsEvent("delete kv key-value", {
|
|
1528
|
-
sendMetrics: config.send_metrics,
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1531
|
-
);
|
|
386
|
+
(keyYargs) => {
|
|
387
|
+
return kvKey(keyYargs.command(subHelp));
|
|
1532
388
|
}
|
|
1533
389
|
);
|
|
1534
390
|
|
|
1535
|
-
//
|
|
391
|
+
// kv bulk
|
|
1536
392
|
wrangler.command(
|
|
1537
393
|
"kv:bulk",
|
|
1538
394
|
"💪 Interact with multiple Workers KV key-value pairs at once",
|
|
1539
|
-
(
|
|
1540
|
-
return
|
|
1541
|
-
.command(subHelp)
|
|
1542
|
-
.command(
|
|
1543
|
-
"put <filename>",
|
|
1544
|
-
"Upload multiple key-value pairs to a namespace",
|
|
1545
|
-
(yargs) => {
|
|
1546
|
-
return yargs
|
|
1547
|
-
.positional("filename", {
|
|
1548
|
-
describe: `The JSON file of key-value pairs to upload, in form [{"key":..., "value":...}"...]`,
|
|
1549
|
-
type: "string",
|
|
1550
|
-
demandOption: true,
|
|
1551
|
-
})
|
|
1552
|
-
.option("binding", {
|
|
1553
|
-
type: "string",
|
|
1554
|
-
requiresArg: true,
|
|
1555
|
-
describe: "The name of the namespace to insert values into",
|
|
1556
|
-
})
|
|
1557
|
-
.option("namespace-id", {
|
|
1558
|
-
type: "string",
|
|
1559
|
-
requiresArg: true,
|
|
1560
|
-
describe: "The id of the namespace to insert values into",
|
|
1561
|
-
})
|
|
1562
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1563
|
-
.option("env", {
|
|
1564
|
-
type: "string",
|
|
1565
|
-
requiresArg: true,
|
|
1566
|
-
describe: "Perform on a specific environment",
|
|
1567
|
-
alias: "e",
|
|
1568
|
-
})
|
|
1569
|
-
.option("preview", {
|
|
1570
|
-
type: "boolean",
|
|
1571
|
-
describe: "Interact with a preview namespace",
|
|
1572
|
-
});
|
|
1573
|
-
},
|
|
1574
|
-
async ({ filename, ...args }) => {
|
|
1575
|
-
await printWranglerBanner();
|
|
1576
|
-
// The simplest implementation I could think of.
|
|
1577
|
-
// This could be made more efficient with a streaming parser/uploader
|
|
1578
|
-
// but we'll do that in the future if needed.
|
|
1579
|
-
|
|
1580
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1581
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1582
|
-
const content = parseJSON(readFileSync(filename), filename);
|
|
1583
|
-
|
|
1584
|
-
if (!Array.isArray(content)) {
|
|
1585
|
-
throw new Error(
|
|
1586
|
-
`Unexpected JSON input from "${filename}".\n` +
|
|
1587
|
-
`Expected an array of key-value objects but got type "${typeof content}".`
|
|
1588
|
-
);
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
const errors: string[] = [];
|
|
1592
|
-
const warnings: string[] = [];
|
|
1593
|
-
for (let i = 0; i < content.length; i++) {
|
|
1594
|
-
const keyValue = content[i];
|
|
1595
|
-
if (!isKVKeyValue(keyValue)) {
|
|
1596
|
-
errors.push(
|
|
1597
|
-
`The item at index ${i} is ${JSON.stringify(keyValue)}`
|
|
1598
|
-
);
|
|
1599
|
-
} else {
|
|
1600
|
-
const props = unexpectedKVKeyValueProps(keyValue);
|
|
1601
|
-
if (props.length > 0) {
|
|
1602
|
-
warnings.push(
|
|
1603
|
-
`The item at index ${i} contains unexpected properties: ${JSON.stringify(
|
|
1604
|
-
props
|
|
1605
|
-
)}.`
|
|
1606
|
-
);
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
if (warnings.length > 0) {
|
|
1611
|
-
logger.warn(
|
|
1612
|
-
`Unexpected key-value properties in "${filename}".\n` +
|
|
1613
|
-
warnings.join("\n")
|
|
1614
|
-
);
|
|
1615
|
-
}
|
|
1616
|
-
if (errors.length > 0) {
|
|
1617
|
-
throw new Error(
|
|
1618
|
-
`Unexpected JSON input from "${filename}".\n` +
|
|
1619
|
-
`Each item in the array should be an object that matches:\n\n` +
|
|
1620
|
-
`interface KeyValue {\n` +
|
|
1621
|
-
` key: string;\n` +
|
|
1622
|
-
` value: string;\n` +
|
|
1623
|
-
` expiration?: number;\n` +
|
|
1624
|
-
` expiration_ttl?: number;\n` +
|
|
1625
|
-
` metadata?: object;\n` +
|
|
1626
|
-
` base64?: boolean;\n` +
|
|
1627
|
-
`}\n\n` +
|
|
1628
|
-
errors.join("\n")
|
|
1629
|
-
);
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
const accountId = await requireAuth(config);
|
|
1633
|
-
await putKVBulkKeyValue(accountId, namespaceId, content);
|
|
1634
|
-
await metrics.sendMetricsEvent("write kv key-values (bulk)", {
|
|
1635
|
-
sendMetrics: config.send_metrics,
|
|
1636
|
-
});
|
|
1637
|
-
|
|
1638
|
-
logger.log("Success!");
|
|
1639
|
-
}
|
|
1640
|
-
)
|
|
1641
|
-
.command(
|
|
1642
|
-
"delete <filename>",
|
|
1643
|
-
"Delete multiple key-value pairs from a namespace",
|
|
1644
|
-
(yargs) => {
|
|
1645
|
-
return yargs
|
|
1646
|
-
.positional("filename", {
|
|
1647
|
-
describe: `The JSON file of keys to delete, in the form ["key1", "key2", ...]`,
|
|
1648
|
-
type: "string",
|
|
1649
|
-
demandOption: true,
|
|
1650
|
-
})
|
|
1651
|
-
.option("binding", {
|
|
1652
|
-
type: "string",
|
|
1653
|
-
requiresArg: true,
|
|
1654
|
-
describe: "The name of the namespace to delete from",
|
|
1655
|
-
})
|
|
1656
|
-
.option("namespace-id", {
|
|
1657
|
-
type: "string",
|
|
1658
|
-
requiresArg: true,
|
|
1659
|
-
describe: "The id of the namespace to delete from",
|
|
1660
|
-
})
|
|
1661
|
-
.check(demandOneOfOption("binding", "namespace-id"))
|
|
1662
|
-
.option("env", {
|
|
1663
|
-
type: "string",
|
|
1664
|
-
requiresArg: true,
|
|
1665
|
-
describe: "Perform on a specific environment",
|
|
1666
|
-
alias: "e",
|
|
1667
|
-
})
|
|
1668
|
-
.option("preview", {
|
|
1669
|
-
type: "boolean",
|
|
1670
|
-
describe: "Interact with a preview namespace",
|
|
1671
|
-
})
|
|
1672
|
-
.option("force", {
|
|
1673
|
-
type: "boolean",
|
|
1674
|
-
alias: "f",
|
|
1675
|
-
describe: "Do not ask for confirmation before deleting",
|
|
1676
|
-
});
|
|
1677
|
-
},
|
|
1678
|
-
async ({ filename, ...args }) => {
|
|
1679
|
-
await printWranglerBanner();
|
|
1680
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1681
|
-
const namespaceId = getKVNamespaceId(args, config);
|
|
1682
|
-
|
|
1683
|
-
if (!args.force) {
|
|
1684
|
-
const result = await confirm(
|
|
1685
|
-
`Are you sure you want to delete all the keys read from "${filename}" from kv-namespace with id "${namespaceId}"?`
|
|
1686
|
-
);
|
|
1687
|
-
if (!result) {
|
|
1688
|
-
logger.log(`Not deleting keys read from "${filename}".`);
|
|
1689
|
-
return;
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
|
|
1693
|
-
const content = parseJSON(
|
|
1694
|
-
readFileSync(filename),
|
|
1695
|
-
filename
|
|
1696
|
-
) as string[];
|
|
1697
|
-
|
|
1698
|
-
if (!Array.isArray(content)) {
|
|
1699
|
-
throw new Error(
|
|
1700
|
-
`Unexpected JSON input from "${filename}".\n` +
|
|
1701
|
-
`Expected an array of strings but got:\n${content}`
|
|
1702
|
-
);
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
const errors: string[] = [];
|
|
1706
|
-
for (let i = 0; i < content.length; i++) {
|
|
1707
|
-
const key = content[i];
|
|
1708
|
-
if (typeof key !== "string") {
|
|
1709
|
-
errors.push(
|
|
1710
|
-
`The item at index ${i} is type: "${typeof key}" - ${JSON.stringify(
|
|
1711
|
-
key
|
|
1712
|
-
)}`
|
|
1713
|
-
);
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
if (errors.length > 0) {
|
|
1717
|
-
throw new Error(
|
|
1718
|
-
`Unexpected JSON input from "${filename}".\n` +
|
|
1719
|
-
`Expected an array of strings.\n` +
|
|
1720
|
-
errors.join("\n")
|
|
1721
|
-
);
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
const accountId = await requireAuth(config);
|
|
1725
|
-
|
|
1726
|
-
await deleteKVBulkKeyValue(accountId, namespaceId, content);
|
|
1727
|
-
await metrics.sendMetricsEvent("delete kv key-values (bulk)", {
|
|
1728
|
-
sendMetrics: config.send_metrics,
|
|
1729
|
-
});
|
|
1730
|
-
|
|
1731
|
-
logger.log("Success!");
|
|
1732
|
-
}
|
|
1733
|
-
);
|
|
395
|
+
(bulkYargs) => {
|
|
396
|
+
return kvBulk(bulkYargs.command(subHelp));
|
|
1734
397
|
}
|
|
1735
398
|
);
|
|
1736
399
|
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
await pages(pagesYargs.command(subHelp));
|
|
1742
|
-
}
|
|
1743
|
-
);
|
|
1744
|
-
|
|
1745
|
-
wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
|
|
1746
|
-
return r2Yargs
|
|
1747
|
-
.command(subHelp)
|
|
1748
|
-
.command("bucket", "Manage R2 buckets", (r2BucketYargs) => {
|
|
1749
|
-
r2BucketYargs.command(
|
|
1750
|
-
"create <name>",
|
|
1751
|
-
"Create a new R2 bucket",
|
|
1752
|
-
(yargs) => {
|
|
1753
|
-
return yargs.positional("name", {
|
|
1754
|
-
describe: "The name of the new bucket",
|
|
1755
|
-
type: "string",
|
|
1756
|
-
demandOption: true,
|
|
1757
|
-
});
|
|
1758
|
-
},
|
|
1759
|
-
async (args) => {
|
|
1760
|
-
await printWranglerBanner();
|
|
1761
|
-
|
|
1762
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1763
|
-
|
|
1764
|
-
const accountId = await requireAuth(config);
|
|
1765
|
-
|
|
1766
|
-
logger.log(`Creating bucket ${args.name}.`);
|
|
1767
|
-
await createR2Bucket(accountId, args.name);
|
|
1768
|
-
logger.log(`Created bucket ${args.name}.`);
|
|
1769
|
-
await metrics.sendMetricsEvent("create r2 bucket", {
|
|
1770
|
-
sendMetrics: config.send_metrics,
|
|
1771
|
-
});
|
|
1772
|
-
}
|
|
1773
|
-
);
|
|
1774
|
-
|
|
1775
|
-
r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
|
|
1776
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
1777
|
-
|
|
1778
|
-
const accountId = await requireAuth(config);
|
|
1779
|
-
|
|
1780
|
-
logger.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
|
|
1781
|
-
await metrics.sendMetricsEvent("list r2 buckets", {
|
|
1782
|
-
sendMetrics: config.send_metrics,
|
|
1783
|
-
});
|
|
1784
|
-
});
|
|
1785
|
-
|
|
1786
|
-
r2BucketYargs.command(
|
|
1787
|
-
"delete <name>",
|
|
1788
|
-
"Delete an R2 bucket",
|
|
1789
|
-
(yargs) => {
|
|
1790
|
-
return yargs.positional("name", {
|
|
1791
|
-
describe: "The name of the bucket to delete",
|
|
1792
|
-
type: "string",
|
|
1793
|
-
demandOption: true,
|
|
1794
|
-
});
|
|
1795
|
-
},
|
|
1796
|
-
async (args) => {
|
|
1797
|
-
await printWranglerBanner();
|
|
1798
|
-
|
|
1799
|
-
const config = readConfig(args.config as ConfigPath, args);
|
|
400
|
+
// pages
|
|
401
|
+
wrangler.command("pages", "⚡️ Configure Cloudflare Pages", (pagesYargs) => {
|
|
402
|
+
return pages(pagesYargs.command(subHelp));
|
|
403
|
+
});
|
|
1800
404
|
|
|
1801
|
-
|
|
405
|
+
// queues
|
|
406
|
+
wrangler.command("queues", "🇶 Configure Workers Queues", (queuesYargs) => {
|
|
407
|
+
return queues(queuesYargs.command(subHelp));
|
|
408
|
+
});
|
|
1802
409
|
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
await metrics.sendMetricsEvent("delete r2 bucket", {
|
|
1807
|
-
sendMetrics: config.send_metrics,
|
|
1808
|
-
});
|
|
1809
|
-
}
|
|
1810
|
-
);
|
|
1811
|
-
return r2BucketYargs;
|
|
1812
|
-
});
|
|
410
|
+
// r2
|
|
411
|
+
wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
|
|
412
|
+
return r2(r2Yargs.command(subHelp));
|
|
1813
413
|
});
|
|
1814
414
|
|
|
415
|
+
// dispatch-namespace
|
|
1815
416
|
wrangler.command(
|
|
1816
|
-
"
|
|
1817
|
-
"📦 Interact with a
|
|
417
|
+
"dispatch-namespace",
|
|
418
|
+
"📦 Interact with a dispatch namespace",
|
|
1818
419
|
(workerNamespaceYargs) => {
|
|
1819
420
|
return workerNamespaceCommands(workerNamespaceYargs, subHelp);
|
|
1820
421
|
}
|
|
1821
422
|
);
|
|
1822
423
|
|
|
424
|
+
// d1
|
|
425
|
+
wrangler.command("d1", "🗄 Interact with a D1 database", (d1Yargs) => {
|
|
426
|
+
return d1(d1Yargs.command(subHelp));
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// pubsub
|
|
1823
430
|
wrangler.command(
|
|
1824
431
|
"pubsub",
|
|
1825
432
|
"📮 Interact and manage Pub/Sub Brokers",
|
|
@@ -1844,6 +451,11 @@ function createCLIParser(argv: string[]) {
|
|
|
1844
451
|
.option("scopes-list", {
|
|
1845
452
|
describe: "List all the available OAuth scopes with descriptions",
|
|
1846
453
|
})
|
|
454
|
+
.option("browser", {
|
|
455
|
+
default: true,
|
|
456
|
+
type: "boolean",
|
|
457
|
+
describe: "Automatically open the OAuth link in a browser",
|
|
458
|
+
})
|
|
1847
459
|
.option("scopes", {
|
|
1848
460
|
describe: "Pick the set of applicable OAuth scopes when logging in",
|
|
1849
461
|
array: true,
|
|
@@ -1870,10 +482,10 @@ function createCLIParser(argv: string[]) {
|
|
|
1870
482
|
`One of ${args.scopes} is not a valid authentication scope. Run "wrangler login --list-scopes" to see the valid scopes.`
|
|
1871
483
|
);
|
|
1872
484
|
}
|
|
1873
|
-
await login({ scopes: args.scopes });
|
|
485
|
+
await login({ scopes: args.scopes, browser: args.browser });
|
|
1874
486
|
return;
|
|
1875
487
|
}
|
|
1876
|
-
await login();
|
|
488
|
+
await login({ browser: args.browser });
|
|
1877
489
|
const config = readConfig(args.config as ConfigPath, args);
|
|
1878
490
|
await metrics.sendMetricsEvent("login user", {
|
|
1879
491
|
sendMetrics: config.send_metrics,
|
|
@@ -1916,6 +528,70 @@ function createCLIParser(argv: string[]) {
|
|
|
1916
528
|
}
|
|
1917
529
|
);
|
|
1918
530
|
|
|
531
|
+
// type generation
|
|
532
|
+
wrangler.command(
|
|
533
|
+
"types",
|
|
534
|
+
"📝 Generate types from bindings & module rules in config",
|
|
535
|
+
() => {},
|
|
536
|
+
async () => {
|
|
537
|
+
await printWranglerBanner();
|
|
538
|
+
const config = readConfig(undefined, {});
|
|
539
|
+
|
|
540
|
+
const configBindings: Partial<Config> = {
|
|
541
|
+
kv_namespaces: config.kv_namespaces ?? [],
|
|
542
|
+
vars: { ...config.vars },
|
|
543
|
+
wasm_modules: config.wasm_modules,
|
|
544
|
+
text_blobs: {
|
|
545
|
+
...config.text_blobs,
|
|
546
|
+
},
|
|
547
|
+
data_blobs: config.data_blobs,
|
|
548
|
+
durable_objects: config.durable_objects,
|
|
549
|
+
r2_buckets: config.r2_buckets,
|
|
550
|
+
d1_databases: config.d1_databases,
|
|
551
|
+
services: config.services,
|
|
552
|
+
analytics_engine_datasets: config.analytics_engine_datasets,
|
|
553
|
+
dispatch_namespaces: config.dispatch_namespaces,
|
|
554
|
+
logfwdr: config.logfwdr,
|
|
555
|
+
unsafe: { bindings: config.unsafe?.bindings },
|
|
556
|
+
rules: config.rules,
|
|
557
|
+
queues: config.queues,
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
await generateTypes(configBindings, config);
|
|
561
|
+
}
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
//deployments
|
|
565
|
+
const deploymentsWarning =
|
|
566
|
+
"🚧`wrangler deployments` is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
|
|
567
|
+
wrangler.command(
|
|
568
|
+
"deployments",
|
|
569
|
+
"🚢 Displays the 10 most recent deployments for a worker",
|
|
570
|
+
(yargs) => {
|
|
571
|
+
yargs
|
|
572
|
+
.option("name", {
|
|
573
|
+
describe: "The name of your worker",
|
|
574
|
+
type: "string",
|
|
575
|
+
})
|
|
576
|
+
.epilogue(deploymentsWarning);
|
|
577
|
+
},
|
|
578
|
+
async (deploymentsYargs: ArgumentsCamelCase<{ name: string }>) => {
|
|
579
|
+
await printWranglerBanner();
|
|
580
|
+
const config = readConfig(
|
|
581
|
+
deploymentsYargs.config as ConfigPath,
|
|
582
|
+
deploymentsYargs
|
|
583
|
+
);
|
|
584
|
+
const accountId = await requireAuth(config);
|
|
585
|
+
const scriptName = getScriptName(
|
|
586
|
+
{ name: deploymentsYargs.name, env: undefined },
|
|
587
|
+
config
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
logger.log(`${deploymentsWarning}\n`);
|
|
591
|
+
await deployments(accountId, scriptName);
|
|
592
|
+
}
|
|
593
|
+
);
|
|
594
|
+
|
|
1919
595
|
// This set to false to allow overwrite of default behaviour
|
|
1920
596
|
wrangler.version(false);
|
|
1921
597
|
|
|
@@ -1933,22 +609,6 @@ function createCLIParser(argv: string[]) {
|
|
|
1933
609
|
}
|
|
1934
610
|
);
|
|
1935
611
|
|
|
1936
|
-
wrangler.option("v", {
|
|
1937
|
-
describe: "Show version number",
|
|
1938
|
-
alias: "version",
|
|
1939
|
-
type: "boolean",
|
|
1940
|
-
});
|
|
1941
|
-
|
|
1942
|
-
wrangler.option("config", {
|
|
1943
|
-
alias: "c",
|
|
1944
|
-
describe: "Path to .toml configuration file",
|
|
1945
|
-
type: "string",
|
|
1946
|
-
requiresArg: true,
|
|
1947
|
-
});
|
|
1948
|
-
|
|
1949
|
-
wrangler.group(["config", "help", "version"], "Flags:");
|
|
1950
|
-
wrangler.help().alias("h", "help");
|
|
1951
|
-
|
|
1952
612
|
wrangler.exitProcess(false);
|
|
1953
613
|
|
|
1954
614
|
return wrangler;
|
|
@@ -1971,6 +631,35 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1971
631
|
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new/choose",
|
|
1972
632
|
});
|
|
1973
633
|
logger.log(formatMessage(e));
|
|
634
|
+
} else if (
|
|
635
|
+
e instanceof Error &&
|
|
636
|
+
e.message.includes("Raw mode is not supported on")
|
|
637
|
+
) {
|
|
638
|
+
// the current terminal doesn't support raw mode, which Ink needs to render
|
|
639
|
+
// Ink doesn't throw a typed error or subclass or anything, so we just check the message content.
|
|
640
|
+
// https://github.com/vadimdemedes/ink/blob/546fe16541fd05ad4e638d6842ca4cbe88b4092b/src/components/App.tsx#L138-L148
|
|
641
|
+
|
|
642
|
+
const currentPlatform = os.platform();
|
|
643
|
+
|
|
644
|
+
const thisTerminalIsUnsupported =
|
|
645
|
+
"This terminal doesn't support raw mode.";
|
|
646
|
+
const soWranglerWontWork =
|
|
647
|
+
"Wrangler uses raw mode to read user input and write output to the terminal, and won't function correctly without it.";
|
|
648
|
+
const tryRunningItIn =
|
|
649
|
+
"Try running your previous command in a terminal that supports raw mode";
|
|
650
|
+
const oneOfThese =
|
|
651
|
+
currentPlatform === "win32"
|
|
652
|
+
? ", such as Command Prompt or Powershell."
|
|
653
|
+
: currentPlatform === "darwin"
|
|
654
|
+
? ", such as Terminal.app or iTerm."
|
|
655
|
+
: "."; // linux user detected, hand holding disengaged.
|
|
656
|
+
|
|
657
|
+
logger.error(
|
|
658
|
+
`${thisTerminalIsUnsupported}\n${soWranglerWontWork}\n${tryRunningItIn}${oneOfThese}`
|
|
659
|
+
);
|
|
660
|
+
} else if (isBuildFailure(e)) {
|
|
661
|
+
logBuildFailure(e);
|
|
662
|
+
logger.error(e.message);
|
|
1974
663
|
} else {
|
|
1975
664
|
logger.error(e instanceof Error ? e.message : e);
|
|
1976
665
|
logger.log(
|
|
@@ -1998,7 +687,7 @@ export function getDevCompatibilityDate(
|
|
|
1998
687
|
"```\n" +
|
|
1999
688
|
`--compatibility-date=${currentDate}\n` +
|
|
2000
689
|
"```\n" +
|
|
2001
|
-
"See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information."
|
|
690
|
+
"See https://developers.cloudflare.com/workers/platform/compatibility-dates/ for more information."
|
|
2002
691
|
);
|
|
2003
692
|
}
|
|
2004
693
|
return compatibilityDate ?? currentDate;
|