wrangler 0.0.13 → 0.0.17

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 (67) hide show
  1. package/bin/wrangler.js +2 -2
  2. package/package.json +20 -11
  3. package/pages/functions/buildWorker.ts +1 -1
  4. package/pages/functions/filepath-routing.test.ts +112 -28
  5. package/pages/functions/filepath-routing.ts +44 -51
  6. package/pages/functions/routes.ts +11 -18
  7. package/pages/functions/template-worker.ts +3 -9
  8. package/src/__tests__/dev.test.tsx +42 -5
  9. package/src/__tests__/guess-worker-format.test.ts +66 -0
  10. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  11. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  12. package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
  13. package/src/__tests__/helpers/mock-account-id.ts +30 -0
  14. package/src/__tests__/helpers/mock-bin.ts +36 -0
  15. package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +43 -9
  16. package/src/__tests__/helpers/mock-console.ts +62 -0
  17. package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
  18. package/src/__tests__/helpers/mock-kv.ts +40 -0
  19. package/src/__tests__/helpers/mock-user.ts +27 -0
  20. package/src/__tests__/helpers/mock-web-socket.ts +37 -0
  21. package/src/__tests__/{run-in-tmp.ts → helpers/run-in-tmp.ts} +1 -1
  22. package/src/__tests__/helpers/run-wrangler.ts +16 -0
  23. package/src/__tests__/helpers/write-wrangler-toml.ts +20 -0
  24. package/src/__tests__/index.test.ts +418 -71
  25. package/src/__tests__/jest.setup.ts +30 -2
  26. package/src/__tests__/kv.test.ts +147 -252
  27. package/src/__tests__/logout.test.ts +50 -0
  28. package/src/__tests__/package-manager.test.ts +206 -0
  29. package/src/__tests__/publish.test.ts +1136 -291
  30. package/src/__tests__/r2.test.ts +206 -0
  31. package/src/__tests__/secret.test.ts +210 -0
  32. package/src/__tests__/sentry.test.ts +146 -0
  33. package/src/__tests__/tail.test.ts +246 -0
  34. package/src/__tests__/whoami.test.tsx +6 -47
  35. package/src/api/form_data.ts +75 -25
  36. package/src/api/preview.ts +2 -2
  37. package/src/api/worker.ts +34 -15
  38. package/src/bundle.ts +127 -0
  39. package/src/cfetch/index.ts +7 -15
  40. package/src/cfetch/internal.ts +41 -6
  41. package/src/cli.ts +10 -0
  42. package/src/config.ts +125 -95
  43. package/src/dev.tsx +300 -193
  44. package/src/dialogs.tsx +2 -2
  45. package/src/guess-worker-format.ts +68 -0
  46. package/src/index.tsx +578 -192
  47. package/src/inspect.ts +29 -10
  48. package/src/kv.tsx +23 -17
  49. package/src/module-collection.ts +32 -12
  50. package/src/open-in-browser.ts +13 -0
  51. package/src/package-manager.ts +120 -0
  52. package/src/pages.tsx +28 -23
  53. package/src/paths.ts +26 -0
  54. package/src/proxy.ts +88 -14
  55. package/src/publish.ts +260 -297
  56. package/src/r2.ts +50 -0
  57. package/src/reporting.ts +115 -0
  58. package/src/sites.tsx +28 -27
  59. package/src/tail.tsx +178 -9
  60. package/src/user.tsx +58 -44
  61. package/templates/new-worker.js +15 -0
  62. package/templates/new-worker.ts +15 -0
  63. package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
  64. package/wrangler-dist/cli.js +124315 -104677
  65. package/wrangler-dist/cli.js.map +3 -3
  66. package/src/__tests__/mock-console.ts +0 -34
  67. package/src/__tests__/run-wrangler.ts +0 -8
@@ -1,15 +1,26 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import type { KVNamespaceInfo } from "../kv";
4
- import { mockKeyListRequest } from "./kv.test";
5
- import { setMockResponse, unsetAllMocks } from "./mock-cfetch";
6
- import { runInTempDir } from "./run-in-tmp";
7
- import { runWrangler } from "./run-wrangler";
8
- import { mockConsoleMethods } from "./mock-console";
9
- import type { Config } from "../config";
10
3
  import * as TOML from "@iarna/toml";
4
+ import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
5
+ import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
6
+ import { mockConsoleMethods } from "./helpers/mock-console";
7
+ import { mockKeyListRequest } from "./helpers/mock-kv";
8
+ import { runInTempDir } from "./helpers/run-in-tmp";
9
+ import { runWrangler } from "./helpers/run-wrangler";
10
+ import writeWranglerToml from "./helpers/write-wrangler-toml";
11
+ import type { WorkerMetadata } from "../api/form_data";
12
+ import type { KVNamespaceInfo } from "../kv";
13
+ import type { FormData, File } from "undici";
11
14
 
