wrangler 0.0.0-e3cab74 → 0.0.0-e3e3243

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 (66) hide show
  1. package/README.md +1 -1
  2. package/bin/wrangler.js +10 -1
  3. package/miniflare-dist/index.mjs +79 -0
  4. package/miniflare-dist/index.mjs.map +7 -0
  5. package/package.json +10 -7
  6. package/pages/functions/filepath-routing.test.ts +125 -25
  7. package/pages/functions/filepath-routing.ts +6 -3
  8. package/src/__tests__/configuration.test.ts +959 -324
  9. package/src/__tests__/dev.test.tsx +512 -84
  10. package/src/__tests__/guess-worker-format.test.ts +19 -17
  11. package/src/__tests__/helpers/mock-account-id.ts +22 -4
  12. package/src/__tests__/helpers/mock-cfetch.ts +3 -3
  13. package/src/__tests__/helpers/mock-console.ts +17 -9
  14. package/src/__tests__/helpers/mock-kv.ts +9 -16
  15. package/src/__tests__/helpers/mock-stdin.ts +103 -0
  16. package/src/__tests__/helpers/run-in-tmp.ts +3 -0
  17. package/src/__tests__/https-options.test.ts +127 -0
  18. package/src/__tests__/index.test.ts +128 -11
  19. package/src/__tests__/jest.setup.ts +16 -4
  20. package/src/__tests__/kv.test.ts +364 -125
  21. package/src/__tests__/logout.test.ts +15 -13
  22. package/src/__tests__/pages.test.ts +82 -0
  23. package/src/__tests__/publish.test.ts +1838 -735
  24. package/src/__tests__/r2.test.ts +4 -4
  25. package/src/__tests__/route.test.ts +45 -0
  26. package/src/__tests__/secret.test.ts +167 -68
  27. package/src/__tests__/tail.test.ts +2 -4
  28. package/src/__tests__/whoami.test.tsx +21 -7
  29. package/src/bundle.ts +27 -5
  30. package/src/cfetch/internal.ts +11 -5
  31. package/src/config/README.md +6 -6
  32. package/src/config/config.ts +54 -101
  33. package/src/config/environment.ts +67 -1
  34. package/src/config/index.ts +13 -3
  35. package/src/config/validation-helpers.ts +207 -23
  36. package/src/config/validation.ts +344 -129
  37. package/src/{api/preview.ts → create-worker-preview.ts} +39 -20
  38. package/src/{api/form_data.ts → create-worker-upload-form.ts} +1 -1
  39. package/src/dev/dev.tsx +392 -0
  40. package/src/dev/local.tsx +232 -0
  41. package/src/dev/remote.tsx +203 -0
  42. package/src/dev/use-esbuild.ts +104 -0
  43. package/src/entry.ts +192 -9
  44. package/src/https-options.ts +122 -0
  45. package/src/index.tsx +577 -515
  46. package/src/inspect.ts +9 -1
  47. package/src/intl-polyfill.d.ts +139 -0
  48. package/src/{kv.tsx → kv.ts} +97 -53
  49. package/src/miniflare-cli/README.md +30 -0
  50. package/src/miniflare-cli/enum-keys.ts +17 -0
  51. package/src/miniflare-cli/index.ts +37 -0
  52. package/src/module-collection.ts +90 -2
  53. package/src/open-in-browser.ts +14 -2
  54. package/src/pages.tsx +26 -10
  55. package/src/proxy.ts +104 -40
  56. package/src/publish.ts +53 -71
  57. package/src/reporting.ts +25 -9
  58. package/src/selfsigned.d.ts +29 -0
  59. package/src/sites.tsx +68 -29
  60. package/src/user.tsx +163 -85
  61. package/src/{api/worker.ts → worker.ts} +1 -24
  62. package/wrangler-dist/cli.js +5933 -3842
  63. package/wrangler-dist/cli.js.map +3 -3
  64. package/src/__tests__/helpers/mock-user.ts +0 -27
  65. package/src/dev.tsx +0 -961
  66. package/src/guess-worker-format.ts +0 -68
@@ -2,14 +2,19 @@ import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import * as TOML from "@iarna/toml";
4
4
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
5
- import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
5
+ import {
6
+ createFetchResult,
7
+ setMockRawResponse,
8
+ setMockResponse,
9
+ unsetAllMocks,
10
+ unsetMockFetchKVGetValues,
11
+ } from "./helpers/mock-cfetch";
6
12
  import { mockConsoleMethods } from "./helpers/mock-console";
7
13
  import { mockKeyListRequest } from "./helpers/mock-kv";
8
14
  import { runInTempDir } from "./helpers/run-in-tmp";
9
15
  import { runWrangler } from "./helpers/run-wrangler";
10
16
  import writeWranglerToml from "./helpers/write-wrangler-toml";
11
- import type { WorkerMetadata } from "../api/form_data";
12
- import type { Config } from "../config";
17
+ import type { WorkerMetadata } from "../create-worker-upload-form";
13
18
  import type { KVNamespaceInfo } from "../kv";
14
19
  import type { FormData, File } from "undici";
15
20
 
