wrangler 0.0.0-e043479 → 0.0.0-e0b9366

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.
Files changed (51) hide show
  1. package/package.json +10 -4
  2. package/pages/functions/filepath-routing.test.ts +125 -25
  3. package/pages/functions/filepath-routing.ts +6 -3
  4. package/src/__tests__/configuration.test.ts +479 -114
  5. package/src/__tests__/dev.test.tsx +162 -8
  6. package/src/__tests__/dev2.test.tsx +152 -0
  7. package/src/__tests__/guess-worker-format.test.ts +9 -17
  8. package/src/__tests__/helpers/mock-account-id.ts +4 -0
  9. package/src/__tests__/helpers/mock-cfetch.ts +3 -3
  10. package/src/__tests__/helpers/mock-kv.ts +9 -16
  11. package/src/__tests__/helpers/run-in-tmp.ts +3 -0
  12. package/src/__tests__/https-options.test.ts +127 -0
  13. package/src/__tests__/index.test.ts +125 -0
  14. package/src/__tests__/jest.setup.ts +1 -1
  15. package/src/__tests__/kv.test.ts +27 -53
  16. package/src/__tests__/logout.test.ts +15 -13
  17. package/src/__tests__/pages.test.ts +44 -0
  18. package/src/__tests__/publish.test.ts +504 -32
  19. package/src/__tests__/route.test.ts +45 -0
  20. package/src/__tests__/whoami.test.tsx +21 -7
  21. package/src/bundle.ts +20 -11
  22. package/src/cfetch/internal.ts +11 -5
  23. package/src/config/config.ts +53 -44
  24. package/src/config/validation-helpers.ts +110 -12
  25. package/src/config/validation.ts +59 -41
  26. package/src/{api/preview.ts → create-worker-preview.ts} +23 -4
  27. package/src/{api/form_data.ts → create-worker-upload-form.ts} +1 -1
  28. package/src/dev/dev.tsx +357 -0
  29. package/src/dev/local.tsx +241 -0
  30. package/src/dev/remote.tsx +201 -0
  31. package/src/dev/use-esbuild.ts +100 -0
  32. package/src/entry.ts +111 -9
  33. package/src/https-options.ts +122 -0
  34. package/src/index.tsx +171 -109
  35. package/src/inspect.ts +9 -1
  36. package/src/{kv.tsx → kv.ts} +0 -0
  37. package/src/module-collection.ts +85 -2
  38. package/src/open-in-browser.ts +14 -2
  39. package/src/pages.tsx +1 -1
  40. package/src/proxy.ts +102 -40
  41. package/src/publish.ts +41 -50
  42. package/src/reporting.ts +25 -9
  43. package/src/selfsigned.d.ts +29 -0
  44. package/src/sites.tsx +51 -16
  45. package/src/user.tsx +132 -77
  46. package/src/{api/worker.ts → worker.ts} +0 -23
  47. package/wrangler-dist/cli.js +5012 -3107
  48. package/wrangler-dist/cli.js.map +3 -3
  49. package/src/__tests__/helpers/mock-user.ts +0 -27
  50. package/src/dev.tsx +0 -960
  51. 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 Dev from "./dev";
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 {
@@ -45,7 +47,6 @@ import {
45
47
  login,
46
48
  logout,
47
49
  listScopes,
48
- initialise as initialiseUserConfig,
49
50
  loginOrRefreshIfRequired,
50
51
  getAccountId,
51
52
  validateScopeKeys,
@@ -55,6 +56,7 @@ import { whoami } from "./whoami";
55
56
  import type { Config } from "./config";
56
57
  import type { TailCLIFilters } from "./tail";
57
58
  import type { RawData } from "ws";
59
+ import type { CommandModule } from "yargs";
58
60
  import type Yargs from "yargs";
59
61
 
60
62
  type ConfigPath = string | undefined;
@@ -81,6 +83,22 @@ ${TOML.stringify({ rules: config.build.upload.rules })}`
81
83
  return rules;
82
84
  }
83
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))
99
+ );
100
+ }
101
+
84
102
  function isLegacyEnv(args: unknown, config: Config): boolean {
85
103
  return (
86
104
  (args as { "legacy-env": boolean | undefined })["legacy-env"] ??
@@ -102,6 +120,9 @@ function getScriptName(
102
120
  : shortScriptName;
103
121
  }
104
122
 
123
+ /**
124
+ * Ensure that a user is logged in, and a valid account_id is available.
125
+ */
105
126
  async function requireAuth(
106
127
  config: Config,
107
128
  isInteractive = true
@@ -200,7 +221,15 @@ export async function main(argv: string[]): Promise<void> {
200
221
  .scriptName("wrangler")
201
222
  .wrap(null);
202
223
 
203
- // the default is to simply print the help menu
224
+ // Default help command that supports the subcommands
225
+ const subHelp: CommandModule = {
226
+ command: ["*"],
227
+ handler: async (args) => {
228
+ setImmediate(() =>
229
+ wrangler.parse([...args._.map((a) => `${a}`), "--help"])
230
+ );
231
+ },
232
+ };
204
233
  wrangler.command(
205
234
  ["*"],
206
235
  false,
@@ -241,7 +270,7 @@ export async function main(argv: string[]): Promise<void> {
241
270
  () => {
242
271
  // "👯 [DEPRECATED]. Scaffold a Cloudflare Workers project from a public GitHub repository.",
243
272
  throw new DeprecationError(
244
- "`wrangler generate` has been deprecated, please refer to TODO://some/path for alternatives"
273
+ "`wrangler generate` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#generate for alternatives"
245
274
  );
246
275
  }
247
276
  );
@@ -263,6 +292,7 @@ export async function main(argv: string[]): Promise<void> {
263
292
  });
264
293
  },
265
294
  async (args) => {
295
+ printWranglerBanner();
266
296
  if ("type" in args) {
267
297
  let message = "The --type option is no longer supported.";
268
298
  if (args.type === "webpack") {
@@ -569,7 +599,7 @@ export async function main(argv: string[]): Promise<void> {
569
599
  () => {
570
600
  // "[DEPRECATED] 🦀 Build your project (if applicable)",
571
601
  throw new DeprecationError(
572
- "`wrangler build` has been deprecated, please refer to TODO://some/path for alternatives"
602
+ "`wrangler build` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#build for alternatives"
573
603
  );
574
604
  }
575
605
  );
@@ -596,6 +626,7 @@ export async function main(argv: string[]): Promise<void> {
596
626
  // TODO: scopes
597
627
  },
598
628
  async (args) => {
629
+ printWranglerBanner();
599
630
  if (args["scopes-list"]) {
600
631
  listScopes();
601
632
  return;
@@ -630,6 +661,7 @@ export async function main(argv: string[]): Promise<void> {
630
661
  // "🚪 Logout from Cloudflare",
631
662
  () => {},
632
663
  async () => {
664
+ printWranglerBanner();
633
665
  await logout();
634
666
  }
635
667
  );
@@ -640,6 +672,7 @@ export async function main(argv: string[]): Promise<void> {
640
672
  "🕵️ Retrieve your user info and test your auth config",
641
673
  () => {},
642
674
  async () => {
675
+ printWranglerBanner();
643
676
  await whoami();
644
677
  }
645
678
  );
@@ -652,7 +685,7 @@ export async function main(argv: string[]): Promise<void> {
652
685
  () => {
653
686
  // "🕵️ Authenticate Wrangler with a Cloudflare API Token",
654
687
  throw new DeprecationError(
655
- "`wrangler config` has been deprecated, please refer to TODO://some/path for alternatives"
688
+ "`wrangler config` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#config for alternatives"
656
689
  );
657
690
  }
658
691
  );
@@ -717,9 +750,8 @@ export async function main(argv: string[]): Promise<void> {
717
750
  "Host to forward requests to, defaults to the zone of project",
718
751
  })
719
752
  .option("local-protocol", {
720
- default: "http",
721
753
  describe: "Protocol to listen to requests on, defaults to http.",
722
- choices: ["http", "https"],
754
+ choices: ["http", "https"] as const,
723
755
  })
724
756
  .option("experimental-public", {
725
757
  describe: "Static assets to be served",
@@ -742,10 +774,9 @@ export async function main(argv: string[]): Promise<void> {
742
774
  array: true,
743
775
  })
744
776
  .option("upstream-protocol", {
745
- default: "https",
746
777
  describe:
747
778
  "Protocol to forward requests to host on, defaults to https.",
748
- choices: ["http", "https"],
779
+ choices: ["http", "https"] as const,
749
780
  })
750
781
  .option("jsx-factory", {
751
782
  describe: "The function that is called for each JSX element",
@@ -767,11 +798,12 @@ export async function main(argv: string[]): Promise<void> {
767
798
  });
768
799
  },
769
800
  async (args) => {
801
+ printWranglerBanner();
770
802
  const config = readConfig(
771
803
  (args.config as ConfigPath) ||
772
804
  (args.script && findWranglerToml(path.dirname(args.script)))
773
805
  );
774
- const entry = getEntry(config, "dev", args.script);
806
+ const entry = await getEntry(args, config, "dev");
775
807
 
776
808
  if (args["experimental-public"]) {
777
809
  console.warn(
@@ -785,11 +817,14 @@ export async function main(argv: string[]): Promise<void> {
785
817
  );
786
818
  }
787
819
 
788
- if (config.site?.["entry-point"]) {
820
+ const upstreamProtocol =
821
+ (args["upstream-protocol"] as "http" | "https") ||
822
+ config.dev.upstream_protocol;
823
+ if (upstreamProtocol === "http") {
789
824
  console.warn(
790
- "Deprecation notice: The `site.entry-point` config field is no longer used.\n" +
791
- "The entry-point is specified via the command line (e.g. `wrangler dev path/to/script`).\n" +
792
- "Please remove the `site.entry-point` field from the `wrangler.toml` file."
825
+ "Setting upstream-protocol to http is not currently implemented.\n" +
826
+ "If this is required in your project, please add your use case to the following issue:\n" +
827
+ "https://github.com/cloudflare/wrangler2/issues/583."
793
828
  );
794
829
  }
795
830
 
@@ -874,10 +909,16 @@ export async function main(argv: string[]): Promise<void> {
874
909
  rules={getRules(config)}
875
910
  legacyEnv={isLegacyEnv(args, config)}
876
911
  buildCommand={config.build || {}}
877
- format={args.format || config.build?.upload?.format}
878
912
  initialMode={args.local ? "local" : "remote"}
879
913
  jsxFactory={args["jsx-factory"] || envRootObj?.jsx_factory}
880
914
  jsxFragment={args["jsx-fragment"] || envRootObj?.jsx_fragment}
915
+ upstreamProtocol={upstreamProtocol}
916
+ localProtocol={
917
+ // The typings are not quite clever enough to handle element accesses, only property accesses,
918
+ // so we need to cast here.
919
+ (args["local-protocol"] as "http" | "https") ||
920
+ config.dev.local_protocol
921
+ }
881
922
  enableLocalPersistence={
882
923
  args["experimental-enable-local-persistence"] || false
883
924
  }
@@ -1016,6 +1057,7 @@ export async function main(argv: string[]): Promise<void> {
1016
1057
  });
1017
1058
  },
1018
1059
  async (args) => {
1060
+ printWranglerBanner();
1019
1061
  if (args["experimental-public"]) {
1020
1062
  console.warn(
1021
1063
  "🚨 The --experimental-public field is experimental and will change in the future."
@@ -1031,7 +1073,7 @@ export async function main(argv: string[]): Promise<void> {
1031
1073
  (args.config as ConfigPath) ||
1032
1074
  (args.script && findWranglerToml(path.dirname(args.script)))
1033
1075
  );
1034
- const entry = getEntry(config, "publish", args.script);
1076
+ const entry = await getEntry(args, config, "publish");
1035
1077
 
1036
1078
  if (args.latest) {
1037
1079
  console.warn(
@@ -1052,7 +1094,6 @@ export async function main(argv: string[]): Promise<void> {
1052
1094
  accountId,
1053
1095
  name: getScriptName(args, config),
1054
1096
  rules: getRules(config),
1055
- format: args.format || config.build?.upload?.format,
1056
1097
  entry,
1057
1098
  env: args.env,
1058
1099
  compatibilityDate: args.latest
@@ -1129,6 +1170,9 @@ export async function main(argv: string[]): Promise<void> {
1129
1170
  );
1130
1171
  },
1131
1172
  async (args) => {
1173
+ if (args.format === "pretty") {
1174
+ printWranglerBanner();
1175
+ }
1132
1176
  const config = readConfig(args.config as ConfigPath);
1133
1177
 
1134
1178
  const scriptName = getScriptName(args, config);
@@ -1243,7 +1287,7 @@ export async function main(argv: string[]): Promise<void> {
1243
1287
  );
1244
1288
 
1245
1289
  const config = readConfig(args.config as ConfigPath);
1246
- const entry = getEntry(config, "dev");
1290
+ const entry = await getEntry({}, config, "dev");
1247
1291
 
1248
1292
  const accountId = await requireAuth(config);
1249
1293
 
@@ -1259,10 +1303,11 @@ export async function main(argv: string[]): Promise<void> {
1259
1303
  zone={undefined}
1260
1304
  legacyEnv={isLegacyEnv(args, config)}
1261
1305
  buildCommand={config.build || {}}
1262
- format={config.build?.upload?.format}
1263
1306
  initialMode={args.local ? "local" : "remote"}
1264
1307
  jsxFactory={envRootObj?.jsx_factory}
1265
1308
  jsxFragment={envRootObj?.jsx_fragment}
1309
+ upstreamProtocol={config.dev.upstream_protocol}
1310
+ localProtocol={config.dev.local_protocol}
1266
1311
  enableLocalPersistence={false}
1267
1312
  accountId={accountId}
1268
1313
  assetPaths={undefined}
@@ -1313,7 +1358,7 @@ export async function main(argv: string[]): Promise<void> {
1313
1358
  }
1314
1359
  );
1315
1360
 
1316
- // route
1361
+ // [DEPRECATED] route
1317
1362
  wrangler.command(
1318
1363
  "route",
1319
1364
  false, // I think we want to hide this command
@@ -1338,21 +1383,21 @@ export async function main(argv: string[]): Promise<void> {
1338
1383
  type: "string",
1339
1384
  });
1340
1385
  },
1341
- async (args) => {
1342
- console.log(":route list", args);
1343
- // TODO: use environment (current wrangler doesn't do so?)
1344
- // TODO: don't get `zone_id` from config at all and require the command line arg `--zone`.
1345
- const config = readConfig(args.config as ConfigPath);
1346
- const zone = args.zone || config.zone_id;
1347
- if (!zone) {
1348
- throw new Error("missing zone id");
1349
- }
1350
-
1351
- console.log(await fetchResult(`/zones/${zone}/workers/routes`));
1386
+ () => {
1387
+ // "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
1388
+ const deprecationNotice =
1389
+ "`wrangler route list` has been deprecated.";
1390
+ const futureRoutes =
1391
+ "Refer to wrangler.toml for a list of routes the worker will be deployed to upon publishing.";
1392
+ const presentRoutes =
1393
+ "Refer to the Cloudflare Dashboard to see the routes this worker is currently running on.";
1394
+ throw new DeprecationError(
1395
+ `${deprecationNotice}\n${futureRoutes}\n${presentRoutes}`
1396
+ );
1352
1397
  }
1353
1398
  )
1354
1399
  .command(
1355
- "delete <id>",
1400
+ "delete",
1356
1401
  "Delete a route associated with a zone",
1357
1402
  (yargs) => {
1358
1403
  return yargs
@@ -1369,22 +1414,22 @@ export async function main(argv: string[]): Promise<void> {
1369
1414
  describe: "Perform on a specific environment",
1370
1415
  });
1371
1416
  },
1372
- async (args) => {
1373
- console.log(":route delete", args);
1374
- // TODO: use environment (current wrangler doesn't do so?)
1375
- const config = readConfig(args.config as ConfigPath);
1376
- const zone = args.zone || config.zone_id;
1377
- if (!zone) {
1378
- throw new Error("missing zone id");
1379
- }
1380
-
1381
- console.log(
1382
- await fetchResult(`/zones/${zone}/workers/routes/${args.id}`, {
1383
- method: "DELETE",
1384
- })
1385
- );
1417
+ () => {
1418
+ // "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
1419
+ const deprecationNotice =
1420
+ "`wrangler route delete` has been deprecated.";
1421
+ const shouldDo =
1422
+ "Remove the unwanted route(s) from wrangler.toml and run `wrangler publish` to remove your worker from those routes.";
1423
+ throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
1386
1424
  }
1387
1425
  );
1426
+ },
1427
+ () => {
1428
+ // "👯 [DEPRECATED]. Use wrangler.toml to manage routes.
1429
+ const deprecationNotice = "`wrangler route` has been deprecated.";
1430
+ const shouldDo =
1431
+ "Please use wrangler.toml and/or `wrangler publish --routes` to modify routes";
1432
+ throw new DeprecationError(`${deprecationNotice}\n${shouldDo}`);
1388
1433
  }
1389
1434
  );
1390
1435
 
@@ -1398,7 +1443,7 @@ export async function main(argv: string[]): Promise<void> {
1398
1443
  },
1399
1444
  () => {
1400
1445
  throw new DeprecationError(
1401
- "`wrangler subdomain` has been deprecated, please refer to TODO://some/path for alternatives"
1446
+ "`wrangler subdomain` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#subdomain for alternatives"
1402
1447
  );
1403
1448
  }
1404
1449
  );
@@ -1409,6 +1454,7 @@ export async function main(argv: string[]): Promise<void> {
1409
1454
  "🤫 Generate a secret that can be referenced in the worker script",
1410
1455
  (secretYargs) => {
1411
1456
  return secretYargs
1457
+ .command(subHelp)
1412
1458
  .command(
1413
1459
  "put <key>",
1414
1460
  "Create or update a secret variable for a script",
@@ -1429,6 +1475,7 @@ export async function main(argv: string[]): Promise<void> {
1429
1475
  });
1430
1476
  },
1431
1477
  async (args) => {
1478
+ printWranglerBanner();
1432
1479
  const config = readConfig(args.config as ConfigPath);
1433
1480
 
1434
1481
  const scriptName = getScriptName(args, config);
@@ -1474,7 +1521,7 @@ export async function main(argv: string[]): Promise<void> {
1474
1521
  : `/accounts/${accountId}/workers/scripts/${scriptName}`,
1475
1522
  {
1476
1523
  method: "PUT",
1477
- body: toFormData({
1524
+ body: createWorkerUploadForm({
1478
1525
  name: scriptName,
1479
1526
  main: {
1480
1527
  name: scriptName,
@@ -1528,6 +1575,7 @@ export async function main(argv: string[]): Promise<void> {
1528
1575
  "delete <key>",
1529
1576
  "Delete a secret variable from a script",
1530
1577
  (yargs) => {
1578
+ printWranglerBanner();
1531
1579
  return yargs
1532
1580
  .positional("key", {
1533
1581
  describe: "The variable name to be accessible in the script",
@@ -1621,6 +1669,7 @@ export async function main(argv: string[]): Promise<void> {
1621
1669
  "🗂️ Interact with your Workers KV Namespaces",
1622
1670
  (namespaceYargs) => {
1623
1671
  return namespaceYargs
1672
+ .command(subHelp)
1624
1673
  .command(
1625
1674
  "create <namespace>",
1626
1675
  "Create a new namespace",
@@ -1641,6 +1690,7 @@ export async function main(argv: string[]): Promise<void> {
1641
1690
  });
1642
1691
  },
1643
1692
  async (args) => {
1693
+ printWranglerBanner();
1644
1694
  if (args._.length > 2) {
1645
1695
  const extraArgs = args._.slice(2).join(" ");
1646
1696
  throw new CommandLineArgsError(
@@ -1726,6 +1776,7 @@ export async function main(argv: string[]): Promise<void> {
1726
1776
  });
1727
1777
  },
1728
1778
  async (args) => {
1779
+ printWranglerBanner();
1729
1780
  const config = readConfig(args.config as ConfigPath);
1730
1781
 
1731
1782
  let id;
@@ -1772,6 +1823,7 @@ export async function main(argv: string[]): Promise<void> {
1772
1823
  "🔑 Individually manage Workers KV key-value pairs",
1773
1824
  (kvKeyYargs) => {
1774
1825
  return kvKeyYargs
1826
+ .command(subHelp)
1775
1827
  .command(
1776
1828
  "put <key> [value]",
1777
1829
  "Writes a single key/value pair to the given namespace.",
@@ -1819,6 +1871,7 @@ export async function main(argv: string[]): Promise<void> {
1819
1871
  .check(demandOneOfOption("value", "path"));
1820
1872
  },
1821
1873
  async ({ key, ttl, expiration, ...args }) => {
1874
+ printWranglerBanner();
1822
1875
  const config = readConfig(args.config as ConfigPath);
1823
1876
  const namespaceId = getNamespaceId(args, config);
1824
1877
  // One of `args.path` and `args.value` must be defined
@@ -1963,6 +2016,7 @@ export async function main(argv: string[]): Promise<void> {
1963
2016
  });
1964
2017
  },
1965
2018
  async ({ key, ...args }) => {
2019
+ printWranglerBanner();
1966
2020
  const config = readConfig(args.config as ConfigPath);
1967
2021
  const namespaceId = getNamespaceId(args, config);
1968
2022
 
@@ -1987,6 +2041,7 @@ export async function main(argv: string[]): Promise<void> {
1987
2041
  "💪 Interact with multiple Workers KV key-value pairs at once",
1988
2042
  (kvBulkYargs) => {
1989
2043
  return kvBulkYargs
2044
+ .command(subHelp)
1990
2045
  .command(
1991
2046
  "put <filename>",
1992
2047
  "Upload multiple key-value pairs to a namespace",
@@ -2016,6 +2071,7 @@ export async function main(argv: string[]): Promise<void> {
2016
2071
  });
2017
2072
  },
2018
2073
  async ({ filename, ...args }) => {
2074
+ printWranglerBanner();
2019
2075
  // The simplest implementation I could think of.
2020
2076
  // This could be made more efficient with a streaming parser/uploader
2021
2077
  // but we'll do that in the future if needed.
@@ -2125,6 +2181,7 @@ export async function main(argv: string[]): Promise<void> {
2125
2181
  });
2126
2182
  },
2127
2183
  async ({ filename, ...args }) => {
2184
+ printWranglerBanner();
2128
2185
  const config = readConfig(args.config as ConfigPath);
2129
2186
  const namespaceId = getNamespaceId(args, config);
2130
2187
 
@@ -2186,77 +2243,83 @@ export async function main(argv: string[]): Promise<void> {
2186
2243
  }
2187
2244
  );
2188
2245
 
2189
- wrangler.command("pages", "⚡️ Configure Cloudflare Pages", pages);
2246
+ wrangler.command("pages", "⚡️ Configure Cloudflare Pages", (pagesYargs) =>
2247
+ pages(pagesYargs.command(subHelp))
2248
+ );
2190
2249
 
2191
2250
  wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
2192
- return r2Yargs.command("bucket", "Manage R2 buckets", (r2BucketYargs) => {
2193
- r2BucketYargs.command(
2194
- "create <name>",
2195
- "Create a new R2 bucket",
2196
- (yargs) => {
2197
- return yargs.positional("name", {
2198
- describe: "The name of the new bucket",
2199
- type: "string",
2200
- demandOption: true,
2201
- });
2202
- },
2203
- async (args) => {
2204
- // We expect three values in `_`: `r2`, `bucket`, `create`.
2205
- if (args._.length > 3) {
2206
- const extraArgs = args._.slice(3).join(" ");
2207
- throw new CommandLineArgsError(
2208
- `Unexpected additional positional arguments "${extraArgs}".`
2209
- );
2251
+ return r2Yargs
2252
+ .command(subHelp)
2253
+ .command("bucket", "Manage R2 buckets", (r2BucketYargs) => {
2254
+ r2BucketYargs.command(
2255
+ "create <name>",
2256
+ "Create a new R2 bucket",
2257
+ (yargs) => {
2258
+ return yargs.positional("name", {
2259
+ describe: "The name of the new bucket",
2260
+ type: "string",
2261
+ demandOption: true,
2262
+ });
2263
+ },
2264
+ async (args) => {
2265
+ printWranglerBanner();
2266
+ // We expect three values in `_`: `r2`, `bucket`, `create`.
2267
+ if (args._.length > 3) {
2268
+ const extraArgs = args._.slice(3).join(" ");
2269
+ throw new CommandLineArgsError(
2270
+ `Unexpected additional positional arguments "${extraArgs}".`
2271
+ );
2272
+ }
2273
+
2274
+ const config = readConfig(args.config as ConfigPath);
2275
+
2276
+ const accountId = await requireAuth(config);
2277
+
2278
+ console.log(`Creating bucket ${args.name}.`);
2279
+ await createR2Bucket(accountId, args.name);
2280
+ console.log(`Created bucket ${args.name}.`);
2210
2281
  }
2282
+ );
2211
2283
 
2284
+ r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
2212
2285
  const config = readConfig(args.config as ConfigPath);
2213
2286
 
2214
2287
  const accountId = await requireAuth(config);
2215
2288
 
2216
- console.log(`Creating bucket ${args.name}.`);
2217
- await createR2Bucket(accountId, args.name);
2218
- console.log(`Created bucket ${args.name}.`);
2219
- }
2220
- );
2289
+ console.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
2290
+ });
2221
2291
 
2222
- r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
2223
- const config = readConfig(args.config as ConfigPath);
2292
+ r2BucketYargs.command(
2293
+ "delete <name>",
2294
+ "Delete an R2 bucket",
2295
+ (yargs) => {
2296
+ return yargs.positional("name", {
2297
+ describe: "The name of the bucket to delete",
2298
+ type: "string",
2299
+ demandOption: true,
2300
+ });
2301
+ },
2302
+ async (args) => {
2303
+ printWranglerBanner();
2304
+ // We expect three values in `_`: `r2`, `bucket`, `delete`.
2305
+ if (args._.length > 3) {
2306
+ const extraArgs = args._.slice(3).join(" ");
2307
+ throw new CommandLineArgsError(
2308
+ `Unexpected additional positional arguments "${extraArgs}".`
2309
+ );
2310
+ }
2224
2311
 
2225
- const accountId = await requireAuth(config);
2312
+ const config = readConfig(args.config as ConfigPath);
2226
2313
 
2227
- console.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
2228
- });
2314
+ const accountId = await requireAuth(config);
2229
2315
 
2230
- r2BucketYargs.command(
2231
- "delete <name>",
2232
- "Delete an R2 bucket",
2233
- (yargs) => {
2234
- return yargs.positional("name", {
2235
- describe: "The name of the bucket to delete",
2236
- type: "string",
2237
- demandOption: true,
2238
- });
2239
- },
2240
- async (args) => {
2241
- // We expect three values in `_`: `r2`, `bucket`, `delete`.
2242
- if (args._.length > 3) {
2243
- const extraArgs = args._.slice(3).join(" ");
2244
- throw new CommandLineArgsError(
2245
- `Unexpected additional positional arguments "${extraArgs}".`
2246
- );
2316
+ console.log(`Deleting bucket ${args.name}.`);
2317
+ await deleteR2Bucket(accountId, args.name);
2318
+ console.log(`Deleted bucket ${args.name}.`);
2247
2319
  }
2248
-
2249
- const config = readConfig(args.config as ConfigPath);
2250
-
2251
- const accountId = await requireAuth(config);
2252
-
2253
- console.log(`Deleting bucket ${args.name}.`);
2254
- await deleteR2Bucket(accountId, args.name);
2255
- console.log(`Deleted bucket ${args.name}.`);
2256
- }
2257
- );
2258
- return r2BucketYargs;
2259
- });
2320
+ );
2321
+ return r2BucketYargs;
2322
+ });
2260
2323
  });
2261
2324
 
2262
2325
  wrangler
@@ -2276,7 +2339,6 @@ export async function main(argv: string[]): Promise<void> {
2276
2339
  wrangler.exitProcess(false);
2277
2340
 
2278
2341
  try {
2279
- await initialiseUserConfig();
2280
2342
  await wrangler.parse();
2281
2343
  } catch (e) {
2282
2344
  if (e instanceof CommandLineArgsError) {
package/src/inspect.ts CHANGED
@@ -5,6 +5,7 @@ import { URL } from "node:url";
5
5
  import { useEffect, useRef, useState } from "react";
6
6
  import WebSocket, { WebSocketServer } from "ws";
7
7
  import { version } from "../package.json";
8
+ import { waitForPortToBeAvailable } from "./proxy";
8
9
  import type Protocol from "devtools-protocol";
9
10
  import type { IncomingMessage, Server, ServerResponse } from "node:http";
10
11
  import type { MessageEvent } from "ws";
@@ -153,7 +154,14 @@ export default function useInspector(props: InspectorProps) {
153
154
  * of the component lifecycle. Convenient.
154
155
  */
155
156
  useEffect(() => {
156
- server.listen(props.port);
157
+ async function startInspectorProxy() {
158
+ await waitForPortToBeAvailable(props.port, {
159
+ retryPeriod: 200,
160
+ timeout: 2000,
161
+ });
162
+ server.listen(props.port);
163
+ }
164
+ startInspectorProxy().catch((err) => console.error(err));
157
165
  return () => {
158
166
  server.close();
159
167
  // Also disconnect any open websockets/devtools connections
File without changes