wrangler 0.0.0-e95bea2 → 0.0.0-e95e5a0

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 (93) hide show
  1. package/README.md +25 -14
  2. package/bin/wrangler.js +13 -1
  3. package/miniflare-dist/index.mjs +4886 -0
  4. package/package.json +33 -25
  5. package/pages/functions/buildPlugin.ts +92 -0
  6. package/pages/functions/buildWorker.ts +80 -4
  7. package/pages/functions/filepath-routing.test.ts +136 -25
  8. package/pages/functions/filepath-routing.ts +14 -3
  9. package/pages/functions/routes.ts +6 -1
  10. package/pages/functions/template-plugin.ts +146 -0
  11. package/pages/functions/template-worker.ts +21 -8
  12. package/src/__tests__/config-cache.test.ts +36 -0
  13. package/src/__tests__/configuration.test.ts +1179 -271
  14. package/src/__tests__/dev.test.tsx +382 -25
  15. package/src/__tests__/guess-worker-format.test.ts +28 -1
  16. package/src/__tests__/helpers/mock-account-id.ts +4 -0
  17. package/src/__tests__/helpers/mock-cfetch.ts +5 -1
  18. package/src/__tests__/helpers/mock-console.ts +20 -3
  19. package/src/__tests__/helpers/mock-dialogs.ts +26 -1
  20. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  21. package/src/__tests__/helpers/mock-istty.ts +27 -0
  22. package/src/__tests__/helpers/mock-kv.ts +9 -16
  23. package/src/__tests__/helpers/mock-oauth-flow.ts +255 -0
  24. package/src/__tests__/helpers/run-in-tmp.ts +10 -0
  25. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  26. package/src/__tests__/https-options.test.ts +5 -2
  27. package/src/__tests__/index.test.ts +27 -769
  28. package/src/__tests__/init.test.ts +1516 -0
  29. package/src/__tests__/jest.setup.ts +4 -4
  30. package/src/__tests__/kv.test.ts +172 -126
  31. package/src/__tests__/logger.test.ts +115 -0
  32. package/src/__tests__/pages.test.ts +311 -26
  33. package/src/__tests__/publish.test.ts +2946 -524
  34. package/src/__tests__/r2.test.ts +26 -10
  35. package/src/__tests__/route.test.ts +4 -4
  36. package/src/__tests__/secret.test.ts +55 -34
  37. package/src/__tests__/tail.test.ts +146 -20
  38. package/src/__tests__/user.test.ts +131 -0
  39. package/src/__tests__/whoami.test.tsx +26 -7
  40. package/src/bundle.ts +30 -3
  41. package/src/cfetch/internal.ts +9 -7
  42. package/src/cli.ts +5 -11
  43. package/src/config/README.md +7 -7
  44. package/src/config/config.ts +33 -78
  45. package/src/config/environment.ts +93 -4
  46. package/src/config/index.ts +15 -4
  47. package/src/config/validation-helpers.ts +202 -15
  48. package/src/config/validation.ts +530 -133
  49. package/src/config-cache.ts +45 -0
  50. package/src/create-worker-preview.ts +22 -13
  51. package/src/create-worker-upload-form.ts +32 -9
  52. package/src/dev/dev-vars.ts +36 -0
  53. package/src/dev/dev.tsx +136 -75
  54. package/src/dev/local.tsx +196 -125
  55. package/src/dev/remote.tsx +25 -13
  56. package/src/dev/use-esbuild.ts +23 -5
  57. package/src/dialogs.tsx +16 -6
  58. package/src/entry.ts +119 -11
  59. package/src/environment-variables.ts +3 -1
  60. package/src/errors.ts +11 -0
  61. package/src/https-options.ts +3 -2
  62. package/src/index.tsx +739 -400
  63. package/src/inspect.ts +17 -11
  64. package/src/intl-polyfill.d.ts +139 -0
  65. package/src/{kv/index.tsx → kv.ts} +8 -28
  66. package/src/logger.ts +66 -0
  67. package/src/miniflare-cli/README.md +30 -0
  68. package/src/miniflare-cli/enum-keys.ts +17 -0
  69. package/src/miniflare-cli/index.ts +41 -0
  70. package/src/miniflare-cli/request-context.ts +40 -0
  71. package/src/module-collection.ts +63 -58
  72. package/src/open-in-browser.ts +5 -4
  73. package/src/package-manager.ts +9 -8
  74. package/src/pages.tsx +883 -62
  75. package/src/parse.ts +1 -1
  76. package/src/proxy.ts +32 -21
  77. package/src/publish.ts +276 -161
  78. package/src/sites.tsx +88 -33
  79. package/src/tail/index.ts +2 -2
  80. package/src/tail/printing.ts +13 -8
  81. package/src/update-check.ts +19 -0
  82. package/src/user.tsx +231 -103
  83. package/src/whoami.tsx +2 -1
  84. package/src/worker.ts +15 -6
  85. package/templates/gitignore +171 -0
  86. package/templates/static-asset-facade.js +1 -1
  87. package/wrangler-dist/cli.js +22087 -49340
  88. package/src/__tests__/dev2.test.tsx +0 -152
  89. package/src/__tests__/helpers/mock-user.ts +0 -27
  90. package/src/__tests__/logout.test.ts +0 -50
  91. package/src/__tests__/sentry.test.ts +0 -146
  92. package/src/reporting.ts +0 -131
  93. package/wrangler-dist/cli.js.map +0 -7