@@ -27,11 +32,12 @@ describe("publish", () => {
27
32
 
28
33
  afterEach(() => {
29
34
  unsetAllMocks();
35
+ unsetMockFetchKVGetValues();
30
36
  });
31
37
 
32
38
  describe("environments", () => {
33
39
  it("should use legacy environments by default", async () => {
34
- writeWranglerToml();
40
+ writeWranglerToml({ env: { "some-env": {} } });
35
41
  writeWorkerSource();
36
42
  mockSubDomainRequest();
37
43
  mockUploadWorkerRequest({
@@ -40,14 +46,9 @@ describe("publish", () => {
40
46
  });
41
47
  await runWrangler("publish index.js --env some-env");
42
48
  expect(std.out).toMatchInlineSnapshot(`
43
- "Uploaded
44
- test-name-some-env
45
- (TIMINGS)
46
- Published
47
- test-name-some-env
48
- (TIMINGS)
49
-
50
- test-name-some-env.test-sub-domain.workers.dev"
49
+ "Uploaded test-name-some-env (TIMINGS)
50
+ Published test-name-some-env (TIMINGS)
51
+ test-name-some-env.test-sub-domain.workers.dev"
51
52
  `);
52
53
  expect(std.err).toMatchInlineSnapshot(`""`);
53
54
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -63,21 +64,16 @@ describe("publish", () => {
63
64
  });
64
65
  await runWrangler("publish index.js --legacy-env true");
65
66
  expect(std.out).toMatchInlineSnapshot(`
66
- "Uploaded
67
- test-name
68
- (TIMINGS)
69
- Published
70
- test-name
71
- (TIMINGS)
72
-
73
- test-name.test-sub-domain.workers.dev"
67
+ "Uploaded test-name (TIMINGS)
68
+ Published test-name (TIMINGS)
69
+ test-name.test-sub-domain.workers.dev"
74
70
  `);
75
71
  expect(std.err).toMatchInlineSnapshot(`""`);
76
72
  expect(std.warn).toMatchInlineSnapshot(`""`);
77
73
  });
78
74
 
79
- it("appends the environment name when provided", async () => {
80
- writeWranglerToml();
75
+ it("appends the environment name when provided, and there is associated config", async () => {
76
+ writeWranglerToml({ env: { "some-env": {} } });
81
77
  writeWorkerSource();
82
78
  mockSubDomainRequest();
83
79
  mockUploadWorkerRequest({
@@ -86,18 +82,77 @@ describe("publish", () => {
86
82
  });
87
83
  await runWrangler("publish index.js --env some-env --legacy-env true");
88
84
  expect(std.out).toMatchInlineSnapshot(`
89
- "Uploaded
90
- test-name-some-env
91
- (TIMINGS)
92
- Published
93
- test-name-some-env
94
- (TIMINGS)
95
-
96
- test-name-some-env.test-sub-domain.workers.dev"
85
+ "Uploaded test-name-some-env (TIMINGS)
86
+ Published test-name-some-env (TIMINGS)
87
+ test-name-some-env.test-sub-domain.workers.dev"
97
88
  `);
98
89
  expect(std.err).toMatchInlineSnapshot(`""`);
99
90
  expect(std.warn).toMatchInlineSnapshot(`""`);
100
91
  });
92
+
93
+ it("appends the environment name when provided (with a warning), if there are no configured environments", async () => {
94
+ writeWranglerToml({});
95
+ writeWorkerSource();
96
+ mockSubDomainRequest();
97
+ mockUploadWorkerRequest({
98
+ env: "some-env",
99
+ legacyEnv: true,
100
+ });
101
+ await runWrangler("publish index.js --env some-env --legacy-env true");
102
+ expect(std.out).toMatchInlineSnapshot(`
103
+ "Uploaded test-name-some-env (TIMINGS)
104
+ Published test-name-some-env (TIMINGS)
105
+ test-name-some-env.test-sub-domain.workers.dev"
106
+ `);
107
+ expect(std.err).toMatchInlineSnapshot(`""`);
108
+ expect(std.warn).toMatchInlineSnapshot(`
109
+ "Processing wrangler.toml configuration:
110
+ - No environment found in configuration with name \\"some-env\\".
111
+ Before using \`--env=some-env\` there should be an equivalent environment section in the configuration.
112
+
113
+ Consider adding an environment configuration section to the wrangler.toml file:
114
+ \`\`\`
115
+ [env.some-env]
116
+ \`\`\`
117
+ "
118
+ `);
119
+ });
120
+
121
+ it("should throw an error when an environment name when provided, which doesn't match those in the config", async () => {
122
+ writeWranglerToml({ env: { "other-env": {} } });
123
+ writeWorkerSource();
124
+ mockSubDomainRequest();
125
+ await expect(
126
+ runWrangler("publish index.js --env some-env --legacy-env true")
127
+ ).rejects.toThrowErrorMatchingInlineSnapshot(`
128
+ "Processing wrangler.toml configuration:
129
+ - No environment found in configuration with name \\"some-env\\".
130
+ Before using \`--env=some-env\` there should be an equivalent environment section in the configuration.
131
+ The available configured environment names are: [\\"other-env\\"]
132
+
133
+ Consider adding an environment configuration section to the wrangler.toml file:
134
+ \`\`\`
135
+ [env.some-env]
136
+ \`\`\`
137
+ "
138
+ `);
139
+ });
140
+
141
+ it("should throw an error w/ helpful message when using --env --name", async () => {
142
+ writeWranglerToml({ env: { "some-env": {} } });
143
+ writeWorkerSource();
144
+ mockSubDomainRequest();
145
+ await runWrangler(
146
+ "publish index.js --name voyager --env some-env --legacy-env true"
147
+ ).catch((err) =>
148
+ expect(err).toMatchInlineSnapshot(`
149
+ [Error: In legacy environment mode you cannot use --name and --env together. If you want to specify a Worker name for a specific environment you can add the following to your wrangler.toml config:
150
+ [env.some-env]
151
+ name = "voyager"
152
+ ]
153
+ `)
154
+ );
155
+ });
101
156
  });
102
157
 
103
158
  describe("services", () => {
@@ -110,21 +165,16 @@ describe("publish", () => {
110
165
  });
111
166
  await runWrangler("publish index.js");
112
167
  expect(std.out).toMatchInlineSnapshot(`
113
- "Uploaded
114
- test-name
115
- (TIMINGS)
116
- Published
117
- test-name
118
- (TIMINGS)
119
-
120
- test-name.test-sub-domain.workers.dev"
168
+ "Uploaded test-name (TIMINGS)
169
+ Published test-name (TIMINGS)
170
+ test-name.test-sub-domain.workers.dev"
121
171
  `);
122
172
  expect(std.err).toMatchInlineSnapshot(`""`);
123
173
  expect(std.warn).toMatchInlineSnapshot(`""`);
124
174
  });
125
175
 
126
176
  it("publishes as an environment when provided", async () => {
127
- writeWranglerToml();
177
+ writeWranglerToml({ env: { "some-env": {} } });
128
178
  writeWorkerSource();
129
179
  mockSubDomainRequest();
130
180
  mockUploadWorkerRequest({
@@ -133,14 +183,9 @@ describe("publish", () => {
133
183
  });
134
184
  await runWrangler("publish index.js --env some-env --legacy-env false");
135
185
  expect(std.out).toMatchInlineSnapshot(`
136
- "Uploaded
137
- test-name (some-env)
138
- (TIMINGS)
139
- Published
140
- test-name (some-env)
141
- (TIMINGS)
142
-
143
- some-env.test-name.test-sub-domain.workers.dev"
186
+ "Uploaded test-name (some-env) (TIMINGS)
187
+ Published test-name (some-env) (TIMINGS)
188
+ some-env.test-name.test-sub-domain.workers.dev"
144
189
  `);
145
190
  expect(std.err).toMatchInlineSnapshot(`""`);
146
191
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -168,18 +213,14 @@ describe("publish", () => {
168
213
  type: "json",
169
214
  },
170
215
  ],
216
+ expectedCompatibilityDate: "2022-01-12",
171
217
  });
172
218
  mockSubDomainRequest();
173
219
  await runWrangler("publish ./some-path/worker/index.js");
174
220
  expect(std.out).toMatchInlineSnapshot(`
175
- "Uploaded
176
- test-name
177
- (TIMINGS)
178
- Published
179
- test-name
180
- (TIMINGS)
181
-
182
- test-name.test-sub-domain.workers.dev"
221
+ "Uploaded test-name (TIMINGS)
222
+ Published test-name (TIMINGS)
223
+ test-name.test-sub-domain.workers.dev"
183
224
  `);
184
225
  expect(std.err).toMatchInlineSnapshot(`""`);
185
226
  });
@@ -255,14 +296,9 @@ describe("publish", () => {
255
296
  await runWrangler("publish ./index");
256
297
 
257
298
  expect(std.out).toMatchInlineSnapshot(`
258
- "Uploaded
259
- test-name
260
- (TIMINGS)
261
- Published
262
- test-name
263
- (TIMINGS)
264
-
265
- test-name.test-sub-domain.workers.dev"
299
+ "Uploaded test-name (TIMINGS)
300
+ Published test-name (TIMINGS)
301
+ test-name.test-sub-domain.workers.dev"
266
302
  `);
267
303
  expect(std.err).toMatchInlineSnapshot(`""`);
268
304
  });
@@ -276,14 +312,9 @@ describe("publish", () => {
276
312
  await runWrangler("publish ./index");
277
313
 
278
314
  expect(std.out).toMatchInlineSnapshot(`
279
- "Uploaded
280
- test-name
281
- (TIMINGS)
282
- Published
283
- test-name
284
- (TIMINGS)
285
-
286
- test-name.test-sub-domain.workers.dev"
315
+ "Uploaded test-name (TIMINGS)
316
+ Published test-name (TIMINGS)
317
+ test-name.test-sub-domain.workers.dev"
287
318
  `);
288
319
  expect(std.err).toMatchInlineSnapshot(`""`);
289
320
  });
@@ -297,14 +328,9 @@ describe("publish", () => {
297
328
  await runWrangler("publish");
298
329
 
299
330
  expect(std.out).toMatchInlineSnapshot(`
300
- "Uploaded
301
- test-name
302
- (TIMINGS)
303
- Published
304
- test-name
305
- (TIMINGS)
306
-
307
- test-name.test-sub-domain.workers.dev"
331
+ "Uploaded test-name (TIMINGS)
332
+ Published test-name (TIMINGS)
333
+ test-name.test-sub-domain.workers.dev"
308
334
  `);
309
335
  expect(std.err).toMatchInlineSnapshot(`""`);
310
336
  });
@@ -320,14 +346,9 @@ describe("publish", () => {
320
346
  await runWrangler("publish");
321
347
 
322
348
  expect(std.out).toMatchInlineSnapshot(`
323
- "Uploaded
324
- test-name
325
- (TIMINGS)
326
- Published
327
- test-name
328
- (TIMINGS)
329
-
330
- test-name.test-sub-domain.workers.dev"
349
+ "Uploaded test-name (TIMINGS)
350
+ Published test-name (TIMINGS)
351
+ test-name.test-sub-domain.workers.dev"
331
352
  `);
332
353
  expect(std.err).toMatchInlineSnapshot(`""`);
333
354
  });
@@ -341,14 +362,9 @@ describe("publish", () => {
341
362
  await runWrangler("publish");
342
363
 
343
364
  expect(std.out).toMatchInlineSnapshot(`
344
- "Uploaded
345
- test-name
346
- (TIMINGS)
347
- Published
348
- test-name
349
- (TIMINGS)
350
-
351
- test-name.test-sub-domain.workers.dev"
365
+ "Uploaded test-name (TIMINGS)
366
+ Published test-name (TIMINGS)
367
+ test-name.test-sub-domain.workers.dev"
352
368
  `);
353
369
  expect(std.err).toMatchInlineSnapshot(`""`);
354
370
  expect(std.warn).toMatchInlineSnapshot(`
@@ -378,14 +394,9 @@ describe("publish", () => {
378
394
  await runWrangler("publish");
379
395
 
380
396
  expect(std.out).toMatchInlineSnapshot(`
381
- "Uploaded
382
- test-name
383
- (TIMINGS)
384
- Published
385
- test-name
386
- (TIMINGS)
387
-
388
- test-name.test-sub-domain.workers.dev"
397
+ "Uploaded test-name (TIMINGS)
398
+ Published test-name (TIMINGS)
399
+ test-name.test-sub-domain.workers.dev"
389
400
  `);
390
401
  expect(std.err).toMatchInlineSnapshot(`""`);
391
402
  expect(std.warn).toMatchInlineSnapshot(`
@@ -428,14 +439,9 @@ describe("publish", () => {
428
439
  await runWrangler("publish index.ts");
429
440
 
430
441
  expect(std.out).toMatchInlineSnapshot(`
431
- "Uploaded
432
- test-name
433
- (TIMINGS)
434
- Published
435
- test-name
436
- (TIMINGS)
437
-
438
- test-name.test-sub-domain.workers.dev"
442
+ "Uploaded test-name (TIMINGS)
443
+ Published test-name (TIMINGS)
444
+ test-name.test-sub-domain.workers.dev"
439
445
  `);
440
446
  expect(std.err).toMatchInlineSnapshot(`""`);
441
447
  });
@@ -451,14 +457,9 @@ describe("publish", () => {
451
457
  await runWrangler("publish index.ts");
452
458
 
453
459
  expect(std.out).toMatchInlineSnapshot(`
454
- "Uploaded
455
- test-name
456
- (TIMINGS)
457
- Published
458
- test-name
459
- (TIMINGS)
460
-
461
- test-name.test-sub-domain.workers.dev"
460
+ "Uploaded test-name (TIMINGS)
461
+ Published test-name (TIMINGS)
462
+ test-name.test-sub-domain.workers.dev"
462
463
  `);
463
464
  expect(std.err).toMatchInlineSnapshot(`""`);
464
465
  });
@@ -486,14 +487,9 @@ export default{
486
487
  mockSubDomainRequest();
487
488
  await runWrangler("publish index.js");
488
489
  expect(std.out).toMatchInlineSnapshot(`
489
- "Uploaded
490
- test-name
491
- (TIMINGS)
492
- Published
493
- test-name
494
- (TIMINGS)
495
-
496
- test-name.test-sub-domain.workers.dev"
490
+ "Uploaded test-name (TIMINGS)
491
+ Published test-name (TIMINGS)
492
+ test-name.test-sub-domain.workers.dev"
497
493
  `);
498
494
  expect(std.err).toMatchInlineSnapshot(`""`);
499
495
  });
@@ -507,14 +503,9 @@ export default{
507
503
  await runWrangler("publish ./src/index.js");
508
504
 
509
505
  expect(std.out).toMatchInlineSnapshot(`
510
- "Uploaded
511
- test-name
512
- (TIMINGS)
513
- Published
514
- test-name
515
- (TIMINGS)
516
-
517
- test-name.test-sub-domain.workers.dev"
506
+ "Uploaded test-name (TIMINGS)
507
+ Published test-name (TIMINGS)
508
+ test-name.test-sub-domain.workers.dev"
518
509
  `);
519
510
  expect(std.err).toMatchInlineSnapshot(`""`);
520
511
  });
@@ -531,23 +522,17 @@ export default{
531
522
  await runWrangler("publish ./src/index.js");
532
523
 
533
524
  expect(std.out).toMatchInlineSnapshot(`
534
- "Uploaded
535
- test-name
536
- (TIMINGS)
537
- Published
538
- test-name
539
- (TIMINGS)
540
-
541
- test-name.test-sub-domain.workers.dev"
525
+ "Uploaded test-name (TIMINGS)
526
+ Published test-name (TIMINGS)
527
+ test-name.test-sub-domain.workers.dev"
542
528
  `);
543
529
  expect(std.err).toMatchInlineSnapshot(`""`);
544
530
  });
545
531
 
546
532
  it('should error if a site definition doesn\'t have a "bucket" field', async () => {
547
533
  writeWranglerToml({
548
- site: {
549
- "entry-point": "./index.js",
550
- } as Config["site"],
534
+ // @ts-expect-error we're intentionally setting an invalid config
535
+ site: {},
551
536
  });
552
537
  writeWorkerSource();
553
538
  mockUploadWorkerRequest();
@@ -556,21 +541,20 @@ export default{
556
541
  await expect(runWrangler("publish ./index.js")).rejects
557
542
  .toThrowErrorMatchingInlineSnapshot(`
558
543
  "Processing wrangler.toml configuration:
559
- - ERROR: \\"site.bucket\\" is a required field."
544
+ - \\"site.bucket\\" is a required field."
560
545
  `);
561
546
 
562
547
  expect(std.out).toMatchInlineSnapshot(`""`);
563
548
  expect(std.err).toMatchInlineSnapshot(`
564
549
  "Processing wrangler.toml configuration:
565
- - ERROR: \\"site.bucket\\" is a required field.
550
+ - \\"site.bucket\\" is a required field.
566
551
 
567
- %s
568
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
552
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
569
553
  `);
570
554
  expect(std.warn).toMatchInlineSnapshot(`""`);
571
555
  });
572
556
 
573
- it("should warn if there is a `site.entry-point` configuration", async () => {
557
+ it("should error if there is a `site.entry-point` configuration", async () => {
574
558
  const assets = [
575
559
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
576
560
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
@@ -594,27 +578,26 @@ export default{
594
578
  mockKeyListRequest(kvNamespace.id, []);
595
579
  mockUploadAssetsToKVRequest(kvNamespace.id, assets);
596
580
 
597
- await runWrangler("publish ./index.js");
581
+ await expect(runWrangler("publish ./index.js")).rejects
582
+ .toThrowErrorMatchingInlineSnapshot(`
583
+ "Processing wrangler.toml configuration:
584
+ - DEPRECATION: \\"site.entry-point\\":
585
+ The \`site.entry-point\` config field is no longer used.
586
+ The entry-point should be specified via the command line or the \`main\` config field."
587
+ `);
598
588
 
599
- expect(std.out).toMatchInlineSnapshot(`
600
- "reading assets/file-1.txt...
601
- uploading as assets/file-1.2ca234f380.txt...
602
- reading assets/file-2.txt...
603
- uploading as assets/file-2.5938485188.txt...
604
- Uploaded
605
- test-name
606
- (TIMINGS)
607
- Published
608
- test-name
609
- (TIMINGS)
589
+ expect(std.out).toMatchInlineSnapshot(`""`);
590
+ expect(std.err).toMatchInlineSnapshot(`
591
+ "Processing wrangler.toml configuration:
592
+ - DEPRECATION: \\"site.entry-point\\":
593
+ The \`site.entry-point\` config field is no longer used.
594
+ The entry-point should be specified via the command line or the \`main\` config field.
610
595
 
611
- test-name.test-sub-domain.workers.dev"
596
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
612
597
  `);
613
- expect(std.err).toMatchInlineSnapshot(`""`);
614
598
  expect(std.warn).toMatchInlineSnapshot(`
615
- "Deprecation notice: The \`site.entry-point\` config field is no longer used.
616
- The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
617
- Please remove the \`site.entry-point\` field from the \`wrangler.toml\` file."
599
+ "Processing wrangler.toml configuration:
600
+ - Unexpected fields found in site field: \\"entry-point\\""
618
601
  `);
619
602
  });
620
603
 
@@ -633,8 +616,7 @@ export default{
633
616
  expect(std.err).toMatchInlineSnapshot(`
634
617
  "Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
635
618
 
636
- %s
637
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
619
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
638
620
  `);
639
621
  });
640
622
  });
@@ -669,14 +651,10 @@ export default{
669
651
  uploading as assets/file-1.2ca234f380.txt...
670
652
  reading assets/file-2.txt...
671
653
  uploading as assets/file-2.5938485188.txt...
672
- Uploaded
673
- test-name
674
- (TIMINGS)
675
- Published
676
- test-name
677
- (TIMINGS)
678
-
679
- test-name.test-sub-domain.workers.dev"
654
+ ↗️ Done syncing assets
655
+ Uploaded test-name (TIMINGS)
656
+ Published test-name (TIMINGS)
657
+ test-name.test-sub-domain.workers.dev"
680
658
  `);
681
659
  expect(std.err).toMatchInlineSnapshot(`""`);
682
660
  });
@@ -729,14 +707,10 @@ export default{
729
707
  uploading as assets/file-1.2ca234f380.txt...
730
708
  reading assets/file-2.txt...
731
709
  uploading as assets/file-2.5938485188.txt...
732
- Uploaded
733
- test-name
734
- (TIMINGS)
735
- Published
736
- test-name
737
- (TIMINGS)
738
-
739
- test-name.test-sub-domain.workers.dev"
710
+ ↗️ Done syncing assets
711
+ Uploaded test-name (TIMINGS)
712
+ Published test-name (TIMINGS)
713
+ test-name.test-sub-domain.workers.dev"
740
714
  `);
741
715
  expect(std.err).toMatchInlineSnapshot(`""`);
742
716
  });
@@ -783,14 +757,10 @@ export default{
783
757
  uploading as assets/file-1.2ca234f380.txt...
784
758
  reading assets/file-2.txt...
785
759
  uploading as assets/file-2.5938485188.txt...
786
- Uploaded
787
- test-name
788
- (TIMINGS)
789
- Published
790
- test-name
791
- (TIMINGS)
792
-
793
- test-name.test-sub-domain.workers.dev"
760
+ ↗️ Done syncing assets
761
+ Uploaded test-name (TIMINGS)
762
+ Published test-name (TIMINGS)
763
+ test-name.test-sub-domain.workers.dev"
794
764
  `);
795
765
  expect(std.err).toMatchInlineSnapshot(`""`);
796
766
  });
@@ -810,6 +780,7 @@ export default{
810
780
  site: {
811
781
  bucket: "assets",
812
782
  },
783
+ env: { "some-env": {} },
813
784
  });
814
785
  writeWorkerSource();
815
786
  writeAssets(assets);
@@ -834,14 +805,10 @@ export default{
834
805
  uploading as assets/file-1.2ca234f380.txt...
835
806
  reading assets/file-2.txt...
836
807
  uploading as assets/file-2.5938485188.txt...
837
- Uploaded
838
- test-name (some-env)
839
- (TIMINGS)
840
- Published
841
- test-name (some-env)
842
- (TIMINGS)
843
-
844
- some-env.test-name.test-sub-domain.workers.dev"
808
+ ↗️ Done syncing assets
809
+ Uploaded test-name (some-env) (TIMINGS)
810
+ Published test-name (some-env) (TIMINGS)
811
+ some-env.test-name.test-sub-domain.workers.dev"
845
812
  `);
846
813
  expect(std.err).toMatchInlineSnapshot(`""`);
847
814
  });
@@ -861,6 +828,7 @@ export default{
861
828
  site: {
862
829
  bucket: "assets",
863
830
  },
831
+ env: { "some-env": {} },
864
832
  });
865
833
  writeWorkerSource();
866
834
  writeAssets(assets);
@@ -886,14 +854,10 @@ export default{
886
854
  uploading as assets/file-1.2ca234f380.txt...
887
855
  reading assets/file-2.txt...
888
856
  uploading as assets/file-2.5938485188.txt...
889
- Uploaded
890
- test-name-some-env
891
- (TIMINGS)
892
- Published
893
- test-name-some-env
894
- (TIMINGS)
895
-
896
- test-name-some-env.test-sub-domain.workers.dev"
857
+ ↗️ Done syncing assets
858
+ Uploaded test-name-some-env (TIMINGS)
859
+ Published test-name-some-env (TIMINGS)
860
+ test-name-some-env.test-sub-domain.workers.dev"
897
861
  `);
898
862
  expect(std.err).toMatchInlineSnapshot(`""`);
899
863
  });
@@ -919,7 +883,9 @@ export default{
919
883
  mockSubDomainRequest();
920
884
  mockListKVNamespacesRequest(kvNamespace);
921
885
  // Put file-1 in the KV namespace
922
- mockKeyListRequest(kvNamespace.id, ["assets/file-1.2ca234f380.txt"]);
886
+ mockKeyListRequest(kvNamespace.id, [
887
+ { name: "assets/file-1.2ca234f380.txt" },
888
+ ]);
923
889
  // Check we do not upload file-1
924
890
  mockUploadAssetsToKVRequest(
925
891
  kvNamespace.id,
@@ -932,14 +898,10 @@ export default{
932
898
  skipping - already uploaded
933
899
  reading assets/file-2.txt...
934
900
  uploading as assets/file-2.5938485188.txt...
935
- Uploaded
936
- test-name
937
- (TIMINGS)
938
- Published
939
- test-name
940
- (TIMINGS)
941
-
942
- test-name.test-sub-domain.workers.dev"
901
+ ↗️ Done syncing assets
902
+ Uploaded test-name (TIMINGS)
903
+ Published test-name (TIMINGS)
904
+ test-name.test-sub-domain.workers.dev"
943
905
  `);
944
906
  expect(std.err).toMatchInlineSnapshot(`""`);
945
907
  });
@@ -975,14 +937,10 @@ export default{
975
937
  expect(std.out).toMatchInlineSnapshot(`
976
938
  "reading assets/file-1.txt...
977
939
  uploading as assets/file-1.2ca234f380.txt...
978
- Uploaded
979
- test-name
980
- (TIMINGS)
981
- Published
982
- test-name
983
- (TIMINGS)
984
-
985
- test-name.test-sub-domain.workers.dev"
940
+ ↗️ Done syncing assets
941
+ Uploaded test-name (TIMINGS)
942
+ Published test-name (TIMINGS)
943
+ test-name.test-sub-domain.workers.dev"
986
944
  `);
987
945
  expect(std.err).toMatchInlineSnapshot(`""`);
988
946
  });
@@ -1018,14 +976,10 @@ export default{
1018
976
  expect(std.out).toMatchInlineSnapshot(`
1019
977
  "reading assets/file-1.txt...
1020
978
  uploading as assets/file-1.2ca234f380.txt...
1021
- Uploaded
1022
- test-name
1023
- (TIMINGS)
1024
- Published
1025
- test-name
1026
- (TIMINGS)
1027
-
1028
- test-name.test-sub-domain.workers.dev"
979
+ ↗️ Done syncing assets
980
+ Uploaded test-name (TIMINGS)
981
+ Published test-name (TIMINGS)
982
+ test-name.test-sub-domain.workers.dev"
1029
983
  `);
1030
984
  expect(std.err).toMatchInlineSnapshot(`""`);
1031
985
  });
@@ -1062,14 +1016,10 @@ export default{
1062
1016
  expect(std.out).toMatchInlineSnapshot(`
1063
1017
  "reading assets/file-1.txt...
1064
1018
  uploading as assets/file-1.2ca234f380.txt...
1065
- Uploaded
1066
- test-name
1067
- (TIMINGS)
1068
- Published
1069
- test-name
1070
- (TIMINGS)
1071
-
1072
- test-name.test-sub-domain.workers.dev"
1019
+ ↗️ Done syncing assets
1020
+ Uploaded test-name (TIMINGS)
1021
+ Published test-name (TIMINGS)
1022
+ test-name.test-sub-domain.workers.dev"
1073
1023
  `);
1074
1024
  expect(std.err).toMatchInlineSnapshot(`""`);
1075
1025
  });
