wrangler 0.0.0-e3cab74 → 0.0.0-e3e3243
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 +1 -1
- package/bin/wrangler.js +10 -1
- package/miniflare-dist/index.mjs +79 -0
- package/miniflare-dist/index.mjs.map +7 -0
- package/package.json +10 -7
- package/pages/functions/filepath-routing.test.ts +125 -25
- package/pages/functions/filepath-routing.ts +6 -3
- package/src/__tests__/configuration.test.ts +959 -324
- package/src/__tests__/dev.test.tsx +512 -84
- package/src/__tests__/guess-worker-format.test.ts +19 -17
- package/src/__tests__/helpers/mock-account-id.ts +22 -4
- package/src/__tests__/helpers/mock-cfetch.ts +3 -3
- package/src/__tests__/helpers/mock-console.ts +17 -9
- package/src/__tests__/helpers/mock-kv.ts +9 -16
- package/src/__tests__/helpers/mock-stdin.ts +103 -0
- package/src/__tests__/helpers/run-in-tmp.ts +3 -0
- package/src/__tests__/https-options.test.ts +127 -0
- package/src/__tests__/index.test.ts +128 -11
- package/src/__tests__/jest.setup.ts +16 -4
- package/src/__tests__/kv.test.ts +364 -125
- package/src/__tests__/logout.test.ts +15 -13
- package/src/__tests__/pages.test.ts +82 -0
- package/src/__tests__/publish.test.ts +1838 -735
- package/src/__tests__/r2.test.ts +4 -4
- package/src/__tests__/route.test.ts +45 -0
- package/src/__tests__/secret.test.ts +167 -68
- package/src/__tests__/tail.test.ts +2 -4
- package/src/__tests__/whoami.test.tsx +21 -7
- package/src/bundle.ts +27 -5
- package/src/cfetch/internal.ts +11 -5
- package/src/config/README.md +6 -6
- package/src/config/config.ts +54 -101
- package/src/config/environment.ts +67 -1
- package/src/config/index.ts +13 -3
- package/src/config/validation-helpers.ts +207 -23
- package/src/config/validation.ts +344 -129
- package/src/{api/preview.ts → create-worker-preview.ts} +39 -20
- package/src/{api/form_data.ts → create-worker-upload-form.ts} +1 -1
- package/src/dev/dev.tsx +392 -0
- package/src/dev/local.tsx +232 -0
- package/src/dev/remote.tsx +203 -0
- package/src/dev/use-esbuild.ts +104 -0
- package/src/entry.ts +192 -9
- package/src/https-options.ts +122 -0
- package/src/index.tsx +577 -515
- package/src/inspect.ts +9 -1
- package/src/intl-polyfill.d.ts +139 -0
- package/src/{kv.tsx → kv.ts} +97 -53
- package/src/miniflare-cli/README.md +30 -0
- package/src/miniflare-cli/enum-keys.ts +17 -0
- package/src/miniflare-cli/index.ts +37 -0
- package/src/module-collection.ts +90 -2
- package/src/open-in-browser.ts +14 -2
- package/src/pages.tsx +26 -10
- package/src/proxy.ts +104 -40
- package/src/publish.ts +53 -71
- package/src/reporting.ts +25 -9
- package/src/selfsigned.d.ts +29 -0
- package/src/sites.tsx +68 -29
- package/src/user.tsx +163 -85
- package/src/{api/worker.ts → worker.ts} +1 -24
- package/wrangler-dist/cli.js +5933 -3842
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/helpers/mock-user.ts +0 -27
- package/src/dev.tsx +0 -961
- package/src/guess-worker-format.ts +0 -68
package/src/index.tsx
CHANGED
|
@@ -3,17 +3,19 @@ import { writeFile, mkdir } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { setTimeout } from "node:timers/promises";
|
|
5
5
|
import TOML from "@iarna/toml";
|
|
6
|
+
import chalk from "chalk";
|
|
6
7
|
import { findUp } from "find-up";
|
|
7
8
|
import getPort from "get-port";
|
|
8
9
|
import { render } from "ink";
|
|
9
10
|
import React from "react";
|
|
10
11
|
import onExit from "signal-exit";
|
|
12
|
+
import supportsColor from "supports-color";
|
|
11
13
|
import makeCLI from "yargs";
|
|
12
14
|
import { version as wranglerVersion } from "../package.json";
|
|
13
|
-
import { toFormData } from "./api/form_data";
|
|
14
15
|
import { fetchResult } from "./cfetch";
|
|
15
16
|
import { findWranglerToml, readConfig } from "./config";
|
|
16
|
-
import
|
|
17
|
+
import { createWorkerUploadForm } from "./create-worker-upload-form";
|
|
18
|
+
import Dev from "./dev/dev";
|
|
17
19
|
import { confirm, prompt } from "./dialogs";
|
|
18
20
|
import { getEntry } from "./entry";
|
|
19
21
|
import {
|
|
@@ -26,9 +28,11 @@ import {
|
|
|
26
28
|
createNamespace,
|
|
27
29
|
isValidNamespaceBinding,
|
|
28
30
|
getKeyValue,
|
|
31
|
+
isKeyValue,
|
|
32
|
+
unexpectedKeyValueProps,
|
|
29
33
|
} from "./kv";
|
|
30
34
|
import { getPackageManager } from "./package-manager";
|
|
31
|
-
import { pages } from "./pages";
|
|
35
|
+
import { pages, pagesBetaWarning } from "./pages";
|
|
32
36
|
import { formatMessage, ParseError, parseJSON, readFileSync } from "./parse";
|
|
33
37
|
import publish from "./publish";
|
|
34
38
|
import { createR2Bucket, deleteR2Bucket, listR2Buckets } from "./r2";
|
|
@@ -43,7 +47,6 @@ import {
|
|
|
43
47
|
login,
|
|
44
48
|
logout,
|
|
45
49
|
listScopes,
|
|
46
|
-
initialise as initialiseUserConfig,
|
|
47
50
|
loginOrRefreshIfRequired,
|
|
48
51
|
getAccountId,
|
|
49
52
|
validateScopeKeys,
|
|
@@ -53,6 +56,7 @@ import { whoami } from "./whoami";
|
|
|
53
56
|
import type { Config } from "./config";
|
|
54
57
|
import type { TailCLIFilters } from "./tail";
|
|
55
58
|
import type { RawData } from "ws";
|
|
59
|
+
import type { CommandModule } from "yargs";
|
|
56
60
|
import type Yargs from "yargs";
|
|
57
61
|
|
|
58
62
|
type ConfigPath = string | undefined;
|
|
@@ -79,25 +83,106 @@ ${TOML.stringify({ rules: config.build.upload.rules })}`
|
|
|
79
83
|
return rules;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
function printWranglerBanner() {
|
|
87
|
+
// Let's not print this in tests
|
|
88
|
+
if (typeof jest !== "undefined") {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const text = ` ⛅️ wrangler ${wranglerVersion} `;
|
|
92
|
+
|
|
93
|
+
console.log(
|
|
94
|
+
text +
|
|
95
|
+
"\n" +
|
|
96
|
+
(supportsColor.stdout
|
|
97
|
+
? chalk.hex("#FF8800")("-".repeat(text.length))
|
|
98
|
+
: "-".repeat(text.length))
|
|
86
99
|
);
|
|
87
100
|
}
|
|
88
101
|
|
|
102
|
+
function isLegacyEnv(args: unknown, config: Config): boolean {
|
|
103
|
+
return config.legacy_env;
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
function getScriptName(
|
|
90
107
|
args: { name: string | undefined; env: string | undefined },
|
|
91
108
|
config: Config
|
|
92
109
|
): string | undefined {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
110
|
+
if (args.name && isLegacyEnv(args, config) && args.env) {
|
|
111
|
+
throw new CommandLineArgsError(
|
|
112
|
+
"In legacy environment mode you cannot use --name and --env together. If you want to specify a Worker name for a specific environment you can add the following to your wrangler.toml config:" +
|
|
113
|
+
`
|
|
114
|
+
[env.${args.env}]
|
|
115
|
+
name = "${args.name}"
|
|
116
|
+
`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return args.name ?? config.name;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Alternative to the getScriptName() because special Legacy cases allowed "name", and "env" together in Wrangler1
|
|
125
|
+
*/
|
|
126
|
+
function getLegacyScriptName(
|
|
127
|
+
args: { name: string | undefined; env: string | undefined },
|
|
128
|
+
config: Config
|
|
129
|
+
) {
|
|
130
|
+
return args.name && args.env && isLegacyEnv(args, config)
|
|
131
|
+
? `${args.name}-${args.env}`
|
|
132
|
+
: args.name ?? config.name;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Ensure that a user is logged in, and a valid account_id is available.
|
|
137
|
+
*/
|
|
138
|
+
async function requireAuth(
|
|
139
|
+
config: Config,
|
|
140
|
+
isInteractive = true
|
|
141
|
+
): Promise<string> {
|
|
142
|
+
const loggedIn = await loginOrRefreshIfRequired(isInteractive);
|
|
143
|
+
if (!loggedIn) {
|
|
144
|
+
// didn't login, let's just quit
|
|
145
|
+
throw new Error("Did not login, quitting...");
|
|
96
146
|
}
|
|
147
|
+
const accountId = config.account_id || (await getAccountId(isInteractive));
|
|
148
|
+
if (!accountId) {
|
|
149
|
+
throw new Error("No account id found, quitting...");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return accountId;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get a promise to the streamed input from stdin.
|
|
157
|
+
*
|
|
158
|
+
* This function can be used to grab the incoming stream of data from, say,
|
|
159
|
+
* piping the output of another process into the wrangler process.
|
|
160
|
+
*/
|
|
161
|
+
function readFromStdin(): Promise<string> {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const stdin = process.stdin;
|
|
164
|
+
const chunks: string[] = [];
|
|
165
|
+
|
|
166
|
+
// When there is data ready to be read, the `readable` event will be triggered.
|
|
167
|
+
// In the handler for `readable` we call `read()` over and over until all the available data has been read.
|
|
168
|
+
stdin.on("readable", () => {
|
|
169
|
+
let chunk;
|
|
170
|
+
while (null !== (chunk = stdin.read())) {
|
|
171
|
+
chunks.push(chunk);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// When the streamed data is complete the `end` event will be triggered.
|
|
176
|
+
// In the handler for `end` we join the chunks together and resolve the promise.
|
|
177
|
+
stdin.on("end", () => {
|
|
178
|
+
resolve(chunks.join(""));
|
|
179
|
+
});
|
|
97
180
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
181
|
+
// If there is an `error` event then the handler will reject the promise.
|
|
182
|
+
stdin.on("error", (err) => {
|
|
183
|
+
reject(err);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
101
186
|
}
|
|
102
187
|
|
|
103
188
|
// a helper to demand one of a set of options
|
|
@@ -134,6 +219,7 @@ class DeprecationError extends Error {
|
|
|
134
219
|
|
|
135
220
|
export async function main(argv: string[]): Promise<void> {
|
|
136
221
|
const wrangler = makeCLI(argv)
|
|
222
|
+
.strict()
|
|
137
223
|
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
138
224
|
// If you want the "help info" to be displayed then throw an instance of `CommandLineArgsError`.
|
|
139
225
|
// Otherwise we just log the error that was thrown without any "help info".
|
|
@@ -148,7 +234,15 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
148
234
|
.scriptName("wrangler")
|
|
149
235
|
.wrap(null);
|
|
150
236
|
|
|
151
|
-
//
|
|
237
|
+
// Default help command that supports the subcommands
|
|
238
|
+
const subHelp: CommandModule = {
|
|
239
|
+
command: ["*"],
|
|
240
|
+
handler: async (args) => {
|
|
241
|
+
setImmediate(() =>
|
|
242
|
+
wrangler.parse([...args._.map((a) => `${a}`), "--help"])
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
};
|
|
152
246
|
wrangler.command(
|
|
153
247
|
["*"],
|
|
154
248
|
false,
|
|
@@ -189,7 +283,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
189
283
|
() => {
|
|
190
284
|
// "👯 [DEPRECATED]. Scaffold a Cloudflare Workers project from a public GitHub repository.",
|
|
191
285
|
throw new DeprecationError(
|
|
192
|
-
"`wrangler generate` has been deprecated, please refer to
|
|
286
|
+
"`wrangler generate` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#generate for alternatives"
|
|
193
287
|
);
|
|
194
288
|
}
|
|
195
289
|
);
|
|
@@ -204,6 +298,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
204
298
|
describe: "The name of your worker",
|
|
205
299
|
type: "string",
|
|
206
300
|
})
|
|
301
|
+
.option("type", {
|
|
302
|
+
describe: "The type of worker to create",
|
|
303
|
+
type: "string",
|
|
304
|
+
choices: ["rust", "javascript", "webpack"],
|
|
305
|
+
deprecated: true,
|
|
306
|
+
})
|
|
207
307
|
.option("yes", {
|
|
208
308
|
describe: 'Answer "yes" to any prompts for new projects',
|
|
209
309
|
type: "boolean",
|
|
@@ -211,7 +311,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
211
311
|
});
|
|
212
312
|
},
|
|
213
313
|
async (args) => {
|
|
214
|
-
|
|
314
|
+
printWranglerBanner();
|
|
315
|
+
if (args.type) {
|
|
215
316
|
let message = "The --type option is no longer supported.";
|
|
216
317
|
if (args.type === "webpack") {
|
|
217
318
|
message +=
|
|
@@ -517,7 +618,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
517
618
|
() => {
|
|
518
619
|
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
519
620
|
throw new DeprecationError(
|
|
520
|
-
"`wrangler build` has been deprecated, please refer to
|
|
621
|
+
"`wrangler build` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#build for alternatives"
|
|
521
622
|
);
|
|
522
623
|
}
|
|
523
624
|
);
|
|
@@ -544,6 +645,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
544
645
|
// TODO: scopes
|
|
545
646
|
},
|
|
546
647
|
async (args) => {
|
|
648
|
+
printWranglerBanner();
|
|
547
649
|
if (args["scopes-list"]) {
|
|
548
650
|
listScopes();
|
|
549
651
|
return;
|
|
@@ -578,6 +680,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
578
680
|
// "🚪 Logout from Cloudflare",
|
|
579
681
|
() => {},
|
|
580
682
|
async () => {
|
|
683
|
+
printWranglerBanner();
|
|
581
684
|
await logout();
|
|
582
685
|
}
|
|
583
686
|
);
|
|
@@ -588,6 +691,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
588
691
|
"🕵️ Retrieve your user info and test your auth config",
|
|
589
692
|
() => {},
|
|
590
693
|
async () => {
|
|
694
|
+
printWranglerBanner();
|
|
591
695
|
await whoami();
|
|
592
696
|
}
|
|
593
697
|
);
|
|
@@ -600,7 +704,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
600
704
|
() => {
|
|
601
705
|
// "🕵️ Authenticate Wrangler with a Cloudflare API Token",
|
|
602
706
|
throw new DeprecationError(
|
|
603
|
-
"`wrangler config` has been deprecated, please refer to
|
|
707
|
+
"`wrangler config` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#config for alternatives"
|
|
604
708
|
);
|
|
605
709
|
}
|
|
606
710
|
);
|
|
@@ -626,6 +730,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
626
730
|
.option("env", {
|
|
627
731
|
describe: "Perform on a specific environment",
|
|
628
732
|
type: "string",
|
|
733
|
+
alias: "e",
|
|
629
734
|
})
|
|
630
735
|
.option("compatibility-date", {
|
|
631
736
|
describe: "Date to use for compatibility checks",
|
|
@@ -642,9 +747,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
642
747
|
default: true,
|
|
643
748
|
})
|
|
644
749
|
.option("ip", {
|
|
645
|
-
describe: "IP address to listen on",
|
|
750
|
+
describe: "IP address to listen on, defaults to `localhost`",
|
|
646
751
|
type: "string",
|
|
647
|
-
default: "127.0.0.1",
|
|
648
752
|
})
|
|
649
753
|
.option("port", {
|
|
650
754
|
describe: "Port to listen on",
|
|
@@ -654,15 +758,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
654
758
|
describe: "Port for devtools to connect to",
|
|
655
759
|
type: "number",
|
|
656
760
|
})
|
|
761
|
+
.option("routes", {
|
|
762
|
+
describe: "Routes to upload",
|
|
763
|
+
alias: "route",
|
|
764
|
+
type: "array",
|
|
765
|
+
})
|
|
657
766
|
.option("host", {
|
|
658
767
|
type: "string",
|
|
659
768
|
describe:
|
|
660
769
|
"Host to forward requests to, defaults to the zone of project",
|
|
661
770
|
})
|
|
662
771
|
.option("local-protocol", {
|
|
663
|
-
default: "http",
|
|
664
772
|
describe: "Protocol to listen to requests on, defaults to http.",
|
|
665
|
-
choices: ["http", "https"],
|
|
773
|
+
choices: ["http", "https"] as const,
|
|
666
774
|
})
|
|
667
775
|
.option("experimental-public", {
|
|
668
776
|
describe: "Static assets to be served",
|
|
@@ -685,10 +793,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
685
793
|
array: true,
|
|
686
794
|
})
|
|
687
795
|
.option("upstream-protocol", {
|
|
688
|
-
default: "https",
|
|
689
796
|
describe:
|
|
690
797
|
"Protocol to forward requests to host on, defaults to https.",
|
|
691
|
-
choices: ["http", "https"],
|
|
798
|
+
choices: ["http", "https"] as const,
|
|
692
799
|
})
|
|
693
800
|
.option("jsx-factory", {
|
|
694
801
|
describe: "The function that is called for each JSX element",
|
|
@@ -698,6 +805,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
698
805
|
describe: "The function that is called for each JSX fragment",
|
|
699
806
|
type: "string",
|
|
700
807
|
})
|
|
808
|
+
.option("tsconfig", {
|
|
809
|
+
describe: "Path to a custom tsconfig.json file",
|
|
810
|
+
type: "string",
|
|
811
|
+
})
|
|
701
812
|
.option("local", {
|
|
702
813
|
alias: "l",
|
|
703
814
|
describe: "Run on my machine",
|
|
@@ -710,11 +821,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
710
821
|
});
|
|
711
822
|
},
|
|
712
823
|
async (args) => {
|
|
713
|
-
|
|
824
|
+
printWranglerBanner();
|
|
825
|
+
const configPath =
|
|
714
826
|
(args.config as ConfigPath) ||
|
|
715
|
-
|
|
716
|
-
);
|
|
717
|
-
const entry = getEntry(config, "dev"
|
|
827
|
+
(args.script && findWranglerToml(path.dirname(args.script)));
|
|
828
|
+
const config = readConfig(configPath, args);
|
|
829
|
+
const entry = await getEntry(args, config, "dev");
|
|
718
830
|
|
|
719
831
|
if (args["experimental-public"]) {
|
|
720
832
|
console.warn(
|
|
@@ -728,52 +840,112 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
728
840
|
);
|
|
729
841
|
}
|
|
730
842
|
|
|
731
|
-
|
|
843
|
+
const upstreamProtocol =
|
|
844
|
+
(args["upstream-protocol"] as "http" | "https") ||
|
|
845
|
+
config.dev.upstream_protocol;
|
|
846
|
+
if (upstreamProtocol === "http") {
|
|
732
847
|
console.warn(
|
|
733
|
-
"
|
|
734
|
-
"
|
|
735
|
-
"
|
|
848
|
+
"Setting upstream-protocol to http is not currently implemented.\n" +
|
|
849
|
+
"If this is required in your project, please add your use case to the following issue:\n" +
|
|
850
|
+
"https://github.com/cloudflare/wrangler2/issues/583."
|
|
736
851
|
);
|
|
737
852
|
}
|
|
738
853
|
|
|
739
|
-
|
|
740
|
-
// -- snip, extract --
|
|
741
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
742
|
-
if (!loggedIn) {
|
|
743
|
-
// didn't login, let's just quit
|
|
744
|
-
console.log("Did not login, quitting...");
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
854
|
+
const accountId = !args.local ? await requireAuth(config) : undefined;
|
|
747
855
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
856
|
+
// TODO: if worker_dev = false and no routes, then error (only for dev)
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Given something that resembles a URL,
|
|
860
|
+
* try to extract a host from it
|
|
861
|
+
*/
|
|
862
|
+
function getHost(urlLike: string): string | undefined {
|
|
863
|
+
if (
|
|
864
|
+
!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))
|
|
865
|
+
) {
|
|
866
|
+
urlLike = "http://" + urlLike;
|
|
753
867
|
}
|
|
754
|
-
|
|
868
|
+
return new URL(urlLike).host;
|
|
755
869
|
}
|
|
756
870
|
|
|
757
|
-
|
|
758
|
-
|
|
871
|
+
/**
|
|
872
|
+
* Given something that resembles a host,
|
|
873
|
+
* try to infer a zone id from it
|
|
874
|
+
*/
|
|
875
|
+
async function getZoneId(host: string): Promise<string | undefined> {
|
|
876
|
+
const zones = await fetchResult<{ id: string }[]>(
|
|
877
|
+
`/zones`,
|
|
878
|
+
{},
|
|
879
|
+
new URLSearchParams({ name: host })
|
|
880
|
+
);
|
|
881
|
+
return zones[0]?.id;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// When we're given a host (in one of the above ways), we do 2 things:
|
|
885
|
+
// - We try to extract a host from it
|
|
886
|
+
// - We try to get a zone id from the host
|
|
887
|
+
//
|
|
888
|
+
// So it turns out it's particularly hard to get a 'valid' domain
|
|
889
|
+
// from a string, so we don't even try to validate TLDs, etc.
|
|
890
|
+
// Once we get something that looks like w.x.y.z-ish, we then try to
|
|
891
|
+
// get a zone id for it, by lopping off subdomains until we get a hit
|
|
892
|
+
// from the API. That's it!
|
|
893
|
+
|
|
894
|
+
let zone: { host: string; id: string } | undefined;
|
|
895
|
+
|
|
896
|
+
if (!args.local) {
|
|
897
|
+
const hostLike =
|
|
898
|
+
args.host ||
|
|
899
|
+
config.dev.host ||
|
|
900
|
+
(args.routes && args.routes[0]) ||
|
|
901
|
+
config.route ||
|
|
902
|
+
(config.routes && config.routes[0]);
|
|
903
|
+
const host =
|
|
904
|
+
typeof hostLike === "string" ? getHost(hostLike) : undefined;
|
|
905
|
+
let zoneId: string | undefined;
|
|
906
|
+
const hostPieces =
|
|
907
|
+
typeof host === "string" ? host.split(".") : undefined;
|
|
908
|
+
while (hostPieces && hostPieces.length > 1) {
|
|
909
|
+
zoneId = await getZoneId(hostPieces.join("."));
|
|
910
|
+
if (zoneId) break;
|
|
911
|
+
hostPieces.shift();
|
|
912
|
+
}
|
|
913
|
+
if (host && !zoneId) {
|
|
914
|
+
throw new Error(`Could not find zone for ${hostLike}`);
|
|
915
|
+
}
|
|
916
|
+
zone =
|
|
917
|
+
typeof zoneId === "string" && typeof host === "string"
|
|
918
|
+
? {
|
|
919
|
+
host,
|
|
920
|
+
id: zoneId,
|
|
921
|
+
}
|
|
922
|
+
: undefined;
|
|
923
|
+
}
|
|
759
924
|
|
|
760
925
|
const { waitUntilExit } = render(
|
|
761
926
|
<Dev
|
|
762
927
|
name={getScriptName(args, config)}
|
|
763
928
|
entry={entry}
|
|
764
929
|
env={args.env}
|
|
765
|
-
zone={
|
|
930
|
+
zone={zone}
|
|
766
931
|
rules={getRules(config)}
|
|
767
932
|
legacyEnv={isLegacyEnv(args, config)}
|
|
768
|
-
|
|
769
|
-
format={args.format || config.build?.upload?.format}
|
|
933
|
+
build={config.build || {}}
|
|
770
934
|
initialMode={args.local ? "local" : "remote"}
|
|
771
|
-
jsxFactory={args["jsx-factory"] ||
|
|
772
|
-
jsxFragment={args["jsx-fragment"] ||
|
|
935
|
+
jsxFactory={args["jsx-factory"] || config.jsx_factory}
|
|
936
|
+
jsxFragment={args["jsx-fragment"] || config.jsx_fragment}
|
|
937
|
+
tsconfig={args.tsconfig ?? config.tsconfig}
|
|
938
|
+
upstreamProtocol={upstreamProtocol}
|
|
939
|
+
localProtocol={
|
|
940
|
+
// The typings are not quite clever enough to handle element accesses, only property accesses,
|
|
941
|
+
// so we need to cast here.
|
|
942
|
+
(args["local-protocol"] as "http" | "https") ||
|
|
943
|
+
config.dev.local_protocol
|
|
944
|
+
}
|
|
773
945
|
enableLocalPersistence={
|
|
774
946
|
args["experimental-enable-local-persistence"] || false
|
|
775
947
|
}
|
|
776
|
-
accountId={
|
|
948
|
+
accountId={accountId}
|
|
777
949
|
assetPaths={getAssetPaths(
|
|
778
950
|
config,
|
|
779
951
|
args.site,
|
|
@@ -783,6 +955,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
783
955
|
port={
|
|
784
956
|
args.port || config.dev?.port || (await getPort({ port: 8787 }))
|
|
785
957
|
}
|
|
958
|
+
ip={args.ip || config.dev.ip}
|
|
786
959
|
inspectorPort={
|
|
787
960
|
args["inspector-port"] ?? (await getPort({ port: 9229 }))
|
|
788
961
|
}
|
|
@@ -796,9 +969,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
796
969
|
(args["compatibility-flags"] as string[]) ||
|
|
797
970
|
config.compatibility_flags
|
|
798
971
|
}
|
|
799
|
-
usageModel={
|
|
972
|
+
usageModel={config.usage_model}
|
|
800
973
|
bindings={{
|
|
801
|
-
kv_namespaces:
|
|
974
|
+
kv_namespaces: config.kv_namespaces?.map(
|
|
802
975
|
({ binding, preview_id, id: _id }) => {
|
|
803
976
|
// In `dev`, we make folks use a separate kv namespace called
|
|
804
977
|
// `preview_id` instead of `id` so that they don't
|
|
@@ -819,12 +992,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
819
992
|
};
|
|
820
993
|
}
|
|
821
994
|
),
|
|
822
|
-
vars:
|
|
995
|
+
vars: config.vars,
|
|
823
996
|
wasm_modules: config.wasm_modules,
|
|
824
997
|
text_blobs: config.text_blobs,
|
|
825
|
-
durable_objects:
|
|
826
|
-
r2_buckets:
|
|
827
|
-
unsafe:
|
|
998
|
+
durable_objects: config.durable_objects,
|
|
999
|
+
r2_buckets: config.r2_buckets,
|
|
1000
|
+
unsafe: config.unsafe?.bindings,
|
|
828
1001
|
}}
|
|
829
1002
|
/>
|
|
830
1003
|
);
|
|
@@ -841,6 +1014,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
841
1014
|
.option("env", {
|
|
842
1015
|
type: "string",
|
|
843
1016
|
describe: "Perform on a specific environment",
|
|
1017
|
+
alias: "e",
|
|
844
1018
|
})
|
|
845
1019
|
.positional("script", {
|
|
846
1020
|
describe: "The path to an entry point for your worker",
|
|
@@ -905,9 +1079,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
905
1079
|
.option("jsx-fragment", {
|
|
906
1080
|
describe: "The function that is called for each JSX fragment",
|
|
907
1081
|
type: "string",
|
|
1082
|
+
})
|
|
1083
|
+
.option("tsconfig", {
|
|
1084
|
+
describe: "Path to a custom tsconfig.json file",
|
|
1085
|
+
type: "string",
|
|
908
1086
|
});
|
|
909
1087
|
},
|
|
910
1088
|
async (args) => {
|
|
1089
|
+
printWranglerBanner();
|
|
911
1090
|
if (args["experimental-public"]) {
|
|
912
1091
|
console.warn(
|
|
913
1092
|
"🚨 The --experimental-public field is experimental and will change in the future."
|
|
@@ -919,11 +1098,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
919
1098
|
);
|
|
920
1099
|
}
|
|
921
1100
|
|
|
922
|
-
const
|
|
1101
|
+
const configPath =
|
|
923
1102
|
(args.config as ConfigPath) ||
|
|
924
|
-
|
|
925
|
-
);
|
|
926
|
-
const entry = getEntry(config, "publish"
|
|
1103
|
+
(args.script && findWranglerToml(path.dirname(args.script)));
|
|
1104
|
+
const config = readConfig(configPath, args);
|
|
1105
|
+
const entry = await getEntry(args, config, "publish");
|
|
927
1106
|
|
|
928
1107
|
if (args.latest) {
|
|
929
1108
|
console.warn(
|
|
@@ -931,21 +1110,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
931
1110
|
);
|
|
932
1111
|
}
|
|
933
1112
|
|
|
934
|
-
|
|
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();
|
|
944
|
-
if (!config.account_id) {
|
|
945
|
-
throw new Error("No account id found, quitting...");
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
// -- snip, end --
|
|
1113
|
+
const accountId = await requireAuth(config);
|
|
949
1114
|
|
|
950
1115
|
const assetPaths = getAssetPaths(
|
|
951
1116
|
config,
|
|
@@ -955,9 +1120,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
955
1120
|
);
|
|
956
1121
|
await publish({
|
|
957
1122
|
config,
|
|
1123
|
+
accountId,
|
|
958
1124
|
name: getScriptName(args, config),
|
|
959
1125
|
rules: getRules(config),
|
|
960
|
-
format: args.format || config.build?.upload?.format,
|
|
961
1126
|
entry,
|
|
962
1127
|
env: args.env,
|
|
963
1128
|
compatibilityDate: args.latest
|
|
@@ -967,6 +1132,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
967
1132
|
triggers: args.triggers,
|
|
968
1133
|
jsxFactory: args["jsx-factory"],
|
|
969
1134
|
jsxFragment: args["jsx-fragment"],
|
|
1135
|
+
tsconfig: args.tsconfig,
|
|
970
1136
|
routes: args.routes,
|
|
971
1137
|
assetPaths,
|
|
972
1138
|
legacyEnv: isLegacyEnv(args, config),
|
|
@@ -1023,6 +1189,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1023
1189
|
.option("env", {
|
|
1024
1190
|
type: "string",
|
|
1025
1191
|
describe: "Perform on a specific environment",
|
|
1192
|
+
alias: "e",
|
|
1026
1193
|
})
|
|
1027
1194
|
.option("debug", {
|
|
1028
1195
|
type: "boolean",
|
|
@@ -1034,31 +1201,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1034
1201
|
);
|
|
1035
1202
|
},
|
|
1036
1203
|
async (args) => {
|
|
1037
|
-
|
|
1204
|
+
if (args.format === "pretty") {
|
|
1205
|
+
printWranglerBanner();
|
|
1206
|
+
}
|
|
1207
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1038
1208
|
|
|
1039
|
-
const scriptName =
|
|
1209
|
+
const scriptName = getLegacyScriptName(args, config);
|
|
1040
1210
|
|
|
1041
1211
|
if (!scriptName) {
|
|
1042
1212
|
throw new Error("Missing script name");
|
|
1043
1213
|
}
|
|
1044
1214
|
|
|
1045
|
-
|
|
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
|
-
}
|
|
1052
|
-
|
|
1053
|
-
if (!config.account_id) {
|
|
1054
|
-
config.account_id = await getAccountId();
|
|
1055
|
-
if (!config.account_id) {
|
|
1056
|
-
throw new Error("No account id found, quitting...");
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
// -- snip, end --
|
|
1060
|
-
|
|
1061
|
-
const accountId = config.account_id;
|
|
1215
|
+
const accountId = await requireAuth(config);
|
|
1062
1216
|
|
|
1063
1217
|
const cliFilters: TailCLIFilters = {
|
|
1064
1218
|
status: args.status as ("ok" | "error" | "canceled")[],
|
|
@@ -1163,27 +1317,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1163
1317
|
"***************************************************\n"
|
|
1164
1318
|
);
|
|
1165
1319
|
|
|
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 --
|
|
1320
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1321
|
+
const entry = await getEntry({}, config, "dev");
|
|
1184
1322
|
|
|
1185
|
-
const
|
|
1186
|
-
const envRootObj = args.env ? environments[args.env] || {} : config;
|
|
1323
|
+
const accountId = await requireAuth(config);
|
|
1187
1324
|
|
|
1188
1325
|
const { waitUntilExit } = render(
|
|
1189
1326
|
<Dev
|
|
@@ -1193,15 +1330,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1193
1330
|
env={args.env}
|
|
1194
1331
|
zone={undefined}
|
|
1195
1332
|
legacyEnv={isLegacyEnv(args, config)}
|
|
1196
|
-
|
|
1197
|
-
format={config.build?.upload?.format}
|
|
1333
|
+
build={config.build || {}}
|
|
1198
1334
|
initialMode={args.local ? "local" : "remote"}
|
|
1199
|
-
jsxFactory={
|
|
1200
|
-
jsxFragment={
|
|
1335
|
+
jsxFactory={config.jsx_factory}
|
|
1336
|
+
jsxFragment={config.jsx_fragment}
|
|
1337
|
+
tsconfig={config.tsconfig}
|
|
1338
|
+
upstreamProtocol={config.dev.upstream_protocol}
|
|
1339
|
+
localProtocol={config.dev.local_protocol}
|
|
1201
1340
|
enableLocalPersistence={false}
|
|
1202
|
-
accountId={
|
|
1341
|
+
accountId={accountId}
|
|
1203
1342
|
assetPaths={undefined}
|
|
1204
1343
|
port={config.dev?.port}
|
|
1344
|
+
ip={config.dev.ip}
|
|
1205
1345
|
public={undefined}
|
|
1206
1346
|
compatibilityDate={
|
|
1207
1347
|
config.compatibility_date ||
|
|
@@ -1213,7 +1353,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1213
1353
|
}
|
|
1214
1354
|
usageModel={config.usage_model}
|
|
1215
1355
|
bindings={{
|
|
1216
|
-
kv_namespaces:
|
|
1356
|
+
kv_namespaces: config.kv_namespaces?.map(
|
|
1217
1357
|
({ binding, preview_id, id: _id }) => {
|
|
1218
1358
|
// In `dev`, we make folks use a separate kv namespace called
|
|
1219
1359
|
// `preview_id` instead of `id` so that they don't
|
|
@@ -1234,12 +1374,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1234
1374
|
};
|
|
1235
1375
|
}
|
|
1236
1376
|
),
|
|
1237
|
-
vars:
|
|
1377
|
+
vars: config.vars,
|
|
1238
1378
|
wasm_modules: config.wasm_modules,
|
|
1239
1379
|
text_blobs: config.text_blobs,
|
|
1240
|
-
durable_objects:
|
|
1241
|
-
r2_buckets:
|
|
1242
|
-
unsafe:
|
|
1380
|
+
durable_objects: config.durable_objects,
|
|
1381
|
+
r2_buckets: config.r2_buckets,
|
|
1382
|
+
unsafe: config.unsafe?.bindings,
|
|
1243
1383
|
}}
|
|
1244
1384
|
inspectorPort={await getPort({ port: 9229 })}
|
|
1245
1385
|
/>
|
|
@@ -1248,7 +1388,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1248
1388
|
}
|
|
1249
1389
|
);
|
|
1250
1390
|
|
|
1251
|
-
// route
|
|
1391
|
+
// [DEPRECATED] route
|
|
1252
1392
|
wrangler.command(
|
|
1253
1393
|
"route",
|
|
1254
1394
|
false, // I think we want to hide this command
|
|
@@ -1273,21 +1413,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1273
1413
|
type: "string",
|
|
1274
1414
|
});
|
|
1275
1415
|
},
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1416
|
+
() => {
|
|
1417
|
+
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
1418
|
+
const deprecationNotice =
|
|
1419
|
+
"`wrangler route list` has been deprecated.";
|
|
1420
|
+
const futureRoutes =
|
|
1421
|
+
"Refer to wrangler.toml for a list of routes the worker will be deployed to upon publishing.";
|
|
1422
|
+
const presentRoutes =
|
|
1423
|
+
"Refer to the Cloudflare Dashboard to see the routes this worker is currently running on.";
|
|
1424
|
+
throw new DeprecationError(
|
|
1425
|
+
`${deprecationNotice}\n${futureRoutes}\n${presentRoutes}`
|
|
1426
|
+
);
|
|
1287
1427
|
}
|
|
1288
1428
|
)
|
|
1289
1429
|
.command(
|
|
1290
|
-
"delete
|
|
1430
|
+
"delete [id]",
|
|
1291
1431
|
"Delete a route associated with a zone",
|
|
1292
1432
|
(yargs) => {
|
|
1293
1433
|
return yargs
|
|
@@ -1304,22 +1444,22 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1304
1444
|
describe: "Perform on a specific environment",
|
|
1305
1445
|
});
|
|
1306
1446
|
},
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
const
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
console.log(
|
|
1317
|
-
await fetchResult(`/zones/${zone}/workers/routes/${args.id}`, {
|
|
1318
|
-
method: "DELETE",
|
|
1319
|
-
})
|
|
1320
|
-
);
|
|
1447
|
+
() => {
|
|
1448
|
+
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
1449
|
+
const deprecationNotice =
|
|
1450
|
+
"`wrangler route delete` has been deprecated.";
|
|
1451
|
+
const shouldDo =
|
|
1452
|
+
"Remove the unwanted route(s) from wrangler.toml and run `wrangler publish` to remove your worker from those routes.";
|
|
1453
|
+
throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
|
|
1321
1454
|
}
|
|
1322
1455
|
);
|
|
1456
|
+
},
|
|
1457
|
+
() => {
|
|
1458
|
+
// "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
|
|
1459
|
+
const deprecationNotice = "`wrangler route` has been deprecated.";
|
|
1460
|
+
const shouldDo =
|
|
1461
|
+
"Please use wrangler.toml and/or `wrangler publish --routes` to modify routes";
|
|
1462
|
+
throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
|
|
1323
1463
|
}
|
|
1324
1464
|
);
|
|
1325
1465
|
|
|
@@ -1333,7 +1473,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1333
1473
|
},
|
|
1334
1474
|
() => {
|
|
1335
1475
|
throw new DeprecationError(
|
|
1336
|
-
"`wrangler subdomain` has been deprecated, please refer to
|
|
1476
|
+
"`wrangler subdomain` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#subdomain for alternatives"
|
|
1337
1477
|
);
|
|
1338
1478
|
}
|
|
1339
1479
|
);
|
|
@@ -1344,6 +1484,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1344
1484
|
"🤫 Generate a secret that can be referenced in the worker script",
|
|
1345
1485
|
(secretYargs) => {
|
|
1346
1486
|
return secretYargs
|
|
1487
|
+
.command(subHelp)
|
|
1347
1488
|
.command(
|
|
1348
1489
|
"put <key>",
|
|
1349
1490
|
"Create or update a secret variable for a script",
|
|
@@ -1361,36 +1502,24 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1361
1502
|
type: "string",
|
|
1362
1503
|
describe:
|
|
1363
1504
|
"Binds the secret to the Worker of the specific environment",
|
|
1505
|
+
alias: "e",
|
|
1364
1506
|
});
|
|
1365
1507
|
},
|
|
1366
1508
|
async (args) => {
|
|
1367
|
-
|
|
1509
|
+
printWranglerBanner();
|
|
1510
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1368
1511
|
|
|
1369
|
-
const scriptName =
|
|
1512
|
+
const scriptName = getLegacyScriptName(args, config);
|
|
1370
1513
|
if (!scriptName) {
|
|
1371
1514
|
throw new Error("Missing script name");
|
|
1372
1515
|
}
|
|
1373
1516
|
|
|
1374
|
-
|
|
1375
|
-
const
|
|
1376
|
-
if (!loggedIn) {
|
|
1377
|
-
// didn't login, let's just quit
|
|
1378
|
-
console.log("Did not login, quitting...");
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1517
|
+
const isInteractive = process.stdin.isTTY;
|
|
1518
|
+
const accountId = await requireAuth(config, isInteractive);
|
|
1381
1519
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
throw new Error("No account id found, quitting...");
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
// -- snip, end --
|
|
1389
|
-
|
|
1390
|
-
const secretValue = await prompt(
|
|
1391
|
-
"Enter a secret value:",
|
|
1392
|
-
"password"
|
|
1393
|
-
);
|
|
1520
|
+
const secretValue = isInteractive
|
|
1521
|
+
? await prompt("Enter a secret value:", "password")
|
|
1522
|
+
: await readFromStdin();
|
|
1394
1523
|
|
|
1395
1524
|
console.log(
|
|
1396
1525
|
`🌀 Creating the secret for script ${scriptName} ${
|
|
@@ -1401,8 +1530,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1401
1530
|
async function submitSecret() {
|
|
1402
1531
|
const url =
|
|
1403
1532
|
!args.env || isLegacyEnv(args, config)
|
|
1404
|
-
? `/accounts/${
|
|
1405
|
-
: `/accounts/${
|
|
1533
|
+
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
1534
|
+
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1406
1535
|
|
|
1407
1536
|
return await fetchResult(url, {
|
|
1408
1537
|
method: "PUT",
|
|
@@ -1415,49 +1544,61 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1415
1544
|
});
|
|
1416
1545
|
}
|
|
1417
1546
|
|
|
1547
|
+
const createDraftWorker = async () => {
|
|
1548
|
+
// TODO: log a warning
|
|
1549
|
+
await fetchResult(
|
|
1550
|
+
!args["legacy-env"] && args.env
|
|
1551
|
+
? `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}`
|
|
1552
|
+
: `/accounts/${accountId}/workers/scripts/${scriptName}`,
|
|
1553
|
+
{
|
|
1554
|
+
method: "PUT",
|
|
1555
|
+
body: createWorkerUploadForm({
|
|
1556
|
+
name: scriptName,
|
|
1557
|
+
main: {
|
|
1558
|
+
name: scriptName,
|
|
1559
|
+
content: `export default { fetch() {} }`,
|
|
1560
|
+
type: "esm",
|
|
1561
|
+
},
|
|
1562
|
+
bindings: {
|
|
1563
|
+
kv_namespaces: [],
|
|
1564
|
+
vars: {},
|
|
1565
|
+
durable_objects: { bindings: [] },
|
|
1566
|
+
r2_buckets: [],
|
|
1567
|
+
wasm_modules: {},
|
|
1568
|
+
text_blobs: {},
|
|
1569
|
+
unsafe: [],
|
|
1570
|
+
},
|
|
1571
|
+
modules: [],
|
|
1572
|
+
migrations: undefined,
|
|
1573
|
+
compatibility_date: undefined,
|
|
1574
|
+
compatibility_flags: undefined,
|
|
1575
|
+
usage_model: undefined,
|
|
1576
|
+
}),
|
|
1577
|
+
}
|
|
1578
|
+
);
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
function isMissingWorkerError(e: unknown): e is { code: 10007 } {
|
|
1582
|
+
return (
|
|
1583
|
+
typeof e === "object" &&
|
|
1584
|
+
e !== null &&
|
|
1585
|
+
(e as { code: 10007 }).code === 10007
|
|
1586
|
+
);
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1418
1589
|
try {
|
|
1419
1590
|
await submitSecret();
|
|
1420
1591
|
} catch (e) {
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
// TODO: log a warning
|
|
1425
|
-
await fetchResult(
|
|
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}`,
|
|
1429
|
-
{
|
|
1430
|
-
method: "PUT",
|
|
1431
|
-
body: toFormData({
|
|
1432
|
-
name: scriptName,
|
|
1433
|
-
main: {
|
|
1434
|
-
name: scriptName,
|
|
1435
|
-
content: `export default { fetch() {} }`,
|
|
1436
|
-
type: "esm",
|
|
1437
|
-
},
|
|
1438
|
-
bindings: {
|
|
1439
|
-
kv_namespaces: [],
|
|
1440
|
-
vars: {},
|
|
1441
|
-
durable_objects: { bindings: [] },
|
|
1442
|
-
r2_buckets: [],
|
|
1443
|
-
wasm_modules: {},
|
|
1444
|
-
text_blobs: {},
|
|
1445
|
-
unsafe: [],
|
|
1446
|
-
},
|
|
1447
|
-
modules: [],
|
|
1448
|
-
migrations: undefined,
|
|
1449
|
-
compatibility_date: undefined,
|
|
1450
|
-
compatibility_flags: undefined,
|
|
1451
|
-
usage_model: undefined,
|
|
1452
|
-
}),
|
|
1453
|
-
}
|
|
1454
|
-
);
|
|
1455
|
-
|
|
1456
|
-
// and then try again
|
|
1592
|
+
if (isMissingWorkerError(e)) {
|
|
1593
|
+
// create a draft worker and try again
|
|
1594
|
+
await createDraftWorker();
|
|
1457
1595
|
await submitSecret();
|
|
1458
1596
|
// TODO: delete the draft worker if this failed too?
|
|
1597
|
+
} else {
|
|
1598
|
+
throw e;
|
|
1459
1599
|
}
|
|
1460
1600
|
}
|
|
1601
|
+
|
|
1461
1602
|
console.log(`✨ Success! Uploaded secret ${args.key}`);
|
|
1462
1603
|
}
|
|
1463
1604
|
)
|
|
@@ -1465,6 +1606,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1465
1606
|
"delete <key>",
|
|
1466
1607
|
"Delete a secret variable from a script",
|
|
1467
1608
|
(yargs) => {
|
|
1609
|
+
printWranglerBanner();
|
|
1468
1610
|
return yargs
|
|
1469
1611
|
.positional("key", {
|
|
1470
1612
|
describe: "The variable name to be accessible in the script",
|
|
@@ -1478,31 +1620,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1478
1620
|
type: "string",
|
|
1479
1621
|
describe:
|
|
1480
1622
|
"Binds the secret to the Worker of the specific environment",
|
|
1623
|
+
alias: "e",
|
|
1481
1624
|
});
|
|
1482
1625
|
},
|
|
1483
1626
|
async (args) => {
|
|
1484
|
-
const config = readConfig(args.config as ConfigPath);
|
|
1627
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1485
1628
|
|
|
1486
|
-
const scriptName =
|
|
1629
|
+
const scriptName = getLegacyScriptName(args, config);
|
|
1487
1630
|
if (!scriptName) {
|
|
1488
1631
|
throw new Error("Missing script name");
|
|
1489
1632
|
}
|
|
1490
1633
|
|
|
1491
|
-
|
|
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
|
-
}
|
|
1498
|
-
|
|
1499
|
-
if (!config.account_id) {
|
|
1500
|
-
config.account_id = await getAccountId();
|
|
1501
|
-
if (!config.account_id) {
|
|
1502
|
-
throw new Error("No account id found, quitting...");
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
// -- snip, end --
|
|
1634
|
+
const accountId = await requireAuth(config);
|
|
1506
1635
|
|
|
1507
1636
|
if (
|
|
1508
1637
|
await confirm(
|
|
@@ -1521,8 +1650,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1521
1650
|
|
|
1522
1651
|
const url =
|
|
1523
1652
|
!args.env || isLegacyEnv(args, config)
|
|
1524
|
-
? `/accounts/${
|
|
1525
|
-
: `/accounts/${
|
|
1653
|
+
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
1654
|
+
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1526
1655
|
|
|
1527
1656
|
await fetchResult(`${url}/${args.key}`, { method: "DELETE" });
|
|
1528
1657
|
console.log(`✨ Success! Deleted secret ${args.key}`);
|
|
@@ -1542,36 +1671,23 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1542
1671
|
type: "string",
|
|
1543
1672
|
describe:
|
|
1544
1673
|
"Binds the secret to the Worker of the specific environment.",
|
|
1674
|
+
alias: "e",
|
|
1545
1675
|
});
|
|
1546
1676
|
},
|
|
1547
1677
|
async (args) => {
|
|
1548
|
-
const config = readConfig(args.config as ConfigPath);
|
|
1678
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1549
1679
|
|
|
1550
|
-
const scriptName =
|
|
1680
|
+
const scriptName = getLegacyScriptName(args, config);
|
|
1551
1681
|
if (!scriptName) {
|
|
1552
1682
|
throw new Error("Missing script name");
|
|
1553
1683
|
}
|
|
1554
1684
|
|
|
1555
|
-
|
|
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
|
-
}
|
|
1562
|
-
|
|
1563
|
-
if (!config.account_id) {
|
|
1564
|
-
config.account_id = await getAccountId();
|
|
1565
|
-
if (!config.account_id) {
|
|
1566
|
-
throw new Error("No account id found, quitting...");
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
// -- snip, end --
|
|
1685
|
+
const accountId = await requireAuth(config);
|
|
1570
1686
|
|
|
1571
1687
|
const url =
|
|
1572
1688
|
!args.env || isLegacyEnv(args, config)
|
|
1573
|
-
? `/accounts/${
|
|
1574
|
-
: `/accounts/${
|
|
1689
|
+
? `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`
|
|
1690
|
+
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1575
1691
|
|
|
1576
1692
|
console.log(JSON.stringify(await fetchResult(url), null, " "));
|
|
1577
1693
|
}
|
|
@@ -1586,6 +1702,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1586
1702
|
"🗂️ Interact with your Workers KV Namespaces",
|
|
1587
1703
|
(namespaceYargs) => {
|
|
1588
1704
|
return namespaceYargs
|
|
1705
|
+
.command(subHelp)
|
|
1589
1706
|
.command(
|
|
1590
1707
|
"create <namespace>",
|
|
1591
1708
|
"Create a new namespace",
|
|
@@ -1599,6 +1716,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1599
1716
|
.option("env", {
|
|
1600
1717
|
type: "string",
|
|
1601
1718
|
describe: "Perform on a specific environment",
|
|
1719
|
+
alias: "e",
|
|
1602
1720
|
})
|
|
1603
1721
|
.option("preview", {
|
|
1604
1722
|
type: "boolean",
|
|
@@ -1606,12 +1724,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1606
1724
|
});
|
|
1607
1725
|
},
|
|
1608
1726
|
async (args) => {
|
|
1609
|
-
|
|
1610
|
-
const extraArgs = args._.slice(2).join(" ");
|
|
1611
|
-
throw new CommandLineArgsError(
|
|
1612
|
-
`Unexpected additional positional arguments "${extraArgs}".`
|
|
1613
|
-
);
|
|
1614
|
-
}
|
|
1727
|
+
printWranglerBanner();
|
|
1615
1728
|
|
|
1616
1729
|
if (!isValidNamespaceBinding(args.namespace)) {
|
|
1617
1730
|
throw new CommandLineArgsError(
|
|
@@ -1619,7 +1732,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1619
1732
|
);
|
|
1620
1733
|
}
|
|
1621
1734
|
|
|
1622
|
-
const config = readConfig(args.config as ConfigPath);
|
|
1735
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1623
1736
|
if (!config.name) {
|
|
1624
1737
|
console.warn(
|
|
1625
1738
|
"No configured name present, using `worker` as a prefix for the title"
|
|
@@ -1631,26 +1744,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1631
1744
|
const preview = args.preview ? "_preview" : "";
|
|
1632
1745
|
const title = `${name}${environment}-${args.namespace}${preview}`;
|
|
1633
1746
|
|
|
1634
|
-
|
|
1635
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1636
|
-
if (!loggedIn) {
|
|
1637
|
-
// didn't login, let's just quit
|
|
1638
|
-
console.log("Did not login, quitting...");
|
|
1639
|
-
return;
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
if (!config.account_id) {
|
|
1643
|
-
config.account_id = await getAccountId();
|
|
1644
|
-
if (!config.account_id) {
|
|
1645
|
-
throw new Error("No account id found, quitting...");
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
// -- snip, end --
|
|
1747
|
+
const accountId = await requireAuth(config);
|
|
1649
1748
|
|
|
1650
1749
|
// TODO: generate a binding name stripping non alphanumeric chars
|
|
1651
1750
|
|
|
1652
1751
|
console.log(`🌀 Creating namespace with title "${title}"`);
|
|
1653
|
-
const namespaceId = await createNamespace(
|
|
1752
|
+
const namespaceId = await createNamespace(accountId, title);
|
|
1654
1753
|
|
|
1655
1754
|
console.log("✨ Success!");
|
|
1656
1755
|
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
@@ -1670,32 +1769,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1670
1769
|
"Outputs a list of all KV namespaces associated with your account id.",
|
|
1671
1770
|
{},
|
|
1672
1771
|
async (args) => {
|
|
1673
|
-
const config = readConfig(args.config as ConfigPath);
|
|
1674
|
-
|
|
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
|
-
}
|
|
1772
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1682
1773
|
|
|
1683
|
-
|
|
1684
|
-
config.account_id = await getAccountId();
|
|
1685
|
-
if (!config.account_id) {
|
|
1686
|
-
throw new Error("No account id found, quitting...");
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
// -- snip, end --
|
|
1774
|
+
const accountId = await requireAuth(config);
|
|
1690
1775
|
|
|
1691
1776
|
// TODO: we should show bindings if they exist for given ids
|
|
1692
1777
|
|
|
1693
1778
|
console.log(
|
|
1694
|
-
JSON.stringify(
|
|
1695
|
-
await listNamespaces(config.account_id),
|
|
1696
|
-
null,
|
|
1697
|
-
" "
|
|
1698
|
-
)
|
|
1779
|
+
JSON.stringify(await listNamespaces(accountId), null, " ")
|
|
1699
1780
|
);
|
|
1700
1781
|
}
|
|
1701
1782
|
)
|
|
@@ -1716,6 +1797,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1716
1797
|
.option("env", {
|
|
1717
1798
|
type: "string",
|
|
1718
1799
|
describe: "Perform on a specific environment",
|
|
1800
|
+
alias: "e",
|
|
1719
1801
|
})
|
|
1720
1802
|
.option("preview", {
|
|
1721
1803
|
type: "boolean",
|
|
@@ -1723,7 +1805,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1723
1805
|
});
|
|
1724
1806
|
},
|
|
1725
1807
|
async (args) => {
|
|
1726
|
-
|
|
1808
|
+
printWranglerBanner();
|
|
1809
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1727
1810
|
|
|
1728
1811
|
let id;
|
|
1729
1812
|
try {
|
|
@@ -1734,24 +1817,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1734
1817
|
);
|
|
1735
1818
|
}
|
|
1736
1819
|
|
|
1737
|
-
|
|
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
|
-
}
|
|
1744
|
-
|
|
1745
|
-
if (!config.account_id) {
|
|
1746
|
-
config.account_id = await getAccountId();
|
|
1747
|
-
if (!config.account_id) {
|
|
1748
|
-
throw new Error("No account id found, quitting...");
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
// -- snip, end --
|
|
1820
|
+
const accountId = await requireAuth(config);
|
|
1752
1821
|
|
|
1753
1822
|
await fetchResult<{ id: string }>(
|
|
1754
|
-
`/accounts/${
|
|
1823
|
+
`/accounts/${accountId}/storage/kv/namespaces/${id}`,
|
|
1755
1824
|
{ method: "DELETE" }
|
|
1756
1825
|
);
|
|
1757
1826
|
|
|
@@ -1783,6 +1852,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1783
1852
|
"🔑 Individually manage Workers KV key-value pairs",
|
|
1784
1853
|
(kvKeyYargs) => {
|
|
1785
1854
|
return kvKeyYargs
|
|
1855
|
+
.command(subHelp)
|
|
1786
1856
|
.command(
|
|
1787
1857
|
"put <key> [value]",
|
|
1788
1858
|
"Writes a single key/value pair to the given namespace.",
|
|
@@ -1809,6 +1879,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1809
1879
|
.option("env", {
|
|
1810
1880
|
type: "string",
|
|
1811
1881
|
describe: "Perform on a specific environment",
|
|
1882
|
+
alias: "e",
|
|
1812
1883
|
})
|
|
1813
1884
|
.option("preview", {
|
|
1814
1885
|
type: "boolean",
|
|
@@ -1830,7 +1901,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1830
1901
|
.check(demandOneOfOption("value", "path"));
|
|
1831
1902
|
},
|
|
1832
1903
|
async ({ key, ttl, expiration, ...args }) => {
|
|
1833
|
-
|
|
1904
|
+
printWranglerBanner();
|
|
1905
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1834
1906
|
const namespaceId = getNamespaceId(args, config);
|
|
1835
1907
|
// One of `args.path` and `args.value` must be defined
|
|
1836
1908
|
const value = args.path
|
|
@@ -1848,23 +1920,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1848
1920
|
);
|
|
1849
1921
|
}
|
|
1850
1922
|
|
|
1851
|
-
|
|
1852
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1853
|
-
if (!loggedIn) {
|
|
1854
|
-
// didn't login, let's just quit
|
|
1855
|
-
console.log("Did not login, quitting...");
|
|
1856
|
-
return;
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
if (!config.account_id) {
|
|
1860
|
-
config.account_id = await getAccountId();
|
|
1861
|
-
if (!config.account_id) {
|
|
1862
|
-
throw new Error("No account id found, quitting...");
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
// -- snip, end --
|
|
1923
|
+
const accountId = await requireAuth(config);
|
|
1866
1924
|
|
|
1867
|
-
await putKeyValue(
|
|
1925
|
+
await putKeyValue(accountId, namespaceId, {
|
|
1926
|
+
key,
|
|
1927
|
+
value,
|
|
1868
1928
|
expiration,
|
|
1869
1929
|
expiration_ttl: ttl,
|
|
1870
1930
|
});
|
|
@@ -1887,6 +1947,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1887
1947
|
.option("env", {
|
|
1888
1948
|
type: "string",
|
|
1889
1949
|
describe: "Perform on a specific environment",
|
|
1950
|
+
alias: "e",
|
|
1890
1951
|
})
|
|
1891
1952
|
.option("preview", {
|
|
1892
1953
|
type: "boolean",
|
|
@@ -1901,27 +1962,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1901
1962
|
},
|
|
1902
1963
|
async ({ prefix, ...args }) => {
|
|
1903
1964
|
// TODO: support for limit+cursor (pagination)
|
|
1904
|
-
const config = readConfig(args.config as ConfigPath);
|
|
1965
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1905
1966
|
const namespaceId = getNamespaceId(args, config);
|
|
1906
1967
|
|
|
1907
|
-
|
|
1908
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
1909
|
-
if (!loggedIn) {
|
|
1910
|
-
// didn't login, let's just quit
|
|
1911
|
-
console.log("Did not login, quitting...");
|
|
1912
|
-
return;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
if (!config.account_id) {
|
|
1916
|
-
config.account_id = await getAccountId();
|
|
1917
|
-
if (!config.account_id) {
|
|
1918
|
-
throw new Error("No account id found, quitting...");
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
|
-
// -- snip, end --
|
|
1968
|
+
const accountId = await requireAuth(config);
|
|
1922
1969
|
|
|
1923
1970
|
const results = await listNamespaceKeys(
|
|
1924
|
-
|
|
1971
|
+
accountId,
|
|
1925
1972
|
namespaceId,
|
|
1926
1973
|
prefix
|
|
1927
1974
|
);
|
|
@@ -1950,6 +1997,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1950
1997
|
.option("env", {
|
|
1951
1998
|
type: "string",
|
|
1952
1999
|
describe: "Perform on a specific environment",
|
|
2000
|
+
alias: "e",
|
|
1953
2001
|
})
|
|
1954
2002
|
.option("preview", {
|
|
1955
2003
|
type: "boolean",
|
|
@@ -1963,26 +2011,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1963
2011
|
});
|
|
1964
2012
|
},
|
|
1965
2013
|
async ({ key, ...args }) => {
|
|
1966
|
-
const config = readConfig(args.config as ConfigPath);
|
|
2014
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1967
2015
|
const namespaceId = getNamespaceId(args, config);
|
|
1968
2016
|
|
|
1969
|
-
|
|
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
|
-
}
|
|
1976
|
-
|
|
1977
|
-
if (!config.account_id) {
|
|
1978
|
-
config.account_id = await getAccountId();
|
|
1979
|
-
if (!config.account_id) {
|
|
1980
|
-
throw new Error("No account id found, quitting...");
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
// -- snip, end --
|
|
2017
|
+
const accountId = await requireAuth(config);
|
|
1984
2018
|
|
|
1985
|
-
console.log(await getKeyValue(
|
|
2019
|
+
console.log(await getKeyValue(accountId, namespaceId, key));
|
|
1986
2020
|
}
|
|
1987
2021
|
)
|
|
1988
2022
|
.command(
|
|
@@ -2007,6 +2041,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2007
2041
|
.option("env", {
|
|
2008
2042
|
type: "string",
|
|
2009
2043
|
describe: "Perform on a specific environment",
|
|
2044
|
+
alias: "e",
|
|
2010
2045
|
})
|
|
2011
2046
|
.option("preview", {
|
|
2012
2047
|
type: "boolean",
|
|
@@ -2014,31 +2049,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2014
2049
|
});
|
|
2015
2050
|
},
|
|
2016
2051
|
async ({ key, ...args }) => {
|
|
2017
|
-
|
|
2052
|
+
printWranglerBanner();
|
|
2053
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2018
2054
|
const namespaceId = getNamespaceId(args, config);
|
|
2019
2055
|
|
|
2020
2056
|
console.log(
|
|
2021
2057
|
`deleting the key "${key}" on namespace ${namespaceId}`
|
|
2022
2058
|
);
|
|
2023
2059
|
|
|
2024
|
-
|
|
2025
|
-
const loggedIn = await loginOrRefreshIfRequired();
|
|
2026
|
-
if (!loggedIn) {
|
|
2027
|
-
// didn't login, let's just quit
|
|
2028
|
-
console.log("Did not login, quitting...");
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
|
|
2032
|
-
if (!config.account_id) {
|
|
2033
|
-
config.account_id = await getAccountId();
|
|
2034
|
-
if (!config.account_id) {
|
|
2035
|
-
throw new Error("No account id found, quitting...");
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
// -- snip, end --
|
|
2060
|
+
const accountId = await requireAuth(config);
|
|
2039
2061
|
|
|
2040
2062
|
await fetchResult(
|
|
2041
|
-
`/accounts/${
|
|
2063
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`,
|
|
2042
2064
|
{ method: "DELETE" }
|
|
2043
2065
|
);
|
|
2044
2066
|
}
|
|
@@ -2052,6 +2074,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2052
2074
|
"💪 Interact with multiple Workers KV key-value pairs at once",
|
|
2053
2075
|
(kvBulkYargs) => {
|
|
2054
2076
|
return kvBulkYargs
|
|
2077
|
+
.command(subHelp)
|
|
2055
2078
|
.command(
|
|
2056
2079
|
"put <filename>",
|
|
2057
2080
|
"Upload multiple key-value pairs to a namespace",
|
|
@@ -2074,6 +2097,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2074
2097
|
.option("env", {
|
|
2075
2098
|
type: "string",
|
|
2076
2099
|
describe: "Perform on a specific environment",
|
|
2100
|
+
alias: "e",
|
|
2077
2101
|
})
|
|
2078
2102
|
.option("preview", {
|
|
2079
2103
|
type: "boolean",
|
|
@@ -2081,33 +2105,80 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2081
2105
|
});
|
|
2082
2106
|
},
|
|
2083
2107
|
async ({ filename, ...args }) => {
|
|
2108
|
+
printWranglerBanner();
|
|
2084
2109
|
// The simplest implementation I could think of.
|
|
2085
2110
|
// This could be made more efficient with a streaming parser/uploader
|
|
2086
2111
|
// but we'll do that in the future if needed.
|
|
2087
2112
|
|
|
2088
|
-
const config = readConfig(args.config as ConfigPath);
|
|
2113
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2089
2114
|
const namespaceId = getNamespaceId(args, config);
|
|
2090
2115
|
const content = parseJSON(readFileSync(filename), filename);
|
|
2091
2116
|
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
return;
|
|
2117
|
+
if (!Array.isArray(content)) {
|
|
2118
|
+
throw new Error(
|
|
2119
|
+
`Unexpected JSON input from "${filename}".\n` +
|
|
2120
|
+
`Expected an array of key-value objects but got type "${typeof content}".`
|
|
2121
|
+
);
|
|
2098
2122
|
}
|
|
2099
2123
|
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2124
|
+
const errors: string[] = [];
|
|
2125
|
+
const warnings: string[] = [];
|
|
2126
|
+
for (let i = 0; i < content.length; i++) {
|
|
2127
|
+
const keyValue = content[i];
|
|
2128
|
+
if (typeof keyValue !== "object") {
|
|
2129
|
+
errors.push(
|
|
2130
|
+
`The item at index ${i} is type: "${typeof keyValue}" - ${JSON.stringify(
|
|
2131
|
+
keyValue
|
|
2132
|
+
)}`
|
|
2133
|
+
);
|
|
2134
|
+
} else if (!isKeyValue(keyValue)) {
|
|
2135
|
+
errors.push(
|
|
2136
|
+
`The item at index ${i} is ${JSON.stringify(keyValue)}`
|
|
2137
|
+
);
|
|
2138
|
+
} else {
|
|
2139
|
+
const props = unexpectedKeyValueProps(keyValue);
|
|
2140
|
+
if (props.length > 0) {
|
|
2141
|
+
warnings.push(
|
|
2142
|
+
`The item at index ${i} contains unexpected properties: ${JSON.stringify(
|
|
2143
|
+
props
|
|
2144
|
+
)}.`
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2104
2147
|
}
|
|
2105
2148
|
}
|
|
2106
|
-
|
|
2149
|
+
if (warnings.length > 0) {
|
|
2150
|
+
console.warn(
|
|
2151
|
+
`Unexpected key-value properties in "${filename}".\n` +
|
|
2152
|
+
warnings.join("\n")
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
if (errors.length > 0) {
|
|
2156
|
+
throw new Error(
|
|
2157
|
+
`Unexpected JSON input from "${filename}".\n` +
|
|
2158
|
+
`Each item in the array should be an object that matches:\n\n` +
|
|
2159
|
+
`interface KeyValue {\n` +
|
|
2160
|
+
` key: string;\n` +
|
|
2161
|
+
` value: string;\n` +
|
|
2162
|
+
` expiration?: number;\n` +
|
|
2163
|
+
` expiration_ttl?: number;\n` +
|
|
2164
|
+
` metadata?: object;\n` +
|
|
2165
|
+
` base64?: boolean;\n` +
|
|
2166
|
+
`}\n\n` +
|
|
2167
|
+
errors.join("\n")
|
|
2168
|
+
);
|
|
2169
|
+
}
|
|
2107
2170
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2171
|
+
const accountId = await requireAuth(config);
|
|
2172
|
+
await putBulkKeyValue(
|
|
2173
|
+
accountId,
|
|
2174
|
+
namespaceId,
|
|
2175
|
+
content,
|
|
2176
|
+
(index, total) => {
|
|
2177
|
+
console.log(`Uploaded ${index} of ${total}.`);
|
|
2178
|
+
}
|
|
2110
2179
|
);
|
|
2180
|
+
|
|
2181
|
+
console.log("Success!");
|
|
2111
2182
|
}
|
|
2112
2183
|
)
|
|
2113
2184
|
.command(
|
|
@@ -2132,156 +2203,148 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2132
2203
|
.option("env", {
|
|
2133
2204
|
type: "string",
|
|
2134
2205
|
describe: "Perform on a specific environment",
|
|
2206
|
+
alias: "e",
|
|
2135
2207
|
})
|
|
2136
2208
|
.option("preview", {
|
|
2137
2209
|
type: "boolean",
|
|
2138
2210
|
describe: "Interact with a preview namespace",
|
|
2211
|
+
})
|
|
2212
|
+
.option("force", {
|
|
2213
|
+
type: "boolean",
|
|
2214
|
+
alias: "f",
|
|
2215
|
+
describe: "Do not ask for confirmation before deleting",
|
|
2139
2216
|
});
|
|
2140
2217
|
},
|
|
2141
2218
|
async ({ filename, ...args }) => {
|
|
2142
|
-
|
|
2219
|
+
printWranglerBanner();
|
|
2220
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2143
2221
|
const namespaceId = getNamespaceId(args, config);
|
|
2144
|
-
const content = parseJSON(readFileSync(filename), filename);
|
|
2145
2222
|
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2223
|
+
if (!args.force) {
|
|
2224
|
+
const result = await confirm(
|
|
2225
|
+
`Are you sure you want to delete all the keys read from "${filename}" from kv-namespace with id "${namespaceId}"?`
|
|
2226
|
+
);
|
|
2227
|
+
if (!result) {
|
|
2228
|
+
console.log(`Not deleting keys read from "${filename}".`);
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
const content = parseJSON(
|
|
2234
|
+
readFileSync(filename),
|
|
2235
|
+
filename
|
|
2236
|
+
) as string[];
|
|
2237
|
+
|
|
2238
|
+
if (!Array.isArray(content)) {
|
|
2239
|
+
throw new Error(
|
|
2240
|
+
`Unexpected JSON input from "${filename}".\n` +
|
|
2241
|
+
`Expected an array of strings but got:\n${content}`
|
|
2242
|
+
);
|
|
2152
2243
|
}
|
|
2153
2244
|
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2245
|
+
const errors: string[] = [];
|
|
2246
|
+
for (let i = 0; i < content.length; i++) {
|
|
2247
|
+
const key = content[i];
|
|
2248
|
+
if (typeof key !== "string") {
|
|
2249
|
+
errors.push(
|
|
2250
|
+
`The item at index ${i} is type: "${typeof key}" - ${JSON.stringify(
|
|
2251
|
+
key
|
|
2252
|
+
)}`
|
|
2253
|
+
);
|
|
2158
2254
|
}
|
|
2159
2255
|
}
|
|
2160
|
-
|
|
2256
|
+
if (errors.length > 0) {
|
|
2257
|
+
throw new Error(
|
|
2258
|
+
`Unexpected JSON input from "${filename}".\n` +
|
|
2259
|
+
`Expected an array of strings.\n` +
|
|
2260
|
+
errors.join("\n")
|
|
2261
|
+
);
|
|
2262
|
+
}
|
|
2161
2263
|
|
|
2162
|
-
|
|
2163
|
-
|
|
2264
|
+
const accountId = await requireAuth(config);
|
|
2265
|
+
|
|
2266
|
+
await deleteBulkKeyValue(
|
|
2267
|
+
accountId,
|
|
2268
|
+
namespaceId,
|
|
2269
|
+
content,
|
|
2270
|
+
(index, total) => {
|
|
2271
|
+
console.log(`Deleted ${index} of ${total}.`);
|
|
2272
|
+
}
|
|
2164
2273
|
);
|
|
2274
|
+
|
|
2275
|
+
console.log("Success!");
|
|
2165
2276
|
}
|
|
2166
2277
|
);
|
|
2167
2278
|
}
|
|
2168
2279
|
);
|
|
2169
2280
|
|
|
2170
|
-
wrangler.command(
|
|
2281
|
+
wrangler.command(
|
|
2282
|
+
"pages",
|
|
2283
|
+
"⚡️ Configure Cloudflare Pages",
|
|
2284
|
+
async (pagesYargs) => {
|
|
2285
|
+
await pages(pagesYargs.command(subHelp).epilogue(pagesBetaWarning));
|
|
2286
|
+
}
|
|
2287
|
+
);
|
|
2171
2288
|
|
|
2172
2289
|
wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
|
|
2173
|
-
return r2Yargs
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
throw new CommandLineArgsError(
|
|
2189
|
-
`Unexpected additional positional arguments "${extraArgs}".`
|
|
2190
|
-
);
|
|
2191
|
-
}
|
|
2290
|
+
return r2Yargs
|
|
2291
|
+
.command(subHelp)
|
|
2292
|
+
.command("bucket", "Manage R2 buckets", (r2BucketYargs) => {
|
|
2293
|
+
r2BucketYargs.command(
|
|
2294
|
+
"create <name>",
|
|
2295
|
+
"Create a new R2 bucket",
|
|
2296
|
+
(yargs) => {
|
|
2297
|
+
return yargs.positional("name", {
|
|
2298
|
+
describe: "The name of the new bucket",
|
|
2299
|
+
type: "string",
|
|
2300
|
+
demandOption: true,
|
|
2301
|
+
});
|
|
2302
|
+
},
|
|
2303
|
+
async (args) => {
|
|
2304
|
+
printWranglerBanner();
|
|
2192
2305
|
|
|
2193
|
-
|
|
2306
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2194
2307
|
|
|
2195
|
-
|
|
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
|
-
}
|
|
2308
|
+
const accountId = await requireAuth(config);
|
|
2202
2309
|
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
throw new Error("No account id found, quitting...");
|
|
2207
|
-
}
|
|
2310
|
+
console.log(`Creating bucket ${args.name}.`);
|
|
2311
|
+
await createR2Bucket(accountId, args.name);
|
|
2312
|
+
console.log(`Created bucket ${args.name}.`);
|
|
2208
2313
|
}
|
|
2209
|
-
|
|
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);
|
|
2314
|
+
);
|
|
2219
2315
|
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
if (!loggedIn) {
|
|
2223
|
-
// didn't login, let's just quit
|
|
2224
|
-
console.log("Did not login, quitting...");
|
|
2225
|
-
return;
|
|
2226
|
-
}
|
|
2316
|
+
r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
|
|
2317
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2227
2318
|
|
|
2228
|
-
|
|
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 --
|
|
2319
|
+
const accountId = await requireAuth(config);
|
|
2235
2320
|
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
);
|
|
2239
|
-
});
|
|
2321
|
+
console.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
|
|
2322
|
+
});
|
|
2240
2323
|
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
if (args._.length > 3) {
|
|
2254
|
-
const extraArgs = args._.slice(3).join(" ");
|
|
2255
|
-
throw new CommandLineArgsError(
|
|
2256
|
-
`Unexpected additional positional arguments "${extraArgs}".`
|
|
2257
|
-
);
|
|
2258
|
-
}
|
|
2324
|
+
r2BucketYargs.command(
|
|
2325
|
+
"delete <name>",
|
|
2326
|
+
"Delete an R2 bucket",
|
|
2327
|
+
(yargs) => {
|
|
2328
|
+
return yargs.positional("name", {
|
|
2329
|
+
describe: "The name of the bucket to delete",
|
|
2330
|
+
type: "string",
|
|
2331
|
+
demandOption: true,
|
|
2332
|
+
});
|
|
2333
|
+
},
|
|
2334
|
+
async (args) => {
|
|
2335
|
+
printWranglerBanner();
|
|
2259
2336
|
|
|
2260
|
-
|
|
2337
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
2261
2338
|
|
|
2262
|
-
|
|
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
|
-
}
|
|
2339
|
+
const accountId = await requireAuth(config);
|
|
2269
2340
|
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
throw new Error("No account id found, quitting...");
|
|
2274
|
-
}
|
|
2341
|
+
console.log(`Deleting bucket ${args.name}.`);
|
|
2342
|
+
await deleteR2Bucket(accountId, args.name);
|
|
2343
|
+
console.log(`Deleted bucket ${args.name}.`);
|
|
2275
2344
|
}
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
await deleteR2Bucket(config.account_id, args.name);
|
|
2280
|
-
console.log(`Deleted bucket ${args.name}.`);
|
|
2281
|
-
}
|
|
2282
|
-
);
|
|
2283
|
-
return r2BucketYargs;
|
|
2284
|
-
});
|
|
2345
|
+
);
|
|
2346
|
+
return r2BucketYargs;
|
|
2347
|
+
});
|
|
2285
2348
|
});
|
|
2286
2349
|
|
|
2287
2350
|
wrangler
|
|
@@ -2301,7 +2364,6 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2301
2364
|
wrangler.exitProcess(false);
|
|
2302
2365
|
|
|
2303
2366
|
try {
|
|
2304
|
-
await initialiseUserConfig();
|
|
2305
2367
|
await wrangler.parse();
|
|
2306
2368
|
} catch (e) {
|
|
2307
2369
|
if (e instanceof CommandLineArgsError) {
|