wrangler 0.0.0-e95e5a0 → 0.0.0-e978986

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 (52) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +3 -1
  3. package/bin/wrangler.js +36 -4
  4. package/package.json +11 -7
  5. package/pages/functions/buildPlugin.ts +13 -0
  6. package/pages/functions/buildWorker.ts +14 -1
  7. package/pages/functions/template-plugin.ts +3 -2
  8. package/src/__tests__/configuration.test.ts +336 -87
  9. package/src/__tests__/dev.test.tsx +243 -25
  10. package/src/__tests__/helpers/mock-dialogs.ts +41 -1
  11. package/src/__tests__/index.test.ts +79 -72
  12. package/src/__tests__/init.test.ts +182 -131
  13. package/src/__tests__/jest.setup.ts +8 -0
  14. package/src/__tests__/kv.test.ts +173 -146
  15. package/src/__tests__/package-manager.test.ts +154 -7
  16. package/src/__tests__/pages.test.ts +381 -53
  17. package/src/__tests__/parse.test.ts +8 -0
  18. package/src/__tests__/publish.test.ts +682 -89
  19. package/src/__tests__/r2.test.ts +55 -36
  20. package/src/__tests__/secret.test.ts +39 -4
  21. package/src/abort.d.ts +3 -0
  22. package/src/bundle.ts +33 -2
  23. package/src/cfetch/index.ts +21 -4
  24. package/src/cfetch/internal.ts +17 -9
  25. package/src/config/config.ts +1 -1
  26. package/src/config/environment.ts +40 -14
  27. package/src/config/index.ts +162 -0
  28. package/src/config/validation.ts +180 -65
  29. package/src/create-worker-preview.ts +17 -7
  30. package/src/create-worker-upload-form.ts +22 -8
  31. package/src/dev/dev.tsx +7 -6
  32. package/src/dev/local.tsx +6 -0
  33. package/src/dev/remote.tsx +15 -1
  34. package/src/dialogs.tsx +48 -0
  35. package/src/durable.ts +102 -0
  36. package/src/entry.ts +64 -9
  37. package/src/index.tsx +357 -177
  38. package/src/inspect.ts +39 -0
  39. package/src/kv.ts +114 -25
  40. package/src/open-in-browser.ts +5 -12
  41. package/src/package-manager.ts +50 -3
  42. package/src/pages.tsx +271 -110
  43. package/src/parse.ts +23 -4
  44. package/src/proxy.ts +38 -22
  45. package/src/publish.ts +227 -113
  46. package/src/sites.tsx +19 -17
  47. package/src/user.tsx +11 -1
  48. package/src/worker.ts +8 -0
  49. package/templates/new-worker-scheduled.js +17 -0
  50. package/templates/new-worker-scheduled.ts +32 -0
  51. package/templates/new-worker.ts +16 -1
  52. package/wrangler-dist/cli.js +36017 -22687
@@ -1,4 +1,5 @@
1
1
  import * as fs from "node:fs";
2
+ import getPort from "get-port";
2
3
  import patchConsole from "patch-console";
3
4
  import dedent from "ts-dedent";
4
5
  import Dev from "../dev/dev";