@@ -1106,14 +1056,10 @@ export default{
1106
1056
  expect(std.out).toMatchInlineSnapshot(`
1107
1057
  "reading assets/file-1.txt...
1108
1058
  uploading as assets/file-1.2ca234f380.txt...
1109
- Uploaded
1110
- test-name
1111
- (TIMINGS)
1112
- Published
1113
- test-name
1114
- (TIMINGS)
1115
-
1116
- test-name.test-sub-domain.workers.dev"
1059
+ ↗️ Done syncing assets
1060
+ Uploaded test-name (TIMINGS)
1061
+ Published test-name (TIMINGS)
1062
+ test-name.test-sub-domain.workers.dev"
1117
1063
  `);
1118
1064
  expect(std.err).toMatchInlineSnapshot(`""`);
1119
1065
  });
@@ -1150,14 +1096,10 @@ export default{
1150
1096
  expect(std.out).toMatchInlineSnapshot(`
1151
1097
  "reading assets/file-1.txt...
1152
1098
  uploading as assets/file-1.2ca234f380.txt...
1153
- Uploaded
1154
- test-name
1155
- (TIMINGS)
1156
- Published
1157
- test-name
1158
- (TIMINGS)
1159
-
1160
- test-name.test-sub-domain.workers.dev"
1099
+ ↗️ Done syncing assets
1100
+ Uploaded test-name (TIMINGS)
1101
+ Published test-name (TIMINGS)
1102
+ test-name.test-sub-domain.workers.dev"
1161
1103
  `);
1162
1104
  expect(std.err).toMatchInlineSnapshot(`""`);
1163
1105
  });
@@ -1194,14 +1136,10 @@ export default{
1194
1136
  expect(std.out).toMatchInlineSnapshot(`
1195
1137
  "reading assets/file-1.txt...
1196
1138
  uploading as assets/file-1.2ca234f380.txt...
1197
- Uploaded
1198
- test-name
1199
- (TIMINGS)
1200
- Published
1201
- test-name
1202
- (TIMINGS)
1203
-
1204
- test-name.test-sub-domain.workers.dev"
1139
+ ↗️ Done syncing assets
1140
+ Uploaded test-name (TIMINGS)
1141
+ Published test-name (TIMINGS)
1142
+ test-name.test-sub-domain.workers.dev"
1205
1143
  `);
1206
1144
  expect(std.err).toMatchInlineSnapshot(`""`);
1207
1145
  });
@@ -1240,14 +1178,10 @@ export default{
1240
1178
  expect(std.out).toMatchInlineSnapshot(`
1241
1179
  "reading assets/directory-1/file-1.txt...
1242
1180
  uploading as assets/directory-1/file-1.2ca234f380.txt...
1243
- Uploaded
1244
- test-name
1245
- (TIMINGS)
1246
- Published
1247
- test-name
1248
- (TIMINGS)
1249
-
1250
- test-name.test-sub-domain.workers.dev"
1181
+ ↗️ Done syncing assets
1182
+ Uploaded test-name (TIMINGS)
1183
+ Published test-name (TIMINGS)
1184
+ test-name.test-sub-domain.workers.dev"
1251
1185
  `);
1252
1186
  expect(std.err).toMatchInlineSnapshot(`""`);
1253
1187
  });
@@ -1290,14 +1224,10 @@ export default{
1290
1224
  expect(std.out).toMatchInlineSnapshot(`
1291
1225
  "reading assets/.well-known/file-2.txt...
1292
1226
  uploading as assets/.well-known/file-2.5938485188.txt...
1293
- Uploaded
1294
- test-name
1295
- (TIMINGS)
1296
- Published
1297
- test-name
1298
- (TIMINGS)
1299
-
1300
- test-name.test-sub-domain.workers.dev"
1227
+ ↗️ Done syncing assets
1228
+ Uploaded test-name (TIMINGS)
1229
+ Published test-name (TIMINGS)
1230
+ test-name.test-sub-domain.workers.dev"
1301
1231
  `);
1302
1232
  expect(std.err).toMatchInlineSnapshot(`""`);
1303
1233
  });
@@ -1345,8 +1275,7 @@ export default{
1345
1275
  expect(std.err).toMatchInlineSnapshot(`
1346
1276
  "File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits
1347
1277
 
1348
- %s
1349
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1278
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1350
1279
  `);
1351
1280
  });
1352
1281
 
@@ -1384,9 +1313,64 @@ export default{
1384
1313
  expect(std.err).toMatchInlineSnapshot(`
1385
1314
  "The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\",
1386
1315
 
1387
- %s
1388
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1316
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1317
+ `);
1318
+ });
1319
+
1320
+ it("should delete uploaded assets that aren't included anymore", async () => {
1321
+ const assets = [
1322
+ { filePath: "assets/file-1.txt", content: "Content of file-1" },
1323
+ { filePath: "assets/file-2.txt", content: "Content of file-2" },
1324
+ ];
1325
+ const kvNamespace = {
1326
+ title: "__test-name-workers_sites_assets",
1327
+ id: "__test-name-workers_sites_assets-id",
1328
+ };
1329
+ writeWranglerToml({
1330
+ main: "./index.js",
1331
+ site: {
1332
+ bucket: "assets",
1333
+ },
1334
+ });
1335
+ writeWorkerSource();
1336
+ writeAssets(assets);
1337
+ mockUploadWorkerRequest();
1338
+ mockSubDomainRequest();
1339
+ mockListKVNamespacesRequest(kvNamespace);
1340
+ mockKeyListRequest(kvNamespace.id, [
1341
+ // Put file-1 in the KV namespace
1342
+ { name: "assets/file-1.2ca234f380.txt" },
1343
+ // As well as a couple from a previous upload
1344
+ { name: "assets/file-3.somehash.txt" },
1345
+ { name: "assets/file-4.anotherhash.txt" },
1346
+ ]);
1347
+
1348
+ // we upload only file-1.txt
1349
+ mockUploadAssetsToKVRequest(kvNamespace.id, [
1350
+ ...assets.filter((a) => a.filePath !== "assets/file-1.txt"),
1351
+ ]);
1352
+
1353
+ // and mark file-3 and file-4 for deletion
1354
+ mockDeleteUnusedAssetsRequest(kvNamespace.id, [
1355
+ "assets/file-3.somehash.txt",
1356
+ "assets/file-4.anotherhash.txt",
1357
+ ]);
1358
+
1359
+ await runWrangler("publish");
1360
+
1361
+ expect(std.out).toMatchInlineSnapshot(`
1362
+ "reading assets/file-1.txt...
1363
+ skipping - already uploaded
1364
+ reading assets/file-2.txt...
1365
+ uploading as assets/file-2.5938485188.txt...
1366
+ deleting assets/file-3.somehash.txt from the asset store...
1367
+ deleting assets/file-4.anotherhash.txt from the asset store...
1368
+ ↗️ Done syncing assets
1369
+ Uploaded test-name (TIMINGS)
1370
+ Published test-name (TIMINGS)
1371
+ test-name.test-sub-domain.workers.dev"
1389
1372
  `);
1373
+ expect(std.err).toMatchInlineSnapshot(`""`);
1390
1374
  });
1391
1375
  });
1392
1376
 
@@ -1400,14 +1384,9 @@ export default{
1400
1384
  await runWrangler("publish ./index");
1401
1385
 
1402
1386
  expect(std.out).toMatchInlineSnapshot(`
1403
- "Uploaded
1404
- test-name
1405
- (TIMINGS)
1406
- Published
1407
- test-name
1408
- (TIMINGS)
1409
-
1410
- test-name.test-sub-domain.workers.dev"
1387
+ "Uploaded test-name (TIMINGS)
1388
+ Published test-name (TIMINGS)
1389
+ test-name.test-sub-domain.workers.dev"
1411
1390
  `);
1412
1391
  expect(std.err).toMatchInlineSnapshot(`""`);
1413
1392
  });
@@ -1423,14 +1402,9 @@ export default{
1423
1402
  await runWrangler("publish ./index");
1424
1403
 
1425
1404
  expect(std.out).toMatchInlineSnapshot(`
1426
- "Uploaded
1427
- test-name
1428
- (TIMINGS)
1429
- Published
1430
- test-name
1431
- (TIMINGS)
1432
-
1433
- test-name.test-sub-domain.workers.dev"
1405
+ "Uploaded test-name (TIMINGS)
1406
+ Published test-name (TIMINGS)
1407
+ test-name.test-sub-domain.workers.dev"
1434
1408
  `);
1435
1409
  expect(std.err).toMatchInlineSnapshot(`""`);
1436
1410
  });
@@ -1441,534 +1415,1522 @@ export default{
1441
1415
  });
1442
1416
  writeWorkerSource();
1443
1417
  mockUploadWorkerRequest();
1444
- mockSubDomainRequest();
1445
1418
  mockUpdateWorkerRequest({ enabled: false });
1446
1419
 
1447
1420
  await runWrangler("publish ./index");
1448
1421
 
1449
1422
  expect(std.out).toMatchInlineSnapshot(`
1450
- "Uploaded
1451
- test-name
1452
- (TIMINGS)
1453
- No publish targets for
1454
- test-name
1455
- (TIMINGS)"
1423
+ "Uploaded test-name (TIMINGS)
1424
+ No publish targets for test-name (TIMINGS)"
1456
1425
  `);
1457
1426
  expect(std.err).toMatchInlineSnapshot(`""`);
1458
1427
  });
1459
1428
 
