wrangler 2.0.5 → 2.0.8

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 (46) hide show
  1. package/README.md +1 -1
  2. package/bin/wrangler.js +16 -4
  3. package/package.json +6 -4
  4. package/pages/functions/buildPlugin.ts +13 -0
  5. package/pages/functions/buildWorker.ts +13 -0
  6. package/src/__tests__/configuration.test.ts +335 -86
  7. package/src/__tests__/dev.test.tsx +166 -15
  8. package/src/__tests__/helpers/mock-dialogs.ts +41 -1
  9. package/src/__tests__/index.test.ts +30 -16
  10. package/src/__tests__/init.test.ts +249 -131
  11. package/src/__tests__/kv.test.ts +101 -101
  12. package/src/__tests__/package-manager.test.ts +154 -7
  13. package/src/__tests__/pages.test.ts +369 -39
  14. package/src/__tests__/parse.test.ts +5 -1
  15. package/src/__tests__/publish.test.ts +556 -84
  16. package/src/__tests__/r2.test.ts +47 -24
  17. package/src/__tests__/secret.test.ts +39 -4
  18. package/src/abort.d.ts +3 -0
  19. package/src/bundle.ts +32 -1
  20. package/src/cfetch/index.ts +21 -4
  21. package/src/cfetch/internal.ts +14 -9
  22. package/src/config/environment.ts +40 -14
  23. package/src/config/index.ts +162 -0
  24. package/src/config/validation.ts +179 -64
  25. package/src/create-worker-preview.ts +17 -7
  26. package/src/create-worker-upload-form.ts +22 -8
  27. package/src/dev/dev.tsx +2 -4
  28. package/src/dev/local.tsx +6 -0
  29. package/src/dev/remote.tsx +15 -1
  30. package/src/dialogs.tsx +48 -0
  31. package/src/durable.ts +102 -0
  32. package/src/index.tsx +314 -144
  33. package/src/inspect.ts +39 -0
  34. package/src/kv.ts +77 -13
  35. package/src/open-in-browser.ts +5 -12
  36. package/src/package-manager.ts +50 -3
  37. package/src/pages.tsx +210 -65
  38. package/src/parse.ts +21 -4
  39. package/src/proxy.ts +38 -22
  40. package/src/publish.ts +227 -113
  41. package/src/sites.tsx +11 -9
  42. package/src/worker.ts +8 -0
  43. package/templates/new-worker-scheduled.js +17 -0
  44. package/templates/new-worker-scheduled.ts +32 -0
  45. package/templates/new-worker.ts +16 -1
  46. package/wrangler-dist/cli.js +35466 -22362