@@ -82,7 +83,7 @@ describe("wrangler dev", () => {
82
83
 
83
84
  expect(std.out).toMatchInlineSnapshot(`
84
85
  "
85
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
86
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
86
87
  `);
87
88
  expect(std.err).toMatchInlineSnapshot(`
88
89
  "X [ERROR] Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler dev path/to/script\`) or the \`main\` config field.
@@ -224,6 +225,32 @@ describe("wrangler dev", () => {
224
225
  );
225
226
  });
226
227
 
228
+ it("should strip leading `*` from given host when deducing a zone id", async () => {
229
+ writeWranglerToml({
230
+ main: "index.js",
231
+ route: "*some-host.com/some/path/*",
232
+ });
233
+ fs.writeFileSync("index.js", `export default {};`);
234
+ mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
235
+ await runWrangler("dev");
236
+ expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
237
+ "some-host.com"
238
+ );
239
+ });
240
+
241
+ it("should strip leading `*.` from given host when deducing a zone id", async () => {
242
+ writeWranglerToml({
243
+ main: "index.js",
244
+ route: "*.some-host.com/some/path/*",
245
+ });
246
+ fs.writeFileSync("index.js", `export default {};`);
247
+ mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
248
+ await runWrangler("dev");
249
+ expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
250
+ "some-host.com"
251
+ );
252
+ });
253
+
227
254
  it("should, when provided, use a configured zone_id", async () => {
228
255
  writeWranglerToml({
229
256
  main: "index.js",
@@ -432,18 +459,20 @@ describe("wrangler dev", () => {
432
459
  },
433
460
  });
434
461
 
435
- await expect(
436
- runWrangler("dev")
437
- ).rejects.toThrowErrorMatchingInlineSnapshot(
438
- `"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\""`
439
- );
462
+ await expect(runWrangler("dev")).rejects
463
+ .toThrowErrorMatchingInlineSnapshot(`
464
+ "The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
465
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build."
466
+ `);
440
467
  expect(std.out).toMatchInlineSnapshot(`
441
468
  "Running custom build: node -e \\"console.log('custom build');\\"
442
469
 
443
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
470
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
444
471
  `);
445
472
  expect(std.err).toMatchInlineSnapshot(`
446
- "X [ERROR] Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
473
+ "X [ERROR] The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
474
+
475
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build.
447
476
 
448
477
  "
449
478
  `);
@@ -580,8 +609,73 @@ describe("wrangler dev", () => {
580
609
  });
581
610
  });
582
611
 
612
+ describe("port", () => {
613
+ it("should default port to 8787 if it is not in use", async () => {
614
+ writeWranglerToml({
615
+ main: "index.js",
616
+ });
617
+ fs.writeFileSync("index.js", `export default {};`);
618
+ await runWrangler("dev");
619
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8787);
620
+ expect(std.out).toMatchInlineSnapshot(`""`);
621
+ expect(std.warn).toMatchInlineSnapshot(`""`);
622
+ expect(std.err).toMatchInlineSnapshot(`""`);
623
+ });
624
+
625
+ it("should use to `port` from `wrangler.toml`, if available", async () => {
626
+ writeWranglerToml({
627
+ main: "index.js",
628
+ dev: {
629
+ port: 8888,
630
+ },
631
+ });
632
+ fs.writeFileSync("index.js", `export default {};`);
633
+ // Mock `getPort()` to resolve to a completely different port.
634
+ (getPort as jest.Mock).mockResolvedValue(98765);
635
+
636
+ await runWrangler("dev");
637
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8888);
638
+ expect(std.out).toMatchInlineSnapshot(`""`);
639
+ expect(std.warn).toMatchInlineSnapshot(`""`);
640
+ expect(std.err).toMatchInlineSnapshot(`""`);
641
+ });
642
+
643
+ it("should use --port command line arg, if provided", async () => {
644
+ writeWranglerToml({
645
+ main: "index.js",
646
+ dev: {
647
+ port: 8888,
648
+ },
649
+ });
650
+ fs.writeFileSync("index.js", `export default {};`);
651
+ // Mock `getPort()` to resolve to a completely different port.
652
+ (getPort as jest.Mock).mockResolvedValue(98765);
653
+
654
+ await runWrangler("dev --port=9999");
655
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(9999);
656
+ expect(std.out).toMatchInlineSnapshot(`""`);
657
+ expect(std.warn).toMatchInlineSnapshot(`""`);
658
+ expect(std.err).toMatchInlineSnapshot(`""`);
659
+ });
660
+
661
+ it("should use a different port to the default if it is in use", async () => {
662
+ writeWranglerToml({
663
+ main: "index.js",
664
+ });
665
+ fs.writeFileSync("index.js", `export default {};`);
666
+ // Mock `getPort()` to resolve to a completely different port.
667
+ (getPort as jest.Mock).mockResolvedValue(98765);
668
+
669
+ await runWrangler("dev");
670
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(98765);
671
+ expect(std.out).toMatchInlineSnapshot(`""`);
672
+ expect(std.warn).toMatchInlineSnapshot(`""`);
673
+ expect(std.err).toMatchInlineSnapshot(`""`);
674
+ });
675
+ });
676
+
583
677
  describe("durable_objects", () => {
584
- it("should warn if there is one or more remote Durable Object", async () => {
678
+ it("should warn if there are remote Durable Objects, or missing migrations for local Durable Objects", async () => {
585
679
  writeWranglerToml({
586
680
  main: "index.js",
587
681
  durable_objects: {
@@ -604,9 +698,33 @@ describe("wrangler dev", () => {
604
698
  fs.writeFileSync("index.js", `export default {};`);
605
699
  await runWrangler("dev");
606
700
  expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("localhost");
607
- expect(std.out).toMatchInlineSnapshot(`""`);
701
+ expect(std.out).toMatchInlineSnapshot(`
702
+ "Your worker has access to the following bindings:
703
+ - Durable Objects:
704
+ - NAME_1: CLASS_1
705
+ - NAME_2: CLASS_2 (defined in SCRIPT_A)
706
+ - NAME_3: CLASS_3
707
+ - NAME_4: CLASS_4 (defined in SCRIPT_B)"
708
+ `);
608
709
  expect(std.warn).toMatchInlineSnapshot(`
609
- "▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.
710
+ "▲ [WARNING] Processing wrangler.toml configuration:
711
+
712
+ - In wrangler.toml, you have configured [durable_objects] exported by this Worker (CLASS_1,
713
+ CLASS_3), but no [migrations] for them. This may not work as expected until you add a [migrations]
714
+ section to your wrangler.toml. Add this configuration to your wrangler.toml:
715
+
716
+ \`\`\`
717
+ [[migrations]]
718
+ tag = \\"v1\\" # Should be unique for each entry
719
+ new_classes = [\\"CLASS_1\\", \\"CLASS_3\\"]
720
+ \`\`\`
721
+
722
+ Refer to
723
+ https://developers.cloudflare.com/workers/learning/using-durable-objects/#durable-object-migrations-in-wranglertoml
724
+ for more details.
725
+
726
+
727
+ ▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.
610
728
 
611
729
  Be aware that changes to the data stored in these Durable Objects will be permanent and affect the
612
730
  live instances.
@@ -661,9 +779,18 @@ describe("wrangler dev", () => {
661
779
  EMPTY: "",
662
780
  UNQUOTED: "unquoted value", // Note that whitespace is trimmed
663
781
  });
664
- expect(std.out).toMatchInlineSnapshot(
665
- `"Using vars defined in .dev.vars"`
666
- );
782
+ expect(std.out).toMatchInlineSnapshot(`
783
+ "Using vars defined in .dev.vars
784
+ Your worker has access to the following bindings:
785
+ - Vars:
786
+ - VAR_1: \\"(hidden)\\"
787
+ - VAR_2: \\"original value 2\\"
788
+ - VAR_3: \\"(hidden)\\"
789
+ - VAR_MULTI_LINE_1: \\"(hidden)\\"
790
+ - VAR_MULTI_LINE_2: \\"(hidden)\\"
791
+ - EMPTY: \\"(hidden)\\"
792
+ - UNQUOTED: \\"(hidden)\\""
793
+ `);
667
794
  expect(std.warn).toMatchInlineSnapshot(`""`);
668
795
  expect(std.err).toMatchInlineSnapshot(`""`);
669
796
  });
@@ -680,7 +807,11 @@ describe("wrangler dev", () => {
680
807
  expect(std).toMatchInlineSnapshot(`
681
808
  Object {
682
809
  "debug": "",
683
- "err": "wrangler dev [script]
810
+ "err": "X [ERROR] Not enough arguments following: site
811
+
812
+ ",
813
+ "out": "
814
+ wrangler dev [script]
684
815
 
685
816
  👂 Start a local server for developing your worker
686
817
 
@@ -688,10 +819,9 @@ describe("wrangler dev", () => {
688
819
  script The path to an entry point for your worker [string]
689
820
 
690
821
  Flags:
691
- -c, --config Path to .toml configuration file [string]
692
- -h, --help Show help [boolean]
693
- -v, --version Show version number [boolean]
694
- --legacy-env Use legacy environments [boolean]
822
+ -c, --config Path to .toml configuration file [string]
823
+ -h, --help Show help [boolean]
824
+ -v, --version Show version number [boolean]
695
825
 
696
826
  Options:
697
827
  --name Name of the worker [string]
@@ -718,12 +848,7 @@ describe("wrangler dev", () => {
718
848
  --minify Minify the script [boolean]
719
849
  --node-compat Enable node.js compatibility [boolean]
720
850
  --experimental-enable-local-persistence Enable persistence for this session (only for local mode) [boolean]
721
- --inspect Enable dev tools [deprecated] [boolean]
722
- X [ERROR] Not enough arguments following: site
723
-
724
- ",
725
- "out": "
726
- ",
851
+ --inspect Enable dev tools [deprecated] [boolean]",
727
852
  "warn": "",
728
853
  }
729
854
  `);
@@ -746,6 +871,99 @@ describe("wrangler dev", () => {
746
871
  `);
747
872
  });
748
873
  });
874
+
875
+ describe("service bindings", () => {
876
+ it("should warn when using service bindings", async () => {
877
+ writeWranglerToml({
878
+ services: [
879
+ { binding: "WorkerA", service: "A" },
880
+ { binding: "WorkerB", service: "B", environment: "staging" },
881
+ ],
882
+ });
883
+ fs.writeFileSync("index.js", `export default {};`);
884
+ await runWrangler("dev index.js");
885
+ expect(std).toMatchInlineSnapshot(`
886
+ Object {
887
+ "debug": "",
888
+ "err": "",
889
+ "out": "Your worker has access to the following bindings:
890
+ - Services:
891
+ - WorkerA: A
892
+ - WorkerB: B - staging",
893
+ "warn": "▲ [WARNING] Processing wrangler.toml configuration:
894
+
895
+ - \\"services\\" fields are experimental and may change or break at any time.
896
+
897
+
898
+ ▲ [WARNING] This worker is bound to live services: WorkerA (A), WorkerB (B@staging)
899
+
900
+ ",
901
+ }
902
+ `);
903
+ });
904
+ });
905
+
906
+ describe("print bindings", () => {
907
+ it("should print bindings", async () => {
908
+ writeWranglerToml({
909
+ services: [
910
+ { binding: "WorkerA", service: "A" },
911
+ { binding: "WorkerB", service: "B", environment: "staging" },
912
+ ],
913
+ });
914
+ fs.writeFileSync("index.js", `export default {};`);
915
+ await runWrangler("dev index.js");
916
+ expect(std).toMatchInlineSnapshot(`
917
+ Object {
918
+ "debug": "",
919
+ "err": "",
920
+ "out": "Your worker has access to the following bindings:
921
+ - Services:
922
+ - WorkerA: A
923
+ - WorkerB: B - staging",
924
+ "warn": "▲ [WARNING] Processing wrangler.toml configuration:
925
+
926
+ - \\"services\\" fields are experimental and may change or break at any time.
927
+
928
+
929
+ ▲ [WARNING] This worker is bound to live services: WorkerA (A), WorkerB (B@staging)
930
+
931
+ ",
932
+ }
933
+ `);
934
+ });
935
+
936
+ it("should mask vars that were overriden in .dev.vars", async () => {
937
+ writeWranglerToml({
938
+ vars: {
939
+ variable: 123,
940
+ overriden: "original values",
941
+ },
942
+ });
943
+ fs.writeFileSync(
944
+ ".dev.vars",
945
+ `
946
+ SECRET = "A secret"
947
+ overriden = "overriden value"
948
+ `
949
+ );
950
+ fs.writeFileSync("index.js", `export default {};`);
951
+ await runWrangler("dev index.js");
952
+ expect(std).toMatchInlineSnapshot(`
953
+ Object {
954
+ "debug": "",
955
+ "err": "",
956
+ "out": "Using vars defined in .dev.vars
957
+ Your worker has access to the following bindings:
958
+ - Vars:
959
+ - variable: \\"123\\"
960
+ - overriden: \\"(hidden)\\"
961
+ - SECRET: \\"(hidden)\\"",
962
+ "warn": "",
963
+ }
964
+ `);
965
+ });
966
+ });
749
967
  });