12
15
  describe("publish", () => {
16
+ beforeEach(() => {
17
+ // @ts-expect-error we're using a very simple setTimeout mock here
18
+ jest.spyOn(global, "setTimeout").mockImplementation((fn, _period) => {
19
+ fn();
20
+ });
21
+ });
22
+ mockAccountId();
23
+ mockApiToken();
13
24
  runInTempDir();
14
25
  const std = mockConsoleMethods();
15
26
 
@@ -17,87 +28,277 @@ describe("publish", () => {
17
28
  unsetAllMocks();
18
29
  });
19
30
 
31
+ it("should resolve wrangler.toml relative to the entrypoint", async () => {
32
+ fs.mkdirSync("./some-path/worker", { recursive: true });
33
+ fs.writeFileSync(
34
+ "./some-path/wrangler.toml",
35
+ TOML.stringify({
36
+ name: "test-name",
37
+ compatibility_date: "2022-01-12",
38
+ vars: { xyz: 123 },
39
+ }),
40
+ "utf-8"
41
+ );
42
+ writeWorkerSource({ basePath: "./some-path/worker" });
43
+ mockUploadWorkerRequest({
44
+ expectedBindings: [
45
+ {
46
+ json: 123,
47
+ name: "xyz",
48
+ type: "json",
49
+ },
50
+ ],
51
+ });
52
+ mockSubDomainRequest();
53
+ await runWrangler("publish ./some-path/worker/index.js");
54
+ expect(std.out).toMatchInlineSnapshot(`
55
+ "Uploaded
56
+ test-name
57
+ (TIMINGS)
58
+ Deployed
59
+ test-name
60
+ (TIMINGS)
61
+
62
+ test-name.test-sub-domain.workers.dev"
63
+ `);
64
+ expect(std.err).toMatchInlineSnapshot(`""`);
65
+ });
66
+
20
67
  describe("entry-points", () => {
21
- it("should be able to use `index` with no extension as the entry-point", async () => {
68
+ it("should be able to use `index` with no extension as the entry-point (esm)", async () => {
22
69
  writeWranglerToml();
23
- writeEsmWorkerSource();
24
- mockUploadWorkerRequest();
70
+ writeWorkerSource();
71
+ mockUploadWorkerRequest({ expectedType: "esm" });
72
+ mockSubDomainRequest();
73
+
74
+ await runWrangler("publish ./index");
75
+
76
+ expect(std.out).toMatchInlineSnapshot(`
77
+ "Uploaded
78
+ test-name
79
+ (TIMINGS)
80
+ Deployed
81
+ test-name
82
+ (TIMINGS)
83
+
84
+ test-name.test-sub-domain.workers.dev"
85
+ `);
86
+ expect(std.err).toMatchInlineSnapshot(`""`);
87
+ });
88
+
89
+ it("should be able to use `index` with no extension as the entry-point (sw)", async () => {
90
+ writeWranglerToml();
91
+ writeWorkerSource({ type: "sw" });
92
+ mockUploadWorkerRequest({ expectedType: "sw" });
25
93
  mockSubDomainRequest();
26
94
 
27
95
  await runWrangler("publish ./index");
28
96
 
29
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
30
- "Uploaded
31
- test-name
32
- (TIMINGS)
33
- Deployed
34
- test-name
35
- (TIMINGS)
36
-
37
- test-name.test-sub-domain.workers.dev"
38
- `);
97
+ expect(std.out).toMatchInlineSnapshot(`
98
+ "Uploaded
99
+ test-name
100
+ (TIMINGS)
101
+ Deployed
102
+ test-name
103
+ (TIMINGS)
104
+
105
+ test-name.test-sub-domain.workers.dev"
106
+ `);
39
107
  expect(std.err).toMatchInlineSnapshot(`""`);
40
108
  });
41
109
 
42
110
  it("should be able to use the `build.upload.main` config as the entry-point for ESM sources", async () => {
43
111
  writeWranglerToml({ build: { upload: { main: "./index.js" } } });
44
- writeEsmWorkerSource();
112
+ writeWorkerSource();
45
113
  mockUploadWorkerRequest();
46
114
  mockSubDomainRequest();
47
115
 
48
116
  await runWrangler("publish");
49
117
 
50
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
51
- "Uploaded
52
- test-name
53
- (TIMINGS)
54
- Deployed
55
- test-name
56
- (TIMINGS)
57
-
58
- test-name.test-sub-domain.workers.dev"
59
- `);
118
+ expect(std.out).toMatchInlineSnapshot(`
119
+ "Uploaded
120
+ test-name
121
+ (TIMINGS)
122
+ Deployed
123
+ test-name
124
+ (TIMINGS)
125
+
126
+ test-name.test-sub-domain.workers.dev"
127
+ `);
128
+ expect(std.err).toMatchInlineSnapshot(`""`);
129
+ });
130
+
131
+ it("should use `build.upload.main` relative to the wrangler.toml not cwd", async () => {
132
+ writeWranglerToml({
133
+ build: {
134
+ upload: {
135
+ main: "./foo/index.js",
136
+ },
137
+ },
138
+ });
139
+ writeWorkerSource({ basePath: "foo" });
140
+ mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
141
+ mockSubDomainRequest();
142
+ process.chdir("foo");
143
+ await runWrangler("publish");
144
+
145
+ expect(std.out).toMatchInlineSnapshot(`
146
+ "Uploaded
147
+ test-name
148
+ (TIMINGS)
149
+ Deployed
150
+ test-name
151
+ (TIMINGS)
152
+
153
+ test-name.test-sub-domain.workers.dev"
154
+ `);
155
+ expect(std.err).toMatchInlineSnapshot(`""`);
156
+ });
157
+
158
+ it("should use `build.upload.main` relative to `build.upload.dir` if format is `modules`", async () => {
159
+ writeWranglerToml({
160
+ build: {
161
+ upload: {
162
+ format: "modules",
163
+ main: "./index.js",
164
+ dir: "./foo",
165
+ },
166
+ },
167
+ });
168
+ writeWorkerSource({ basePath: "./foo" });
169
+ mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
170
+ mockSubDomainRequest();
171
+ process.chdir("foo");
172
+ await runWrangler("publish");
173
+
174
+ expect(std.out).toMatchInlineSnapshot(`
175
+ "Uploaded
176
+ test-name
177
+ (TIMINGS)
178
+ Deployed
179
+ test-name
180
+ (TIMINGS)
181
+
182
+ test-name.test-sub-domain.workers.dev"
183
+ `);
184
+ expect(std.err).toMatchInlineSnapshot(`""`);
185
+ });
186
+
187
+ it("should be able to transpile TypeScript (esm)", async () => {
188
+ writeWranglerToml();
189
+ writeWorkerSource({ format: "ts" });
190
+ mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
191
+ mockSubDomainRequest();
192
+ await runWrangler("publish index.ts");
193
+
194
+ expect(std.out).toMatchInlineSnapshot(`
195
+ "Uploaded
196
+ test-name
197
+ (TIMINGS)
198
+ Deployed
199
+ test-name
200
+ (TIMINGS)
201
+
202
+ test-name.test-sub-domain.workers.dev"
203
+ `);
60
204
  expect(std.err).toMatchInlineSnapshot(`""`);
61
205
  });
62
206
 
63
- it("should be able to transpile TypeScript", async () => {
207
+ it("should be able to transpile TypeScript (sw)", async () => {
64
208
  writeWranglerToml();
65
- writeEsmWorkerSource({ format: "ts" });
66
- mockUploadWorkerRequest({ expectedBody: "var foo = 100;" });
209
+ writeWorkerSource({ format: "ts", type: "sw" });
210
+ mockUploadWorkerRequest({
211
+ expectedEntry: "var foo = 100;",
212
+ expectedType: "sw",
213
+ });
67
214
  mockSubDomainRequest();
68
215
  await runWrangler("publish index.ts");
69
216
 
70
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
71
- "Uploaded
72
- test-name
73
- (TIMINGS)
74
- Deployed
75
- test-name
76
- (TIMINGS)
77
-
78
- test-name.test-sub-domain.workers.dev"
79
- `);
217
+ expect(std.out).toMatchInlineSnapshot(`
218
+ "Uploaded
219
+ test-name
220
+ (TIMINGS)
221
+ Deployed
222
+ test-name
223
+ (TIMINGS)
224
+
225
+ test-name.test-sub-domain.workers.dev"
226
+ `);
227
+ expect(std.err).toMatchInlineSnapshot(`""`);
228
+ });
229
+
230
+ it("should inline referenced text modules into the worker", async () => {
231
+ writeWranglerToml();
232
+ fs.writeFileSync(
233
+ "./index.js",
234
+ `
235
+ import txt from './textfile.txt';
236
+ export default{
237
+ fetch(){
238
+ return new Response(txt);
239
+ }
240
+ }
241
+ `
242
+ );
243
+ fs.writeFileSync("./textfile.txt", "Hello, World!");
244
+ mockUploadWorkerRequest({ expectedEntry: "Hello, World!" });
245
+ mockSubDomainRequest();
246
+ await runWrangler("publish index.js");
247
+ expect(std.out).toMatchInlineSnapshot(`
248
+ "Uploaded
249
+ test-name
250
+ (TIMINGS)
251
+ Deployed
252
+ test-name
253
+ (TIMINGS)
254
+
255
+ test-name.test-sub-domain.workers.dev"
256
+ `);
257
+ expect(std.err).toMatchInlineSnapshot(`""`);
258
+ });
259
+
260
+ it("should be able to transpile entry-points in sub-directories (esm)", async () => {
261
+ writeWranglerToml();
262
+ writeWorkerSource({ basePath: "./src" });
263
+ mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
264
+ mockSubDomainRequest();
265
+
266
+ await runWrangler("publish ./src/index.js");
267
+
268
+ expect(std.out).toMatchInlineSnapshot(`
269
+ "Uploaded
270
+ test-name
271
+ (TIMINGS)
272
+ Deployed
273
+ test-name
274
+ (TIMINGS)
275
+
276
+ test-name.test-sub-domain.workers.dev"
277
+ `);
80
278
  expect(std.err).toMatchInlineSnapshot(`""`);
81
279
  });
82
280
 
83
- it("should be able to transpile entry-points in sub-directories", async () => {
281
+ it("should be able to transpile entry-points in sub-directories (sw)", async () => {
84
282
  writeWranglerToml();
85
- writeEsmWorkerSource({ basePath: "./src" });
86
- mockUploadWorkerRequest({ expectedBody: "var foo = 100;" });
283
+ writeWorkerSource({ basePath: "./src", type: "sw" });
284
+ mockUploadWorkerRequest({
285
+ expectedEntry: "var foo = 100;",
286
+ expectedType: "sw",
287
+ });
87
288
  mockSubDomainRequest();
88
289
 
89
290
  await runWrangler("publish ./src/index.js");
90
291
 
91
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
92
- "Uploaded
93
- test-name
94
- (TIMINGS)
95
- Deployed
96
- test-name
97
- (TIMINGS)
98
-
99
- test-name.test-sub-domain.workers.dev"
100
- `);
292
+ expect(std.out).toMatchInlineSnapshot(`
293
+ "Uploaded
294
+ test-name
295
+ (TIMINGS)
296
+ Deployed
297
+ test-name
298
+ (TIMINGS)
299
+
300
+ test-name.test-sub-domain.workers.dev"
301
+ `);
101
302
  expect(std.err).toMatchInlineSnapshot(`""`);
102
303
  });
103
304
 
@@ -108,19 +309,19 @@ describe("publish", () => {
108
309
  "entry-point": "./index.js",
109
310
  },
110
311
  });
111
- writeEsmWorkerSource();
312
+ writeWorkerSource();
112
313
  mockUploadWorkerRequest();
113
314
  mockSubDomainRequest();
114
- let error: Error | undefined;
115
- try {
116
- await runWrangler("publish ./index.js");
117
- } catch (e) {
118
- error = e;
119
- }
315
+
316
+ await expect(
317
+ runWrangler("publish ./index.js")
318
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
319
+ `"A [site] definition requires a \`bucket\` field with a path to the site's public directory."`
320
+ );
120
321
 
121
322
  expect(std.out).toMatchInlineSnapshot(`""`);
122
323
  expect(std.err).toMatchInlineSnapshot(`
123
- "A [site] definition requires a \`bucket\` field with a path to the site's public directory.
324
+ "AssertionError [ERR_ASSERTION]: A [site] definition requires a \`bucket\` field with a path to the site's public directory.
124
325
 
125
326
  %s
126
327
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
@@ -130,9 +331,6 @@ describe("publish", () => {
130
331
  The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.
131
332
  Please remove the \`site.entry-point\` field from the \`wrangler.toml\` file."
132
333
  `);
133
- expect(error).toMatchInlineSnapshot(
134
- `[AssertionError: A [site] definition requires a \`bucket\` field with a path to the site's public directory.]`
135
- );
136
334
  });
137
335
 
138
336
  it("should warn if there is a `site.entry-point` configuration", async () => {
@@ -141,8 +339,8 @@ describe("publish", () => {
141
339
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
142
340
  ];
143
341
  const kvNamespace = {
144
- title: "__test-name_sites_assets",
145
- id: "__test-name_sites_assets-id",
342
+ title: "__test-name-workers_sites_assets",
343
+ id: "__test-name-workers_sites_assets-id",
146
344
  };
147
345
 
148
346
  writeWranglerToml({
@@ -151,7 +349,7 @@ describe("publish", () => {
151
349
  bucket: "assets",
152
350
  },
153
351
  });
154
- writeEsmWorkerSource();
352
+ writeWorkerSource();
155
353
  writeAssets(assets);
156
354
  mockUploadWorkerRequest();
157
355
  mockSubDomainRequest();
@@ -161,7 +359,7 @@ describe("publish", () => {
161
359
 
162
360
  await runWrangler("publish ./index.js");
163
361
 
164
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
362
+ expect(std.out).toMatchInlineSnapshot(`
165
363
  "reading assets/file-1.txt...
166
364
  uploading as assets/file-1.2ca234f380.txt...
167
365
  reading assets/file-2.txt...
@@ -172,7 +370,7 @@ describe("publish", () => {
172
370
  Deployed
173
371
  test-name
174
372
  (TIMINGS)
175
-
373
+
176
374
  test-name.test-sub-domain.workers.dev"
177
375
  `);
178
376
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -185,26 +383,22 @@ describe("publish", () => {
185
383
 
186
384
  it("should error if there is no entry-point specified", async () => {
187
385
  writeWranglerToml();
188
- writeEsmWorkerSource();
386
+ writeWorkerSource();
189
387
  mockUploadWorkerRequest();
190
388
  mockSubDomainRequest();
191
- let error: Error | undefined;
192
- try {
193
- await runWrangler("publish");
194
- } catch (e) {
195
- error = e;
196
- }
389
+ await expect(
390
+ runWrangler("publish")
391
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
392
+ `"Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field."`
393
+ );
197
394
 
198
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`""`);
395
+ expect(std.out).toMatchInlineSnapshot(`""`);
199
396
  expect(std.err).toMatchInlineSnapshot(`
200
397
  "Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.
201
398
 
202
399
  %s
203
400
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
204
401
  `);
205
- expect(error).toMatchInlineSnapshot(
206
- `[Error: Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.]`
207
- );
208
402
  });
209
403
  });
210
404
 
@@ -215,8 +409,8 @@ describe("publish", () => {
215
409
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
216
410
  ];
217
411
  const kvNamespace = {
218
- title: "__test-name_sites_assets",
219
- id: "__test-name_sites_assets-id",
412
+ title: "__test-name-workers_sites_assets",
413
+ id: "__test-name-workers_sites_assets-id",
220
414
  };
221
415
  writeWranglerToml({
222
416
  build: { upload: { main: "./index.js" } },
@@ -224,7 +418,7 @@ describe("publish", () => {
224
418
  bucket: "assets",
225
419
  },
226
420
  });
227
- writeEsmWorkerSource();
421
+ writeWorkerSource();
228
422
  writeAssets(assets);
229
423
  mockUploadWorkerRequest();
230
424
  mockSubDomainRequest();
@@ -233,7 +427,7 @@ describe("publish", () => {
233
427
  mockUploadAssetsToKVRequest(kvNamespace.id, assets);
234
428
  await runWrangler("publish");
235
429
 
236
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
430
+ expect(std.out).toMatchInlineSnapshot(`
237
431
  "reading assets/file-1.txt...
238
432
  uploading as assets/file-1.2ca234f380.txt...
239
433
  reading assets/file-2.txt...
@@ -244,20 +438,20 @@ describe("publish", () => {
244
438
  Deployed
245
439
  test-name
246
440
  (TIMINGS)
247
-
441
+
248
442
  test-name.test-sub-domain.workers.dev"
249
443
  `);
250
444
  expect(std.err).toMatchInlineSnapshot(`""`);
251
445
  });
252
446
 
253
- it("should only upload files that are not already in the KV namespace", async () => {
447
+ it("when using a service worker type, it should inline an asset manifest, and bind to a namespace", async () => {
254
448
  const assets = [
255
449
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
256
450
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
257
451
  ];
258
452
  const kvNamespace = {
259
- title: "__test-name_sites_assets",
260
- id: "__test-name_sites_assets-id",
453
+ title: "__test-name-workers_sites_assets",
454
+ id: "__test-name-workers_sites_assets-id",
261
455
  };
262
456
  writeWranglerToml({
263
457
  build: { upload: { main: "./index.js" } },
@@ -265,23 +459,29 @@ describe("publish", () => {
265
459
  bucket: "assets",
266
460
  },
267
461
  });
268
- writeEsmWorkerSource();
462
+ writeWorkerSource({ type: "sw" });
269
463
  writeAssets(assets);
270
- mockUploadWorkerRequest();
464
+ mockUploadWorkerRequest({
465
+ expectedType: "sw",
466
+ expectedEntry: `const __STATIC_CONTENT_MANIFEST = {"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"};`,
467
+ expectedBindings: [
468
+ {
469
+ name: "__STATIC_CONTENT",
470
+ namespace_id: "__test-name-workers_sites_assets-id",
471
+ type: "kv_namespace",
472
+ },
473
+ ],
474
+ });
271
475
  mockSubDomainRequest();
272
476
  mockListKVNamespacesRequest(kvNamespace);
273
- // Put file-1 in the KV namespace
274
- mockKeyListRequest(kvNamespace.id, ["assets/file-1.2ca234f380.txt"]);
275
- // Check we do not upload file-1
276
- mockUploadAssetsToKVRequest(
277
- kvNamespace.id,
278
- assets.filter((a) => a.filePath !== "assets/file-1.txt")
279
- );
477
+ mockKeyListRequest(kvNamespace.id, []);
478
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets);
479
+
280
480
  await runWrangler("publish");
281
481
 
282
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
482
+ expect(std.out).toMatchInlineSnapshot(`
283
483
  "reading assets/file-1.txt...
284
- skipping - already uploaded
484
+ uploading as assets/file-1.2ca234f380.txt...
285
485
  reading assets/file-2.txt...
286
486
  uploading as assets/file-2.5938485188.txt...
287
487
  Uploaded
@@ -290,20 +490,20 @@ describe("publish", () => {
290
490
  Deployed
291
491
  test-name
292
492
  (TIMINGS)
293
-
493
+
294
494
  test-name.test-sub-domain.workers.dev"
295
495
  `);
296
496
  expect(std.err).toMatchInlineSnapshot(`""`);
297
497
  });
298
498
 
299
- it("should only upload files that match the `site-include` arg", async () => {
499
+ it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
300
500
  const assets = [
301
501
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
302
502
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
303
503
  ];
304
504
  const kvNamespace = {
305
- title: "__test-name_sites_assets",
306
- id: "__test-name_sites_assets-id",
505
+ title: "__test-name-workers_sites_assets",
506
+ id: "__test-name-workers_sites_assets-id",
307
507
  };
308
508
  writeWranglerToml({
309
509
  build: { upload: { main: "./index.js" } },
@@ -311,42 +511,54 @@ describe("publish", () => {
311
511
  bucket: "assets",
312
512
  },
313
513
  });
314
- writeEsmWorkerSource();
514
+ writeWorkerSource({ type: "esm" });
315
515
  writeAssets(assets);
316
- mockUploadWorkerRequest();
516
+ mockUploadWorkerRequest({
517
+ expectedBindings: [
518
+ {
519
+ name: "__STATIC_CONTENT",
520
+ namespace_id: "__test-name-workers_sites_assets-id",
521
+ type: "kv_namespace",
522
+ },
523
+ ],
524
+ expectedModules: {
525
+ __STATIC_CONTENT_MANIFEST:
526
+ '{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
527
+ },
528
+ });
317
529
  mockSubDomainRequest();
318
530
  mockListKVNamespacesRequest(kvNamespace);
319
531
  mockKeyListRequest(kvNamespace.id, []);
320
- // Check we only upload file-1
321
- mockUploadAssetsToKVRequest(
322
- kvNamespace.id,
323
- assets.filter((a) => a.filePath === "assets/file-1.txt")
324
- );
325
- await runWrangler("publish --site-include file-1.txt");
532
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets);
326
533
 
327
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
328
- "reading assets/file-1.txt...
329
- uploading as assets/file-1.2ca234f380.txt...
330
- Uploaded
331
- test-name
332
- (TIMINGS)
333
- Deployed
334
- test-name
335
- (TIMINGS)
336
-
337
- test-name.test-sub-domain.workers.dev"
338
- `);
534
+ await runWrangler("publish");
535
+
536
+ expect(std.out).toMatchInlineSnapshot(`
537
+ "reading assets/file-1.txt...
538
+ uploading as assets/file-1.2ca234f380.txt...
539
+ reading assets/file-2.txt...
540
+ uploading as assets/file-2.5938485188.txt...
541
+ Uploaded
542
+ test-name
543
+ (TIMINGS)
544
+ Deployed
545
+ test-name
546
+ (TIMINGS)
547
+
548
+ test-name.test-sub-domain.workers.dev"
549
+ `);
339
550
  expect(std.err).toMatchInlineSnapshot(`""`);
340
551
  });
341
552
 
342
- it("should not upload files that match the `site-exclude` arg", async () => {
553
+ it("should make environment specific kv namespace for assets", async () => {
554
+ // This is the same test as the one before this, but with an env arg
343
555
  const assets = [
344
556
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
345
557
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
346
558
  ];
347
559
  const kvNamespace = {
348
- title: "__test-name_sites_assets",
349
- id: "__test-name_sites_assets-id",
560
+ title: "__test-name-some-env-workers_sites_assets",
561
+ id: "__test-name-some-env-workers_sites_assets-id",
350
562
  };
351
563
  writeWranglerToml({
352
564
  build: { upload: { main: "./index.js" } },
@@ -354,95 +566,234 @@ describe("publish", () => {
354
566
  bucket: "assets",
355
567
  },
356
568
  });
357
- writeEsmWorkerSource();
569
+ writeWorkerSource();
358
570
  writeAssets(assets);
359
- mockUploadWorkerRequest();
571
+ mockUploadWorkerRequest({
572
+ env: "some-env",
573
+ expectedBindings: [
574
+ {
575
+ name: "__STATIC_CONTENT",
576
+ namespace_id: "__test-name-some-env-workers_sites_assets-id",
577
+ type: "kv_namespace",
578
+ },
579
+ ],
580
+ });
360
581
  mockSubDomainRequest();
361
582
  mockListKVNamespacesRequest(kvNamespace);
362
583
  mockKeyListRequest(kvNamespace.id, []);
363
- // Check we only upload file-1
364
- mockUploadAssetsToKVRequest(
365
- kvNamespace.id,
366
- assets.filter((a) => a.filePath === "assets/file-1.txt")
367
- );
368
- await runWrangler("publish --site-exclude file-2.txt");
584
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets);
585
+ await runWrangler("publish --env some-env");
586
+
587
+ expect(std.out).toMatchInlineSnapshot(`
588
+ "reading assets/file-1.txt...
589
+ uploading as assets/file-1.2ca234f380.txt...
590
+ reading assets/file-2.txt...
591
+ uploading as assets/file-2.5938485188.txt...
592
+ Uploaded
593
+ test-name (some-env)
594
+ (TIMINGS)
595
+ Deployed
596
+ test-name (some-env)
597
+ (TIMINGS)
369
598
 
370
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
371
- "reading assets/file-1.txt...
372
- uploading as assets/file-1.2ca234f380.txt...
373
- Uploaded
374
- test-name
375
- (TIMINGS)
376
- Deployed
377
- test-name
378
- (TIMINGS)
379
-
380
- test-name.test-sub-domain.workers.dev"
381
- `);
599
+ some-env.test-name.test-sub-domain.workers.dev"
600
+ `);
382
601
  expect(std.err).toMatchInlineSnapshot(`""`);
383
602
  });
384
603
 
385
- it("should only upload files that match the `site.include` config", async () => {
604
+ it("should only upload files that are not already in the KV namespace", async () => {
386
605
  const assets = [
387
606
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
388
607
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
389
608
  ];
390
609
  const kvNamespace = {
391
- title: "__test-name_sites_assets",
392
- id: "__test-name_sites_assets-id",
610
+ title: "__test-name-workers_sites_assets",
611
+ id: "__test-name-workers_sites_assets-id",
393
612
  };
394
613
  writeWranglerToml({
395
614
  build: { upload: { main: "./index.js" } },
396
615
  site: {
397
616
  bucket: "assets",
398
- include: ["file-1.txt"],
399
617
  },
400
618
  });
401
- writeEsmWorkerSource();
619
+ writeWorkerSource();
402
620
  writeAssets(assets);
403
621
  mockUploadWorkerRequest();
404
622
  mockSubDomainRequest();
405
623
  mockListKVNamespacesRequest(kvNamespace);
406
- mockKeyListRequest(kvNamespace.id, []);
407
- // Check we only upload file-1
624
+ // Put file-1 in the KV namespace
625
+ mockKeyListRequest(kvNamespace.id, ["assets/file-1.2ca234f380.txt"]);
626
+ // Check we do not upload file-1
408
627
  mockUploadAssetsToKVRequest(
409
628
  kvNamespace.id,
410
- assets.filter((a) => a.filePath === "assets/file-1.txt")
629
+ assets.filter((a) => a.filePath !== "assets/file-1.txt")
411
630
  );
412
631
  await runWrangler("publish");
413
632
 
414
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
415
- "reading assets/file-1.txt...
416
- uploading as assets/file-1.2ca234f380.txt...
417
- Uploaded
418
- test-name
419
- (TIMINGS)
420
- Deployed
421
- test-name
422
- (TIMINGS)
423
-
424
- test-name.test-sub-domain.workers.dev"
425
- `);
633
+ expect(std.out).toMatchInlineSnapshot(`
634
+ "reading assets/file-1.txt...
635
+ skipping - already uploaded
636
+ reading assets/file-2.txt...
637
+ uploading as assets/file-2.5938485188.txt...
638
+ Uploaded
639
+ test-name
640
+ (TIMINGS)
641
+ Deployed
642
+ test-name
643
+ (TIMINGS)
644
+
645
+ test-name.test-sub-domain.workers.dev"
646
+ `);
426
647
  expect(std.err).toMatchInlineSnapshot(`""`);
427
648
  });
428
649
 
429
- it("should not upload files that match the `site.exclude` config", async () => {
650
+ it("should only upload files that match the `site-include` arg", async () => {
430
651
  const assets = [
431
652
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
432
653
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
433
654
  ];
434
655
  const kvNamespace = {
435
- title: "__test-name_sites_assets",
436
- id: "__test-name_sites_assets-id",
656
+ title: "__test-name-workers_sites_assets",
657
+ id: "__test-name-workers_sites_assets-id",
437
658
  };
438
659
  writeWranglerToml({
439
660
  build: { upload: { main: "./index.js" } },
440
661
  site: {
441
662
  bucket: "assets",
442
- exclude: ["file-2.txt"],
443
663
  },
444
664
  });
445
- writeEsmWorkerSource();
665
+ writeWorkerSource();
666
+ writeAssets(assets);
667
+ mockUploadWorkerRequest();
668
+ mockSubDomainRequest();
669
+ mockListKVNamespacesRequest(kvNamespace);
670
+ mockKeyListRequest(kvNamespace.id, []);
671
+ // Check we only upload file-1
672
+ mockUploadAssetsToKVRequest(
673
+ kvNamespace.id,
674
+ assets.filter((a) => a.filePath === "assets/file-1.txt")
675
+ );
676
+ await runWrangler("publish --site-include file-1.txt");
677
+
678
+ expect(std.out).toMatchInlineSnapshot(`
679
+ "reading assets/file-1.txt...
680
+ uploading as assets/file-1.2ca234f380.txt...
681
+ Uploaded
682
+ test-name
683
+ (TIMINGS)
684
+ Deployed
685
+ test-name
686
+ (TIMINGS)
687
+
688
+ test-name.test-sub-domain.workers.dev"
689
+ `);
690
+ expect(std.err).toMatchInlineSnapshot(`""`);
691
+ });
692
+
693
+ it("should not upload files that match the `site-exclude` arg", async () => {
694
+ const assets = [
695
+ { filePath: "assets/file-1.txt", content: "Content of file-1" },
696
+ { filePath: "assets/file-2.txt", content: "Content of file-2" },
697
+ ];
698
+ const kvNamespace = {
699
+ title: "__test-name-workers_sites_assets",
700
+ id: "__test-name-workers_sites_assets-id",
701
+ };
702
+ writeWranglerToml({
703
+ build: { upload: { main: "./index.js" } },
704
+ site: {
705
+ bucket: "assets",
706
+ },
707
+ });
708
+ writeWorkerSource();
709
+ writeAssets(assets);
710
+ mockUploadWorkerRequest();
711
+ mockSubDomainRequest();
712
+ mockListKVNamespacesRequest(kvNamespace);
713
+ mockKeyListRequest(kvNamespace.id, []);
714
+ // Check we only upload file-1
715
+ mockUploadAssetsToKVRequest(
716
+ kvNamespace.id,
717
+ assets.filter((a) => a.filePath === "assets/file-1.txt")
718
+ );
719
+ await runWrangler("publish --site-exclude file-2.txt");
720
+
721
+ expect(std.out).toMatchInlineSnapshot(`
722
+ "reading assets/file-1.txt...
723
+ uploading as assets/file-1.2ca234f380.txt...
724
+ Uploaded
725
+ test-name
726
+ (TIMINGS)
727
+ Deployed
728
+ test-name
729
+ (TIMINGS)
730
+
731
+ test-name.test-sub-domain.workers.dev"
732
+ `);
733
+ expect(std.err).toMatchInlineSnapshot(`""`);
734
+ });
735
+
736
+ it("should only upload files that match the `site.include` config", async () => {
737
+ const assets = [
738
+ { filePath: "assets/file-1.txt", content: "Content of file-1" },
739
+ { filePath: "assets/file-2.txt", content: "Content of file-2" },
740
+ ];
741
+ const kvNamespace = {
742
+ title: "__test-name-workers_sites_assets",
743
+ id: "__test-name-workers_sites_assets-id",
744
+ };
745
+ writeWranglerToml({
746
+ build: { upload: { main: "./index.js" } },
747
+ site: {
748
+ bucket: "assets",
749
+ include: ["file-1.txt"],
750
+ },
751
+ });
752
+ writeWorkerSource();
753
+ writeAssets(assets);
754
+ mockUploadWorkerRequest();
755
+ mockSubDomainRequest();
756
+ mockListKVNamespacesRequest(kvNamespace);
757
+ mockKeyListRequest(kvNamespace.id, []);
758
+ // Check we only upload file-1
759
+ mockUploadAssetsToKVRequest(
760
+ kvNamespace.id,
761
+ assets.filter((a) => a.filePath === "assets/file-1.txt")
762
+ );
763
+ await runWrangler("publish");
764
+
765
+ expect(std.out).toMatchInlineSnapshot(`
766
+ "reading assets/file-1.txt...
767
+ uploading as assets/file-1.2ca234f380.txt...
768
+ Uploaded
769
+ test-name
770
+ (TIMINGS)
771
+ Deployed
772
+ test-name
773
+ (TIMINGS)
774
+
775
+ test-name.test-sub-domain.workers.dev"
776
+ `);
777
+ expect(std.err).toMatchInlineSnapshot(`""`);
778
+ });
779
+
780
+ it("should not upload files that match the `site.exclude` config", async () => {
781
+ const assets = [
782
+ { filePath: "assets/file-1.txt", content: "Content of file-1" },
783
+ { filePath: "assets/file-2.txt", content: "Content of file-2" },
784
+ ];
785
+ const kvNamespace = {
786
+ title: "__test-name-workers_sites_assets",
787
+ id: "__test-name-workers_sites_assets-id",
788
+ };
789
+ writeWranglerToml({
790
+ build: { upload: { main: "./index.js" } },
791
+ site: {
792
+ bucket: "assets",
793
+ exclude: ["file-2.txt"],
794
+ },
795
+ });
796
+ writeWorkerSource();
446
797
  writeAssets(assets);
447
798
  mockUploadWorkerRequest();
448
799
  mockSubDomainRequest();
@@ -455,18 +806,18 @@ describe("publish", () => {
455
806
  );
456
807
  await runWrangler("publish");
457
808
 
458
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
459
- "reading assets/file-1.txt...
460
- uploading as assets/file-1.2ca234f380.txt...
461
- Uploaded
462
- test-name
463
- (TIMINGS)
464
- Deployed
465
- test-name
466
- (TIMINGS)
467
-
468
- test-name.test-sub-domain.workers.dev"
469
- `);
809
+ expect(std.out).toMatchInlineSnapshot(`
810
+ "reading assets/file-1.txt...
811
+ uploading as assets/file-1.2ca234f380.txt...
812
+ Uploaded
813
+ test-name
814
+ (TIMINGS)
815
+ Deployed
816
+ test-name
817
+ (TIMINGS)
818
+
819
+ test-name.test-sub-domain.workers.dev"
820
+ `);
470
821
  expect(std.err).toMatchInlineSnapshot(`""`);
471
822
  });
472
823
 
@@ -476,8 +827,8 @@ describe("publish", () => {
476
827
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
477
828
  ];
478
829
  const kvNamespace = {
479
- title: "__test-name_sites_assets",
480
- id: "__test-name_sites_assets-id",
830
+ title: "__test-name-workers_sites_assets",
831
+ id: "__test-name-workers_sites_assets-id",
481
832
  };
482
833
  writeWranglerToml({
483
834
  build: { upload: { main: "./index.js" } },
@@ -486,7 +837,7 @@ describe("publish", () => {
486
837
  include: ["file-2.txt"],
487
838
  },
488
839
  });
489
- writeEsmWorkerSource();
840
+ writeWorkerSource();
490
841
  writeAssets(assets);
491
842
  mockUploadWorkerRequest();
492
843
  mockSubDomainRequest();
@@ -499,18 +850,18 @@ describe("publish", () => {
499
850
  );
500
851
  await runWrangler("publish --site-include file-1.txt");
501
852
 
502
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
503
- "reading assets/file-1.txt...
504
- uploading as assets/file-1.2ca234f380.txt...
505
- Uploaded
506
- test-name
507
- (TIMINGS)
508
- Deployed
509
- test-name
510
- (TIMINGS)
511
-
512
- test-name.test-sub-domain.workers.dev"
513
- `);
853
+ expect(std.out).toMatchInlineSnapshot(`
854
+ "reading assets/file-1.txt...
855
+ uploading as assets/file-1.2ca234f380.txt...
856
+ Uploaded
857
+ test-name
858
+ (TIMINGS)
859
+ Deployed
860
+ test-name
861
+ (TIMINGS)
862
+
863
+ test-name.test-sub-domain.workers.dev"
864
+ `);
514
865
  expect(std.err).toMatchInlineSnapshot(`""`);
515
866
  });
516
867
 
@@ -520,8 +871,8 @@ describe("publish", () => {
520
871
  { filePath: "assets/file-2.txt", content: "Content of file-2" },
521
872
  ];
522
873
  const kvNamespace = {
523
- title: "__test-name_sites_assets",
524
- id: "__test-name_sites_assets-id",
874
+ title: "__test-name-workers_sites_assets",
875
+ id: "__test-name-workers_sites_assets-id",
525
876
  };
526
877
  writeWranglerToml({
527
878
  build: { upload: { main: "./index.js" } },
@@ -530,7 +881,7 @@ describe("publish", () => {
530
881
  exclude: ["assets/file-1.txt"],
531
882
  },
532
883
  });
533
- writeEsmWorkerSource();
884
+ writeWorkerSource();
534
885
  writeAssets(assets);
535
886
  mockUploadWorkerRequest();
536
887
  mockSubDomainRequest();
@@ -543,18 +894,18 @@ describe("publish", () => {
543
894
  );
544
895
  await runWrangler("publish --site-exclude file-2.txt");
545
896
 
546
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
547
- "reading assets/file-1.txt...
548
- uploading as assets/file-1.2ca234f380.txt...
549
- Uploaded
550
- test-name
551
- (TIMINGS)
552
- Deployed
553
- test-name
554
- (TIMINGS)
555
-
556
- test-name.test-sub-domain.workers.dev"
557
- `);
897
+ expect(std.out).toMatchInlineSnapshot(`
898
+ "reading assets/file-1.txt...
899
+ uploading as assets/file-1.2ca234f380.txt...
900
+ Uploaded
901
+ test-name
902
+ (TIMINGS)
903
+ Deployed
904
+ test-name
905
+ (TIMINGS)
906
+
907
+ test-name.test-sub-domain.workers.dev"
908
+ `);
558
909
  expect(std.err).toMatchInlineSnapshot(`""`);
559
910
  });
560
911
 
@@ -570,8 +921,8 @@ describe("publish", () => {
570
921
  },
571
922
  ];
572
923
  const kvNamespace = {
573
- title: "__test-name_sites_assets",
574
- id: "__test-name_sites_assets-id",
924
+ title: "__test-name-workers_sites_assets",
925
+ id: "__test-name-workers_sites_assets-id",
575
926
  };
576
927
  writeWranglerToml({
577
928
  build: { upload: { main: "./index.js" } },
@@ -579,7 +930,7 @@ describe("publish", () => {
579
930
  bucket: "assets",
580
931
  },
581
932
  });
582
- writeEsmWorkerSource();
933
+ writeWorkerSource();
583
934
  writeAssets(assets);
584
935
  mockUploadWorkerRequest();
585
936
  mockSubDomainRequest();
@@ -589,7 +940,7 @@ describe("publish", () => {
589
940
  mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(0, 1));
590
941
  await runWrangler("publish");
591
942
 
592
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
943
+ expect(std.out).toMatchInlineSnapshot(`
593
944
  "reading assets/directory-1/file-1.txt...
594
945
  uploading as assets/directory-1/file-1.2ca234f380.txt...
595
946
  Uploaded
@@ -598,7 +949,7 @@ describe("publish", () => {
598
949
  Deployed
599
950
  test-name
600
951
  (TIMINGS)
601
-
952
+
602
953
  test-name.test-sub-domain.workers.dev"
603
954
  `);
604
955
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -620,8 +971,8 @@ describe("publish", () => {
620
971
  },
621
972
  ];
622
973
  const kvNamespace = {
623
- title: "__test-name_sites_assets",
624
- id: "__test-name_sites_assets-id",
974
+ title: "__test-name-workers_sites_assets",
975
+ id: "__test-name-workers_sites_assets-id",
625
976
  };
626
977
  writeWranglerToml({
627
978
  build: { upload: { main: "./index.js" } },
@@ -629,7 +980,7 @@ describe("publish", () => {
629
980
  bucket: "assets",
630
981
  },
631
982
  });
632
- writeEsmWorkerSource();
983
+ writeWorkerSource();
633
984
  writeAssets(assets);
634
985
  mockUploadWorkerRequest();
635
986
  mockSubDomainRequest();
@@ -639,7 +990,7 @@ describe("publish", () => {
639
990
  mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(2));
640
991
  await runWrangler("publish");
641
992
 
642
- expect(stripTimings(std.out)).toMatchInlineSnapshot(`
993
+ expect(std.out).toMatchInlineSnapshot(`
643
994
  "reading assets/.well-known/file-2.txt...
644
995
  uploading as assets/.well-known/file-2.5938485188.txt...
645
996
  Uploaded
@@ -648,7 +999,7 @@ describe("publish", () => {
648
999
  Deployed
649
1000
  test-name
650
1001
  (TIMINGS)
651
-
1002
+
652
1003
  test-name.test-sub-domain.workers.dev"
653
1004
  `);
654
1005
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -667,8 +1018,8 @@ describe("publish", () => {
667
1018
  },
668
1019
  ];
669
1020
  const kvNamespace = {
670
- title: "__test-name_sites_assets",
671
- id: "__test-name_sites_assets-id",
1021
+ title: "__test-name-workers_sites_assets",
1022
+ id: "__test-name-workers_sites_assets-id",
672
1023
  };
673
1024
  writeWranglerToml({
674
1025
  build: { upload: { main: "./index.js" } },
@@ -677,19 +1028,19 @@ describe("publish", () => {
677
1028
  exclude: ["assets/file-1.txt"],
678
1029
  },
679
1030
  });
680
- writeEsmWorkerSource();
1031
+ writeWorkerSource();
681
1032
  writeAssets(assets);
682
1033
  mockUploadWorkerRequest();
683
1034
  mockSubDomainRequest();
684
1035
  mockListKVNamespacesRequest(kvNamespace);
685
1036
  mockKeyListRequest(kvNamespace.id, []);
686
1037
 
687
- let error: Error | undefined;
688
- try {
689
- await runWrangler("publish");
690
- } catch (e) {
691
- error = e;
692
- }
1038
+ await expect(
1039
+ runWrangler("publish")
1040
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
1041
+ `"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"`
1042
+ );
1043
+
693
1044
  expect(std.out).toMatchInlineSnapshot(`
694
1045
  "reading assets/large-file.txt...
695
1046
  uploading as assets/large-file.0ea0637a45.txt..."
@@ -700,9 +1051,6 @@ describe("publish", () => {
700
1051
  %s
701
1052
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
702
1053
  `);
703
- expect(error).toMatchInlineSnapshot(
704
- `[Error: 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]`
705
- );
706
1054
  });
707
1055
 
708
1056
  it("should error if the asset key is over 512 characters", async () => {
@@ -711,8 +1059,8 @@ describe("publish", () => {
711
1059
  content: "content of file",
712
1060
  };
713
1061
  const kvNamespace = {
714
- title: "__test-name_sites_assets",
715
- id: "__test-name_sites_assets-id",
1062
+ title: "__test-name-workers_sites_assets",
1063
+ id: "__test-name-workers_sites_assets-id",
716
1064
  };
717
1065
  writeWranglerToml({
718
1066
  build: { upload: { main: "./index.js" } },
@@ -720,19 +1068,18 @@ describe("publish", () => {
720
1068
  bucket: "assets",
721
1069
  },
722
1070
  });
723
- writeEsmWorkerSource();
1071
+ writeWorkerSource();
724
1072
  writeAssets([longFilePathAsset]);
725
1073
  mockUploadWorkerRequest();
726
1074
  mockSubDomainRequest();
727
1075
  mockListKVNamespacesRequest(kvNamespace);
728
1076
  mockKeyListRequest(kvNamespace.id, []);
729
1077
 
730
- let error: Error | undefined;
731
- try {
732
- await runWrangler("publish");
733
- } catch (e) {
734
- error = e;
735
- }
1078
+ await expect(
1079
+ runWrangler("publish")
1080
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
1081
+ `"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\\","`
1082
+ );
736
1083
 
737
1084
  expect(std.out).toMatchInlineSnapshot(
738
1085
  `"reading 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.txt..."`
@@ -743,48 +1090,503 @@ describe("publish", () => {
743
1090
  %s
744
1091
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
745
1092
  `);
746
- expect(error).toMatchInlineSnapshot(
747
- `[Error: 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",]`
1093
+ });
1094
+ });
1095
+
1096
+ describe("workers_dev setting", () => {
1097
+ it("should deploy to a workers.dev domain if workers_dev is undefined", async () => {
1098
+ writeWranglerToml();
1099
+ writeWorkerSource();
1100
+ mockUploadWorkerRequest();
1101
+ mockSubDomainRequest();
1102
+
1103
+ await runWrangler("publish ./index");
1104
+
1105
+ expect(std.out).toMatchInlineSnapshot(`
1106
+ "Uploaded
1107
+ test-name
1108
+ (TIMINGS)
1109
+ Deployed
1110
+ test-name
1111
+ (TIMINGS)
1112
+
1113
+ test-name.test-sub-domain.workers.dev"
1114
+ `);
1115
+ expect(std.err).toMatchInlineSnapshot(`""`);
1116
+ });
1117
+
1118
+ it("should deploy to the workers.dev domain if workers_dev is `true`", async () => {
1119
+ writeWranglerToml({
1120
+ workers_dev: true,
1121
+ });
1122
+ writeWorkerSource();
1123
+ mockUploadWorkerRequest();
1124
+ mockSubDomainRequest();
1125
+
1126
+ await runWrangler("publish ./index");
1127
+
1128
+ expect(std.out).toMatchInlineSnapshot(`
1129
+ "Uploaded
1130
+ test-name
1131
+ (TIMINGS)
1132
+ Deployed
1133
+ test-name
1134
+ (TIMINGS)
1135
+
1136
+ test-name.test-sub-domain.workers.dev"
1137
+ `);
1138
+ expect(std.err).toMatchInlineSnapshot(`""`);
1139
+ });
1140
+
1141
+ it("should disable the workers.dev domain if workers_dev is `false`", async () => {
1142
+ writeWranglerToml({
1143
+ workers_dev: false,
1144
+ });
1145
+ writeWorkerSource();
1146
+ mockUploadWorkerRequest();
1147
+ mockSubDomainRequest();
1148
+ mockUpdateWorkerRequest({ enabled: false });
1149
+
1150
+ await runWrangler("publish ./index");
1151
+
1152
+ expect(std.out).toMatchInlineSnapshot(`
1153
+ "Uploaded
1154
+ test-name
1155
+ (TIMINGS)
1156
+ No deployment targets for
1157
+ test-name
1158
+ (TIMINGS)"
1159
+ `);
1160
+ expect(std.err).toMatchInlineSnapshot(`""`);
1161
+ });
1162
+
1163
+ it("should enable the workers.dev domain if workers_dev is undefined and subdomain is not already available", async () => {
1164
+ writeWranglerToml();
1165
+ writeWorkerSource();
1166
+ mockUploadWorkerRequest({ available_on_subdomain: false });
1167
+ mockSubDomainRequest();
1168
+ mockUpdateWorkerRequest({ enabled: true });
1169
+
1170
+ await runWrangler("publish ./index");
1171
+
1172
+ expect(std.out).toMatchInlineSnapshot(`
1173
+ "Uploaded
1174
+ test-name
1175
+ (TIMINGS)
1176
+ Deployed
1177
+ test-name
1178
+ (TIMINGS)
1179
+
1180
+ test-name.test-sub-domain.workers.dev"
1181
+ `);
1182
+ expect(std.err).toMatchInlineSnapshot(`""`);
1183
+ });
1184
+
1185
+ it("should enable the workers.dev domain if workers_dev is true and subdomain is not already available", async () => {
1186
+ writeWranglerToml({ workers_dev: true });
1187
+ writeWorkerSource();
1188
+ mockUploadWorkerRequest({ available_on_subdomain: false });
1189
+ mockSubDomainRequest();
1190
+ mockUpdateWorkerRequest({ enabled: true });
1191
+
1192
+ await runWrangler("publish ./index");
1193
+
1194
+ expect(std.out).toMatchInlineSnapshot(`
1195
+ "Uploaded
1196
+ test-name
1197
+ (TIMINGS)
1198
+ Deployed
1199
+ test-name
1200
+ (TIMINGS)
1201
+
1202
+ test-name.test-sub-domain.workers.dev"
1203
+ `);
1204
+ expect(std.err).toMatchInlineSnapshot(`""`);
1205
+ });
1206
+ });
1207
+
1208
+ describe("custom builds", () => {
1209
+ beforeEach(() => {
1210
+ // @ts-expect-error disable the mock we'd setup earlier
1211
+ // or else custom builds will timeout immediately
1212
+ global.setTimeout.mockRestore();
1213
+ });
1214
+ it("should run a custom build before publishing", async () => {
1215
+ writeWranglerToml({
1216
+ build: {
1217
+ command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
1218
+ },
1219
+ });
1220
+
1221
+ mockUploadWorkerRequest({
1222
+ expectedEntry: "return new Response(123)",
1223
+ });
1224
+ mockSubDomainRequest();
1225
+
1226
+ await runWrangler("publish index.js");
1227
+ expect(std.out).toMatchInlineSnapshot(`
1228
+ "running:
1229
+ node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\"
1230
+ Uploaded
1231
+ test-name
1232
+ (TIMINGS)
1233
+ Deployed
1234
+ test-name
1235
+ (TIMINGS)
1236
+
1237
+ test-name.test-sub-domain.workers.dev"
1238
+ `);
1239
+ expect(std.err).toMatchInlineSnapshot(`""`);
1240
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1241
+ });
1242
+
1243
+ if (process.platform !== "win32") {
1244
+ it("should run a custom build of multiple steps combined by && before publishing", async () => {
1245
+ writeWranglerToml({
1246
+ build: {
1247
+ command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
1248
+ },
1249
+ });
1250
+
1251
+ mockUploadWorkerRequest({
1252
+ expectedEntry: "return new Response(123)",
1253
+ });
1254
+ mockSubDomainRequest();
1255
+
1256
+ await runWrangler("publish index.js");
1257
+ expect(std.out).toMatchInlineSnapshot(`
1258
+ "running:
1259
+ echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js
1260
+ Uploaded
1261
+ test-name
1262
+ (TIMINGS)
1263
+ Deployed
1264
+ test-name
1265
+ (TIMINGS)
1266
+
1267
+ test-name.test-sub-domain.workers.dev"
1268
+ `);
1269
+ expect(std.err).toMatchInlineSnapshot(`""`);
1270
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1271
+ });
1272
+ }
1273
+ });
1274
+
1275
+ describe("[wasm_modules]", () => {
1276
+ it("should be able to define wasm modules for service-worker format workers", async () => {
1277
+ writeWranglerToml({
1278
+ wasm_modules: {
1279
+ TESTWASMNAME: "./path/to/test.wasm",
1280
+ },
1281
+ });
1282
+ writeWorkerSource({ type: "sw" });
1283
+ fs.mkdirSync("./path/to", { recursive: true });
1284
+ fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1285
+ mockUploadWorkerRequest({
1286
+ expectedType: "sw",
1287
+ expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1288
+ expectedBindings: [
1289
+ { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1290
+ ],
1291
+ });
1292
+ mockSubDomainRequest();
1293
+ await runWrangler("publish index.js");
1294
+ expect(std.out).toMatchInlineSnapshot(`
1295
+ "Uploaded
1296
+ test-name
1297
+ (TIMINGS)
1298
+ Deployed
1299
+ test-name
1300
+ (TIMINGS)
1301
+
1302
+ test-name.test-sub-domain.workers.dev"
1303
+ `);
1304
+ expect(std.err).toMatchInlineSnapshot(`""`);
1305
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1306
+ });
1307
+
1308
+ it("should error when defining wasm modules for modules format workers", async () => {
1309
+ writeWranglerToml({
1310
+ wasm_modules: {
1311
+ TESTWASMNAME: "./path/to/test.wasm",
1312
+ },
1313
+ });
1314
+ writeWorkerSource({ type: "esm" });
1315
+ fs.mkdirSync("./path/to", { recursive: true });
1316
+ fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1317
+
1318
+ await expect(
1319
+ runWrangler("publish index.js")
1320
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
1321
+ `"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"`
1322
+ );
1323
+ expect(std.out).toMatchInlineSnapshot(`""`);
1324
+ expect(std.err).toMatchInlineSnapshot(`
1325
+ "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
1326
+
1327
+ %s
1328
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1329
+ `);
1330
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1331
+ });
1332
+
1333
+ it("should resolve wasm modules relative to the wrangler.toml file", async () => {
1334
+ fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
1335
+ fs.writeFileSync(
1336
+ "./path/to/wrangler.toml",
1337
+ TOML.stringify({
1338
+ compatibility_date: "2022-01-12",
1339
+ name: "test-name",
1340
+ wasm_modules: {
1341
+ TESTWASMNAME: "./and/the/path/to/test.wasm",
1342
+ },
1343
+ }),
1344
+
1345
+ "utf-8"
1346
+ );
1347
+
1348
+ writeWorkerSource({ type: "sw" });
1349
+ fs.writeFileSync(
1350
+ "./path/to/and/the/path/to/test.wasm",
1351
+ "SOME WASM CONTENT"
1352
+ );
1353
+ mockUploadWorkerRequest({
1354
+ expectedType: "sw",
1355
+ expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1356
+ expectedBindings: [
1357
+ { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1358
+ ],
1359
+ });
1360
+ mockSubDomainRequest();
1361
+ await runWrangler("publish index.js --config ./path/to/wrangler.toml");
1362
+ expect(std.out).toMatchInlineSnapshot(`
1363
+ "Uploaded
1364
+ test-name
1365
+ (TIMINGS)
1366
+ Deployed
1367
+ test-name
1368
+ (TIMINGS)
1369
+
1370
+ test-name.test-sub-domain.workers.dev"
1371
+ `);
1372
+ expect(std.err).toMatchInlineSnapshot(`""`);
1373
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1374
+ });
1375
+
1376
+ it("should be able to import .wasm modules from service-worker format workers", async () => {
1377
+ writeWranglerToml();
1378
+ fs.writeFileSync("./index.js", "import TESTWASMNAME from './test.wasm';");
1379
+ fs.writeFileSync("./test.wasm", "SOME WASM CONTENT");
1380
+ mockUploadWorkerRequest({
1381
+ expectedType: "sw",
1382
+ expectedModules: {
1383
+ __94b240d0d692281e6467aa42043986e5c7eea034_test_wasm:
1384
+ "SOME WASM CONTENT",
1385
+ },
1386
+ expectedBindings: [
1387
+ {
1388
+ name: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1389
+ part: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1390
+ type: "wasm_module",
1391
+ },
1392
+ ],
1393
+ });
1394
+ mockSubDomainRequest();
1395
+ await runWrangler("publish index.js");
1396
+ expect(std.out).toMatchInlineSnapshot(`
1397
+ "Uploaded
1398
+ test-name
1399
+ (TIMINGS)
1400
+ Deployed
1401
+ test-name
1402
+ (TIMINGS)
1403
+
1404
+ test-name.test-sub-domain.workers.dev"
1405
+ `);
1406
+ expect(std.err).toMatchInlineSnapshot(`""`);
1407
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1408
+ });
1409
+ });
1410
+
1411
+ describe("vars bindings", () => {
1412
+ it("should support json bindings", async () => {
1413
+ writeWranglerToml({
1414
+ vars: {
1415
+ text: "plain ol' string",
1416
+ count: 1,
1417
+ complex: { enabled: true, id: 123 },
1418
+ },
1419
+ });
1420
+ writeWorkerSource();
1421
+ mockSubDomainRequest();
1422
+ mockUploadWorkerRequest({
1423
+ expectedBindings: [
1424
+ { name: "text", type: "plain_text", text: "plain ol' string" },
1425
+ { name: "count", type: "json", json: 1 },
1426
+ {
1427
+ name: "complex",
1428
+ type: "json",
1429
+ json: { enabled: true, id: 123 },
1430
+ },
1431
+ ],
1432
+ });
1433
+
1434
+ await runWrangler("publish index.js");
1435
+ expect(std.out).toMatchInlineSnapshot(`
1436
+ "Uploaded
1437
+ test-name
1438
+ (TIMINGS)
1439
+ Deployed
1440
+ test-name
1441
+ (TIMINGS)
1442
+
1443
+ test-name.test-sub-domain.workers.dev"
1444
+ `);
1445
+ expect(std.err).toMatchInlineSnapshot(`""`);
1446
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1447
+ });
1448
+ });
1449
+
1450
+ describe("r2 bucket bindings", () => {
1451
+ it("should support r2 bucket bindings", async () => {
1452
+ writeWranglerToml({
1453
+ r2_buckets: [{ binding: "FOO", bucket_name: "foo-bucket" }],
1454
+ });
1455
+ writeWorkerSource();
1456
+ mockSubDomainRequest();
1457
+ mockUploadWorkerRequest({
1458
+ expectedBindings: [
1459
+ { bucket_name: "foo-bucket", name: "FOO", type: "r2_bucket" },
1460
+ ],
1461
+ });
1462
+
1463
+ await runWrangler("publish index.js");
1464
+ expect(std.out).toMatchInlineSnapshot(`
1465
+ "Uploaded
1466
+ test-name
1467
+ (TIMINGS)
1468
+ Deployed
1469
+ test-name
1470
+ (TIMINGS)
1471
+
1472
+ test-name.test-sub-domain.workers.dev"
1473
+ `);
1474
+ expect(std.err).toMatchInlineSnapshot(`""`);
1475
+ expect(std.warn).toMatchInlineSnapshot(`""`);
1476
+ });
1477
+ });
1478
+
1479
+ describe("unsafe bindings", () => {
1480
+ it("should warn if using unsafe bindings", async () => {
1481
+ writeWranglerToml({
1482
+ unsafe: {
1483
+ bindings: [
1484
+ {
1485
+ name: "my-binding",
1486
+ type: "binding-type",
1487
+ param: "binding-param",
1488
+ },
1489
+ ],
1490
+ },
1491
+ });
1492
+ writeWorkerSource();
1493
+ mockSubDomainRequest();
1494
+ mockUploadWorkerRequest({
1495
+ expectedBindings: [
1496
+ {
1497
+ name: "my-binding",
1498
+ type: "binding-type",
1499
+ param: "binding-param",
1500
+ },
1501
+ ],
1502
+ });
1503
+
1504
+ await runWrangler("publish index.js");
1505
+ expect(std.out).toMatchInlineSnapshot(`
1506
+ "Uploaded
1507
+ test-name
1508
+ (TIMINGS)
1509
+ Deployed
1510
+ test-name
1511
+ (TIMINGS)
1512
+
1513
+ test-name.test-sub-domain.workers.dev"
1514
+ `);
1515
+ expect(std.err).toMatchInlineSnapshot(`""`);
1516
+ expect(std.warn).toMatchInlineSnapshot(
1517
+ `"'unsafe' fields are experimental and may change or break at any time."`
748
1518
  );
749
1519
  });
1520
+ it("should warn if using unsafe bindings already handled by wrangler", async () => {
1521
+ writeWranglerToml({
1522
+ unsafe: {
1523
+ bindings: [
1524
+ {
1525
+ name: "my-binding",
1526
+ type: "plain_text",
1527
+ text: "text",
1528
+ },
1529
+ ],
1530
+ },
1531
+ });
1532
+ writeWorkerSource();
1533
+ mockSubDomainRequest();
1534
+ mockUploadWorkerRequest({
1535
+ expectedBindings: [
1536
+ {
1537
+ name: "my-binding",
1538
+ type: "plain_text",
1539
+ text: "text",
1540
+ },
1541
+ ],
1542
+ });
1543
+
1544
+ await runWrangler("publish index.js");
1545
+ expect(std.out).toMatchInlineSnapshot(`
1546
+ "Uploaded
1547
+ test-name
1548
+ (TIMINGS)
1549
+ Deployed
1550
+ test-name
1551
+ (TIMINGS)
1552
+
1553
+ test-name.test-sub-domain.workers.dev"
1554
+ `);
1555
+ expect(std.err).toMatchInlineSnapshot(`""`);
1556
+ expect(std.warn).toMatchInlineSnapshot(`
1557
+ "'unsafe' fields are experimental and may change or break at any time.
1558
+ Raw 'plain_text' bindings are not directly supported by wrangler. Consider migrating to a format for 'plain_text' bindings that is supported by wrangler for optimal support: https://developers.cloudflare.com/workers/cli-wrangler/configuration"
1559
+ `);
1560
+ });
750
1561
  });
751
1562
  });
752
1563
 
753
- /** Write a mock wrangler.toml file to disk. */
754
- function writeWranglerToml(config: Omit<Config, "env"> = {}) {
755
- // We Omit `env` from config because TOML.stringify() appears to
756
- // have a weird type signature that appears to fail. We'll revisit this
757
- // when we write tests for publishing environments
758
- fs.writeFileSync(
759
- "./wrangler.toml",
760
- TOML.stringify({
761
- compatibility_date: "2022-01-12",
762
- name: "test-name",
763
- ...config,
764
- }),
765
-
766
- "utf-8"
767
- );
768
- }
769
-
770
1564
  /** Write a mock Worker script to disk. */
771
- function writeEsmWorkerSource({
1565
+ function writeWorkerSource({
772
1566
  basePath = ".",
773
1567
  format = "js",
774
- }: { basePath?: string; format?: "js" | "ts" | "jsx" | "tsx" | "mjs" } = {}) {
1568
+ type = "esm",
1569
+ }: {
1570
+ basePath?: string;
1571
+ format?: "js" | "ts" | "jsx" | "tsx" | "mjs";
1572
+ type?: "esm" | "sw";
1573
+ } = {}) {
775
1574
  if (basePath !== ".") {
776
1575
  fs.mkdirSync(basePath, { recursive: true });
777
1576
  }
778
1577
  fs.writeFileSync(
779
1578
  `${basePath}/index.${format}`,
780
- [
781
- `import { foo } from "./another";`,
782
- `export default {`,
783
- ` async fetch(request) {`,
784
- ` return new Response('Hello' + foo);`,
785
- ` },`,
786
- `};`,
787
- ].join("\n")
1579
+ type === "esm"
1580
+ ? `import { foo } from "./another";
1581
+ export default {
1582
+ async fetch(request) {
1583
+ return new Response('Hello' + foo);
1584
+ },
1585
+ };`
1586
+ : `import { foo } from "./another";
1587
+ addEventListener('fetch', event => {
1588
+ event.respondWith(new Response('Hello' + foo));
1589
+ })`
788
1590
  );
789
1591
  fs.writeFileSync(`${basePath}/another.${format}`, `export const foo = 100;`);
790
1592
  }
@@ -800,23 +1602,50 @@ function writeAssets(assets: { filePath: string; content: string }[]) {
800
1602
  /** Create a mock handler for the request to upload a worker script. */
801
1603
  function mockUploadWorkerRequest({
802
1604
  available_on_subdomain = true,
803
- expectedBody,
1605
+ expectedEntry,
1606
+ expectedType = "esm",
1607
+ expectedBindings,
1608
+ expectedModules = {},
1609
+ env = undefined,
804
1610
  }: {
805
1611
  available_on_subdomain?: boolean;
806
- expectedBody?: string;
1612
+ expectedEntry?: string;
1613
+ expectedType?: "esm" | "sw";
1614
+ expectedBindings?: unknown;
1615
+ expectedModules?: Record<string, string>;
1616
+ env?: string | undefined;
807
1617
  } = {}) {
808
1618
  setMockResponse(
809
- "/accounts/:accountId/workers/scripts/:scriptName",
1619
+ env
1620
+ ? `/accounts/:accountId/workers/services/:scriptName/environments/:envName`
1621
+ : "/accounts/:accountId/workers/scripts/:scriptName",
810
1622
  "PUT",
811
1623
  async ([_url, accountId, scriptName], { body }, queryParams) => {
812
1624
  expect(accountId).toEqual("some-account-id");
813
1625
  expect(scriptName).toEqual("test-name");
814
- expect(queryParams.get("available_on_subdomains")).toEqual("true");
815
- if (expectedBody !== undefined) {
816
- expect(
817
- await ((body as FormData).get("index.js") as File).text()
818
- ).toMatch(expectedBody);
1626
+ expect(queryParams.get("available_on_subdomain")).toEqual("true");
1627
+ const formBody = body as FormData;
1628
+ if (expectedEntry !== undefined) {
1629
+ expect(await (formBody.get("index.js") as File).text()).toMatch(
1630
+ expectedEntry
1631
+ );
819
1632
  }
1633
+
1634
+ const metadata = JSON.parse(
1635
+ formBody.get("metadata") as string
1636
+ ) as WorkerMetadata;
1637
+ if (expectedType === "esm") {
1638
+ expect(metadata.main_module).toEqual("index.js");
1639
+ } else {
1640
+ expect(metadata.body_part).toEqual("index.js");
1641
+ }
1642
+ if (expectedBindings !== undefined) {
1643
+ expect(metadata.bindings).toEqual(expectedBindings);
1644
+ }
1645
+ for (const [name, content] of Object.entries(expectedModules)) {
1646
+ expect(await (formBody.get(name) as File).text()).toMatch(content);
1647
+ }
1648
+
820
1649
  return { available_on_subdomain };
821
1650
  }
822
1651
  );
@@ -824,11 +1653,32 @@ function mockUploadWorkerRequest({
824
1653
 
825
1654
  /** Create a mock handler for the request to get the account's subdomain. */
826
1655
  function mockSubDomainRequest(subdomain = "test-sub-domain") {
827
- setMockResponse("/accounts/:accountId/workers/subdomain", () => {
1656
+ setMockResponse("/accounts/:accountId/workers/subdomain", "GET", () => {
828
1657
  return { subdomain };
829
1658
  });
830
1659
  }
831
1660
 
1661
+ function mockUpdateWorkerRequest({
1662
+ env,
1663
+ enabled,
1664
+ }: {
1665
+ env?: string | undefined;
1666
+ enabled: boolean;
1667
+ }) {
1668
+ const requests = { count: 0 };
1669
+ const servicesOrScripts = env ? "services" : "scripts";
1670
+ const environment = env ? "/environments/:envName" : "";
1671
+ setMockResponse(
1672
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/subdomain`,
1673
+ "POST",
1674
+ (_, { body }) => {
1675
+ expect(JSON.parse(body as string)).toEqual({ enabled });
1676
+ return null;
1677
+ }
1678
+ );
1679
+ return requests;
1680
+ }
1681
+
832
1682
  /** Create a mock handler for the request to get a list of all KV namespaces. */
833
1683
  function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
834
1684
  setMockResponse(
@@ -878,8 +1728,3 @@ function mockUploadAssetsToKVRequest(
878
1728
  }
879
1729
  );
880
1730
  }
881
-
882
- /** Strip timing data out of the stdout, since this is not always deterministic. */
883
- function stripTimings(stdout: string): string {
884
- return stdout.replace(/\(\d+\.\d+ sec\)/g, "(TIMINGS)");
885
- }