@@ -83,7 +83,7 @@ describe("wrangler dev", () => {
83
83
 
84
84
  expect(std.out).toMatchInlineSnapshot(`
85
85
  "
86
- 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"
87
87
  `);
88
88
  expect(std.err).toMatchInlineSnapshot(`
89
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.
@@ -225,6 +225,32 @@ describe("wrangler dev", () => {
225
225
  );
226
226
  });
227
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
+
228
254
  it("should, when provided, use a configured zone_id", async () => {
229
255
  writeWranglerToml({
230
256
  main: "index.js",
@@ -441,7 +467,7 @@ describe("wrangler dev", () => {
441
467
  expect(std.out).toMatchInlineSnapshot(`
442
468
  "Running custom build: node -e \\"console.log('custom build');\\"
443
469
 
444
- 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"
445
471
  `);
446
472
  expect(std.err).toMatchInlineSnapshot(`
447
473
  "X [ERROR] The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
@@ -649,7 +675,7 @@ describe("wrangler dev", () => {
649
675
  });
650
676
 
651
677
  describe("durable_objects", () => {
652
- 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 () => {
653
679
  writeWranglerToml({
654
680
  main: "index.js",
655
681
  durable_objects: {
@@ -672,9 +698,33 @@ describe("wrangler dev", () => {
672
698
  fs.writeFileSync("index.js", `export default {};`);
673
699
  await runWrangler("dev");
674
700
  expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("localhost");
675
- 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
+ `);
676
709
  expect(std.warn).toMatchInlineSnapshot(`
677
- "â–² [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.
678
728
 
679
729
  Be aware that changes to the data stored in these Durable Objects will be permanent and affect the
680
730
  live instances.
@@ -729,9 +779,18 @@ describe("wrangler dev", () => {
729
779
  EMPTY: "",
730
780
  UNQUOTED: "unquoted value", // Note that whitespace is trimmed
731
781
  });
732
- expect(std.out).toMatchInlineSnapshot(
733
- `"Using vars defined in .dev.vars"`
734
- );
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
+ `);
735
794
  expect(std.warn).toMatchInlineSnapshot(`""`);
736
795
  expect(std.err).toMatchInlineSnapshot(`""`);
737
796
  });
@@ -748,7 +807,11 @@ describe("wrangler dev", () => {
748
807
  expect(std).toMatchInlineSnapshot(`
749
808
  Object {
750
809
  "debug": "",
751
- "err": "wrangler dev [script]
810
+ "err": "X [ERROR] Not enough arguments following: site
811
+
812
+ ",
813
+ "out": "
814
+ wrangler dev [script]
752
815
 
753
816
  👂 Start a local server for developing your worker
754
817
 
@@ -785,12 +848,7 @@ describe("wrangler dev", () => {
785
848
  --minify Minify the script [boolean]
786
849
  --node-compat Enable node.js compatibility [boolean]
787
850
  --experimental-enable-local-persistence Enable persistence for this session (only for local mode) [boolean]
788
- --inspect Enable dev tools [deprecated] [boolean]
789
- X [ERROR] Not enough arguments following: site
790
-
791
- ",
792
- "out": "
793
- ",
851
+ --inspect Enable dev tools [deprecated] [boolean]",
794
852
  "warn": "",
795
853
  }
796
854
  `);
@@ -813,6 +871,99 @@ describe("wrangler dev", () => {
813
871
  `);
814
872
  });
815
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
+ });
816
967
  });
817
968
 
818
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", () => {
@@ -63,10 +65,7 @@ describe("wrangler", () => {
63
65
 
64
66
  expect(std.out).toMatchInlineSnapshot(`
65
67
  "
66
- "
67
- `);
68
- expect(std.err).toMatchInlineSnapshot(`
69
- "wrangler
68
+ wrangler
70
69
 
71
70
  Commands:
72
71
  wrangler init [name] 📥 Create a wrangler.toml configuration file
@@ -86,8 +85,10 @@ describe("wrangler", () => {
86
85
  Flags:
87
86
  -c, --config Path to .toml configuration file [string]
88
87
  -h, --help Show help [boolean]
89
- -v, --version Show version number [boolean]
90
- X [ERROR] Unknown argument: invalid-command
88
+ -v, --version Show version number [boolean]"
89
+ `);
90
+ expect(std.err).toMatchInlineSnapshot(`
91
+ "X [ERROR] Unknown argument: invalid-command
91
92
 
92
93
  "
93
94
  `);
@@ -114,9 +115,6 @@ describe("wrangler", () => {
114
115
  });
115
116
 
116
117
  describe("subcommand implicit help ran on incomplete command execution", () => {
117
- function endEventLoop() {
118
- return new Promise((resolve) => setImmediate(resolve));
119
- }
120
118
  it("no subcommand for 'secret' should display a list of available subcommands", async () => {
121
119
  await runWrangler("secret");
122
120
  await endEventLoop();
@@ -196,6 +194,7 @@ describe("wrangler", () => {
196
194
  -v, --version Show version number [boolean]"
197
195
  `);
198
196
  });
197
+
199
198
  it("no subcommand 'r2' should display a list of available subcommands", async () => {
200
199
  await runWrangler("r2");
201
200
  await endEventLoop();
@@ -214,6 +213,7 @@ describe("wrangler", () => {
214
213
  `);
215
214
  });
216
215
  });
216
+
217
217
  describe("Deprecated commands", () => {
218
218
  it("should print a deprecation message for 'generate'", async () => {
219
219
  await runWrangler("generate").catch((err) => {
@@ -230,13 +230,27 @@ describe("wrangler", () => {
230
230
  `);
231
231
  });
232
232
  });
233
- it("should print a deprecation message for 'build'", async () => {
234
- await runWrangler("build").catch((err) => {
235
- expect(err.message).toMatchInlineSnapshot(`
236
- "Deprecation:
237
- \`wrangler build\` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#build for alternatives"
238
- `);
239
- });
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",
240
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
+ `);
241
251
  });
242
252
  });
253
+
254
+ function endEventLoop() {
255
+ return new Promise((resolve) => setImmediate(resolve));
256
+ }