750
968
 
751
969
  function mockGetZones(domain: string, zones: { id: string }[] = []) {
@@ -1,4 +1,4 @@
1
- import { confirm, prompt } from "../../dialogs";
1
+ import { confirm, prompt, select } from "../../dialogs";
2
2
  import { normalizeSlashes } from "./mock-console";
3
3
 
4
4
  /**
@@ -88,3 +88,43 @@ export function clearPromptMocks() {
88
88
  );
89
89
  });
90
90
  }
91
+
92
+ /**
93
+ * The expected values for a select request.
94
+ */
95
+ export interface SelectExpectation {
96
+ /** The text expected to be seen in the select dialog. */
97
+ text: string;
98
+ /** The mock response send back from the select dialog. */
99
+ result: string;
100
+ }
101
+
102
+ /**
103
+ * Mock the implementation of `select()` that will respond with configured results
104
+ * for configured select text messages.
105
+ *
106
+ * If there is a call to `select()` that does not match any of the expectations
107
+ * then an error is thrown.
108
+ */
109
+ export function mockSelect(...expectations: SelectExpectation[]) {
110
+ (select as jest.Mock).mockImplementation((text: string) => {
111
+ for (const { text: expectedText, result } of expectations) {
112
+ if (normalizeSlashes(text) === normalizeSlashes(expectedText)) {
113
+ return Promise.resolve(result);
114
+ }
115
+ }
116
+ throw new Error(`Unexpected select message: ${text}`);
117
+ });
118
+ }
119
+
120
+ export function clearSelectMocks() {
121
+ (select as jest.Mock).mockReset();
122
+ // Because select was originally a spy, calling mockReset will simply reset
123
+ // it as a function with no return value (!), so we need to additionally reset
124
+ // the mock implementation to the one that throws (from jest.setup.js).
125
+ (select as jest.Mock).mockImplementation((text: string) => {
126
+ throw new Error(
127
+ `Unexpected call to \`select("${text}")\`.\nYou should use \`mockSelect()\` to mock calls to \`select()\` with expectations. Search the codebase for \`mockSelect\` to learn more.`
128
+ );
129
+ });
130
+ }
@@ -2,6 +2,8 @@ import { getPackageManager } from "../package-manager";
2
2
  import { mockConsoleMethods } from "./helpers/mock-console";
3
3
  import { runInTempDir } from "./helpers/run-in-tmp";
4
4
  import { runWrangler } from "./helpers/run-wrangler";
5
+ import { writeWorkerSource } from "./helpers/write-worker-source";
6
+ import writeWranglerToml from "./helpers/write-wrangler-toml";
5
7
  import type { PackageManager } from "../package-manager";
6
8
 
7
9
  describe("wrangler", () => {
@@ -44,10 +46,9 @@ describe("wrangler", () => {
44
46
  wrangler whoami 🕵️ Retrieve your user info and test your auth config
45
47
 
46
48
  Flags:
47
- -c, --config Path to .toml configuration file [string]
48
- -h, --help Show help [boolean]
49
- -v, --version Show version number [boolean]
50
- --legacy-env Use legacy environments [boolean]"
49
+ -c, --config Path to .toml configuration file [string]
50
+ -h, --help Show help [boolean]
51
+ -v, --version Show version number [boolean]"
51
52
  `);
52
53
 
53
54
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -64,10 +65,7 @@ describe("wrangler", () => {
64
65
 
65
66
  expect(std.out).toMatchInlineSnapshot(`
66
67
  "
67
- "
68
- `);
69
- expect(std.err).toMatchInlineSnapshot(`
70
- "wrangler
68
+ wrangler
71
69
 
72
70
  Commands:
73
71
  wrangler init [name] 📥 Create a wrangler.toml configuration file
@@ -85,11 +83,12 @@ describe("wrangler", () => {
85
83
  wrangler whoami 🕵️ Retrieve your user info and test your auth config
86
84
 
87
85
  Flags:
88
- -c, --config Path to .toml configuration file [string]
89
- -h, --help Show help [boolean]
90
- -v, --version Show version number [boolean]
91
- --legacy-env Use legacy environments [boolean]
92
- X [ERROR] Unknown argument: invalid-command
86
+ -c, --config Path to .toml configuration file [string]
87
+ -h, --help Show help [boolean]
88
+ -v, --version Show version number [boolean]"
89
+ `);
90
+ expect(std.err).toMatchInlineSnapshot(`
91
+ "X [ERROR] Unknown argument: invalid-command
93
92
 
94
93
  "
95
94
  `);
@@ -116,9 +115,6 @@ describe("wrangler", () => {
116
115
  });
117
116
 
118
117
  describe("subcommand implicit help ran on incomplete command execution", () => {
119
- function endEventLoop() {
120
- return new Promise((resolve) => setImmediate(resolve));
121
- }
122
118
  it("no subcommand for 'secret' should display a list of available subcommands", async () => {
123
119
  await runWrangler("secret");
124
120
  await endEventLoop();
@@ -133,10 +129,9 @@ describe("wrangler", () => {
133
129
  wrangler secret list List all secrets for a script
134
130
 
135
131
  Flags:
136
- -c, --config Path to .toml configuration file [string]
137
- -h, --help Show help [boolean]
138
- -v, --version Show version number [boolean]
139
- --legacy-env Use legacy environments [boolean]"
132
+ -c, --config Path to .toml configuration file [string]
133
+ -h, --help Show help [boolean]
134
+ -v, --version Show version number [boolean]"
140
135
  `);
141
136
  });
142
137
 
@@ -144,20 +139,19 @@ describe("wrangler", () => {
144
139
  await runWrangler("kv:namespace");
145
140
  await endEventLoop();
146
141
  expect(std.out).toMatchInlineSnapshot(`
147
- "wrangler kv:namespace
142
+ "wrangler kv:namespace
148
143
 
149
- 🗂️ Interact with your Workers KV Namespaces
144
+ 🗂️ Interact with your Workers KV Namespaces
150
145
 
151
- Commands:
152
- wrangler kv:namespace create <namespace> Create a new namespace
153
- wrangler kv:namespace list Outputs a list of all KV namespaces associated with your account id.
154
- wrangler kv:namespace delete Deletes a given namespace.
146
+ Commands:
147
+ wrangler kv:namespace create <namespace> Create a new namespace
148
+ wrangler kv:namespace list Outputs a list of all KV namespaces associated with your account id.
149
+ wrangler kv:namespace delete Deletes a given namespace.
155
150
 
156
- Flags:
157
- -c, --config Path to .toml configuration file [string]
158
- -h, --help Show help [boolean]
159
- -v, --version Show version number [boolean]
160
- --legacy-env Use legacy environments [boolean]"
151
+ Flags:
152
+ -c, --config Path to .toml configuration file [string]
153
+ -h, --help Show help [boolean]
154
+ -v, --version Show version number [boolean]"
161
155
  `);
162
156
  });
163
157
 
@@ -165,62 +159,61 @@ describe("wrangler", () => {
165
159
  await runWrangler("kv:key");
166
160
  await endEventLoop();
167
161
  expect(std.out).toMatchInlineSnapshot(`
168
- "wrangler kv:key
162
+ "wrangler kv:key
169
163
 
170
- 🔑 Individually manage Workers KV key-value pairs
164
+ 🔑 Individually manage Workers KV key-value pairs
171
165
 
172
- Commands:
173
- wrangler kv:key put <key> [value] Writes a single key/value pair to the given namespace.
174
- wrangler kv:key list Outputs a list of all keys in a given namespace.
175
- wrangler kv:key get <key> Reads a single value by key from the given namespace.
176
- wrangler kv:key delete <key> Removes a single key value pair from the given namespace.
166
+ Commands:
167
+ wrangler kv:key put <key> [value] Writes a single key/value pair to the given namespace.
168
+ wrangler kv:key list Outputs a list of all keys in a given namespace.
169
+ wrangler kv:key get <key> Reads a single value by key from the given namespace.
170
+ wrangler kv:key delete <key> Removes a single key value pair from the given namespace.
177
171
 
178
- Flags:
179
- -c, --config Path to .toml configuration file [string]
180
- -h, --help Show help [boolean]
181
- -v, --version Show version number [boolean]
182
- --legacy-env Use legacy environments [boolean]"
183
- `);
172
+ Flags:
173
+ -c, --config Path to .toml configuration file [string]
174
+ -h, --help Show help [boolean]
175
+ -v, --version Show version number [boolean]"
176
+ `);
184
177
  });
185
178
 
186
179
  it("no subcommand 'kv:bulk' should display a list of available subcommands", async () => {
187
180
  await runWrangler("kv:bulk");
188
181
  await endEventLoop();
189
182
  expect(std.out).toMatchInlineSnapshot(`
190
- "wrangler kv:bulk
183
+ "wrangler kv:bulk
191
184
 
192
- 💪 Interact with multiple Workers KV key-value pairs at once
185
+ 💪 Interact with multiple Workers KV key-value pairs at once
193
186
 
194
- Commands:
195
- wrangler kv:bulk put <filename> Upload multiple key-value pairs to a namespace
196
- wrangler kv:bulk delete <filename> Delete multiple key-value pairs from a namespace
187
+ Commands:
188
+ wrangler kv:bulk put <filename> Upload multiple key-value pairs to a namespace
189
+ wrangler kv:bulk delete <filename> Delete multiple key-value pairs from a namespace
197
190
 
198
- Flags:
199
- -c, --config Path to .toml configuration file [string]
200
- -h, --help Show help [boolean]
201
- -v, --version Show version number [boolean]
202
- --legacy-env Use legacy environments [boolean]"
203
- `);
191
+ Flags:
192
+ -c, --config Path to .toml configuration file [string]
193
+ -h, --help Show help [boolean]
194
+ -v, --version Show version number [boolean]"
195
+ `);
204
196
  });
197
+
205
198
  it("no subcommand 'r2' should display a list of available subcommands", async () => {
206
199
  await runWrangler("r2");
207
200
  await endEventLoop();
208
201
  expect(std.out).toMatchInlineSnapshot(`
209
- "wrangler r2
202
+ "wrangler r2
210
203
 
211
- 📦 Interact with an R2 store
204
+ 📦 Interact with an R2 store
212
205
 
213
- Commands:
214
- wrangler r2 bucket Manage R2 buckets
206
+ Commands:
207
+ wrangler r2 bucket Manage R2 buckets
215
208
 
216
- Flags:
217
- -c, --config Path to .toml configuration file [string]
218
- -h, --help Show help [boolean]
219
- -v, --version Show version number [boolean]
220
- --legacy-env Use legacy environments [boolean]"
221
- `);
209
+ Flags:
210
+ -c, --config Path to .toml configuration file [string]
211
+ -h, --help Show help [boolean]
212
+ -v, --version Show version number [boolean]"
213
+ `);
222
214
  });
223
215
  });
216
+
224
217
  describe("Deprecated commands", () => {
225
218
  it("should print a deprecation message for 'generate'", async () => {
226
219
  await runWrangler("generate").catch((err) => {
@@ -237,13 +230,27 @@ describe("wrangler", () => {
237
230
  `);
238
231
  });
239
232
  });
240
- it("should print a deprecation message for 'build'", async () => {
241
- await runWrangler("build").catch((err) => {
242
- expect(err.message).toMatchInlineSnapshot(`
243
- "Deprecation:
244
- \`wrangler build\` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#build for alternatives"
245
- `);
246
- });
233
+ });
234
+
235
+ it("should print a deprecation message for 'build' and then try to run `publish --dry-run --outdir`", async () => {
236
+ writeWranglerToml({
237
+ main: "index.js",
247
238
  });
239
+ writeWorkerSource();
240
+ await runWrangler("build");
241
+ await endEventLoop();
242
+ expect(std.out).toMatchInlineSnapshot(`
243
+ "▲ [WARNING] Deprecation: \`wrangler build\` has been deprecated.
244
+
245
+ Please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#build for more information.
246
+ Attempting to run \`wrangler publish --dry-run --outdir=dist\` for you instead:
247
+
248
+
249
+ --dry-run: exiting now."
250
+ `);
248
251
  });
249
252
  });
253
+
254
+ function endEventLoop() {
255
+ return new Promise((resolve) => setImmediate(resolve));
256
+ }