@@ -1,6 +1,6 @@
1
1
  import * as fs from "node:fs";
2
- import { readFileSync } from "node:fs";
3
2
  import patchConsole from "patch-console";
3
+ import dedent from "ts-dedent";
4
4
  import Dev from "../dev/dev";
5
5
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
6
6
  import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
@@ -9,7 +9,7 @@ import { runInTempDir } from "./helpers/run-in-tmp";
9
9
  import { runWrangler } from "./helpers/run-wrangler";
10
10
  import writeWranglerToml from "./helpers/write-wrangler-toml";
11
11
 
12
- describe("Dev component", () => {
12
+ describe("wrangler dev", () => {
13
13
  mockAccountId();
14
14
  mockApiToken();
15
15
  runInTempDir();
@@ -20,6 +20,56 @@ describe("Dev component", () => {
20
20
  unsetAllMocks();
21
21
  });
22
22
 
23
+ describe("compatibility-date", () => {
24
+ it("should not warn if there is no wrangler.toml and no compatibility-date specified", async () => {
25
+ fs.writeFileSync("index.js", `export default {};`);
26
+ await runWrangler("dev index.js");
27
+ expect(std.out).toMatchInlineSnapshot(`""`);
28
+ expect(std.warn).toMatchInlineSnapshot(`""`);
29
+ expect(std.err).toMatchInlineSnapshot(`""`);
30
+ });
31
+
32
+ it("should warn if there is a wrangler.toml but no compatibility-date", async () => {
33
+ writeWranglerToml({
34
+ main: "index.js",
35
+ compatibility_date: undefined,
36
+ });
37
+ fs.writeFileSync("index.js", `export default {};`);
38
+ await runWrangler("dev");
39
+ const currentDate = new Date().toISOString().substring(0, 10);
40
+ expect(std.out).toMatchInlineSnapshot(`""`);
41
+ expect(std.warn.replaceAll(currentDate, "<current-date>"))
42
+ .toMatchInlineSnapshot(`
43
+ "▲ [WARNING] No compatibility_date was specified. Using today's date: <current-date>.
44
+
45
+ Add one to your wrangler.toml file:
46
+ \`\`\`
47
+ compatibility_date = \\"<current-date>\\"
48
+ \`\`\`
49
+ or pass it in your terminal:
50
+ \`\`\`
51
+ --compatibility-date=<current-date>
52
+ \`\`\`
53
+ See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.
54
+
55
+ "
56
+ `);
57
+ expect(std.err).toMatchInlineSnapshot(`""`);
58
+ });
59
+
60
+ it("should not warn if there is a wrangler.toml but compatibility-date is specified at the command line", async () => {
61
+ writeWranglerToml({
62
+ main: "index.js",
63
+ compatibility_date: undefined,
64
+ });
65
+ fs.writeFileSync("index.js", `export default {};`);
66
+ await runWrangler("dev --compatibility-date=2020-01-01");
67
+ expect(std.out).toMatchInlineSnapshot(`""`);
68
+ expect(std.warn).toMatchInlineSnapshot(`""`);
69
+ expect(std.err).toMatchInlineSnapshot(`""`);
70
+ });
71
+ });
72
+
23
73
  describe("entry-points", () => {
24
74
  it("should error if there is no entry-point specified", async () => {
25
75
  writeWranglerToml();
@@ -30,13 +80,67 @@ describe("Dev component", () => {
30
80
  `"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."`
31
81
  );
32
82
 
33
- expect(std.out).toMatchInlineSnapshot(`""`);
83
+ expect(std.out).toMatchInlineSnapshot(`
84
+ "
85
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
86
+ `);
34
87
  expect(std.err).toMatchInlineSnapshot(`
35
- "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.
88
+ "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.
36
89
 
37
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
90
+ "
38
91
  `);
39
92
  });
93
+
94
+ it("should use `main` from the top-level environment", async () => {
95
+ writeWranglerToml({
96
+ main: "index.js",
97
+ });
98
+ fs.writeFileSync("index.js", `export default {};`);
99
+ await runWrangler("dev");
100
+ expect((Dev as jest.Mock).mock.calls[0][0].entry.file).toMatch(
101
+ /index\.js$/
102
+ );
103
+ expect(std.out).toMatchInlineSnapshot(`""`);
104
+ expect(std.warn).toMatchInlineSnapshot(`""`);
105
+ expect(std.err).toMatchInlineSnapshot(`""`);
106
+ });
107
+
108
+ it("should use `main` from a named environment", async () => {
109
+ writeWranglerToml({
110
+ env: {
111
+ ENV1: {
112
+ main: "index.js",
113
+ },
114
+ },
115
+ });
116
+ fs.writeFileSync("index.js", `export default {};`);
117
+ await runWrangler("dev --env=ENV1");
118
+ expect((Dev as jest.Mock).mock.calls[0][0].entry.file).toMatch(
119
+ /index\.js$/
120
+ );
121
+ expect(std.out).toMatchInlineSnapshot(`""`);
122
+ expect(std.warn).toMatchInlineSnapshot(`""`);
123
+ expect(std.err).toMatchInlineSnapshot(`""`);
124
+ });
125
+
126
+ it("should use `main` from a named environment, rather than the top-level", async () => {
127
+ writeWranglerToml({
128
+ main: "other.js",
129
+ env: {
130
+ ENV1: {
131
+ main: "index.js",
132
+ },
133
+ },
134
+ });
135
+ fs.writeFileSync("index.js", `export default {};`);
136
+ await runWrangler("dev --env=ENV1");
137
+ expect((Dev as jest.Mock).mock.calls[0][0].entry.file).toMatch(
138
+ /index\.js$/
139
+ );
140
+ expect(std.out).toMatchInlineSnapshot(`""`);
141
+ expect(std.warn).toMatchInlineSnapshot(`""`);
142
+ expect(std.err).toMatchInlineSnapshot(`""`);
143
+ });
40
144
  });
41
145
 
42
146
  describe("host", () => {
@@ -120,6 +224,38 @@ describe("Dev component", () => {
120
224
  );
121
225
  });
122
226
 
227
+ it("should, when provided, use a configured zone_id", async () => {
228
+ writeWranglerToml({
229
+ main: "index.js",
230
+ routes: [
231
+ { pattern: "https://some-domain.com/*", zone_id: "some-zone-id" },
232
+ ],
233
+ });
234
+ fs.writeFileSync("index.js", `export default {};`);
235
+ await runWrangler("dev");
236
+ expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
237
+ host: "some-domain.com",
238
+ id: "some-zone-id",
239
+ });
240
+ });
241
+
242
+ it("should, when provided, use a zone_name to get a zone_id", async () => {
243
+ writeWranglerToml({
244
+ main: "index.js",
245
+ routes: [
246
+ { pattern: "https://some-domain.com/*", zone_name: "some-zone.com" },
247
+ ],
248
+ });
249
+ fs.writeFileSync("index.js", `export default {};`);
250
+ mockGetZones("some-zone.com", [{ id: "a-zone-id" }]);
251
+ await runWrangler("dev");
252
+ expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
253
+ // note that it uses the provided zone_name as a host too
254
+ host: "some-zone.com",
255
+ id: "a-zone-id",
256
+ });
257
+ });
258
+
123
259
  it("given a long host, it should use the longest subdomain that resolves to a zone", async () => {
124
260
  writeWranglerToml({
125
261
  main: "index.js",
@@ -135,7 +271,7 @@ describe("Dev component", () => {
135
271
  });
136
272
  });
137
273
 
138
- it("should, in order, use args.host/config.dev.host/args.routes/config.route/config.routes", async () => {
274
+ it("should, in order, use args.host/config.dev.host/args.routes/(config.route|config.routes)", async () => {
139
275
  // This test might seem like it's testing implementation details, but let's be specific and consider it a spec
140
276
 
141
277
  fs.writeFileSync("index.js", `export default {};`);
@@ -158,7 +294,6 @@ describe("Dev component", () => {
158
294
  writeWranglerToml({
159
295
  main: "index.js",
160
296
  route: "https://4.some-host.com/some/path/*",
161
- routes: ["http://5.some-host.com/some/path/*"],
162
297
  });
163
298
  await runWrangler("dev");
164
299
  expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
@@ -172,7 +307,6 @@ describe("Dev component", () => {
172
307
  writeWranglerToml({
173
308
  main: "index.js",
174
309
  route: "https://4.some-host.com/some/path/*",
175
- routes: ["http://5.some-host.com/some/path/*"],
176
310
  });
177
311
  await runWrangler("dev --routes http://3.some-host.com/some/path/*");
178
312
  expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
@@ -189,7 +323,6 @@ describe("Dev component", () => {
189
323
  host: `2.some-host.com`,
190
324
  },
191
325
  route: "4.some-host.com/some/path/*",
192
- routes: ["5.some-host.com/some/path/*"],
193
326
  });
194
327
  await runWrangler("dev --routes http://3.some-host.com/some/path/*");
195
328
  expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
@@ -206,7 +339,6 @@ describe("Dev component", () => {
206
339
  host: `2.some-host.com`,
207
340
  },
208
341
  route: "4.some-host.com/some/path/*",
209
- routes: ["5.some-host.com/some/path/*"],
210
342
  });
211
343
  await runWrangler(
212
344
  "dev --routes http://3.some-host.com/some/path/* --host 1.some-host.com"
@@ -230,6 +362,15 @@ describe("Dev component", () => {
230
362
  `"Could not find zone for some-host.com"`
231
363
  );
232
364
  });
365
+
366
+ it("should not try to resolve a zone when starting in local mode", async () => {
367
+ writeWranglerToml({
368
+ main: "index.js",
369
+ });
370
+ fs.writeFileSync("index.js", `export default {};`);
371
+ await runWrangler("dev --host some-host.com --local");
372
+ expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual(undefined);
373
+ });
233
374
  });
234
375
 
235
376
  describe("custom builds", () => {
@@ -242,19 +383,19 @@ describe("Dev component", () => {
242
383
 
243
384
  await runWrangler("dev index.js");
244
385
 
245
- expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(
386
+ expect(fs.readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(
246
387
  `"export default { fetch(){ return new Response(123) } }"`
247
388
  );
248
389
 
249
390
  // and the command would pass through
250
- expect((Dev as jest.Mock).mock.calls[0][0].buildCommand).toEqual({
391
+ expect((Dev as jest.Mock).mock.calls[0][0].build).toEqual({
251
392
  command:
252
393
  "node -e \"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\"",
253
394
  cwd: undefined,
254
- watch_dir: undefined,
395
+ watch_dir: "src",
255
396
  });
256
397
  expect(std.out).toMatchInlineSnapshot(
257
- `"running: node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\""`
398
+ `"Running custom build: node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\""`
258
399
  );
259
400
  expect(std.err).toMatchInlineSnapshot(`""`);
260
401
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -270,13 +411,13 @@ describe("Dev component", () => {
270
411
 
271
412
  await runWrangler("dev index.js");
272
413
 
273
- expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(`
414
+ expect(fs.readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(`
274
415
  "export default { fetch(){ return new Response(123) } }
275
416
  "
276
417
  `);
277
418
 
278
419
  expect(std.out).toMatchInlineSnapshot(
279
- `"running: echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js"`
420
+ `"Running custom build: echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js"`
280
421
  );
281
422
  expect(std.err).toMatchInlineSnapshot(`""`);
282
423
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -296,13 +437,15 @@ describe("Dev component", () => {
296
437
  ).rejects.toThrowErrorMatchingInlineSnapshot(
297
438
  `"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\""`
298
439
  );
299
- expect(std.out).toMatchInlineSnapshot(
300
- `"running: node -e \\"console.log('custom build');\\""`
301
- );
440
+ expect(std.out).toMatchInlineSnapshot(`
441
+ "Running custom build: node -e \\"console.log('custom build');\\"
442
+
443
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
444
+ `);
302
445
  expect(std.err).toMatchInlineSnapshot(`
303
- "Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
446
+ "X [ERROR] Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
304
447
 
305
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
448
+ "
306
449
  `);
307
450
  expect(std.warn).toMatchInlineSnapshot(`""`);
308
451
  });
@@ -334,9 +477,12 @@ describe("Dev component", () => {
334
477
  );
335
478
  expect(std.out).toMatchInlineSnapshot(`""`);
336
479
  expect(std.warn).toMatchInlineSnapshot(`
337
- "Setting upstream-protocol to http is not currently implemented.
338
- If this is required in your project, please add your use case to the following issue:
339
- https://github.com/cloudflare/wrangler2/issues/583."
480
+ "▲ [WARNING] Setting upstream-protocol to http is not currently implemented.
481
+
482
+ If this is required in your project, please add your use case to the following issue:
483
+ https://github.com/cloudflare/wrangler2/issues/583.
484
+
485
+ "
340
486
  `);
341
487
  expect(std.err).toMatchInlineSnapshot(`""`);
342
488
  });
@@ -355,7 +501,7 @@ describe("Dev component", () => {
355
501
  expect(std.err).toMatchInlineSnapshot(`""`);
356
502
  });
357
503
 
358
- it("should use to `local_protocol` from `wrangler.toml`, if available", async () => {
504
+ it("should use `local_protocol` from `wrangler.toml`, if available", async () => {
359
505
  writeWranglerToml({
360
506
  main: "index.js",
361
507
  dev: {
@@ -389,6 +535,217 @@ describe("Dev component", () => {
389
535
  expect(std.err).toMatchInlineSnapshot(`""`);
390
536
  });
391
537
  });
538
+
539
+ describe("ip", () => {
540
+ it("should default ip to localhost", async () => {
541
+ writeWranglerToml({
542
+ main: "index.js",
543
+ });
544
+ fs.writeFileSync("index.js", `export default {};`);
545
+ await runWrangler("dev");
546
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("localhost");
547
+ expect(std.out).toMatchInlineSnapshot(`""`);
548
+ expect(std.warn).toMatchInlineSnapshot(`""`);
549
+ expect(std.err).toMatchInlineSnapshot(`""`);
550
+ });
551
+
552
+ it("should use to `ip` from `wrangler.toml`, if available", async () => {
553
+ writeWranglerToml({
554
+ main: "index.js",
555
+ dev: {
556
+ ip: "0.0.0.0",
557
+ },
558
+ });
559
+ fs.writeFileSync("index.js", `export default {};`);
560
+ await runWrangler("dev");
561
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
562
+ expect(std.out).toMatchInlineSnapshot(`""`);
563
+ expect(std.warn).toMatchInlineSnapshot(`""`);
564
+ expect(std.err).toMatchInlineSnapshot(`""`);
565
+ });
566
+
567
+ it("should use --ip command line arg, if provided", async () => {
568
+ writeWranglerToml({
569
+ main: "index.js",
570
+ dev: {
571
+ ip: "1.1.1.1",
572
+ },
573
+ });
574
+ fs.writeFileSync("index.js", `export default {};`);
575
+ await runWrangler("dev --ip=0.0.0.0");
576
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
577
+ expect(std.out).toMatchInlineSnapshot(`""`);
578
+ expect(std.warn).toMatchInlineSnapshot(`""`);
579
+ expect(std.err).toMatchInlineSnapshot(`""`);
580
+ });
581
+ });
582
+
583
+ describe("durable_objects", () => {
584
+ it("should warn if there is one or more remote Durable Object", async () => {
585
+ writeWranglerToml({
586
+ main: "index.js",
587
+ durable_objects: {
588
+ bindings: [
589
+ { name: "NAME_1", class_name: "CLASS_1" },
590
+ {
591
+ name: "NAME_2",
592
+ class_name: "CLASS_2",
593
+ script_name: "SCRIPT_A",
594
+ },
595
+ { name: "NAME_3", class_name: "CLASS_3" },
596
+ {
597
+ name: "NAME_4",
598
+ class_name: "CLASS_4",
599
+ script_name: "SCRIPT_B",
600
+ },
601
+ ],
602
+ },
603
+ });
604
+ fs.writeFileSync("index.js", `export default {};`);
605
+ await runWrangler("dev");
606
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("localhost");
607
+ expect(std.out).toMatchInlineSnapshot(`""`);
608
+ expect(std.warn).toMatchInlineSnapshot(`
609
+ "▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.
610
+
611
+ Be aware that changes to the data stored in these Durable Objects will be permanent and affect the
612
+ live instances.
613
+ Remote Durable Objects that are affected:
614
+ - {\\"name\\":\\"NAME_2\\",\\"class_name\\":\\"CLASS_2\\",\\"script_name\\":\\"SCRIPT_A\\"}
615
+ - {\\"name\\":\\"NAME_4\\",\\"class_name\\":\\"CLASS_4\\",\\"script_name\\":\\"SCRIPT_B\\"}
616
+
617
+ "
618
+ `);
619
+ expect(std.err).toMatchInlineSnapshot(`""`);
620
+ });
621
+ });
622
+
623
+ describe(".dev.vars", () => {
624
+ it("should override `vars` bindings from `wrangler.toml` with values in `.dev.vars`", async () => {
625
+ fs.writeFileSync("index.js", `export default {};`);
626
+
627
+ const localVarsEnvContent = dedent`
628
+ # Preceding comment
629
+ VAR_1="var #1 value" # End of line comment
630
+ VAR_3="var #3 value"
631
+ VAR_MULTI_LINE_1="A: line 1
632
+ line 2"
633
+ VAR_MULTI_LINE_2="B: line 1\\nline 2"
634
+ EMPTY=
635
+ UNQUOTED= unquoted value
636
+ `;
637
+ fs.writeFileSync(".dev.vars", localVarsEnvContent, "utf8");
638
+
639
+ writeWranglerToml({
640
+ main: "index.js",
641
+ vars: {
642
+ VAR_1: "original value 1",
643
+ VAR_2: "original value 2", // should not get overridden
644
+ VAR_3: "original value 3",
645
+ VAR_MULTI_LINE_1: "original multi-line 1",
646
+ VAR_MULTI_LINE_2: "original multi-line 2",
647
+ EMPTY: "original empty",
648
+ UNQUOTED: "original unquoted",
649
+ },
650
+ });
651
+ await runWrangler("dev");
652
+ const varBindings: Record<string, unknown> = (Dev as jest.Mock).mock
653
+ .calls[0][0].bindings.vars;
654
+
655
+ expect(varBindings).toEqual({
656
+ VAR_1: "var #1 value",
657
+ VAR_2: "original value 2",
658
+ VAR_3: "var #3 value",
659
+ VAR_MULTI_LINE_1: "A: line 1\nline 2",
660
+ VAR_MULTI_LINE_2: "B: line 1\nline 2",
661
+ EMPTY: "",
662
+ UNQUOTED: "unquoted value", // Note that whitespace is trimmed
663
+ });
664
+ expect(std.out).toMatchInlineSnapshot(
665
+ `"Using vars defined in .dev.vars"`
666
+ );
667
+ expect(std.warn).toMatchInlineSnapshot(`""`);
668
+ expect(std.err).toMatchInlineSnapshot(`""`);
669
+ });
670
+ });
671
+
672
+ describe("site", () => {
673
+ it("should error if --site is used with no value", async () => {
674
+ await expect(
675
+ runWrangler("dev --site")
676
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
677
+ `"Not enough arguments following: site"`
678
+ );
679
+
680
+ expect(std).toMatchInlineSnapshot(`
681
+ Object {
682
+ "debug": "",
683
+ "err": "wrangler dev [script]
684
+
685
+ 👂 Start a local server for developing your worker
686
+
687
+ Positionals:
688
+ script The path to an entry point for your worker [string]
689
+
690
+ 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]
695
+
696
+ Options:
697
+ --name Name of the worker [string]
698
+ --format Choose an entry type [deprecated] [choices: \\"modules\\", \\"service-worker\\"]
699
+ -e, --env Perform on a specific environment [string]
700
+ --compatibility-date Date to use for compatibility checks [string]
701
+ --compatibility-flags, --compatibility-flag Flags to use for compatibility checks [array]
702
+ --latest Use the latest version of the worker runtime [boolean] [default: true]
703
+ --ip IP address to listen on, defaults to \`localhost\` [string]
704
+ --port Port to listen on [number]
705
+ --inspector-port Port for devtools to connect to [number]
706
+ --routes, --route Routes to upload [array]
707
+ --host Host to forward requests to, defaults to the zone of project [string]
708
+ --local-protocol Protocol to listen to requests on, defaults to http. [choices: \\"http\\", \\"https\\"]
709
+ --experimental-public Static assets to be served [string]
710
+ --site Root folder of static assets for Workers Sites [string]
711
+ --site-include Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded. [array]
712
+ --site-exclude Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded. [array]
713
+ --upstream-protocol Protocol to forward requests to host on, defaults to https. [choices: \\"http\\", \\"https\\"]
714
+ --jsx-factory The function that is called for each JSX element [string]
715
+ --jsx-fragment The function that is called for each JSX fragment [string]
716
+ --tsconfig Path to a custom tsconfig.json file [string]
717
+ -l, --local Run on my machine [boolean] [default: false]
718
+ --minify Minify the script [boolean]
719
+ --node-compat Enable node.js compatibility [boolean]
720
+ --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
+ ",
727
+ "warn": "",
728
+ }
729
+ `);
730
+ });
731
+ });
732
+
733
+ describe("--inspect", () => {
734
+ it("should warn if --inspect is used", async () => {
735
+ fs.writeFileSync("index.js", `export default {};`);
736
+ await runWrangler("dev index.js --inspect");
737
+ expect(std).toMatchInlineSnapshot(`
738
+ Object {
739
+ "debug": "",
740
+ "err": "",
741
+ "out": "",
742
+ "warn": "▲ [WARNING] Passing --inspect is unnecessary, now you can always connect to devtools.
743
+
744
+ ",
745
+ }
746
+ `);
747
+ });
748
+ });
392
749
  });
393
750
 
394
751
  function mockGetZones(domain: string, zones: { id: string }[] = []) {
@@ -1,10 +1,12 @@
1
1
  import { writeFile } from "fs/promises";
2
2
  import path from "path";
3
3
  import guessWorkerFormat from "../entry";
4
+ import { mockConsoleMethods } from "./helpers/mock-console";
4
5
  import { runInTempDir } from "./helpers/run-in-tmp";
5
6
 
6
7
  describe("guess worker format", () => {
7
8
  runInTempDir();
9
+ const std = mockConsoleMethods();
8
10
  it('should detect a "modules" worker', async () => {
9
11
  await writeFile("./index.ts", "export default {};");
10
12
  // Note that this isn't actually a valid worker, because it's missing
@@ -39,7 +41,7 @@ describe("guess worker format", () => {
39
41
  "service-worker"
40
42
  )
41
43
  ).rejects.toThrow(
42
- "You configured this worker to be a 'service-worker', but the file you are trying to build appears to have ES module exports. Please pass `--format modules`, or simply remove the configuration."
44
+ "You configured this worker to be a 'service-worker', but the file you are trying to build appears to have a `default` export like a module worker. Please pass `--format modules`, or simply remove the configuration."
43
45
  );
44
46
  });
45
47
 
@@ -55,4 +57,29 @@ describe("guess worker format", () => {
55
57
  "You configured this worker to be 'modules', but the file you are trying to build doesn't export a handler. Please pass `--format service-worker`, or simply remove the configuration."
56
58
  );
57
59
  });
60
+
61
+ it("should not error if a .js entry point has jsx", async () => {
62
+ await writeFile("./index.js", "console.log(<div/>)");
63
+ const guess = await guessWorkerFormat(
64
+ path.join(process.cwd(), "./index.js"),
65
+ process.cwd(),
66
+ undefined
67
+ );
68
+ expect(guess).toBe("service-worker");
69
+ });
70
+
71
+ it("logs a warning when a worker has exports, but not a default one", async () => {
72
+ await writeFile("./index.ts", "export const foo = 1;");
73
+ const guess = await guessWorkerFormat(
74
+ path.join(process.cwd(), "./index.ts"),
75
+ process.cwd(),
76
+ undefined
77
+ );
78
+ expect(guess).toBe("service-worker");
79
+ expect(std.warn).toMatchInlineSnapshot(`
80
+ "▲ [WARNING] The entrypoint index.ts has exports like an ES Module, but hasn't defined a default export like a module worker normally would. Building the worker using \\"service-worker\\" format...
81
+
82
+ "
83
+ `);
84
+ });
58
85
  });
@@ -1,3 +1,5 @@
1
+ import { reinitialiseAuthTokens } from "../../user";
2
+
1
3
  const ORIGINAL_CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN;
2
4
  const ORIGINAL_CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID;
3
5
 
@@ -16,6 +18,8 @@ export function mockApiToken({
16
18
  } else {
17
19
  process.env.CLOUDFLARE_API_TOKEN = apiToken;
18
20
  }
21
+ // Now we have updated the environment, we must reinitialize the user auth state.
22
+ reinitialiseAuthTokens();
19
23
  });
20
24
  afterEach(() => {
21
25
  process.env.CLOUDFLARE_API_TOKEN = ORIGINAL_CLOUDFLARE_API_TOKEN;
@@ -181,6 +181,9 @@ export function unsetAllMocks() {
181
181
 
182
182
  const kvGetMocks = new Map<string, string>();
183
183
 
184
+ /**
185
+ * @mocked typeof fetchKVGetValue
186
+ */
184
187
  export function mockFetchKVGetValue(
185
188
  accountId: string,
186
189
  namespaceId: string,
@@ -188,7 +191,8 @@ export function mockFetchKVGetValue(
188
191
  ) {
189
192
  const mapKey = `${accountId}/${namespaceId}/${key}`;
190
193
  if (kvGetMocks.has(mapKey)) {
191
- return kvGetMocks.get(mapKey);
194
+ const value = kvGetMocks.get(mapKey);
195
+ if (value !== undefined) return Promise.resolve(value);
192
196
  }
193
197
  throw new Error(`no mock value found for \`kv:key get\` - ${mapKey}`);
194
198
  }