1460
- it("should enable the workers.dev domain if workers_dev is undefined and subdomain is not already available", async () => {
1461
- writeWranglerToml();
1429
+ it("should disable the workers.dev domain if workers_dev is undefined but overwritten to `false` in environment", async () => {
1430
+ writeWranglerToml({
1431
+ env: {
1432
+ dev: {
1433
+ workers_dev: false,
1434
+ },
1435
+ },
1436
+ });
1462
1437
  writeWorkerSource();
1463
- mockUploadWorkerRequest({ available_on_subdomain: false });
1464
- mockSubDomainRequest();
1465
- mockUpdateWorkerRequest({ enabled: true });
1438
+ mockUploadWorkerRequest({
1439
+ env: "dev",
1440
+ });
1441
+ mockUpdateWorkerRequest({ enabled: false, env: "dev" });
1466
1442
 
1467
- await runWrangler("publish ./index");
1443
+ await runWrangler("publish ./index --env dev --legacy-env false");
1468
1444
 
1469
1445
  expect(std.out).toMatchInlineSnapshot(`
1470
- "Uploaded
1471
- test-name
1472
- (TIMINGS)
1473
- Published
1474
- test-name
1475
- (TIMINGS)
1476
-
1477
- test-name.test-sub-domain.workers.dev"
1446
+ "Uploaded test-name (dev) (TIMINGS)
1447
+ No publish targets for test-name (dev) (TIMINGS)"
1478
1448
  `);
1479
1449
  expect(std.err).toMatchInlineSnapshot(`""`);
1480
1450
  });
1481
1451
 
1482
- it("should enable the workers.dev domain if workers_dev is true and subdomain is not already available", async () => {
1483
- writeWranglerToml({ workers_dev: true });
1452
+ it("should disable the workers.dev domain if workers_dev is `true` but overwritten to `false` in environment", async () => {
1453
+ writeWranglerToml({
1454
+ workers_dev: true,
1455
+ env: {
1456
+ dev: {
1457
+ workers_dev: false,
1458
+ },
1459
+ },
1460
+ });
1484
1461
  writeWorkerSource();
1485
- mockUploadWorkerRequest({ available_on_subdomain: false });
1486
- mockSubDomainRequest();
1487
- mockUpdateWorkerRequest({ enabled: true });
1462
+ mockUploadWorkerRequest({
1463
+ env: "dev",
1464
+ });
1465
+ mockUpdateWorkerRequest({ enabled: false, env: "dev" });
1488
1466
 
1489
- await runWrangler("publish ./index");
1467
+ await runWrangler("publish ./index --env dev --legacy-env false");
1490
1468
 
1491
1469
  expect(std.out).toMatchInlineSnapshot(`
1492
- "Uploaded
1493
- test-name
1494
- (TIMINGS)
1495
- Published
1496
- test-name
1497
- (TIMINGS)
1498
-
1499
- test-name.test-sub-domain.workers.dev"
1470
+ "Uploaded test-name (dev) (TIMINGS)
1471
+ No publish targets for test-name (dev) (TIMINGS)"
1500
1472
  `);
1501
1473
  expect(std.err).toMatchInlineSnapshot(`""`);
1502
1474
  });
1503
- });
1504
1475
 
1505
- describe("custom builds", () => {
1506
- beforeEach(() => {
1507
- // @ts-expect-error disable the mock we'd setup earlier
1508
- // or else custom builds will timeout immediately
1509
- global.setTimeout.mockRestore();
1510
- });
1511
- it("should run a custom build before publishing", async () => {
1476
+ it("should publish to a workers.dev domain if workers_dev is undefined but overwritten to `true` in environment", async () => {
1512
1477
  writeWranglerToml({
1513
- build: {
1514
- command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
1478
+ env: {
1479
+ dev: {
1480
+ workers_dev: true,
1481
+ },
1515
1482
  },
1516
1483
  });
1517
-
1484
+ writeWorkerSource();
1518
1485
  mockUploadWorkerRequest({
1519
- expectedEntry: "return new Response(123)",
1486
+ env: "dev",
1520
1487
  });
1521
1488
  mockSubDomainRequest();
1489
+ mockUpdateWorkerRequest({ enabled: true, env: "dev" });
1522
1490
 
1523
- await runWrangler("publish index.js");
1524
- expect(std.out).toMatchInlineSnapshot(`
1525
- "running:
1526
- node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\"
1527
- Uploaded
1528
- test-name
1529
- (TIMINGS)
1530
- Published
1531
- test-name
1532
- (TIMINGS)
1491
+ await runWrangler("publish ./index --env dev --legacy-env false");
1533
1492
 
1534
- test-name.test-sub-domain.workers.dev"
1493
+ expect(std.out).toMatchInlineSnapshot(`
1494
+ "Uploaded test-name (dev) (TIMINGS)
1495
+ Published test-name (dev) (TIMINGS)
1496
+ dev.test-name.test-sub-domain.workers.dev"
1535
1497
  `);
1536
1498
  expect(std.err).toMatchInlineSnapshot(`""`);
1537
- expect(std.warn).toMatchInlineSnapshot(`""`);
1538
1499
  });
1539
1500
 
1540
- if (process.platform !== "win32") {
1541
- it("should run a custom build of multiple steps combined by && before publishing", async () => {
1542
- writeWranglerToml({
1543
- build: {
1544
- command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
1545
- },
1546
- });
1547
-
1548
- mockUploadWorkerRequest({
1549
- expectedEntry: "return new Response(123)",
1550
- });
1551
- mockSubDomainRequest();
1552
-
1553
- await runWrangler("publish index.js");
1554
- expect(std.out).toMatchInlineSnapshot(`
1555
- "running:
1556
- echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js
1557
- Uploaded
1558
- test-name
1559
- (TIMINGS)
1560
- Published
1561
- test-name
1562
- (TIMINGS)
1563
-
1564
- test-name.test-sub-domain.workers.dev"
1565
- `);
1566
- expect(std.err).toMatchInlineSnapshot(`""`);
1567
- expect(std.warn).toMatchInlineSnapshot(`""`);
1568
- });
1569
- }
1570
- });
1571
-
1572
- describe("[wasm_modules]", () => {
1573
- it("should be able to define wasm modules for service-worker format workers", async () => {
1501
+ it("should publish to a workers.dev domain if workers_dev is `false` but overwritten to `true` in environment", async () => {
1574
1502
  writeWranglerToml({
1575
- wasm_modules: {
1576
- TESTWASMNAME: "./path/to/test.wasm",
1503
+ workers_dev: false,
1504
+ env: {
1505
+ dev: {
1506
+ workers_dev: true,
1507
+ },
1577
1508
  },
1578
1509
  });
1579
- writeWorkerSource({ type: "sw" });
1580
- fs.mkdirSync("./path/to", { recursive: true });
1581
- fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1510
+ writeWorkerSource();
1582
1511
  mockUploadWorkerRequest({
1583
- expectedType: "sw",
1584
- expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1585
- expectedBindings: [
1586
- { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1587
- ],
1512
+ env: "dev",
1588
1513
  });
1589
1514
  mockSubDomainRequest();
1590
- await runWrangler("publish index.js");
1591
- expect(std.out).toMatchInlineSnapshot(`
1592
- "Uploaded
1593
- test-name
1594
- (TIMINGS)
1595
- Published
1596
- test-name
1597
- (TIMINGS)
1515
+ mockUpdateWorkerRequest({ enabled: true, env: "dev" });
1598
1516
 
1599
- test-name.test-sub-domain.workers.dev"
1517
+ await runWrangler("publish ./index --env dev --legacy-env false");
1518
+
1519
+ expect(std.out).toMatchInlineSnapshot(`
1520
+ "Uploaded test-name (dev) (TIMINGS)
1521
+ Published test-name (dev) (TIMINGS)
1522
+ dev.test-name.test-sub-domain.workers.dev"
1600
1523
  `);
1601
1524
  expect(std.err).toMatchInlineSnapshot(`""`);
1602
- expect(std.warn).toMatchInlineSnapshot(`""`);
1603
1525
  });
1604
1526
 
1605
- it("should error when defining wasm modules for modules format workers", async () => {
1527
+ it("should use the global compatibility_date and compatibility_flags if they are not overwritten by the environment", async () => {
1606
1528
  writeWranglerToml({
1607
- wasm_modules: {
1608
- TESTWASMNAME: "./path/to/test.wasm",
1529
+ compatibility_date: "2022-01-12",
1530
+ compatibility_flags: ["no_global_navigator"],
1531
+ env: {
1532
+ dev: {},
1609
1533
  },
1610
1534
  });
1611
- writeWorkerSource({ type: "esm" });
1612
- fs.mkdirSync("./path/to", { recursive: true });
1613
- fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1535
+ writeWorkerSource();
1536
+ mockUploadWorkerRequest({
1537
+ env: "dev",
1538
+ expectedCompatibilityDate: "2022-01-12",
1539
+ expectedCompatibilityFlags: ["no_global_navigator"],
1540
+ });
1541
+ mockSubDomainRequest();
1542
+ mockUpdateWorkerRequest({ enabled: true, env: "dev" });
1614
1543
 
1615
- await expect(
1616
- runWrangler("publish index.js")
1617
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1618
- `"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"`
1619
- );
1620
- expect(std.out).toMatchInlineSnapshot(`""`);
1621
- expect(std.err).toMatchInlineSnapshot(`
1622
- "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
1544
+ await runWrangler("publish ./index --env dev --legacy-env false");
1623
1545
 
1624
- %s
1625
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1546
+ expect(std.out).toMatchInlineSnapshot(`
1547
+ "Uploaded test-name (dev) (TIMINGS)
1548
+ Published test-name (dev) (TIMINGS)
1549
+ dev.test-name.test-sub-domain.workers.dev"
1626
1550
  `);
1627
- expect(std.warn).toMatchInlineSnapshot(`""`);
1551
+ expect(std.err).toMatchInlineSnapshot(`""`);
1628
1552
  });
1629
1553
 
1630
- it("should resolve wasm modules relative to the wrangler.toml file", async () => {
1631
- fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
1632
- fs.writeFileSync(
1633
- "./path/to/wrangler.toml",
1634
- TOML.stringify({
1635
- compatibility_date: "2022-01-12",
1636
- name: "test-name",
1637
- wasm_modules: {
1638
- TESTWASMNAME: "./and/the/path/to/test.wasm",
1554
+ it("should use the environment specific compatibility_date and compatibility_flags", async () => {
1555
+ writeWranglerToml({
1556
+ compatibility_date: "2022-01-12",
1557
+ compatibility_flags: ["no_global_navigator"],
1558
+ env: {
1559
+ dev: {
1560
+ compatibility_date: "2022-01-13",
1561
+ compatibility_flags: ["global_navigator"],
1639
1562
  },
1640
- }),
1563
+ },
1564
+ });
1565
+ writeWorkerSource();
1566
+ mockUploadWorkerRequest({
1567
+ env: "dev",
1568
+ expectedCompatibilityDate: "2022-01-13",
1569
+ expectedCompatibilityFlags: ["global_navigator"],
1570
+ });
1571
+ mockSubDomainRequest();
1572
+ mockUpdateWorkerRequest({ enabled: true, env: "dev" });
1641
1573
 
1642
- "utf-8"
1643
- );
1574
+ await runWrangler("publish ./index --env dev --legacy-env false");
1644
1575
 
1645
- writeWorkerSource({ type: "sw" });
1646
- fs.writeFileSync(
1647
- "./path/to/and/the/path/to/test.wasm",
1648
- "SOME WASM CONTENT"
1649
- );
1576
+ expect(std.out).toMatchInlineSnapshot(`
1577
+ "Uploaded test-name (dev) (TIMINGS)
1578
+ Published test-name (dev) (TIMINGS)
1579
+ dev.test-name.test-sub-domain.workers.dev"
1580
+ `);
1581
+ expect(std.err).toMatchInlineSnapshot(`""`);
1582
+ });
1583
+
1584
+ it("should use the command line --compatibility-date and --compatibility-flags if they are specified", async () => {
1585
+ writeWranglerToml({
1586
+ compatibility_date: "2022-01-12",
1587
+ compatibility_flags: ["no_global_navigator"],
1588
+ env: {
1589
+ dev: {
1590
+ compatibility_date: "2022-01-13",
1591
+ compatibility_flags: ["global_navigator"],
1592
+ },
1593
+ },
1594
+ });
1595
+ writeWorkerSource();
1650
1596
  mockUploadWorkerRequest({
1651
- expectedType: "sw",
1652
- expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1653
- expectedBindings: [
1654
- { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1655
- ],
1597
+ env: "dev",
1598
+ expectedCompatibilityDate: "2022-01-14",
1599
+ expectedCompatibilityFlags: ["url_standard"],
1656
1600
  });
1657
1601
  mockSubDomainRequest();
1658
- await runWrangler("publish index.js --config ./path/to/wrangler.toml");
1659
- expect(std.out).toMatchInlineSnapshot(`
1660
- "Uploaded
1661
- test-name
1662
- (TIMINGS)
1663
- Published
1664
- test-name
1665
- (TIMINGS)
1602
+ mockUpdateWorkerRequest({ enabled: true, env: "dev" });
1666
1603
 
1667
- test-name.test-sub-domain.workers.dev"
1604
+ await runWrangler(
1605
+ "publish ./index --env dev --legacy-env false --compatibility-date 2022-01-14 --compatibility-flags url_standard"
1606
+ );
1607
+
1608
+ expect(std.out).toMatchInlineSnapshot(`
1609
+ "Uploaded test-name (dev) (TIMINGS)
1610
+ Published test-name (dev) (TIMINGS)
1611
+ dev.test-name.test-sub-domain.workers.dev"
1668
1612
  `);
1669
1613
  expect(std.err).toMatchInlineSnapshot(`""`);
1670
- expect(std.warn).toMatchInlineSnapshot(`""`);
1671
1614
  });
1672
1615
 
1673
- it("should be able to import .wasm modules from service-worker format workers", async () => {
1616
+ it("should enable the workers.dev domain if workers_dev is undefined and subdomain is not already available", async () => {
1674
1617
  writeWranglerToml();
1675
- fs.writeFileSync("./index.js", "import TESTWASMNAME from './test.wasm';");
1676
- fs.writeFileSync("./test.wasm", "SOME WASM CONTENT");
1677
- mockUploadWorkerRequest({
1678
- expectedType: "sw",
1679
- expectedModules: {
1680
- __94b240d0d692281e6467aa42043986e5c7eea034_test_wasm:
1681
- "SOME WASM CONTENT",
1682
- },
1683
- expectedBindings: [
1684
- {
1685
- name: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1686
- part: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1687
- type: "wasm_module",
1688
- },
1689
- ],
1618
+ writeWorkerSource();
1619
+ mockUploadWorkerRequest({ available_on_subdomain: false });
1620
+ mockSubDomainRequest();
1621
+ mockUpdateWorkerRequest({ enabled: true });
1622
+
1623
+ await runWrangler("publish ./index");
1624
+
1625
+ expect(std.out).toMatchInlineSnapshot(`
1626
+ "Uploaded test-name (TIMINGS)
1627
+ Published test-name (TIMINGS)
1628
+ test-name.test-sub-domain.workers.dev"
1629
+ `);
1630
+ expect(std.err).toMatchInlineSnapshot(`""`);
1631
+ });
1632
+
1633
+ it("should enable the workers.dev domain if workers_dev is true and subdomain is not already available", async () => {
1634
+ writeWranglerToml({ workers_dev: true });
1635
+ writeWorkerSource();
1636
+ mockUploadWorkerRequest({ available_on_subdomain: false });
1637
+ mockSubDomainRequest();
1638
+ mockUpdateWorkerRequest({ enabled: true });
1639
+
1640
+ await runWrangler("publish ./index");
1641
+
1642
+ expect(std.out).toMatchInlineSnapshot(`
1643
+ "Uploaded test-name (TIMINGS)
1644
+ Published test-name (TIMINGS)
1645
+ test-name.test-sub-domain.workers.dev"
1646
+ `);
1647
+ expect(std.err).toMatchInlineSnapshot(`""`);
1648
+ });
1649
+
1650
+ it("should error politely when publishing to workers_dev when there is no workers.dev subdomain", async () => {
1651
+ writeWranglerToml({
1652
+ workers_dev: true,
1653
+ });
1654
+ writeWorkerSource();
1655
+ mockUploadWorkerRequest();
1656
+ mockSubDomainRequest("does-not-exist", false);
1657
+
1658
+ await expect(runWrangler("publish ./index")).rejects
1659
+ .toThrowErrorMatchingInlineSnapshot(`
1660
+ "Error: You need to register a workers.dev subdomain before publishing to workers.dev
1661
+ You can either publish your worker to one or more routes by specifying them in wrangler.toml, or register a workers.dev subdomain here:
1662
+ https://dash.cloudflare.com/some-account-id/workers/onboarding"
1663
+ `);
1664
+ });
1665
+
1666
+ it("should not deploy to workers.dev if there are any routes defined", async () => {
1667
+ writeWranglerToml({
1668
+ routes: ["http://example.com/*"],
1690
1669
  });
1670
+ writeWorkerSource();
1691
1671
  mockSubDomainRequest();
1672
+ mockUploadWorkerRequest();
1673
+ mockUpdateWorkerRequest({
1674
+ enabled: false,
1675
+ });
1676
+ mockPublishRoutesRequest({ routes: ["http://example.com/*"] });
1692
1677
  await runWrangler("publish index.js");
1693
- expect(std.out).toMatchInlineSnapshot(`
1694
- "Uploaded
1695
- test-name
1696
- (TIMINGS)
1697
- Published
1698
- test-name
1699
- (TIMINGS)
1700
1678
 
1701
- test-name.test-sub-domain.workers.dev"
1679
+ expect(std.out).toMatchInlineSnapshot(`
1680
+ "Uploaded test-name (TIMINGS)
1681
+ Published test-name (TIMINGS)
1682
+ http://example.com/*"
1702
1683
  `);
1703
1684
  expect(std.err).toMatchInlineSnapshot(`""`);
1704
1685
  expect(std.warn).toMatchInlineSnapshot(`""`);
1705
1686
  });
1706
- });
1707
1687
 
1708
- describe("[text_blobs]", () => {
1709
- it("should be able to define text blobs for service-worker format workers", async () => {
1688
+ it("should not deploy to workers.dev if there are any routes defined (environments)", async () => {
1710
1689
  writeWranglerToml({
1711
- text_blobs: {
1712
- TESTTEXTBLOBNAME: "./path/to/text.file",
1690
+ routes: ["http://example.com/*"],
1691
+ env: {
1692
+ production: {
1693
+ routes: ["http://production.example.com/*"],
1694
+ },
1713
1695
  },
1714
1696
  });
1715
- writeWorkerSource({ type: "sw" });
1716
- fs.mkdirSync("./path/to", { recursive: true });
1717
- fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
1718
- mockUploadWorkerRequest({
1719
- expectedType: "sw",
1720
- expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
1721
- expectedBindings: [
1722
- {
1723
- name: "TESTTEXTBLOBNAME",
1724
- part: "TESTTEXTBLOBNAME",
1725
- type: "text_blob",
1697
+ writeWorkerSource();
1698
+ mockSubDomainRequest();
1699
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1700
+ mockUpdateWorkerRequest({
1701
+ enabled: false,
1702
+ env: "production",
1703
+ legacyEnv: true,
1704
+ });
1705
+ mockPublishRoutesRequest({
1706
+ routes: ["http://production.example.com/*"],
1707
+ env: "production",
1708
+ legacyEnv: true,
1709
+ });
1710
+ await runWrangler("publish index.js --env production");
1711
+
1712
+ expect(std.out).toMatchInlineSnapshot(`
1713
+ "Uploaded test-name-production (TIMINGS)
1714
+ Published test-name-production (TIMINGS)
1715
+ http://production.example.com/*"
1716
+ `);
1717
+ expect(std.err).toMatchInlineSnapshot(`""`);
1718
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1719
+ });
1720
+
1721
+ it("should not deploy to workers.dev if there are any routes defined (only in environments)", async () => {
1722
+ writeWranglerToml({
1723
+ env: {
1724
+ production: {
1725
+ routes: ["http://production.example.com/*"],
1726
1726
  },
1727
- ],
1727
+ },
1728
1728
  });
1729
+ writeWorkerSource();
1729
1730
  mockSubDomainRequest();
1730
- await runWrangler("publish index.js");
1731
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1732
+ mockUpdateWorkerRequest({
1733
+ enabled: false,
1734
+ env: "production",
1735
+ legacyEnv: true,
1736
+ });
1737
+ mockPublishRoutesRequest({
1738
+ routes: ["http://production.example.com/*"],
1739
+ env: "production",
1740
+ legacyEnv: true,
1741
+ });
1742
+ await runWrangler("publish index.js --env production");
1743
+
1731
1744
  expect(std.out).toMatchInlineSnapshot(`
1732
- "Uploaded
1733
- test-name
1734
- (TIMINGS)
1735
- Published
1736
- test-name
1737
- (TIMINGS)
1745
+ "Uploaded test-name-production (TIMINGS)
1746
+ Published test-name-production (TIMINGS)
1747
+ http://production.example.com/*"
1748
+ `);
1749
+ expect(std.err).toMatchInlineSnapshot(`""`);
1750
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1751
+ });
1738
1752
 
1739
- test-name.test-sub-domain.workers.dev"
1753
+ it("can deploy to both workers.dev and routes if both defined ", async () => {
1754
+ writeWranglerToml({
1755
+ workers_dev: true,
1756
+ routes: ["http://example.com/*"],
1757
+ });
1758
+ writeWorkerSource();
1759
+ mockSubDomainRequest();
1760
+ mockUploadWorkerRequest();
1761
+ mockUpdateWorkerRequest({
1762
+ enabled: false,
1763
+ });
1764
+ mockPublishRoutesRequest({
1765
+ routes: ["http://example.com/*"],
1766
+ });
1767
+ await runWrangler("publish index.js");
1768
+
1769
+ expect(std.out).toMatchInlineSnapshot(`
1770
+ "Uploaded test-name (TIMINGS)
1771
+ Published test-name (TIMINGS)
1772
+ test-name.test-sub-domain.workers.dev
1773
+ http://example.com/*"
1740
1774
  `);
1741
1775
  expect(std.err).toMatchInlineSnapshot(`""`);
1742
1776
  expect(std.warn).toMatchInlineSnapshot(`""`);
1743
1777
  });
1744
1778
 
1745
- it("should error when defining text blobs for modules format workers", async () => {
1779
+ it("can deploy to both workers.dev and routes if both defined (environments: 1)", async () => {
1746
1780
  writeWranglerToml({
1747
- text_blobs: {
1748
- TESTTEXTBLOBNAME: "./path/to/text.file",
1781
+ workers_dev: true,
1782
+ env: {
1783
+ production: {
1784
+ routes: ["http://production.example.com/*"],
1785
+ },
1749
1786
  },
1750
1787
  });
1751
- writeWorkerSource({ type: "esm" });
1752
- fs.mkdirSync("./path/to", { recursive: true });
1753
- fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
1754
-
1755
- await expect(
1756
- runWrangler("publish index.js")
1757
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1758
- `"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml"`
1759
- );
1760
- expect(std.out).toMatchInlineSnapshot(`""`);
1761
- expect(std.err).toMatchInlineSnapshot(`
1762
- "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml
1788
+ writeWorkerSource();
1789
+ mockSubDomainRequest();
1790
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1791
+ mockUpdateWorkerRequest({
1792
+ enabled: false,
1793
+ env: "production",
1794
+ legacyEnv: true,
1795
+ });
1796
+ mockPublishRoutesRequest({
1797
+ routes: ["http://production.example.com/*"],
1798
+ env: "production",
1799
+ legacyEnv: true,
1800
+ });
1801
+ await runWrangler("publish index.js --env production");
1763
1802
 
1764
- %s
1765
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1803
+ expect(std.out).toMatchInlineSnapshot(`
1804
+ "Uploaded test-name-production (TIMINGS)
1805
+ Published test-name-production (TIMINGS)
1806
+ test-name-production.test-sub-domain.workers.dev
1807
+ http://production.example.com/*"
1766
1808
  `);
1809
+ expect(std.err).toMatchInlineSnapshot(`""`);
1767
1810
  expect(std.warn).toMatchInlineSnapshot(`""`);
1768
1811
  });
1769
1812
 
1770
- it("should resolve text blobs relative to the wrangler.toml file", async () => {
1771
- fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
1772
- fs.writeFileSync(
1773
- "./path/to/wrangler.toml",
1774
- TOML.stringify({
1775
- compatibility_date: "2022-01-12",
1776
- name: "test-name",
1777
- text_blobs: {
1778
- TESTTEXTBLOBNAME: "./and/the/path/to/text.file",
1813
+ it("can deploy to both workers.dev and routes if both defined (environments: 2)", async () => {
1814
+ writeWranglerToml({
1815
+ env: {
1816
+ production: {
1817
+ workers_dev: true,
1818
+ routes: ["http://production.example.com/*"],
1779
1819
  },
1780
- }),
1820
+ },
1821
+ });
1822
+ writeWorkerSource();
1823
+ mockSubDomainRequest();
1824
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1825
+ mockUpdateWorkerRequest({
1826
+ enabled: false,
1827
+ env: "production",
1828
+ legacyEnv: true,
1829
+ });
1830
+ mockPublishRoutesRequest({
1831
+ routes: ["http://production.example.com/*"],
1832
+ env: "production",
1833
+ legacyEnv: true,
1834
+ });
1835
+ await runWrangler("publish index.js --env production");
1781
1836
 
1782
- "utf-8"
1783
- );
1837
+ expect(std.out).toMatchInlineSnapshot(`
1838
+ "Uploaded test-name-production (TIMINGS)
1839
+ Published test-name-production (TIMINGS)
1840
+ test-name-production.test-sub-domain.workers.dev
1841
+ http://production.example.com/*"
1842
+ `);
1843
+ expect(std.err).toMatchInlineSnapshot(`""`);
1844
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1845
+ });
1784
1846
 
1785
- writeWorkerSource({ type: "sw" });
1786
- fs.writeFileSync(
1787
- "./path/to/and/the/path/to/text.file",
1788
- "SOME TEXT CONTENT"
1789
- );
1790
- mockUploadWorkerRequest({
1791
- expectedType: "sw",
1792
- expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
1793
- expectedBindings: [
1794
- {
1795
- name: "TESTTEXTBLOBNAME",
1796
- part: "TESTTEXTBLOBNAME",
1797
- type: "text_blob",
1847
+ it("will deploy only to routes when workers_dev is false (environments 1) ", async () => {
1848
+ writeWranglerToml({
1849
+ workers_dev: false,
1850
+ env: {
1851
+ production: {
1852
+ routes: ["http://production.example.com/*"],
1798
1853
  },
1799
- ],
1854
+ },
1800
1855
  });
1856
+ writeWorkerSource();
1801
1857
  mockSubDomainRequest();
1802
- await runWrangler("publish index.js --config ./path/to/wrangler.toml");
1803
- expect(std.out).toMatchInlineSnapshot(`
1804
- "Uploaded
1805
- test-name
1806
- (TIMINGS)
1807
- Published
1808
- test-name
1809
- (TIMINGS)
1858
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1859
+ mockUpdateWorkerRequest({
1860
+ enabled: false,
1861
+ env: "production",
1862
+ legacyEnv: true,
1863
+ });
1864
+ mockPublishRoutesRequest({
1865
+ routes: ["http://production.example.com/*"],
1866
+ env: "production",
1867
+ legacyEnv: true,
1868
+ });
1869
+ await runWrangler("publish index.js --env production");
1810
1870
 
1811
- test-name.test-sub-domain.workers.dev"
1871
+ expect(std.out).toMatchInlineSnapshot(`
1872
+ "Uploaded test-name-production (TIMINGS)
1873
+ Published test-name-production (TIMINGS)
1874
+ http://production.example.com/*"
1812
1875
  `);
1813
1876
  expect(std.err).toMatchInlineSnapshot(`""`);
1814
1877
  expect(std.warn).toMatchInlineSnapshot(`""`);
1815
1878
  });
1816
- });
1817
1879
 
1818
- describe("vars bindings", () => {
1819
- it("should support json bindings", async () => {
1820
- writeWranglerToml({
1821
- vars: {
1822
- text: "plain ol' string",
1823
- count: 1,
1824
- complex: { enabled: true, id: 123 },
1825
- },
1880
+ it("will deploy only to routes when workers_dev is false (environments 2) ", async () => {
1881
+ writeWranglerToml({
1882
+ env: {
1883
+ production: {
1884
+ workers_dev: false,
1885
+ routes: ["http://production.example.com/*"],
1886
+ },
1887
+ },
1888
+ });
1889
+ writeWorkerSource();
1890
+ mockSubDomainRequest();
1891
+ mockUploadWorkerRequest({ env: "production", legacyEnv: true });
1892
+ mockUpdateWorkerRequest({
1893
+ enabled: false,
1894
+ env: "production",
1895
+ legacyEnv: true,
1896
+ });
1897
+ mockPublishRoutesRequest({
1898
+ routes: ["http://production.example.com/*"],
1899
+ env: "production",
1900
+ legacyEnv: true,
1901
+ });
1902
+ await runWrangler("publish index.js --env production");
1903
+
1904
+ expect(std.out).toMatchInlineSnapshot(`
1905
+ "Uploaded test-name-production (TIMINGS)
1906
+ Published test-name-production (TIMINGS)
1907
+ http://production.example.com/*"
1908
+ `);
1909
+ expect(std.err).toMatchInlineSnapshot(`""`);
1910
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1911
+ });
1912
+ });
1913
+
1914
+ describe("custom builds", () => {
1915
+ beforeEach(() => {
1916
+ // @ts-expect-error disable the mock we'd setup earlier
1917
+ // or else custom builds will timeout immediately
1918
+ global.setTimeout.mockRestore();
1919
+ });
1920
+ it("should run a custom build before publishing", async () => {
1921
+ writeWranglerToml({
1922
+ build: {
1923
+ command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
1924
+ },
1925
+ });
1926
+
1927
+ mockUploadWorkerRequest({
1928
+ expectedEntry: "return new Response(123)",
1929
+ });
1930
+ mockSubDomainRequest();
1931
+
1932
+ await runWrangler("publish index.js");
1933
+ expect(std.out).toMatchInlineSnapshot(`
1934
+ "running: node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\"
1935
+ Uploaded test-name (TIMINGS)
1936
+ Published test-name (TIMINGS)
1937
+ test-name.test-sub-domain.workers.dev"
1938
+ `);
1939
+ expect(std.err).toMatchInlineSnapshot(`""`);
1940
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1941
+ });
1942
+
1943
+ if (process.platform !== "win32") {
1944
+ it("should run a custom build of multiple steps combined by && before publishing", async () => {
1945
+ writeWranglerToml({
1946
+ build: {
1947
+ command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
1948
+ },
1949
+ });
1950
+
1951
+ mockUploadWorkerRequest({
1952
+ expectedEntry: "return new Response(123)",
1953
+ });
1954
+ mockSubDomainRequest();
1955
+
1956
+ await runWrangler("publish index.js");
1957
+ expect(std.out).toMatchInlineSnapshot(`
1958
+ "running: echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js
1959
+ Uploaded test-name (TIMINGS)
1960
+ Published test-name (TIMINGS)
1961
+ test-name.test-sub-domain.workers.dev"
1962
+ `);
1963
+ expect(std.err).toMatchInlineSnapshot(`""`);
1964
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1965
+ });
1966
+ }
1967
+
1968
+ it("should throw an error if the entry doesn't exist after the build finishes", async () => {
1969
+ writeWranglerToml({
1970
+ main: "index.js",
1971
+ build: {
1972
+ command: `node -e "console.log('custom build');"`,
1973
+ },
1974
+ });
1975
+
1976
+ await expect(
1977
+ runWrangler("publish index.js")
1978
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
1979
+ `"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\""`
1980
+ );
1981
+ expect(std.out).toMatchInlineSnapshot(
1982
+ `"running: node -e \\"console.log('custom build');\\""`
1983
+ );
1984
+ expect(std.err).toMatchInlineSnapshot(`
1985
+ "Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
1986
+
1987
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1988
+ `);
1989
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1990
+ });
1991
+ });
1992
+
1993
+ describe("bindings", () => {
1994
+ it("should allow bindings with different names", async () => {
1995
+ writeWranglerToml({
1996
+ durable_objects: {
1997
+ bindings: [
1998
+ {
1999
+ name: "DURABLE_OBJECT_ONE",
2000
+ class_name: "SomeDurableObject",
2001
+ script_name: "some-durable-object-worker",
2002
+ },
2003
+ {
2004
+ name: "DURABLE_OBJECT_TWO",
2005
+ class_name: "AnotherDurableObject",
2006
+ script_name: "another-durable-object-worker",
2007
+ },
2008
+ ],
2009
+ },
2010
+ kv_namespaces: [
2011
+ { binding: "KV_NAMESPACE_ONE", id: "kv-ns-one-id" },
2012
+ { binding: "KV_NAMESPACE_TWO", id: "kv-ns-two-id" },
2013
+ ],
2014
+ r2_buckets: [
2015
+ { binding: "R2_BUCKET_ONE", bucket_name: "r2-bucket-one-name" },
2016
+ { binding: "R2_BUCKET_TWO", bucket_name: "r2-bucket-two-name" },
2017
+ ],
2018
+ text_blobs: {
2019
+ TEXT_BLOB_ONE: "./my-entire-app-depends-on-this.cfg",
2020
+ TEXT_BLOB_TWO: "./the-entirety-of-human-knowledge.txt",
2021
+ },
2022
+ unsafe: {
2023
+ bindings: [
2024
+ {
2025
+ name: "UNSAFE_BINDING_ONE",
2026
+ type: "some unsafe thing",
2027
+ data: { some: { unsafe: "thing" } },
2028
+ },
2029
+ {
2030
+ name: "UNSAFE_BINDING_TWO",
2031
+ type: "another unsafe thing",
2032
+ data: 1337,
2033
+ },
2034
+ ],
2035
+ },
2036
+ vars: {
2037
+ ENV_VAR_ONE: 123,
2038
+ ENV_VAR_TWO: "Hello, I'm an environment variable",
2039
+ },
2040
+ wasm_modules: {
2041
+ WASM_MODULE_ONE: "./some_wasm.wasm",
2042
+ WASM_MODULE_TWO: "./more_wasm.wasm",
2043
+ },
2044
+ });
2045
+
2046
+ writeWorkerSource({ type: "sw" });
2047
+ fs.writeFileSync("./my-entire-app-depends-on-this.cfg", "config = value");
2048
+ fs.writeFileSync(
2049
+ "./the-entirety-of-human-knowledge.txt",
2050
+ "Everything's bigger in Texas"
2051
+ );
2052
+ fs.writeFileSync("./some_wasm.wasm", "some wasm");
2053
+ fs.writeFileSync("./more_wasm.wasm", "more wasm");
2054
+
2055
+ mockUploadWorkerRequest({
2056
+ expectedType: "sw",
2057
+ expectedBindings: [
2058
+ {
2059
+ name: "KV_NAMESPACE_ONE",
2060
+ namespace_id: "kv-ns-one-id",
2061
+ type: "kv_namespace",
2062
+ },
2063
+ {
2064
+ name: "KV_NAMESPACE_TWO",
2065
+ namespace_id: "kv-ns-two-id",
2066
+ type: "kv_namespace",
2067
+ },
2068
+ {
2069
+ class_name: "SomeDurableObject",
2070
+ name: "DURABLE_OBJECT_ONE",
2071
+ script_name: "some-durable-object-worker",
2072
+ type: "durable_object_namespace",
2073
+ },
2074
+ {
2075
+ class_name: "AnotherDurableObject",
2076
+ name: "DURABLE_OBJECT_TWO",
2077
+ script_name: "another-durable-object-worker",
2078
+ type: "durable_object_namespace",
2079
+ },
2080
+ {
2081
+ bucket_name: "r2-bucket-one-name",
2082
+ name: "R2_BUCKET_ONE",
2083
+ type: "r2_bucket",
2084
+ },
2085
+ {
2086
+ bucket_name: "r2-bucket-two-name",
2087
+ name: "R2_BUCKET_TWO",
2088
+ type: "r2_bucket",
2089
+ },
2090
+ { json: 123, name: "ENV_VAR_ONE", type: "json" },
2091
+ {
2092
+ name: "ENV_VAR_TWO",
2093
+ text: "Hello, I'm an environment variable",
2094
+ type: "plain_text",
2095
+ },
2096
+ {
2097
+ name: "WASM_MODULE_ONE",
2098
+ part: "WASM_MODULE_ONE",
2099
+ type: "wasm_module",
2100
+ },
2101
+ {
2102
+ name: "WASM_MODULE_TWO",
2103
+ part: "WASM_MODULE_TWO",
2104
+ type: "wasm_module",
2105
+ },
2106
+ { name: "TEXT_BLOB_ONE", part: "TEXT_BLOB_ONE", type: "text_blob" },
2107
+ { name: "TEXT_BLOB_TWO", part: "TEXT_BLOB_TWO", type: "text_blob" },
2108
+ {
2109
+ data: { some: { unsafe: "thing" } },
2110
+ name: "UNSAFE_BINDING_ONE",
2111
+ type: "some unsafe thing",
2112
+ },
2113
+ {
2114
+ data: 1337,
2115
+ name: "UNSAFE_BINDING_TWO",
2116
+ type: "another unsafe thing",
2117
+ },
2118
+ ],
2119
+ });
2120
+ mockSubDomainRequest();
2121
+
2122
+ await expect(runWrangler("publish index.js")).resolves.toBeUndefined();
2123
+ expect(std.out).toMatchInlineSnapshot(`
2124
+ "Uploaded test-name (TIMINGS)
2125
+ Published test-name (TIMINGS)
2126
+ test-name.test-sub-domain.workers.dev"
2127
+ `);
2128
+ expect(std.err).toMatchInlineSnapshot(`""`);
2129
+ expect(std.warn).toMatchInlineSnapshot(`
2130
+ "Processing wrangler.toml configuration:
2131
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2132
+ `);
2133
+ });
2134
+
2135
+ it("should error when bindings of different types have the same name", async () => {
2136
+ writeWranglerToml({
2137
+ durable_objects: {
2138
+ bindings: [
2139
+ {
2140
+ name: "CONFLICTING_NAME_ONE",
2141
+ class_name: "SomeDurableObject",
2142
+ script_name: "some-durable-object-worker",
2143
+ },
2144
+ {
2145
+ name: "CONFLICTING_NAME_TWO",
2146
+ class_name: "AnotherDurableObject",
2147
+ script_name: "another-durable-object-worker",
2148
+ },
2149
+ ],
2150
+ },
2151
+ kv_namespaces: [
2152
+ { binding: "CONFLICTING_NAME_ONE", id: "kv-ns-one-id" },
2153
+ { binding: "CONFLICTING_NAME_TWO", id: "kv-ns-two-id" },
2154
+ ],
2155
+ r2_buckets: [
2156
+ {
2157
+ binding: "CONFLICTING_NAME_ONE",
2158
+ bucket_name: "r2-bucket-one-name",
2159
+ },
2160
+ {
2161
+ binding: "CONFLICTING_NAME_THREE",
2162
+ bucket_name: "r2-bucket-two-name",
2163
+ },
2164
+ ],
2165
+ text_blobs: {
2166
+ CONFLICTING_NAME_THREE: "./my-entire-app-depends-on-this.cfg",
2167
+ CONFLICTING_NAME_FOUR: "./the-entirety-of-human-knowledge.txt",
2168
+ },
2169
+ unsafe: {
2170
+ bindings: [
2171
+ {
2172
+ name: "CONFLICTING_NAME_THREE",
2173
+ type: "some unsafe thing",
2174
+ data: { some: { unsafe: "thing" } },
2175
+ },
2176
+ {
2177
+ name: "CONFLICTING_NAME_FOUR",
2178
+ type: "another unsafe thing",
2179
+ data: 1337,
2180
+ },
2181
+ ],
2182
+ },
2183
+ vars: {
2184
+ ENV_VAR_ONE: 123,
2185
+ CONFLICTING_NAME_THREE: "Hello, I'm an environment variable",
2186
+ },
2187
+ wasm_modules: {
2188
+ WASM_MODULE_ONE: "./some_wasm.wasm",
2189
+ CONFLICTING_NAME_THREE: "./more_wasm.wasm",
2190
+ },
2191
+ });
2192
+
2193
+ writeWorkerSource({ type: "sw" });
2194
+ fs.writeFileSync("./my-entire-app-depends-on-this.cfg", "config = value");
2195
+ fs.writeFileSync(
2196
+ "./the-entirety-of-human-knowledge.txt",
2197
+ "Everything's bigger in Texas"
2198
+ );
2199
+ fs.writeFileSync("./some_wasm.wasm", "some wasm");
2200
+ fs.writeFileSync("./more_wasm.wasm", "more wasm");
2201
+
2202
+ await expect(runWrangler("publish index.js")).rejects
2203
+ .toMatchInlineSnapshot(`
2204
+ [Error: Processing wrangler.toml configuration:
2205
+ - CONFLICTING_NAME_ONE assigned to Durable Object, KV Namespace, and R2 Bucket bindings.
2206
+ - CONFLICTING_NAME_TWO assigned to Durable Object and KV Namespace bindings.
2207
+ - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings.
2208
+ - CONFLICTING_NAME_FOUR assigned to Text Blob and Unsafe bindings.
2209
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2210
+ Please change your bindings to have unique names.]
2211
+ `);
2212
+ expect(std.out).toMatchInlineSnapshot(`""`);
2213
+ expect(std.err).toMatchInlineSnapshot(`
2214
+ "Processing wrangler.toml configuration:
2215
+ - CONFLICTING_NAME_ONE assigned to Durable Object, KV Namespace, and R2 Bucket bindings.
2216
+ - CONFLICTING_NAME_TWO assigned to Durable Object and KV Namespace bindings.
2217
+ - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings.
2218
+ - CONFLICTING_NAME_FOUR assigned to Text Blob and Unsafe bindings.
2219
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2220
+ Please change your bindings to have unique names.
2221
+
2222
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2223
+ `);
2224
+ expect(std.warn).toMatchInlineSnapshot(`
2225
+ "Processing wrangler.toml configuration:
2226
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2227
+ `);
2228
+ });
2229
+
2230
+ it("should error when bindings of the same type have the same name", async () => {
2231
+ writeWranglerToml({
2232
+ durable_objects: {
2233
+ bindings: [
2234
+ {
2235
+ name: "CONFLICTING_DURABLE_OBJECT_NAME",
2236
+ class_name: "SomeDurableObject",
2237
+ script_name: "some-durable-object-worker",
2238
+ },
2239
+ {
2240
+ name: "CONFLICTING_DURABLE_OBJECT_NAME",
2241
+ class_name: "AnotherDurableObject",
2242
+ script_name: "another-durable-object-worker",
2243
+ },
2244
+ ],
2245
+ },
2246
+ kv_namespaces: [
2247
+ { binding: "CONFLICTING_KV_NAMESPACE_NAME", id: "kv-ns-one-id" },
2248
+ { binding: "CONFLICTING_KV_NAMESPACE_NAME", id: "kv-ns-two-id" },
2249
+ ],
2250
+ r2_buckets: [
2251
+ {
2252
+ binding: "CONFLICTING_R2_BUCKET_NAME",
2253
+ bucket_name: "r2-bucket-one-name",
2254
+ },
2255
+ {
2256
+ binding: "CONFLICTING_R2_BUCKET_NAME",
2257
+ bucket_name: "r2-bucket-two-name",
2258
+ },
2259
+ ],
2260
+ unsafe: {
2261
+ bindings: [
2262
+ {
2263
+ name: "CONFLICTING_UNSAFE_NAME",
2264
+ type: "some unsafe thing",
2265
+ data: { some: { unsafe: "thing" } },
2266
+ },
2267
+ {
2268
+ name: "CONFLICTING_UNSAFE_NAME",
2269
+ type: "another unsafe thing",
2270
+ data: 1337,
2271
+ },
2272
+ ],
2273
+ },
2274
+ // text_blobs, vars, and wasm_modules are fine because they're object literals,
2275
+ // and by definition cannot have two keys of the same name
2276
+ //
2277
+ // text_blobs: {
2278
+ // CONFLICTING_TEXT_BLOB_NAME: "./my-entire-app-depends-on-this.cfg",
2279
+ // CONFLICTING_TEXT_BLOB_NAME: "./the-entirety-of-human-knowledge.txt",
2280
+ // },
2281
+ // vars: {
2282
+ // CONFLICTING_VARS_NAME: 123,
2283
+ // CONFLICTING_VARS_NAME: "Hello, I'm an environment variable",
2284
+ // },
2285
+ // wasm_modules: {
2286
+ // CONFLICTING_WASM_MODULE_NAME: "./some_wasm.wasm",
2287
+ // CONFLICTING_WASM_MODULE_NAME: "./more_wasm.wasm",
2288
+ // },
2289
+ });
2290
+
2291
+ writeWorkerSource({ type: "sw" });
2292
+
2293
+ await expect(runWrangler("publish index.js")).rejects
2294
+ .toMatchInlineSnapshot(`
2295
+ [Error: Processing wrangler.toml configuration:
2296
+ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings.
2297
+ - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings.
2298
+ - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings.
2299
+ - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings.
2300
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2301
+ Please change your bindings to have unique names.]
2302
+ `);
2303
+ expect(std.out).toMatchInlineSnapshot(`""`);
2304
+ expect(std.err).toMatchInlineSnapshot(`
2305
+ "Processing wrangler.toml configuration:
2306
+ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings.
2307
+ - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings.
2308
+ - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings.
2309
+ - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings.
2310
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2311
+ Please change your bindings to have unique names.
2312
+
2313
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2314
+ `);
2315
+ expect(std.warn).toMatchInlineSnapshot(`
2316
+ "Processing wrangler.toml configuration:
2317
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2318
+ `);
2319
+ });
2320
+
2321
+ it("should error correctly when bindings of the same and different types use the same name", async () => {
2322
+ writeWranglerToml({
2323
+ durable_objects: {
2324
+ bindings: [
2325
+ {
2326
+ name: "CONFLICTING_DURABLE_OBJECT_NAME",
2327
+ class_name: "SomeDurableObject",
2328
+ script_name: "some-durable-object-worker",
2329
+ },
2330
+ {
2331
+ name: "CONFLICTING_DURABLE_OBJECT_NAME",
2332
+ class_name: "AnotherDurableObject",
2333
+ script_name: "another-durable-object-worker",
2334
+ },
2335
+ ],
2336
+ },
2337
+ kv_namespaces: [
2338
+ {
2339
+ binding: "CONFLICTING_KV_NAMESPACE_NAME",
2340
+ id: "kv-ns-one-id",
2341
+ },
2342
+ {
2343
+ binding: "CONFLICTING_KV_NAMESPACE_NAME",
2344
+ id: "kv-ns-two-id",
2345
+ },
2346
+ { binding: "CONFLICTING_NAME_ONE", id: "kv-ns-three-id" },
2347
+ { binding: "CONFLICTING_NAME_TWO", id: "kv-ns-four-id" },
2348
+ ],
2349
+ r2_buckets: [
2350
+ {
2351
+ binding: "CONFLICTING_R2_BUCKET_NAME",
2352
+ bucket_name: "r2-bucket-one-name",
2353
+ },
2354
+ {
2355
+ binding: "CONFLICTING_R2_BUCKET_NAME",
2356
+ bucket_name: "r2-bucket-two-name",
2357
+ },
2358
+ {
2359
+ binding: "CONFLICTING_NAME_THREE",
2360
+ bucket_name: "r2-bucket-three-name",
2361
+ },
2362
+ {
2363
+ binding: "CONFLICTING_NAME_FOUR",
2364
+ bucket_name: "r2-bucket-four-name",
2365
+ },
2366
+ ],
2367
+ text_blobs: {
2368
+ CONFLICTING_NAME_THREE: "./my-entire-app-depends-on-this.cfg",
2369
+ CONFLICTING_NAME_FOUR: "./the-entirety-of-human-knowledge.txt",
2370
+ },
2371
+ unsafe: {
2372
+ bindings: [
2373
+ {
2374
+ name: "CONFLICTING_UNSAFE_NAME",
2375
+ type: "some unsafe thing",
2376
+ data: { some: { unsafe: "thing" } },
2377
+ },
2378
+ {
2379
+ name: "CONFLICTING_UNSAFE_NAME",
2380
+ type: "another unsafe thing",
2381
+ data: 1337,
2382
+ },
2383
+ {
2384
+ name: "CONFLICTING_NAME_THREE",
2385
+ type: "yet another unsafe thing",
2386
+ data: "how is a string unsafe?",
2387
+ },
2388
+ {
2389
+ name: "CONFLICTING_NAME_FOUR",
2390
+ type: "a fourth unsafe thing",
2391
+ data: null,
2392
+ },
2393
+ ],
2394
+ },
2395
+ vars: {
2396
+ ENV_VAR_ONE: 123,
2397
+ CONFLICTING_NAME_THREE: "Hello, I'm an environment variable",
2398
+ },
2399
+ wasm_modules: {
2400
+ WASM_MODULE_ONE: "./some_wasm.wasm",
2401
+ CONFLICTING_NAME_THREE: "./more_wasm.wasm",
2402
+ },
2403
+ });
2404
+
2405
+ writeWorkerSource({ type: "sw" });
2406
+ fs.writeFileSync("./my-entire-app-depends-on-this.cfg", "config = value");
2407
+ fs.writeFileSync(
2408
+ "./the-entirety-of-human-knowledge.txt",
2409
+ "Everything's bigger in Texas"
2410
+ );
2411
+ fs.writeFileSync("./some_wasm.wasm", "some wasm");
2412
+ fs.writeFileSync("./more_wasm.wasm", "more wasm");
2413
+
2414
+ await expect(runWrangler("publish index.js")).rejects
2415
+ .toMatchInlineSnapshot(`
2416
+ [Error: Processing wrangler.toml configuration:
2417
+ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings.
2418
+ - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings.
2419
+ - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings.
2420
+ - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings.
2421
+ - CONFLICTING_NAME_FOUR assigned to R2 Bucket, Text Blob, and Unsafe bindings.
2422
+ - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings.
2423
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2424
+ Please change your bindings to have unique names.]
2425
+ `);
2426
+ expect(std.out).toMatchInlineSnapshot(`""`);
2427
+ expect(std.err).toMatchInlineSnapshot(`
2428
+ "Processing wrangler.toml configuration:
2429
+ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings.
2430
+ - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings.
2431
+ - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings.
2432
+ - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings.
2433
+ - CONFLICTING_NAME_FOUR assigned to R2 Bucket, Text Blob, and Unsafe bindings.
2434
+ - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings.
2435
+ - Bindings must have unique names, so that they can all be referenced in the worker.
2436
+ Please change your bindings to have unique names.
2437
+
2438
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2439
+ `);
2440
+ expect(std.warn).toMatchInlineSnapshot(`
2441
+ "Processing wrangler.toml configuration:
2442
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2443
+ `);
2444
+ });
2445
+
2446
+ describe("[wasm_modules]", () => {
2447
+ it("should be able to define wasm modules for service-worker format workers", async () => {
2448
+ writeWranglerToml({
2449
+ wasm_modules: {
2450
+ TESTWASMNAME: "./path/to/test.wasm",
2451
+ },
2452
+ });
2453
+ writeWorkerSource({ type: "sw" });
2454
+ fs.mkdirSync("./path/to", { recursive: true });
2455
+ fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
2456
+ mockUploadWorkerRequest({
2457
+ expectedType: "sw",
2458
+ expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
2459
+ expectedBindings: [
2460
+ { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
2461
+ ],
2462
+ });
2463
+ mockSubDomainRequest();
2464
+ await runWrangler("publish index.js");
2465
+ expect(std.out).toMatchInlineSnapshot(`
2466
+ "Uploaded test-name (TIMINGS)
2467
+ Published test-name (TIMINGS)
2468
+ test-name.test-sub-domain.workers.dev"
2469
+ `);
2470
+ expect(std.err).toMatchInlineSnapshot(`""`);
2471
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2472
+ });
2473
+
2474
+ it("should error when defining wasm modules for modules format workers", async () => {
2475
+ writeWranglerToml({
2476
+ wasm_modules: {
2477
+ TESTWASMNAME: "./path/to/test.wasm",
2478
+ },
2479
+ });
2480
+ writeWorkerSource({ type: "esm" });
2481
+ fs.mkdirSync("./path/to", { recursive: true });
2482
+ fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
2483
+
2484
+ await expect(
2485
+ runWrangler("publish index.js")
2486
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
2487
+ `"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"`
2488
+ );
2489
+ expect(std.out).toMatchInlineSnapshot(`""`);
2490
+ expect(std.err).toMatchInlineSnapshot(`
2491
+ "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
2492
+
2493
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2494
+ `);
2495
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2496
+ });
2497
+
2498
+ it("should resolve wasm modules relative to the wrangler.toml file", async () => {
2499
+ fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
2500
+ fs.writeFileSync(
2501
+ "./path/to/wrangler.toml",
2502
+ TOML.stringify({
2503
+ compatibility_date: "2022-01-12",
2504
+ name: "test-name",
2505
+ wasm_modules: {
2506
+ TESTWASMNAME: "./and/the/path/to/test.wasm",
2507
+ },
2508
+ }),
2509
+
2510
+ "utf-8"
2511
+ );
2512
+
2513
+ writeWorkerSource({ type: "sw" });
2514
+ fs.writeFileSync(
2515
+ "./path/to/and/the/path/to/test.wasm",
2516
+ "SOME WASM CONTENT"
2517
+ );
2518
+ mockUploadWorkerRequest({
2519
+ expectedType: "sw",
2520
+ expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
2521
+ expectedBindings: [
2522
+ { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
2523
+ ],
2524
+ expectedCompatibilityDate: "2022-01-12",
2525
+ });
2526
+ mockSubDomainRequest();
2527
+ await runWrangler("publish index.js --config ./path/to/wrangler.toml");
2528
+ expect(std.out).toMatchInlineSnapshot(`
2529
+ "Uploaded test-name (TIMINGS)
2530
+ Published test-name (TIMINGS)
2531
+ test-name.test-sub-domain.workers.dev"
2532
+ `);
2533
+ expect(std.err).toMatchInlineSnapshot(`""`);
2534
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2535
+ });
2536
+
2537
+ it("should be able to import .wasm modules from service-worker format workers", async () => {
2538
+ writeWranglerToml();
2539
+ fs.writeFileSync(
2540
+ "./index.js",
2541
+ "import TESTWASMNAME from './test.wasm';"
2542
+ );
2543
+ fs.writeFileSync("./test.wasm", "SOME WASM CONTENT");
2544
+ mockUploadWorkerRequest({
2545
+ expectedType: "sw",
2546
+ expectedModules: {
2547
+ __94b240d0d692281e6467aa42043986e5c7eea034_test_wasm:
2548
+ "SOME WASM CONTENT",
2549
+ },
2550
+ expectedBindings: [
2551
+ {
2552
+ name: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
2553
+ part: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
2554
+ type: "wasm_module",
2555
+ },
2556
+ ],
2557
+ });
2558
+ mockSubDomainRequest();
2559
+ await runWrangler("publish index.js");
2560
+ expect(std.out).toMatchInlineSnapshot(`
2561
+ "Uploaded test-name (TIMINGS)
2562
+ Published test-name (TIMINGS)
2563
+ test-name.test-sub-domain.workers.dev"
2564
+ `);
2565
+ expect(std.err).toMatchInlineSnapshot(`""`);
2566
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2567
+ });
2568
+ });
2569
+
2570
+ describe("[text_blobs]", () => {
2571
+ it("should be able to define text blobs for service-worker format workers", async () => {
2572
+ writeWranglerToml({
2573
+ text_blobs: {
2574
+ TESTTEXTBLOBNAME: "./path/to/text.file",
2575
+ },
2576
+ });
2577
+ writeWorkerSource({ type: "sw" });
2578
+ fs.mkdirSync("./path/to", { recursive: true });
2579
+ fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
2580
+ mockUploadWorkerRequest({
2581
+ expectedType: "sw",
2582
+ expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
2583
+ expectedBindings: [
2584
+ {
2585
+ name: "TESTTEXTBLOBNAME",
2586
+ part: "TESTTEXTBLOBNAME",
2587
+ type: "text_blob",
2588
+ },
2589
+ ],
2590
+ });
2591
+ mockSubDomainRequest();
2592
+ await runWrangler("publish index.js");
2593
+ expect(std.out).toMatchInlineSnapshot(`
2594
+ "Uploaded test-name (TIMINGS)
2595
+ Published test-name (TIMINGS)
2596
+ test-name.test-sub-domain.workers.dev"
2597
+ `);
2598
+ expect(std.err).toMatchInlineSnapshot(`""`);
2599
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2600
+ });
2601
+
2602
+ it("should error when defining text blobs for modules format workers", async () => {
2603
+ writeWranglerToml({
2604
+ text_blobs: {
2605
+ TESTTEXTBLOBNAME: "./path/to/text.file",
2606
+ },
2607
+ });
2608
+ writeWorkerSource({ type: "esm" });
2609
+ fs.mkdirSync("./path/to", { recursive: true });
2610
+ fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
2611
+
2612
+ await expect(
2613
+ runWrangler("publish index.js")
2614
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
2615
+ `"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml"`
2616
+ );
2617
+ expect(std.out).toMatchInlineSnapshot(`""`);
2618
+ expect(std.err).toMatchInlineSnapshot(`
2619
+ "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml
2620
+
2621
+ %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2622
+ `);
2623
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2624
+ });
2625
+
2626
+ it("should resolve text blobs relative to the wrangler.toml file", async () => {
2627
+ fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
2628
+ fs.writeFileSync(
2629
+ "./path/to/wrangler.toml",
2630
+ TOML.stringify({
2631
+ compatibility_date: "2022-01-12",
2632
+ name: "test-name",
2633
+ text_blobs: {
2634
+ TESTTEXTBLOBNAME: "./and/the/path/to/text.file",
2635
+ },
2636
+ }),
2637
+
2638
+ "utf-8"
2639
+ );
2640
+
2641
+ writeWorkerSource({ type: "sw" });
2642
+ fs.writeFileSync(
2643
+ "./path/to/and/the/path/to/text.file",
2644
+ "SOME TEXT CONTENT"
2645
+ );
2646
+ mockUploadWorkerRequest({
2647
+ expectedType: "sw",
2648
+ expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
2649
+ expectedBindings: [
2650
+ {
2651
+ name: "TESTTEXTBLOBNAME",
2652
+ part: "TESTTEXTBLOBNAME",
2653
+ type: "text_blob",
2654
+ },
2655
+ ],
2656
+ expectedCompatibilityDate: "2022-01-12",
2657
+ });
2658
+ mockSubDomainRequest();
2659
+ await runWrangler("publish index.js --config ./path/to/wrangler.toml");
2660
+ expect(std.out).toMatchInlineSnapshot(`
2661
+ "Uploaded test-name (TIMINGS)
2662
+ Published test-name (TIMINGS)
2663
+ test-name.test-sub-domain.workers.dev"
2664
+ `);
2665
+ expect(std.err).toMatchInlineSnapshot(`""`);
2666
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2667
+ });
2668
+ });
2669
+
2670
+ describe("[vars]", () => {
2671
+ it("should support json bindings", async () => {
2672
+ writeWranglerToml({
2673
+ vars: {
2674
+ text: "plain ol' string",
2675
+ count: 1,
2676
+ complex: { enabled: true, id: 123 },
2677
+ },
2678
+ });
2679
+ writeWorkerSource();
2680
+ mockSubDomainRequest();
2681
+ mockUploadWorkerRequest({
2682
+ expectedBindings: [
2683
+ { name: "text", type: "plain_text", text: "plain ol' string" },
2684
+ { name: "count", type: "json", json: 1 },
2685
+ {
2686
+ name: "complex",
2687
+ type: "json",
2688
+ json: { enabled: true, id: 123 },
2689
+ },
2690
+ ],
2691
+ });
2692
+
2693
+ await runWrangler("publish index.js");
2694
+ expect(std.out).toMatchInlineSnapshot(`
2695
+ "Uploaded test-name (TIMINGS)
2696
+ Published test-name (TIMINGS)
2697
+ test-name.test-sub-domain.workers.dev"
2698
+ `);
2699
+ expect(std.err).toMatchInlineSnapshot(`""`);
2700
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2701
+ });
2702
+ });
2703
+
2704
+ describe("[r2_buckets]", () => {
2705
+ it("should support r2 bucket bindings", async () => {
2706
+ writeWranglerToml({
2707
+ r2_buckets: [{ binding: "FOO", bucket_name: "foo-bucket" }],
2708
+ });
2709
+ writeWorkerSource();
2710
+ mockSubDomainRequest();
2711
+ mockUploadWorkerRequest({
2712
+ expectedBindings: [
2713
+ { bucket_name: "foo-bucket", name: "FOO", type: "r2_bucket" },
2714
+ ],
2715
+ });
2716
+
2717
+ await runWrangler("publish index.js");
2718
+ expect(std.out).toMatchInlineSnapshot(`
2719
+ "Uploaded test-name (TIMINGS)
2720
+ Published test-name (TIMINGS)
2721
+ test-name.test-sub-domain.workers.dev"
2722
+ `);
2723
+ expect(std.err).toMatchInlineSnapshot(`""`);
2724
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1826
2725
  });
1827
- writeWorkerSource();
1828
- mockSubDomainRequest();
1829
- mockUploadWorkerRequest({
1830
- expectedBindings: [
1831
- { name: "text", type: "plain_text", text: "plain ol' string" },
1832
- { name: "count", type: "json", json: 1 },
1833
- {
1834
- name: "complex",
1835
- type: "json",
1836
- json: { enabled: true, id: 123 },
2726
+ });
2727
+
2728
+ describe("[durable_objects]", () => {
2729
+ it("should support durable object bindings", async () => {
2730
+ writeWranglerToml({
2731
+ durable_objects: {
2732
+ bindings: [
2733
+ {
2734
+ name: "EXAMPLE_DO_BINDING",
2735
+ class_name: "ExampleDurableObject",
2736
+ },
2737
+ ],
1837
2738
  },
1838
- ],
1839
- });
2739
+ });
2740
+ writeWorkerSource({ type: "esm" });
2741
+ mockSubDomainRequest();
2742
+ mockUploadWorkerRequest({
2743
+ expectedBindings: [
2744
+ {
2745
+ class_name: "ExampleDurableObject",
2746
+ name: "EXAMPLE_DO_BINDING",
2747
+ type: "durable_object_namespace",
2748
+ },
2749
+ ],
2750
+ });
1840
2751
 
1841
- await runWrangler("publish index.js");
1842
- expect(std.out).toMatchInlineSnapshot(`
1843
- "Uploaded
1844
- test-name
1845
- (TIMINGS)
1846
- Published
1847
- test-name
1848
- (TIMINGS)
2752
+ await runWrangler("publish index.js");
2753
+ expect(std.out).toMatchInlineSnapshot(`
2754
+ "Uploaded test-name (TIMINGS)
2755
+ Published test-name (TIMINGS)
2756
+ test-name.test-sub-domain.workers.dev"
2757
+ `);
2758
+ expect(std.err).toMatchInlineSnapshot(`""`);
2759
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2760
+ });
1849
2761
 
1850
- test-name.test-sub-domain.workers.dev"
1851
- `);
1852
- expect(std.err).toMatchInlineSnapshot(`""`);
1853
- expect(std.warn).toMatchInlineSnapshot(`""`);
1854
- });
1855
- });
2762
+ it("should support service-workers binding to external durable objects", async () => {
2763
+ writeWranglerToml({
2764
+ durable_objects: {
2765
+ bindings: [
2766
+ {
2767
+ name: "EXAMPLE_DO_BINDING",
2768
+ class_name: "ExampleDurableObject",
2769
+ script_name: "example-do-binding-worker",
2770
+ },
2771
+ ],
2772
+ },
2773
+ });
2774
+ writeWorkerSource({ type: "sw" });
2775
+ mockSubDomainRequest();
2776
+ mockUploadWorkerRequest({
2777
+ expectedType: "sw",
2778
+ expectedBindings: [
2779
+ {
2780
+ name: "EXAMPLE_DO_BINDING",
2781
+ class_name: "ExampleDurableObject",
2782
+ script_name: "example-do-binding-worker",
2783
+ type: "durable_object_namespace",
2784
+ },
2785
+ ],
2786
+ });
1856
2787
 
1857
- describe("r2 bucket bindings", () => {
1858
- it("should support r2 bucket bindings", async () => {
1859
- writeWranglerToml({
1860
- r2_buckets: [{ binding: "FOO", bucket_name: "foo-bucket" }],
2788
+ await runWrangler("publish index.js");
2789
+ expect(std.out).toMatchInlineSnapshot(`
2790
+ "Uploaded test-name (TIMINGS)
2791
+ Published test-name (TIMINGS)
2792
+ test-name.test-sub-domain.workers.dev"
2793
+ `);
2794
+ expect(std.err).toMatchInlineSnapshot(`""`);
2795
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1861
2796
  });
1862
- writeWorkerSource();
1863
- mockSubDomainRequest();
1864
- mockUploadWorkerRequest({
1865
- expectedBindings: [
1866
- { bucket_name: "foo-bucket", name: "FOO", type: "r2_bucket" },
1867
- ],
2797
+
2798
+ it("should support module workers implementing durable objects", async () => {
2799
+ writeWranglerToml({
2800
+ durable_objects: {
2801
+ bindings: [
2802
+ {
2803
+ name: "EXAMPLE_DO_BINDING",
2804
+ class_name: "ExampleDurableObject",
2805
+ },
2806
+ ],
2807
+ },
2808
+ });
2809
+ writeWorkerSource({ type: "esm" });
2810
+ mockSubDomainRequest();
2811
+ mockUploadWorkerRequest({
2812
+ expectedType: "esm",
2813
+ expectedBindings: [
2814
+ {
2815
+ name: "EXAMPLE_DO_BINDING",
2816
+ class_name: "ExampleDurableObject",
2817
+ type: "durable_object_namespace",
2818
+ },
2819
+ ],
2820
+ });
2821
+
2822
+ await runWrangler("publish index.js");
2823
+ expect(std.out).toMatchInlineSnapshot(`
2824
+ "Uploaded test-name (TIMINGS)
2825
+ Published test-name (TIMINGS)
2826
+ test-name.test-sub-domain.workers.dev"
2827
+ `);
2828
+ expect(std.err).toMatchInlineSnapshot(`""`);
2829
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1868
2830
  });
1869
2831
 
1870
- await runWrangler("publish index.js");
1871
- expect(std.out).toMatchInlineSnapshot(`
1872
- "Uploaded
1873
- test-name
1874
- (TIMINGS)
1875
- Published
1876
- test-name
1877
- (TIMINGS)
2832
+ it("should error when detecting service workers implementing durable objects", async () => {
2833
+ writeWranglerToml({
2834
+ durable_objects: {
2835
+ bindings: [
2836
+ {
2837
+ name: "EXAMPLE_DO_BINDING",
2838
+ class_name: "ExampleDurableObject",
2839
+ },
2840
+ ],
2841
+ },
2842
+ });
2843
+ writeWorkerSource({ type: "sw" });
2844
+ mockSubDomainRequest();
1878
2845
 
1879
- test-name.test-sub-domain.workers.dev"
1880
- `);
1881
- expect(std.err).toMatchInlineSnapshot(`""`);
1882
- expect(std.warn).toMatchInlineSnapshot(`""`);
2846
+ await expect(runWrangler("publish index.js")).rejects
2847
+ .toThrowErrorMatchingInlineSnapshot(`
2848
+ "You seem to be trying to use Durable Objects in a Worker written with Service Worker syntax.
2849
+ You can use Durable Objects defined in other Workers by specifying a \`script_name\` in your wrangler.toml, where \`script_name\` is the name of the Worker that implements that Durable Object. For example:
2850
+ { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject } ==> { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject, script_name = example-do-binding-worker }
2851
+ Alternatively, migrate your worker to ES Module syntax to implement a Durable Object in this Worker:
2852
+ https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
2853
+ `);
2854
+ });
1883
2855
  });
1884
- });
1885
2856
 
1886
- describe("unsafe bindings", () => {
1887
- it("should warn if using unsafe bindings", async () => {
1888
- writeWranglerToml({
1889
- unsafe: {
1890
- bindings: [
2857
+ describe("[unsafe]", () => {
2858
+ it("should warn if using unsafe bindings", async () => {
2859
+ writeWranglerToml({
2860
+ unsafe: {
2861
+ bindings: [
2862
+ {
2863
+ name: "my-binding",
2864
+ type: "binding-type",
2865
+ param: "binding-param",
2866
+ },
2867
+ ],
2868
+ },
2869
+ });
2870
+ writeWorkerSource();
2871
+ mockSubDomainRequest();
2872
+ mockUploadWorkerRequest({
2873
+ expectedBindings: [
1891
2874
  {
1892
2875
  name: "my-binding",
1893
2876
  type: "binding-type",
1894
2877
  param: "binding-param",
1895
2878
  },
1896
2879
  ],
1897
- },
2880
+ });
2881
+
2882
+ await runWrangler("publish index.js");
2883
+ expect(std.out).toMatchInlineSnapshot(`
2884
+ "Uploaded test-name (TIMINGS)
2885
+ Published test-name (TIMINGS)
2886
+ test-name.test-sub-domain.workers.dev"
2887
+ `);
2888
+ expect(std.err).toMatchInlineSnapshot(`""`);
2889
+ expect(std.warn).toMatchInlineSnapshot(`
2890
+ "Processing wrangler.toml configuration:
2891
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2892
+ `);
1898
2893
  });
1899
- writeWorkerSource();
1900
- mockSubDomainRequest();
1901
- mockUploadWorkerRequest({
1902
- expectedBindings: [
1903
- {
1904
- name: "my-binding",
1905
- type: "binding-type",
1906
- param: "binding-param",
2894
+ it("should warn if using unsafe bindings already handled by wrangler", async () => {
2895
+ writeWranglerToml({
2896
+ unsafe: {
2897
+ bindings: [
2898
+ {
2899
+ name: "my-binding",
2900
+ type: "plain_text",
2901
+ text: "text",
2902
+ },
2903
+ ],
1907
2904
  },
1908
- ],
1909
- });
1910
-
1911
- await runWrangler("publish index.js");
1912
- expect(std.out).toMatchInlineSnapshot(`
1913
- "Uploaded
1914
- test-name
1915
- (TIMINGS)
1916
- Published
1917
- test-name
1918
- (TIMINGS)
1919
-
1920
- test-name.test-sub-domain.workers.dev"
1921
- `);
1922
- expect(std.err).toMatchInlineSnapshot(`""`);
1923
- expect(std.warn).toMatchInlineSnapshot(`
1924
- "Processing wrangler.toml configuration:
1925
- - \\"unsafe\\" fields are experimental and may change or break at any time."
1926
- `);
1927
- });
1928
- it("should warn if using unsafe bindings already handled by wrangler", async () => {
1929
- writeWranglerToml({
1930
- unsafe: {
1931
- bindings: [
2905
+ });
2906
+ writeWorkerSource();
2907
+ mockSubDomainRequest();
2908
+ mockUploadWorkerRequest({
2909
+ expectedBindings: [
1932
2910
  {
1933
2911
  name: "my-binding",
1934
2912
  type: "plain_text",
1935
2913
  text: "text",
1936
2914
  },
1937
2915
  ],
1938
- },
1939
- });
1940
- writeWorkerSource();
1941
- mockSubDomainRequest();
1942
- mockUploadWorkerRequest({
1943
- expectedBindings: [
1944
- {
1945
- name: "my-binding",
1946
- type: "plain_text",
1947
- text: "text",
1948
- },
1949
- ],
1950
- });
1951
-
1952
- await runWrangler("publish index.js");
1953
- expect(std.out).toMatchInlineSnapshot(`
1954
- "Uploaded
1955
- test-name
1956
- (TIMINGS)
1957
- Published
1958
- test-name
1959
- (TIMINGS)
2916
+ });
1960
2917
 
1961
- test-name.test-sub-domain.workers.dev"
1962
- `);
1963
- expect(std.err).toMatchInlineSnapshot(`""`);
1964
- expect(std.warn).toMatchInlineSnapshot(`
1965
- "Processing wrangler.toml configuration:
1966
- - \\"unsafe\\" fields are experimental and may change or break at any time.
1967
- - \\"unsafe.bindings[0]\\": {\\"name\\":\\"my-binding\\",\\"type\\":\\"plain_text\\",\\"text\\":\\"text\\"}
1968
- - The binding type \\"plain_text\\" is directly supported by wrangler.
1969
- Consider migrating this unsafe binding to a format for 'plain_text' bindings that is supported by wrangler for optimal support.
1970
- For more details, see https://developers.cloudflare.com/workers/cli-wrangler/configuration"
1971
- `);
2918
+ await runWrangler("publish index.js");
2919
+ expect(std.out).toMatchInlineSnapshot(`
2920
+ "Uploaded test-name (TIMINGS)
2921
+ Published test-name (TIMINGS)
2922
+ test-name.test-sub-domain.workers.dev"
2923
+ `);
2924
+ expect(std.err).toMatchInlineSnapshot(`""`);
2925
+ expect(std.warn).toMatchInlineSnapshot(`
2926
+ "Processing wrangler.toml configuration:
2927
+ - \\"unsafe\\" fields are experimental and may change or break at any time.
2928
+ - \\"unsafe.bindings[0]\\": {\\"name\\":\\"my-binding\\",\\"type\\":\\"plain_text\\",\\"text\\":\\"text\\"}
2929
+ - The binding type \\"plain_text\\" is directly supported by wrangler.
2930
+ Consider migrating this unsafe binding to a format for 'plain_text' bindings that is supported by wrangler for optimal support.
2931
+ For more details, see https://developers.cloudflare.com/workers/cli-wrangler/configuration"
2932
+ `);
2933
+ });
1972
2934
  });
1973
2935
  });
1974
2936
 
@@ -1996,14 +2958,9 @@ export default{
1996
2958
  });
1997
2959
  await runWrangler("publish index.js");
1998
2960
  expect(std.out).toMatchInlineSnapshot(`
1999
- "Uploaded
2000
- test-name
2001
- (TIMINGS)
2002
- Published
2003
- test-name
2004
- (TIMINGS)
2005
-
2006
- test-name.test-sub-domain.workers.dev"
2961
+ "Uploaded test-name (TIMINGS)
2962
+ Published test-name (TIMINGS)
2963
+ test-name.test-sub-domain.workers.dev"
2007
2964
  `);
2008
2965
  expect(std.err).toMatchInlineSnapshot(`""`);
2009
2966
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -2029,14 +2986,9 @@ export default{
2029
2986
  });
2030
2987
  await runWrangler("publish index.js");
2031
2988
  expect(std.out).toMatchInlineSnapshot(`
2032
- "Uploaded
2033
- test-name
2034
- (TIMINGS)
2035
- Published
2036
- test-name
2037
- (TIMINGS)
2038
-
2039
- test-name.test-sub-domain.workers.dev"
2989
+ "Uploaded test-name (TIMINGS)
2990
+ Published test-name (TIMINGS)
2991
+ test-name.test-sub-domain.workers.dev"
2040
2992
  `);
2041
2993
  expect(std.err).toMatchInlineSnapshot(`""`);
2042
2994
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -2066,14 +3018,9 @@ export default{
2066
3018
  });
2067
3019
  await runWrangler("publish index.js");
2068
3020
  expect(std.out).toMatchInlineSnapshot(`
2069
- "Uploaded
2070
- test-name
2071
- (TIMINGS)
2072
- Published
2073
- test-name
2074
- (TIMINGS)
2075
-
2076
- test-name.test-sub-domain.workers.dev"
3021
+ "Uploaded test-name (TIMINGS)
3022
+ Published test-name (TIMINGS)
3023
+ test-name.test-sub-domain.workers.dev"
2077
3024
  `);
2078
3025
  expect(std.err).toMatchInlineSnapshot(`""`);
2079
3026
  expect(std.warn).toMatchInlineSnapshot(`
@@ -2114,14 +3061,9 @@ export default{
2114
3061
  });
2115
3062
  await runWrangler("publish index.js");
2116
3063
  expect(std.out).toMatchInlineSnapshot(`
2117
- "Uploaded
2118
- test-name
2119
- (TIMINGS)
2120
- Published
2121
- test-name
2122
- (TIMINGS)
2123
-
2124
- test-name.test-sub-domain.workers.dev"
3064
+ "Uploaded test-name (TIMINGS)
3065
+ Published test-name (TIMINGS)
3066
+ test-name.test-sub-domain.workers.dev"
2125
3067
  `);
2126
3068
  expect(std.err).toMatchInlineSnapshot(`""`);
2127
3069
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -2185,6 +3127,120 @@ export default{
2185
3127
  The default module rule {\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.txt\\",\\"**/*.html\\"]} has the same type as a previous rule (at position 0, {\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.file\\"]}). This rule will be ignored. To the previous rule, add \`fallthrough = true\` to allow the default one to also be used, or \`fallthrough = false\` to silence this warning."
2186
3128
  `);
2187
3129
  });
3130
+
3131
+ describe("inject process.env.NODE_ENV", () => {
3132
+ let actualProcessEnvNodeEnv: string | undefined;
3133
+ beforeEach(() => {
3134
+ actualProcessEnvNodeEnv = process.env.NODE_ENV;
3135
+ process.env.NODE_ENV = "some-node-env";
3136
+ });
3137
+ afterEach(() => {
3138
+ process.env.NODE_ENV = actualProcessEnvNodeEnv;
3139
+ });
3140
+ it("should replace `process.env.NODE_ENV` in scripts", async () => {
3141
+ writeWranglerToml();
3142
+ fs.writeFileSync(
3143
+ "./index.js",
3144
+ `export default {
3145
+ fetch(){
3146
+ return new Response(process.env.NODE_ENV);
3147
+ }
3148
+ }`
3149
+ );
3150
+ mockSubDomainRequest();
3151
+ mockUploadWorkerRequest({
3152
+ expectedEntry: `return new Response("some-node-env");`,
3153
+ });
3154
+ await runWrangler("publish index.js");
3155
+ expect(std.out).toMatchInlineSnapshot(`
3156
+ "Uploaded test-name (TIMINGS)
3157
+ Published test-name (TIMINGS)
3158
+ test-name.test-sub-domain.workers.dev"
3159
+ `);
3160
+ expect(std.err).toMatchInlineSnapshot(`""`);
3161
+ expect(std.warn).toMatchInlineSnapshot(`""`);
3162
+ });
3163
+ });
3164
+ });
3165
+
3166
+ describe("legacy module specifiers", () => {
3167
+ it("should work with legacy module specifiers, with a deprecation warning (1)", async () => {
3168
+ writeWranglerToml({
3169
+ rules: [{ type: "Text", globs: ["**/*.file"], fallthrough: false }],
3170
+ });
3171
+ fs.writeFileSync(
3172
+ "./index.js",
3173
+ `import TEXT from 'text.file'; export default {};`
3174
+ );
3175
+ fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
3176
+ mockSubDomainRequest();
3177
+ mockUploadWorkerRequest({
3178
+ expectedModules: {
3179
+ "./2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0-text.file":
3180
+ "SOME TEXT CONTENT",
3181
+ },
3182
+ });
3183
+ await runWrangler("publish index.js");
3184
+ expect(std.out).toMatchInlineSnapshot(`
3185
+ "Uploaded test-name (TIMINGS)
3186
+ Published test-name (TIMINGS)
3187
+ test-name.test-sub-domain.workers.dev"
3188
+ `);
3189
+ expect(std.err).toMatchInlineSnapshot(`""`);
3190
+ expect(std.warn).toMatchInlineSnapshot(
3191
+ `"Deprecation warning: detected a legacy module import in \\"./index.js\\". This will stop working in the future. Replace references to \\"text.file\\" with \\"./text.file\\";"`
3192
+ );
3193
+ });
3194
+ });
3195
+
3196
+ it("should work with legacy module specifiers, with a deprecation warning (2)", async () => {
3197
+ writeWranglerToml();
3198
+ fs.writeFileSync(
3199
+ "./index.js",
3200
+ `import WASM from 'index.wasm'; export default {};`
3201
+ );
3202
+ fs.writeFileSync("./index.wasm", "SOME WASM CONTENT");
3203
+ mockSubDomainRequest();
3204
+ mockUploadWorkerRequest({
3205
+ expectedModules: {
3206
+ "./94b240d0d692281e6467aa42043986e5c7eea034-index.wasm":
3207
+ "SOME WASM CONTENT",
3208
+ },
3209
+ });
3210
+ await runWrangler("publish index.js");
3211
+ expect(std.out).toMatchInlineSnapshot(`
3212
+ "Uploaded test-name (TIMINGS)
3213
+ Published test-name (TIMINGS)
3214
+ test-name.test-sub-domain.workers.dev"
3215
+ `);
3216
+ expect(std.err).toMatchInlineSnapshot(`""`);
3217
+ expect(std.warn).toMatchInlineSnapshot(
3218
+ `"Deprecation warning: detected a legacy module import in \\"./index.js\\". This will stop working in the future. Replace references to \\"index.wasm\\" with \\"./index.wasm\\";"`
3219
+ );
3220
+ });
3221
+
3222
+ it("should not match regular module specifiers when there aren't any possible legacy module matches", async () => {
3223
+ // see https://github.com/cloudflare/wrangler2/issues/655 for bug details
3224
+
3225
+ fs.writeFileSync(
3226
+ "./index.js",
3227
+ `import inner from './inner/index.js'; export default {};`
3228
+ );
3229
+ fs.mkdirSync("./inner", { recursive: true });
3230
+ fs.writeFileSync("./inner/index.js", `export default 123`);
3231
+ mockSubDomainRequest();
3232
+ mockUploadWorkerRequest();
3233
+
3234
+ await runWrangler(
3235
+ "publish index.js --compatibility-date 2022-03-17 --name test-name"
3236
+ );
3237
+ expect(std.out).toMatchInlineSnapshot(`
3238
+ "Uploaded test-name (TIMINGS)
3239
+ Published test-name (TIMINGS)
3240
+ test-name.test-sub-domain.workers.dev"
3241
+ `);
3242
+ expect(std.err).toMatchInlineSnapshot(`""`);
3243
+ expect(std.warn).toMatchInlineSnapshot(`""`);
2188
3244
  });
2189
3245
  });
2190
3246
 
@@ -2233,6 +3289,8 @@ function mockUploadWorkerRequest({
2233
3289
  expectedType = "esm",
2234
3290
  expectedBindings,
2235
3291
  expectedModules = {},
3292
+ expectedCompatibilityDate,
3293
+ expectedCompatibilityFlags,
2236
3294
  env = undefined,
2237
3295
  legacyEnv = false,
2238
3296
  }: {
@@ -2241,8 +3299,10 @@ function mockUploadWorkerRequest({
2241
3299
  expectedType?: "esm" | "sw";
2242
3300
  expectedBindings?: unknown;
2243
3301
  expectedModules?: Record<string, string>;
2244
- env?: string | undefined;
2245
- legacyEnv?: boolean | undefined;
3302
+ expectedCompatibilityDate?: string;
3303
+ expectedCompatibilityFlags?: string[];
3304
+ env?: string;
3305
+ legacyEnv?: boolean;
2246
3306
  } = {}) {
2247
3307
  setMockResponse(
2248
3308
  env && !legacyEnv
@@ -2264,7 +3324,6 @@ function mockUploadWorkerRequest({
2264
3324
  expectedEntry
2265
3325
  );
2266
3326
  }
2267
-
2268
3327
  const metadata = JSON.parse(
2269
3328
  formBody.get("metadata") as string
2270
3329
  ) as WorkerMetadata;
@@ -2276,6 +3335,14 @@ function mockUploadWorkerRequest({
2276
3335
  if (expectedBindings !== undefined) {
2277
3336
  expect(metadata.bindings).toEqual(expectedBindings);
2278
3337
  }
3338
+ if (expectedCompatibilityDate !== undefined) {
3339
+ expect(metadata.compatibility_date).toEqual(expectedCompatibilityDate);
3340
+ }
3341
+ if (expectedCompatibilityFlags !== undefined) {
3342
+ expect(metadata.compatibility_flags).toEqual(
3343
+ expectedCompatibilityFlags
3344
+ );
3345
+ }
2279
3346
  for (const [name, content] of Object.entries(expectedModules)) {
2280
3347
  expect(await (formBody.get(name) as File).text()).toEqual(content);
2281
3348
  }
@@ -2286,10 +3353,21 @@ function mockUploadWorkerRequest({
2286
3353
  }
2287
3354
 
2288
3355
  /** Create a mock handler for the request to get the account's subdomain. */
2289
- function mockSubDomainRequest(subdomain = "test-sub-domain") {
2290
- setMockResponse("/accounts/:accountId/workers/subdomain", "GET", () => {
2291
- return { subdomain };
2292
- });
3356
+ function mockSubDomainRequest(
3357
+ subdomain = "test-sub-domain",
3358
+ registeredWorkersDev = true
3359
+ ) {
3360
+ if (registeredWorkersDev) {
3361
+ setMockResponse("/accounts/:accountId/workers/subdomain", "GET", () => {
3362
+ return { subdomain };
3363
+ });
3364
+ } else {
3365
+ setMockRawResponse("/accounts/:accountId/workers/subdomain", "GET", () => {
3366
+ return createFetchResult(null, false, [
3367
+ { code: 10007, message: "haven't registered workers.dev" },
3368
+ ]);
3369
+ });
3370
+ }
2293
3371
  }
2294
3372
 
2295
3373
  /** Create a mock handler to toggle a <script>.<user>.workers.dev subdomain */
@@ -2370,7 +3448,12 @@ function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
2370
3448
  /** Create a mock handler for the request that tries to do a bulk upload of assets to a KV namespace. */
2371
3449
  function mockUploadAssetsToKVRequest(
2372
3450
  expectedNamespaceId: string,
2373
- assets: { filePath: string; content: string }[]
3451
+ assets: {
3452
+ filePath: string;
3453
+ content: string;
3454
+ expiration?: number;
3455
+ expiration_ttl?: number;
3456
+ }[]
2374
3457
  ) {
2375
3458
  setMockResponse(
2376
3459
  "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
@@ -2399,8 +3482,28 @@ function mockUploadAssetsToKVRequest(
2399
3482
  expect(Buffer.from(upload.value, "base64").toString()).toEqual(
2400
3483
  asset.content
2401
3484
  );
3485
+ expect(upload.expiration).toEqual(asset.expiration);
3486
+ expect(upload.expiration_ttl).toEqual(asset.expiration_ttl);
2402
3487
  }
2403
3488
  return null;
2404
3489
  }
2405
3490
  );
2406
3491
  }
3492
+
3493
+ /** Create a mock handler for thr request that does a bulk delete of unused assets */
3494
+ function mockDeleteUnusedAssetsRequest(
3495
+ expectedNamespaceId: string,
3496
+ assets: string[]
3497
+ ) {
3498
+ setMockResponse(
3499
+ "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
3500
+ "DELETE",
3501
+ ([_url, accountId, namespaceId], { body }) => {
3502
+ expect(accountId).toEqual("some-account-id");
3503
+ expect(namespaceId).toEqual(expectedNamespaceId);
3504
+ const deletes = JSON.parse(body as string);
3505
+ expect(assets).toEqual(deletes);
3506
+ return null;
3507
+ }
3508
+ );
3509
+ }