wrangler 2.0.3 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/wrangler.js +2 -2
- package/package.json +5 -3
- package/pages/functions/buildPlugin.ts +13 -0
- package/pages/functions/buildWorker.ts +13 -0
- package/src/__tests__/configuration.test.ts +217 -29
- package/src/__tests__/dev.test.tsx +71 -9
- package/src/__tests__/index.test.ts +30 -16
- package/src/__tests__/init.test.ts +61 -20
- package/src/__tests__/kv.test.ts +109 -103
- package/src/__tests__/pages.test.ts +363 -33
- package/src/__tests__/parse.test.ts +5 -1
- package/src/__tests__/publish.test.ts +486 -72
- package/src/__tests__/r2.test.ts +47 -24
- package/src/__tests__/secret.test.ts +35 -0
- package/src/abort.d.ts +3 -0
- package/src/bundle.ts +32 -1
- package/src/cfetch/index.ts +4 -2
- package/src/cfetch/internal.ts +11 -9
- package/src/config/environment.ts +40 -14
- package/src/config/index.ts +162 -0
- package/src/config/validation.ts +126 -37
- package/src/create-worker-preview.ts +17 -7
- package/src/create-worker-upload-form.ts +22 -8
- package/src/dev/dev.tsx +5 -4
- package/src/dev/local.tsx +6 -0
- package/src/dev/remote.tsx +15 -1
- package/src/durable.ts +102 -0
- package/src/index.tsx +185 -98
- package/src/inspect.ts +39 -0
- package/src/kv.ts +111 -24
- package/src/open-in-browser.ts +5 -12
- package/src/pages.tsx +206 -65
- package/src/parse.ts +21 -4
- package/src/proxy.ts +38 -22
- package/src/publish.ts +227 -113
- package/src/sites.tsx +13 -16
- package/src/worker.ts +8 -0
- package/templates/new-worker.ts +16 -1
- package/wrangler-dist/cli.js +32273 -19295
package/src/index.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import { render } from "ink";
|
|
|
11
11
|
import React from "react";
|
|
12
12
|
import onExit from "signal-exit";
|
|
13
13
|
import supportsColor from "supports-color";
|
|
14
|
+
import { setGlobalDispatcher, ProxyAgent } from "undici";
|
|
14
15
|
import makeCLI from "yargs";
|
|
15
16
|
import { version as wranglerVersion } from "../package.json";
|
|
16
17
|
import { fetchResult } from "./cfetch";
|
|
@@ -22,17 +23,19 @@ import { confirm, prompt } from "./dialogs";
|
|
|
22
23
|
import { getEntry } from "./entry";
|
|
23
24
|
import { DeprecationError } from "./errors";
|
|
24
25
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
getKVNamespaceId,
|
|
27
|
+
listKVNamespaces,
|
|
28
|
+
listKVNamespaceKeys,
|
|
29
|
+
putKVKeyValue,
|
|
30
|
+
putKVBulkKeyValue,
|
|
31
|
+
deleteKVBulkKeyValue,
|
|
32
|
+
createKVNamespace,
|
|
33
|
+
isValidKVNamespaceBinding,
|
|
34
|
+
getKVKeyValue,
|
|
35
|
+
isKVKeyValue,
|
|
36
|
+
unexpectedKVKeyValueProps,
|
|
37
|
+
deleteKVNamespace,
|
|
38
|
+
deleteKVKeyValue,
|
|
36
39
|
} from "./kv";
|
|
37
40
|
import { logger } from "./logger";
|
|
38
41
|
import { getPackageManager } from "./package-manager";
|
|
@@ -41,6 +44,7 @@ import {
|
|
|
41
44
|
formatMessage,
|
|
42
45
|
ParseError,
|
|
43
46
|
parseJSON,
|
|
47
|
+
parsePackageJSON,
|
|
44
48
|
parseTOML,
|
|
45
49
|
readFileSync,
|
|
46
50
|
} from "./parse";
|
|
@@ -75,6 +79,17 @@ const resetColor = "\x1b[0m";
|
|
|
75
79
|
const fgGreenColor = "\x1b[32m";
|
|
76
80
|
const DEFAULT_LOCAL_PORT = 8787;
|
|
77
81
|
|
|
82
|
+
const proxy =
|
|
83
|
+
process.env.https_proxy ||
|
|
84
|
+
process.env.HTTPS_PROXY ||
|
|
85
|
+
process.env.http_proxy ||
|
|
86
|
+
process.env.HTTP_PROXY ||
|
|
87
|
+
undefined;
|
|
88
|
+
|
|
89
|
+
if (proxy) {
|
|
90
|
+
setGlobalDispatcher(new ProxyAgent(proxy));
|
|
91
|
+
}
|
|
92
|
+
|
|
78
93
|
function getRules(config: Config): Config["rules"] {
|
|
79
94
|
const rules = config.rules ?? config.build?.upload?.rules ?? [];
|
|
80
95
|
|
|
@@ -204,9 +219,17 @@ function demandOneOfOption(...options: string[]) {
|
|
|
204
219
|
};
|
|
205
220
|
}
|
|
206
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Remove trailing white space from inputs.
|
|
224
|
+
* Matching Wrangler legacy behavior with handling inputs
|
|
225
|
+
*/
|
|
226
|
+
function trimTrailingWhitespace(str: string) {
|
|
227
|
+
return str.trimEnd();
|
|
228
|
+
}
|
|
229
|
+
|
|
207
230
|
class CommandLineArgsError extends Error {}
|
|
208
231
|
|
|
209
|
-
|
|
232
|
+
function createCLIParser(argv: string[]) {
|
|
210
233
|
const wrangler = makeCLI(argv)
|
|
211
234
|
.strict()
|
|
212
235
|
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
@@ -323,6 +346,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
323
346
|
throw new CommandLineArgsError(message);
|
|
324
347
|
}
|
|
325
348
|
|
|
349
|
+
const devDepsToInstall: string[] = [];
|
|
350
|
+
const instructions: string[] = [];
|
|
351
|
+
let shouldRunPackageManagerInstall = false;
|
|
326
352
|
const creationDirectory = path.resolve(process.cwd(), args.name ?? "");
|
|
327
353
|
|
|
328
354
|
if (args.site) {
|
|
@@ -411,19 +437,16 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
411
437
|
try {
|
|
412
438
|
isGitInstalled = (await execa("git", ["--version"])).exitCode === 0;
|
|
413
439
|
} catch (err) {
|
|
414
|
-
|
|
415
|
-
// only throw if the error is not because git is not installed
|
|
416
|
-
throw err;
|
|
417
|
-
} else {
|
|
418
|
-
isGitInstalled = false;
|
|
419
|
-
}
|
|
440
|
+
isGitInstalled = false;
|
|
420
441
|
}
|
|
421
442
|
if (!isInsideGitProject && isGitInstalled) {
|
|
422
443
|
const shouldInitGit =
|
|
423
444
|
yesFlag ||
|
|
424
445
|
(await confirm("Would you like to use git to manage this Worker?"));
|
|
425
446
|
if (shouldInitGit) {
|
|
426
|
-
await execa("git", ["init"], {
|
|
447
|
+
await execa("git", ["init", "--initial-branch=main"], {
|
|
448
|
+
cwd: creationDirectory,
|
|
449
|
+
});
|
|
427
450
|
await writeFile(
|
|
428
451
|
path.join(creationDirectory, ".gitignore"),
|
|
429
452
|
readFileSync(path.join(__dirname, "../templates/gitignore"))
|
|
@@ -469,7 +492,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
469
492
|
) + "\n"
|
|
470
493
|
);
|
|
471
494
|
|
|
472
|
-
|
|
495
|
+
shouldRunPackageManagerInstall = true;
|
|
473
496
|
pathToPackageJson = path.join(creationDirectory, "package.json");
|
|
474
497
|
logger.log(
|
|
475
498
|
`✨ Created ${path.relative(process.cwd(), pathToPackageJson)}`
|
|
@@ -480,7 +503,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
480
503
|
} else {
|
|
481
504
|
// If package.json exists and wrangler isn't installed,
|
|
482
505
|
// then ask to add wrangler to devDependencies
|
|
483
|
-
const packageJson =
|
|
506
|
+
const packageJson = parsePackageJSON(
|
|
484
507
|
readFileSync(pathToPackageJson),
|
|
485
508
|
pathToPackageJson
|
|
486
509
|
);
|
|
@@ -499,8 +522,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
499
522
|
)}?`
|
|
500
523
|
));
|
|
501
524
|
if (shouldInstall) {
|
|
502
|
-
|
|
503
|
-
logger.log(`✨ Installed wrangler`);
|
|
525
|
+
devDepsToInstall.push(`wrangler@${wranglerVersion}`);
|
|
504
526
|
}
|
|
505
527
|
}
|
|
506
528
|
}
|
|
@@ -518,23 +540,18 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
518
540
|
path.join(creationDirectory, "./tsconfig.json"),
|
|
519
541
|
readFileSync(path.join(__dirname, "../templates/tsconfig.json"))
|
|
520
542
|
);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
"typescript"
|
|
524
|
-
);
|
|
543
|
+
devDepsToInstall.push("@cloudflare/workers-types");
|
|
544
|
+
devDepsToInstall.push("typescript");
|
|
525
545
|
pathToTSConfig = path.join(creationDirectory, "tsconfig.json");
|
|
526
546
|
logger.log(
|
|
527
|
-
`✨ Created ${path.relative(
|
|
528
|
-
process.cwd(),
|
|
529
|
-
pathToTSConfig
|
|
530
|
-
)}, installed @cloudflare/workers-types into devDependencies`
|
|
547
|
+
`✨ Created ${path.relative(process.cwd(), pathToTSConfig)}`
|
|
531
548
|
);
|
|
532
549
|
}
|
|
533
550
|
} else {
|
|
534
551
|
isTypescriptProject = true;
|
|
535
552
|
// If there's a tsconfig, check if @cloudflare/workers-types
|
|
536
553
|
// is already installed, and offer to install it if not
|
|
537
|
-
const packageJson =
|
|
554
|
+
const packageJson = parsePackageJSON(
|
|
538
555
|
readFileSync(pathToPackageJson),
|
|
539
556
|
pathToPackageJson
|
|
540
557
|
);
|
|
@@ -548,13 +565,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
548
565
|
"Would you like to install the type definitions for Workers into your package.json?"
|
|
549
566
|
);
|
|
550
567
|
if (shouldInstall) {
|
|
551
|
-
|
|
568
|
+
devDepsToInstall.push("@cloudflare/workers-types");
|
|
552
569
|
// We don't update the tsconfig.json because
|
|
553
570
|
// it could be complicated in existing projects
|
|
554
571
|
// and we don't want to break them. Instead, we simply
|
|
555
572
|
// tell the user that they need to update their tsconfig.json
|
|
556
|
-
|
|
557
|
-
|
|
573
|
+
instructions.push(
|
|
574
|
+
`🚨 Please add "@cloudflare/workers-types" to compilerOptions.types in ${path.relative(
|
|
558
575
|
process.cwd(),
|
|
559
576
|
pathToTSConfig
|
|
560
577
|
)}`
|
|
@@ -563,7 +580,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
563
580
|
}
|
|
564
581
|
}
|
|
565
582
|
|
|
566
|
-
const packageJsonContent =
|
|
583
|
+
const packageJsonContent = parsePackageJSON(
|
|
567
584
|
readFileSync(pathToPackageJson),
|
|
568
585
|
pathToPackageJson
|
|
569
586
|
);
|
|
@@ -572,6 +589,41 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
572
589
|
!packageJsonContent.scripts?.publish &&
|
|
573
590
|
shouldCreatePackageJson;
|
|
574
591
|
|
|
592
|
+
/*
|
|
593
|
+
* Passes the array of accumulated devDeps to install through to
|
|
594
|
+
* the package manager. Also generates a human-readable list
|
|
595
|
+
* of packages it installed.
|
|
596
|
+
* If there are no devDeps to install, optionally runs
|
|
597
|
+
* the package manager's install command.
|
|
598
|
+
*/
|
|
599
|
+
async function installPackages(
|
|
600
|
+
shouldRunInstall: boolean,
|
|
601
|
+
depsToInstall: string[]
|
|
602
|
+
) {
|
|
603
|
+
//lets install the devDeps they asked for
|
|
604
|
+
//and run their package manager's install command if needed
|
|
605
|
+
if (depsToInstall.length > 0) {
|
|
606
|
+
const formatter = new Intl.ListFormat("en", {
|
|
607
|
+
style: "long",
|
|
608
|
+
type: "conjunction",
|
|
609
|
+
});
|
|
610
|
+
await packageManager.addDevDeps(...depsToInstall);
|
|
611
|
+
const versionlessPackages = depsToInstall.map((dep) =>
|
|
612
|
+
dep === `wrangler@${wranglerVersion}` ? "wrangler" : dep
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
logger.log(
|
|
616
|
+
`✨ Installed ${formatter.format(
|
|
617
|
+
versionlessPackages
|
|
618
|
+
)} into devDependencies`
|
|
619
|
+
);
|
|
620
|
+
} else {
|
|
621
|
+
if (shouldRunInstall) {
|
|
622
|
+
await packageManager.install();
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
575
627
|
async function writePackageJsonScriptsAndUpdateWranglerToml(
|
|
576
628
|
isWritingScripts: boolean,
|
|
577
629
|
isCreatingWranglerToml: boolean,
|
|
@@ -615,21 +667,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
615
667
|
2
|
|
616
668
|
) + "\n"
|
|
617
669
|
);
|
|
618
|
-
|
|
670
|
+
instructions.push(
|
|
619
671
|
`\nTo start developing your Worker, run \`${
|
|
620
672
|
isNamedWorker ? `cd ${args.name} && ` : ""
|
|
621
673
|
}npm start\``
|
|
622
674
|
);
|
|
623
|
-
|
|
675
|
+
instructions.push(
|
|
624
676
|
`To publish your Worker to the Internet, run \`npm run publish\``
|
|
625
677
|
);
|
|
626
678
|
} else {
|
|
627
|
-
|
|
679
|
+
instructions.push(
|
|
628
680
|
`\nTo start developing your Worker, run \`npx wrangler dev\`${
|
|
629
681
|
isCreatingWranglerToml ? "" : ` ${scriptPath}`
|
|
630
682
|
}`
|
|
631
683
|
);
|
|
632
|
-
|
|
684
|
+
instructions.push(
|
|
633
685
|
`To publish your Worker to the Internet, run \`npx wrangler publish\`${
|
|
634
686
|
isCreatingWranglerToml ? "" : ` ${scriptPath}`
|
|
635
687
|
}`
|
|
@@ -708,6 +760,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
708
760
|
}
|
|
709
761
|
}
|
|
710
762
|
}
|
|
763
|
+
// install packages as the final step of init
|
|
764
|
+
try {
|
|
765
|
+
await installPackages(shouldRunPackageManagerInstall, devDepsToInstall);
|
|
766
|
+
} catch (e) {
|
|
767
|
+
// fetching packages could fail due to loss of internet, etc
|
|
768
|
+
// we should let folks know we failed to fetch, but their
|
|
769
|
+
// workers project is still ready to go
|
|
770
|
+
logger.error(e instanceof Error ? e.message : e);
|
|
771
|
+
instructions.push(
|
|
772
|
+
"\n🚨 wrangler was unable to fetch your npm packages, but your project is ready to go"
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// let users know what to do now
|
|
777
|
+
instructions.forEach((instruction) => logger.log(instruction));
|
|
711
778
|
}
|
|
712
779
|
);
|
|
713
780
|
|
|
@@ -718,13 +785,34 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
718
785
|
(yargs) => {
|
|
719
786
|
return yargs.option("env", {
|
|
720
787
|
describe: "Perform on a specific environment",
|
|
788
|
+
type: "string",
|
|
721
789
|
});
|
|
722
790
|
},
|
|
723
|
-
() => {
|
|
791
|
+
async (buildArgs) => {
|
|
724
792
|
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
725
|
-
|
|
726
|
-
|
|
793
|
+
|
|
794
|
+
const envFlag = buildArgs.env ? ` --env=${buildArgs.env}` : "";
|
|
795
|
+
logger.log(
|
|
796
|
+
formatMessage({
|
|
797
|
+
kind: "warning",
|
|
798
|
+
text: "Deprecation: `wrangler build` has been deprecated.",
|
|
799
|
+
notes: [
|
|
800
|
+
{
|
|
801
|
+
text: "Please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#build for more information.",
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
text: `Attempting to run \`wrangler publish --dry-run --outdir=dist${envFlag}\` for you instead:`,
|
|
805
|
+
},
|
|
806
|
+
],
|
|
807
|
+
})
|
|
727
808
|
);
|
|
809
|
+
|
|
810
|
+
await createCLIParser([
|
|
811
|
+
"publish",
|
|
812
|
+
"--dry-run",
|
|
813
|
+
"--outdir=dist",
|
|
814
|
+
...(buildArgs.env ? ["--env", buildArgs.env] : []),
|
|
815
|
+
]).parse();
|
|
728
816
|
}
|
|
729
817
|
);
|
|
730
818
|
|
|
@@ -895,6 +983,19 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
895
983
|
const config = readConfig(configPath, args);
|
|
896
984
|
const entry = await getEntry(args, config, "dev");
|
|
897
985
|
|
|
986
|
+
if (config.services && config.services.length > 0) {
|
|
987
|
+
logger.warn(
|
|
988
|
+
`This worker is bound to live services: ${config.services
|
|
989
|
+
.map(
|
|
990
|
+
(service) =>
|
|
991
|
+
`${service.binding} (${service.service}${
|
|
992
|
+
service.environment ? `@${service.environment}` : ""
|
|
993
|
+
})`
|
|
994
|
+
)
|
|
995
|
+
.join(", ")}`
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
|
|
898
999
|
if (args.inspect) {
|
|
899
1000
|
logger.warn(
|
|
900
1001
|
"Passing --inspect is unnecessary, now you can always connect to devtools."
|
|
@@ -932,6 +1033,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
932
1033
|
* try to extract a host from it
|
|
933
1034
|
*/
|
|
934
1035
|
function getHost(urlLike: string): string | undefined {
|
|
1036
|
+
// strip leading * / *.
|
|
1037
|
+
urlLike = urlLike.replace(/^\*(\.)?/g, "");
|
|
1038
|
+
|
|
935
1039
|
if (
|
|
936
1040
|
!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))
|
|
937
1041
|
) {
|
|
@@ -1102,6 +1206,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1102
1206
|
};
|
|
1103
1207
|
}
|
|
1104
1208
|
),
|
|
1209
|
+
services: config.services,
|
|
1105
1210
|
unsafe: config.unsafe?.bindings,
|
|
1106
1211
|
}}
|
|
1107
1212
|
crons={config.triggers.crons}
|
|
@@ -1256,7 +1361,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1256
1361
|
);
|
|
1257
1362
|
}
|
|
1258
1363
|
|
|
1259
|
-
const accountId = await requireAuth(config);
|
|
1364
|
+
const accountId = args.dryRun ? undefined : await requireAuth(config);
|
|
1260
1365
|
|
|
1261
1366
|
const assetPaths = getAssetPaths(
|
|
1262
1367
|
config,
|
|
@@ -1264,6 +1369,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1264
1369
|
args.siteInclude,
|
|
1265
1370
|
args.siteExclude
|
|
1266
1371
|
);
|
|
1372
|
+
|
|
1267
1373
|
await publish({
|
|
1268
1374
|
config,
|
|
1269
1375
|
accountId,
|
|
@@ -1554,6 +1660,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1554
1660
|
};
|
|
1555
1661
|
}
|
|
1556
1662
|
),
|
|
1663
|
+
services: config.services,
|
|
1557
1664
|
unsafe: config.unsafe?.bindings,
|
|
1558
1665
|
}}
|
|
1559
1666
|
crons={config.triggers.crons}
|
|
@@ -1704,9 +1811,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1704
1811
|
const accountId = await requireAuth(config);
|
|
1705
1812
|
|
|
1706
1813
|
const isInteractive = process.stdin.isTTY;
|
|
1707
|
-
const secretValue =
|
|
1708
|
-
|
|
1709
|
-
|
|
1814
|
+
const secretValue = trimTrailingWhitespace(
|
|
1815
|
+
isInteractive
|
|
1816
|
+
? await prompt("Enter a secret value:", "password")
|
|
1817
|
+
: await readFromStdin()
|
|
1818
|
+
);
|
|
1710
1819
|
|
|
1711
1820
|
logger.log(
|
|
1712
1821
|
`🌀 Creating the secret for script ${scriptName} ${
|
|
@@ -1751,6 +1860,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1751
1860
|
vars: {},
|
|
1752
1861
|
durable_objects: { bindings: [] },
|
|
1753
1862
|
r2_buckets: [],
|
|
1863
|
+
services: [],
|
|
1754
1864
|
wasm_modules: {},
|
|
1755
1865
|
text_blobs: {},
|
|
1756
1866
|
data_blobs: {},
|
|
@@ -1919,7 +2029,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1919
2029
|
async (args) => {
|
|
1920
2030
|
await printWranglerBanner();
|
|
1921
2031
|
|
|
1922
|
-
if (!
|
|
2032
|
+
if (!isValidKVNamespaceBinding(args.namespace)) {
|
|
1923
2033
|
throw new CommandLineArgsError(
|
|
1924
2034
|
`The namespace binding name "${args.namespace}" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.`
|
|
1925
2035
|
);
|
|
@@ -1942,7 +2052,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1942
2052
|
// TODO: generate a binding name stripping non alphanumeric chars
|
|
1943
2053
|
|
|
1944
2054
|
logger.log(`🌀 Creating namespace with title "${title}"`);
|
|
1945
|
-
const namespaceId = await
|
|
2055
|
+
const namespaceId = await createKVNamespace(accountId, title);
|
|
1946
2056
|
|
|
1947
2057
|
logger.log("✨ Success!");
|
|
1948
2058
|
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
@@ -1969,7 +2079,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1969
2079
|
// TODO: we should show bindings if they exist for given ids
|
|
1970
2080
|
|
|
1971
2081
|
logger.log(
|
|
1972
|
-
JSON.stringify(await
|
|
2082
|
+
JSON.stringify(await listKVNamespaces(accountId), null, " ")
|
|
1973
2083
|
);
|
|
1974
2084
|
}
|
|
1975
2085
|
)
|
|
@@ -2006,7 +2116,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2006
2116
|
|
|
2007
2117
|
let id;
|
|
2008
2118
|
try {
|
|
2009
|
-
id =
|
|
2119
|
+
id = getKVNamespaceId(args, config);
|
|
2010
2120
|
} catch (e) {
|
|
2011
2121
|
throw new CommandLineArgsError(
|
|
2012
2122
|
"Not able to delete namespace.\n" + ((e as Error).message ?? e)
|
|
@@ -2015,12 +2125,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2015
2125
|
|
|
2016
2126
|
const accountId = await requireAuth(config);
|
|
2017
2127
|
|
|
2018
|
-
await
|
|
2019
|
-
`/accounts/${accountId}/storage/kv/namespaces/${encodeURIComponent(
|
|
2020
|
-
id
|
|
2021
|
-
)}`,
|
|
2022
|
-
{ method: "DELETE" }
|
|
2023
|
-
);
|
|
2128
|
+
await deleteKVNamespace(accountId, id);
|
|
2024
2129
|
|
|
2025
2130
|
// TODO: recommend they remove it from wrangler.toml
|
|
2026
2131
|
|
|
@@ -2105,7 +2210,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2105
2210
|
async ({ key, ttl, expiration, ...args }) => {
|
|
2106
2211
|
await printWranglerBanner();
|
|
2107
2212
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2108
|
-
const namespaceId =
|
|
2213
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2109
2214
|
// One of `args.path` and `args.value` must be defined
|
|
2110
2215
|
const value = args.path
|
|
2111
2216
|
? readFileSync(args.path)
|
|
@@ -2124,7 +2229,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2124
2229
|
|
|
2125
2230
|
const accountId = await requireAuth(config);
|
|
2126
2231
|
|
|
2127
|
-
await
|
|
2232
|
+
await putKVKeyValue(accountId, namespaceId, {
|
|
2128
2233
|
key,
|
|
2129
2234
|
value,
|
|
2130
2235
|
expiration,
|
|
@@ -2169,11 +2274,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2169
2274
|
async ({ prefix, ...args }) => {
|
|
2170
2275
|
// TODO: support for limit+cursor (pagination)
|
|
2171
2276
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2172
|
-
const namespaceId =
|
|
2277
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2173
2278
|
|
|
2174
2279
|
const accountId = await requireAuth(config);
|
|
2175
2280
|
|
|
2176
|
-
const results = await
|
|
2281
|
+
const results = await listKVNamespaceKeys(
|
|
2177
2282
|
accountId,
|
|
2178
2283
|
namespaceId,
|
|
2179
2284
|
prefix
|
|
@@ -2221,11 +2326,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2221
2326
|
},
|
|
2222
2327
|
async ({ key, ...args }) => {
|
|
2223
2328
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2224
|
-
const namespaceId =
|
|
2329
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2225
2330
|
|
|
2226
2331
|
const accountId = await requireAuth(config);
|
|
2227
2332
|
|
|
2228
|
-
logger.log(await
|
|
2333
|
+
logger.log(await getKVKeyValue(accountId, namespaceId, key));
|
|
2229
2334
|
}
|
|
2230
2335
|
)
|
|
2231
2336
|
.command(
|
|
@@ -2263,7 +2368,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2263
2368
|
async ({ key, ...args }) => {
|
|
2264
2369
|
await printWranglerBanner();
|
|
2265
2370
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2266
|
-
const namespaceId =
|
|
2371
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2267
2372
|
|
|
2268
2373
|
logger.log(
|
|
2269
2374
|
`Deleting the key "${key}" on namespace ${namespaceId}.`
|
|
@@ -2271,12 +2376,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2271
2376
|
|
|
2272
2377
|
const accountId = await requireAuth(config);
|
|
2273
2378
|
|
|
2274
|
-
await
|
|
2275
|
-
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
2276
|
-
key
|
|
2277
|
-
)}`,
|
|
2278
|
-
{ method: "DELETE" }
|
|
2279
|
-
);
|
|
2379
|
+
await deleteKVKeyValue(accountId, namespaceId, key);
|
|
2280
2380
|
}
|
|
2281
2381
|
);
|
|
2282
2382
|
}
|
|
@@ -2328,7 +2428,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2328
2428
|
// but we'll do that in the future if needed.
|
|
2329
2429
|
|
|
2330
2430
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2331
|
-
const namespaceId =
|
|
2431
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2332
2432
|
const content = parseJSON(readFileSync(filename), filename);
|
|
2333
2433
|
|
|
2334
2434
|
if (!Array.isArray(content)) {
|
|
@@ -2342,18 +2442,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2342
2442
|
const warnings: string[] = [];
|
|
2343
2443
|
for (let i = 0; i < content.length; i++) {
|
|
2344
2444
|
const keyValue = content[i];
|
|
2345
|
-
if (
|
|
2346
|
-
errors.push(
|
|
2347
|
-
`The item at index ${i} is type: "${typeof keyValue}" - ${JSON.stringify(
|
|
2348
|
-
keyValue
|
|
2349
|
-
)}`
|
|
2350
|
-
);
|
|
2351
|
-
} else if (!isKeyValue(keyValue)) {
|
|
2445
|
+
if (!isKVKeyValue(keyValue)) {
|
|
2352
2446
|
errors.push(
|
|
2353
2447
|
`The item at index ${i} is ${JSON.stringify(keyValue)}`
|
|
2354
2448
|
);
|
|
2355
2449
|
} else {
|
|
2356
|
-
const props =
|
|
2450
|
+
const props = unexpectedKVKeyValueProps(keyValue);
|
|
2357
2451
|
if (props.length > 0) {
|
|
2358
2452
|
warnings.push(
|
|
2359
2453
|
`The item at index ${i} contains unexpected properties: ${JSON.stringify(
|
|
@@ -2386,14 +2480,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2386
2480
|
}
|
|
2387
2481
|
|
|
2388
2482
|
const accountId = await requireAuth(config);
|
|
2389
|
-
await
|
|
2390
|
-
accountId,
|
|
2391
|
-
namespaceId,
|
|
2392
|
-
content,
|
|
2393
|
-
(index, total) => {
|
|
2394
|
-
logger.log(`Uploaded ${index} of ${total}.`);
|
|
2395
|
-
}
|
|
2396
|
-
);
|
|
2483
|
+
await putKVBulkKeyValue(accountId, namespaceId, content);
|
|
2397
2484
|
|
|
2398
2485
|
logger.log("Success!");
|
|
2399
2486
|
}
|
|
@@ -2438,7 +2525,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2438
2525
|
async ({ filename, ...args }) => {
|
|
2439
2526
|
await printWranglerBanner();
|
|
2440
2527
|
const config = readConfig(args.config as ConfigPath, args);
|
|
2441
|
-
const namespaceId =
|
|
2528
|
+
const namespaceId = getKVNamespaceId(args, config);
|
|
2442
2529
|
|
|
2443
2530
|
if (!args.force) {
|
|
2444
2531
|
const result = await confirm(
|
|
@@ -2483,14 +2570,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2483
2570
|
|
|
2484
2571
|
const accountId = await requireAuth(config);
|
|
2485
2572
|
|
|
2486
|
-
await
|
|
2487
|
-
accountId,
|
|
2488
|
-
namespaceId,
|
|
2489
|
-
content,
|
|
2490
|
-
(index, total) => {
|
|
2491
|
-
logger.log(`Deleted ${index} of ${total}.`);
|
|
2492
|
-
}
|
|
2493
|
-
);
|
|
2573
|
+
await deleteKVBulkKeyValue(accountId, namespaceId, content);
|
|
2494
2574
|
|
|
2495
2575
|
logger.log("Success!");
|
|
2496
2576
|
}
|
|
@@ -2655,14 +2735,21 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2655
2735
|
wrangler.version(wranglerVersion).alias("v", "version");
|
|
2656
2736
|
wrangler.exitProcess(false);
|
|
2657
2737
|
|
|
2738
|
+
return wrangler;
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
export async function main(argv: string[]): Promise<void> {
|
|
2742
|
+
const wrangler = createCLIParser(argv);
|
|
2658
2743
|
try {
|
|
2659
2744
|
await wrangler.parse();
|
|
2660
2745
|
} catch (e) {
|
|
2661
2746
|
logger.log(""); // Just adds a bit of space
|
|
2662
2747
|
if (e instanceof CommandLineArgsError) {
|
|
2663
|
-
wrangler.showHelp("error");
|
|
2664
|
-
logger.log(""); // Add a bit of space.
|
|
2665
2748
|
logger.error(e.message);
|
|
2749
|
+
// We are not able to ask the `wrangler` CLI parser to show help for a subcommand programmatically.
|
|
2750
|
+
// The workaround is to re-run the parsing with an additional `--help` flag, which will result in the correct help message being displayed.
|
|
2751
|
+
// The `wrangler` object is "frozen"; we cannot reuse that with different args, so we must create a new CLI parser to generate the help message.
|
|
2752
|
+
await createCLIParser([...argv, "--help"]).parse();
|
|
2666
2753
|
} else if (e instanceof ParseError) {
|
|
2667
2754
|
e.notes.push({
|
|
2668
2755
|
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new",
|
package/src/inspect.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { createServer } from "node:http";
|
|
3
|
+
import os from "node:os";
|
|
3
4
|
import { URL } from "node:url";
|
|
4
5
|
|
|
6
|
+
import open from "open";
|
|
5
7
|
import { useEffect, useRef, useState } from "react";
|
|
6
8
|
import WebSocket, { WebSocketServer } from "ws";
|
|
7
9
|
import { version } from "../package.json";
|
|
@@ -621,3 +623,40 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
621
623
|
logger.warn("console event:", evt);
|
|
622
624
|
}
|
|
623
625
|
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Opens the chrome debugger
|
|
629
|
+
*/
|
|
630
|
+
export const openInspector = async (inspectorPort: number) => {
|
|
631
|
+
const url = `https://built-devtools.pages.dev/js_app?experiments=true&v8only=true&ws=localhost:${inspectorPort}/ws`;
|
|
632
|
+
const errorMessage =
|
|
633
|
+
"Failed to open inspector.\nInspector depends on having a Chromium-based browser installed, maybe you need to install one?";
|
|
634
|
+
|
|
635
|
+
// see: https://github.com/sindresorhus/open/issues/177#issue-610016699
|
|
636
|
+
let braveBrowser: string;
|
|
637
|
+
switch (os.platform()) {
|
|
638
|
+
case "darwin":
|
|
639
|
+
case "win32":
|
|
640
|
+
braveBrowser = "Brave";
|
|
641
|
+
break;
|
|
642
|
+
default:
|
|
643
|
+
braveBrowser = "brave";
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const childProcess = await open(url, {
|
|
647
|
+
app: [
|
|
648
|
+
{
|
|
649
|
+
name: open.apps.chrome,
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: braveBrowser,
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
name: open.apps.edge,
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
});
|
|
659
|
+
childProcess.on("error", () => {
|
|
660
|
+
logger.warn(errorMessage);
|
|
661
|
+
});
|
|
662
|
+
};
|