wrangler 2.0.22 → 2.0.25

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 (75) hide show
  1. package/README.md +20 -2
  2. package/bin/wrangler.js +1 -1
  3. package/miniflare-dist/index.mjs +643 -7
  4. package/package.json +17 -5
  5. package/src/__tests__/configuration.test.ts +89 -17
  6. package/src/__tests__/dev.test.tsx +121 -8
  7. package/src/__tests__/generate.test.ts +93 -0
  8. package/src/__tests__/helpers/mock-cfetch.ts +54 -2
  9. package/src/__tests__/index.test.ts +10 -27
  10. package/src/__tests__/jest.setup.ts +31 -1
  11. package/src/__tests__/kv.test.ts +82 -61
  12. package/src/__tests__/metrics.test.ts +5 -0
  13. package/src/__tests__/publish.test.ts +573 -254
  14. package/src/__tests__/r2.test.ts +173 -71
  15. package/src/__tests__/tail.test.ts +93 -39
  16. package/src/__tests__/user.test.ts +1 -0
  17. package/src/__tests__/validate-dev-props.test.ts +56 -0
  18. package/src/__tests__/version.test.ts +35 -0
  19. package/src/__tests__/whoami.test.tsx +60 -1
  20. package/src/api/dev.ts +49 -9
  21. package/src/bundle.ts +298 -37
  22. package/src/cfetch/internal.ts +34 -2
  23. package/src/config/config.ts +15 -3
  24. package/src/config/environment.ts +40 -8
  25. package/src/config/index.ts +13 -0
  26. package/src/config/validation.ts +111 -9
  27. package/src/create-worker-preview.ts +3 -1
  28. package/src/create-worker-upload-form.ts +25 -0
  29. package/src/dev/dev.tsx +145 -31
  30. package/src/dev/local.tsx +116 -24
  31. package/src/dev/remote.tsx +39 -12
  32. package/src/dev/use-esbuild.ts +28 -0
  33. package/src/dev/validate-dev-props.ts +31 -0
  34. package/src/dev-registry.tsx +160 -0
  35. package/src/dev.tsx +148 -67
  36. package/src/generate.ts +112 -14
  37. package/src/index.tsx +252 -7
  38. package/src/inspect.ts +90 -5
  39. package/src/metrics/index.ts +1 -0
  40. package/src/metrics/metrics-dispatcher.ts +1 -0
  41. package/src/metrics/metrics-usage-headers.ts +24 -0
  42. package/src/metrics/send-event.ts +2 -2
  43. package/src/miniflare-cli/assets.ts +546 -0
  44. package/src/miniflare-cli/index.ts +157 -6
  45. package/src/module-collection.ts +3 -3
  46. package/src/pages/build.tsx +36 -28
  47. package/src/pages/constants.ts +4 -0
  48. package/src/pages/deployments.tsx +10 -10
  49. package/src/pages/dev.tsx +155 -651
  50. package/src/pages/functions/buildPlugin.ts +4 -0
  51. package/src/pages/functions/buildWorker.ts +4 -0
  52. package/src/pages/functions/routes-consolidation.test.ts +66 -0
  53. package/src/pages/functions/routes-consolidation.ts +29 -0
  54. package/src/pages/functions/routes-transformation.test.ts +271 -0
  55. package/src/pages/functions/routes-transformation.ts +125 -0
  56. package/src/pages/projects.tsx +9 -3
  57. package/src/pages/publish.tsx +57 -15
  58. package/src/pages/types.ts +9 -0
  59. package/src/pages/upload.tsx +38 -21
  60. package/src/publish.ts +139 -112
  61. package/src/r2.ts +81 -0
  62. package/src/tail/index.ts +15 -2
  63. package/src/tail/printing.ts +41 -3
  64. package/src/user/choose-account.tsx +20 -11
  65. package/src/user/user.tsx +20 -2
  66. package/src/whoami.tsx +79 -1
  67. package/src/worker.ts +12 -0
  68. package/templates/first-party-worker-module-facade.ts +18 -0
  69. package/templates/format-dev-errors.ts +32 -0
  70. package/templates/pages-shim.ts +9 -0
  71. package/templates/{static-asset-facade.js → serve-static-assets.ts} +21 -7
  72. package/templates/service-bindings-module-facade.js +51 -0
  73. package/templates/service-bindings-sw-facade.js +39 -0
  74. package/wrangler-dist/cli.d.ts +38 -3
  75. package/wrangler-dist/cli.js +45244 -25199
@@ -1,5 +1,10 @@
1
+ import * as fs from "node:fs";
1
2
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
2
- import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
3
+ import {
4
+ setMockFetchR2Objects,
5
+ setMockResponse,
6
+ unsetAllMocks,
7
+ } from "./helpers/mock-cfetch";
3
8
  import { mockConsoleMethods } from "./helpers/mock-console";
4
9
  import { runInTempDir } from "./helpers/run-in-tmp";
5
10
  import { runWrangler } from "./helpers/run-wrangler";
@@ -22,26 +27,26 @@ describe("wrangler", () => {
22
27
  runWrangler("r2 bucket foo")
23
28
  ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unknown argument: foo"`);
24
29
  expect(std.err).toMatchInlineSnapshot(`
25
- "X [ERROR] Unknown argument: foo
30
+ "X [ERROR] Unknown argument: foo
26
31
 
27
- "
28
- `);
32
+ "
33
+ `);
29
34
  expect(std.out).toMatchInlineSnapshot(`
30
- "
31
- wrangler r2 bucket
35
+ "
36
+ wrangler r2 bucket
32
37
 
33
- Manage R2 buckets
38
+ Manage R2 buckets
34
39
 
35
- Commands:
36
- wrangler r2 bucket create <name> Create a new R2 bucket
37
- wrangler r2 bucket list List R2 buckets
38
- wrangler r2 bucket delete <name> Delete an R2 bucket
40
+ Commands:
41
+ wrangler r2 bucket create <name> Create a new R2 bucket
42
+ wrangler r2 bucket list List R2 buckets
43
+ wrangler r2 bucket delete <name> Delete an R2 bucket
39
44
 
40
- Flags:
41
- -c, --config Path to .toml configuration file [string]
42
- -h, --help Show help [boolean]
43
- -v, --version Show version number [boolean]"
44
- `);
45
+ Flags:
46
+ -c, --config Path to .toml configuration file [string]
47
+ -h, --help Show help [boolean]
48
+ -v, --version Show version number [boolean]"
49
+ `);
45
50
  });
46
51
 
47
52
  describe("list", () => {
@@ -95,24 +100,24 @@ describe("wrangler", () => {
95
100
  `"Not enough non-option arguments: got 0, need at least 1"`
96
101
  );
97
102
  expect(std.out).toMatchInlineSnapshot(`
98
- "
99
- wrangler r2 bucket create <name>
103
+ "
104
+ wrangler r2 bucket create <name>
100
105
 
101
- Create a new R2 bucket
106
+ Create a new R2 bucket
102
107
 
103
- Positionals:
104
- name The name of the new bucket [string] [required]
108
+ Positionals:
109
+ name The name of the new bucket [string] [required]
105
110
 
106
- Flags:
107
- -c, --config Path to .toml configuration file [string]
108
- -h, --help Show help [boolean]
109
- -v, --version Show version number [boolean]"
110
- `);
111
+ Flags:
112
+ -c, --config Path to .toml configuration file [string]
113
+ -h, --help Show help [boolean]
114
+ -v, --version Show version number [boolean]"
115
+ `);
111
116
  expect(std.err).toMatchInlineSnapshot(`
112
- "X [ERROR] Not enough non-option arguments: got 0, need at least 1
117
+ "X [ERROR] Not enough non-option arguments: got 0, need at least 1
113
118
 
114
- "
115
- `);
119
+ "
120
+ `);
116
121
  });
117
122
 
118
123
  it("should error if the bucket to create contains spaces", async () => {
@@ -122,33 +127,33 @@ describe("wrangler", () => {
122
127
  `"Unknown arguments: def, ghi"`
123
128
  );
124
129
  expect(std.out).toMatchInlineSnapshot(`
125
- "
126
- wrangler r2 bucket create <name>
130
+ "
131
+ wrangler r2 bucket create <name>
127
132
 
128
- Create a new R2 bucket
133
+ Create a new R2 bucket
129
134
 
130
- Positionals:
131
- name The name of the new bucket [string] [required]
135
+ Positionals:
136
+ name The name of the new bucket [string] [required]
132
137
 
133
- Flags:
134
- -c, --config Path to .toml configuration file [string]
135
- -h, --help Show help [boolean]
136
- -v, --version Show version number [boolean]"
137
- `);
138
+ Flags:
139
+ -c, --config Path to .toml configuration file [string]
140
+ -h, --help Show help [boolean]
141
+ -v, --version Show version number [boolean]"
142
+ `);
138
143
  expect(std.err).toMatchInlineSnapshot(`
139
- "X [ERROR] Unknown arguments: def, ghi
144
+ "X [ERROR] Unknown arguments: def, ghi
140
145
 
141
- "
142
- `);
146
+ "
147
+ `);
143
148
  });
144
149
 
145
150
  it("should create a bucket", async () => {
146
151
  const requests = mockCreateRequest("testBucket");
147
152
  await runWrangler("r2 bucket create testBucket");
148
153
  expect(std.out).toMatchInlineSnapshot(`
149
- "Creating bucket testBucket.
150
- Created bucket testBucket."
151
- `);
154
+ "Creating bucket testBucket.
155
+ Created bucket testBucket."
156
+ `);
152
157
  expect(requests.count).toEqual(1);
153
158
  });
154
159
  });
@@ -175,24 +180,24 @@ describe("wrangler", () => {
175
180
  `"Not enough non-option arguments: got 0, need at least 1"`
176
181
  );
177
182
  expect(std.out).toMatchInlineSnapshot(`
178
- "
179
- wrangler r2 bucket delete <name>
183
+ "
184
+ wrangler r2 bucket delete <name>
180
185
 
181
- Delete an R2 bucket
186
+ Delete an R2 bucket
182
187
 
183
- Positionals:
184
- name The name of the bucket to delete [string] [required]
188
+ Positionals:
189
+ name The name of the bucket to delete [string] [required]
185
190
 
186
- Flags:
187
- -c, --config Path to .toml configuration file [string]
188
- -h, --help Show help [boolean]
189
- -v, --version Show version number [boolean]"
190
- `);
191
+ Flags:
192
+ -c, --config Path to .toml configuration file [string]
193
+ -h, --help Show help [boolean]
194
+ -v, --version Show version number [boolean]"
195
+ `);
191
196
  expect(std.err).toMatchInlineSnapshot(`
192
- "X [ERROR] Not enough non-option arguments: got 0, need at least 1
197
+ "X [ERROR] Not enough non-option arguments: got 0, need at least 1
193
198
 
194
- "
195
- `);
199
+ "
200
+ `);
196
201
  });
197
202
 
198
203
  it("should error if the bucket name to delete contains spaces", async () => {
@@ -202,24 +207,24 @@ describe("wrangler", () => {
202
207
  `"Unknown arguments: def, ghi"`
203
208
  );
204
209
  expect(std.out).toMatchInlineSnapshot(`
205
- "
206
- wrangler r2 bucket delete <name>
210
+ "
211
+ wrangler r2 bucket delete <name>
207
212
 
208
- Delete an R2 bucket
213
+ Delete an R2 bucket
209
214
 
210
- Positionals:
211
- name The name of the bucket to delete [string] [required]
215
+ Positionals:
216
+ name The name of the bucket to delete [string] [required]
212
217
 
213
- Flags:
214
- -c, --config Path to .toml configuration file [string]
215
- -h, --help Show help [boolean]
216
- -v, --version Show version number [boolean]"
217
- `);
218
+ Flags:
219
+ -c, --config Path to .toml configuration file [string]
220
+ -h, --help Show help [boolean]
221
+ -v, --version Show version number [boolean]"
222
+ `);
218
223
  expect(std.err).toMatchInlineSnapshot(`
219
- "X [ERROR] Unknown arguments: def, ghi
224
+ "X [ERROR] Unknown arguments: def, ghi
220
225
 
221
- "
222
- `);
226
+ "
227
+ `);
223
228
  });
224
229
 
225
230
  it("should delete a bucket specified by name", async () => {
@@ -229,5 +234,102 @@ describe("wrangler", () => {
229
234
  });
230
235
  });
231
236
  });
237
+
238
+ describe("r2 object", () => {
239
+ it("should download R2 object from bucket", async () => {
240
+ setMockFetchR2Objects({
241
+ accountId: "some-account-id",
242
+ bucketName: "bucketName-object-test",
243
+ objectName: "wormhole-img.png",
244
+ mockResponse: "R2-objects-test-data",
245
+ });
246
+
247
+ await runWrangler(
248
+ `r2 object get bucketName-object-test/wormhole-img.png --file ./wormhole-img.png`
249
+ );
250
+
251
+ expect(std.out).toMatchInlineSnapshot(`
252
+ "Downloading \\"wormhole-img.png\\" from \\"bucketName-object-test\\".
253
+ Download complete."
254
+ `);
255
+ });
256
+
257
+ it("should upload R2 object from bucket", async () => {
258
+ setMockFetchR2Objects({
259
+ accountId: "some-account-id",
260
+ bucketName: "bucketName-object-test",
261
+ objectName: "wormhole-img.png",
262
+ });
263
+ fs.writeFileSync("wormhole-img.png", "passageway");
264
+ await runWrangler(
265
+ `r2 object put bucketName-object-test/wormhole-img.png --file ./wormhole-img.png`
266
+ );
267
+
268
+ expect(std.out).toMatchInlineSnapshot(`
269
+ "Creating object \\"wormhole-img.png\\" in bucket \\"bucketName-object-test\\".
270
+ Upload complete."
271
+ `);
272
+ });
273
+
274
+ it("should pass all fetch option flags into requestInit", async () => {
275
+ fs.writeFileSync("wormhole-img.png", "passageway");
276
+ setMockFetchR2Objects({
277
+ accountId: "some-account-id",
278
+ bucketName: "bucketName-object-test",
279
+ objectName: "wormhole-img.png",
280
+ });
281
+ const flags =
282
+ "--ct content-type --cd content-disposition --ce content-encoding --cl content-lang --cc cache-control --e expire-time";
283
+
284
+ await runWrangler(
285
+ `r2 object put bucketName-object-test/wormhole-img.png ${flags} --file wormhole-img.png`
286
+ );
287
+
288
+ expect(std.out).toMatchInlineSnapshot(`
289
+ "Creating object \\"wormhole-img.png\\" in bucket \\"bucketName-object-test\\".
290
+ Upload complete."
291
+ `);
292
+ });
293
+
294
+ it("should delete R2 object from bucket", async () => {
295
+ setMockFetchR2Objects({
296
+ accountId: "some-account-id",
297
+ bucketName: "bucketName-object-test",
298
+ objectName: "wormhole-img.png",
299
+ });
300
+
301
+ await runWrangler(
302
+ `r2 object delete bucketName-object-test/wormhole-img.png`
303
+ );
304
+
305
+ expect(std.out).toMatchInlineSnapshot(`
306
+ "Deleting object \\"wormhole-img.png\\" from bucket \\"bucketName-object-test\\".
307
+ Delete complete."
308
+ `);
309
+ });
310
+
311
+ it("should not allow `--pipe` & `--file` to run together", async () => {
312
+ fs.writeFileSync("wormhole-img.png", "passageway");
313
+ setMockFetchR2Objects({
314
+ accountId: "some-account-id",
315
+ bucketName: "bucketName-object-test",
316
+ objectName: "wormhole-img.png",
317
+ });
318
+
319
+ await expect(
320
+ runWrangler(
321
+ `r2 object put bucketName-object-test/wormhole-img.png --pipe --file wormhole-img.png`
322
+ )
323
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
324
+ `"Arguments pipe and file are mutually exclusive"`
325
+ );
326
+
327
+ expect(std.err).toMatchInlineSnapshot(`
328
+ "X [ERROR] Arguments pipe and file are mutually exclusive
329
+
330
+ "
331
+ `);
332
+ });
333
+ });
232
334
  });
233
335
  });
@@ -6,7 +6,12 @@ import { mockConsoleMethods } from "./helpers/mock-console";
6
6
  import { useMockIsTTY } from "./helpers/mock-istty";
7
7
  import { runInTempDir } from "./helpers/run-in-tmp";
8
8
  import { runWrangler } from "./helpers/run-wrangler";
9
- import type { TailEventMessage, RequestEvent, ScheduledEvent } from "../tail";
9
+ import type {
10
+ TailEventMessage,
11
+ RequestEvent,
12
+ ScheduledEvent,
13
+ AlarmEvent,
14
+ } from "../tail";
10
15
  import type WebSocket from "ws";
11
16
 
12
17
  describe("tail", () => {
@@ -251,6 +256,18 @@ describe("tail", () => {
251
256
  expect(std.out).toMatch(deserializeToJson(serializedMessage));
252
257
  });
253
258
 
259
+ it("logs alarm messages in json format", async () => {
260
+ const api = mockWebsocketAPIs();
261
+ await runWrangler("tail test-worker --format json");
262
+
263
+ const event = generateMockAlarmEvent();
264
+ const message = generateMockEventMessage({ event });
265
+ const serializedMessage = serialize(message);
266
+
267
+ api.ws.send(serializedMessage);
268
+ expect(std.out).toMatch(deserializeToJson(serializedMessage));
269
+ });
270
+
254
271
  it("logs request messages in pretty format", async () => {
255
272
  const api = mockWebsocketAPIs();
256
273
  await runWrangler("tail test-worker --format pretty");
@@ -271,10 +288,10 @@ describe("tail", () => {
271
288
  "[mock expiration date]"
272
289
  )
273
290
  ).toMatchInlineSnapshot(`
274
- "Successfully created tail, expires at [mock expiration date]
275
- Connected to test-worker, waiting for logs...
276
- GET https://example.org/ - Ok @ [mock event timestamp]"
277
- `);
291
+ "Successfully created tail, expires at [mock expiration date]
292
+ Connected to test-worker, waiting for logs...
293
+ GET https://example.org/ - Ok @ [mock event timestamp]"
294
+ `);
278
295
  });
279
296
 
280
297
  it("logs scheduled messages in pretty format", async () => {
@@ -297,35 +314,61 @@ describe("tail", () => {
297
314
  "[mock expiration date]"
298
315
  )
299
316
  ).toMatchInlineSnapshot(`
300
- "Successfully created tail, expires at [mock expiration date]
301
- Connected to test-worker, waiting for logs...
302
- \\"* * * * *\\" @ [mock timestamp string] - Ok"
303
- `);
317
+ "Successfully created tail, expires at [mock expiration date]
318
+ Connected to test-worker, waiting for logs...
319
+ \\"* * * * *\\" @ [mock timestamp string] - Ok"
320
+ `);
304
321
  });
305
322
 
306
- it("should not crash when the tail message has a void event", async () => {
323
+ it("logs alarm messages in pretty format", async () => {
307
324
  const api = mockWebsocketAPIs();
308
325
  await runWrangler("tail test-worker --format pretty");
309
326
 
310
- const message = generateMockEventMessage({ event: null });
327
+ const event = generateMockAlarmEvent();
328
+ const message = generateMockEventMessage({ event });
311
329
  const serializedMessage = serialize(message);
312
330
 
313
331
  api.ws.send(serializedMessage);
314
332
  expect(
315
333
  std.out
316
334
  .replace(
317
- new Date(mockEventTimestamp).toLocaleString(),
318
- "[mock timestamp string]"
335
+ new Date(mockEventScheduledTime).toLocaleString(),
336
+ "[mock scheduled time]"
319
337
  )
320
338
  .replace(
321
339
  mockTailExpiration.toLocaleString(),
322
340
  "[mock expiration date]"
323
341
  )
324
342
  ).toMatchInlineSnapshot(`
325
- "Successfully created tail, expires at [mock expiration date]
326
- Connected to test-worker, waiting for logs...
327
- [missing request] - Ok @ [mock timestamp string]"
328
- `);
343
+ "Successfully created tail, expires at [mock expiration date]
344
+ Connected to test-worker, waiting for logs...
345
+ Alarm @ [mock scheduled time] - Ok"
346
+ `);
347
+ });
348
+
349
+ it("should not crash when the tail message has a void event", async () => {
350
+ const api = mockWebsocketAPIs();
351
+ await runWrangler("tail test-worker --format pretty");
352
+
353
+ const message = generateMockEventMessage({ event: null });
354
+ const serializedMessage = serialize(message);
355
+
356
+ api.ws.send(serializedMessage);
357
+ expect(
358
+ std.out
359
+ .replace(
360
+ mockTailExpiration.toLocaleString(),
361
+ "[mock expiration date]"
362
+ )
363
+ .replace(
364
+ new Date(mockEventTimestamp).toLocaleString(),
365
+ "[mock timestamp string]"
366
+ )
367
+ ).toMatchInlineSnapshot(`
368
+ "Successfully created tail, expires at [mock expiration date]
369
+ Connected to test-worker, waiting for logs...
370
+ Unknown Event - Ok @ [mock timestamp string]"
371
+ `);
329
372
  });
330
373
 
331
374
  it("defaults to logging in pretty format when the output is a TTY", async () => {
@@ -349,10 +392,10 @@ describe("tail", () => {
349
392
  "[mock expiration date]"
350
393
  )
351
394
  ).toMatchInlineSnapshot(`
352
- "Successfully created tail, expires at [mock expiration date]
353
- Connected to test-worker, waiting for logs...
354
- GET https://example.org/ - Ok @ [mock event timestamp]"
355
- `);
395
+ "Successfully created tail, expires at [mock expiration date]
396
+ Connected to test-worker, waiting for logs...
397
+ GET https://example.org/ - Ok @ [mock event timestamp]"
398
+ `);
356
399
  });
357
400
 
358
401
  it("defaults to logging in json format when the output is not a TTY", async () => {
@@ -405,21 +448,21 @@ describe("tail", () => {
405
448
  "[mock expiration date]"
406
449
  )
407
450
  ).toMatchInlineSnapshot(`
408
- "Successfully created tail, expires at [mock expiration date]
409
- Connected to test-worker, waiting for logs...
410
- GET https://example.org/ - Ok @ [mock event timestamp]
411
- (log) some string
412
- (log) { complex: 'object' }
413
- (error) 1234"
414
- `);
451
+ "Successfully created tail, expires at [mock expiration date]
452
+ Connected to test-worker, waiting for logs...
453
+ GET https://example.org/ - Ok @ [mock event timestamp]
454
+ (log) some string
455
+ (log) { complex: 'object' }
456
+ (error) 1234"
457
+ `);
415
458
  expect(std.err).toMatchInlineSnapshot(`
416
- "X [ERROR]  Error: some error
459
+ "X [ERROR]  Error: some error
417
460
 
418
461
 
419
- X [ERROR]  Error: { complex: 'error' }
462
+ X [ERROR]  Error: { complex: 'error' }
420
463
 
421
- "
422
- `);
464
+ "
465
+ `);
423
466
  expect(std.warn).toMatchInlineSnapshot(`""`);
424
467
  });
425
468
  });
@@ -437,8 +480,8 @@ describe("tail", () => {
437
480
  * @returns the same type we expect when deserializing in wrangler
438
481
  */
439
482
  function serialize(message: TailEventMessage): WebSocket.RawData {
440
- if (isScheduled(message.event)) {
441
- // `ScheduledEvent`s work just fine
483
+ if (!isRequest(message.event)) {
484
+ // `ScheduledEvent`s and `TailEvent`s work just fine
442
485
  const stringified = JSON.stringify(message);
443
486
  return Buffer.from(stringified, "utf-8");
444
487
  } else {
@@ -470,12 +513,12 @@ function serialize(message: TailEventMessage): WebSocket.RawData {
470
513
  * Small helper to disambiguate the event types possible in a `TailEventMessage`
471
514
  *
472
515
  * @param event A TailEvent
473
- * @returns whether event is a ScheduledEvent (true) or a RequestEvent
516
+ * @returns true if `event` is a RequestEvent
474
517
  */
475
- function isScheduled(
476
- event: ScheduledEvent | RequestEvent | undefined | null
477
- ): event is ScheduledEvent {
478
- return Boolean(event && "cron" in event);
518
+ function isRequest(
519
+ event: ScheduledEvent | RequestEvent | AlarmEvent | undefined | null
520
+ ): event is RequestEvent {
521
+ return Boolean(event && "request" in event);
479
522
  }
480
523
 
481
524
  /**
@@ -559,6 +602,11 @@ const mockTailExpiration = new Date(3005, 1);
559
602
  */
560
603
  const mockEventTimestamp = 1645454470467;
561
604
 
605
+ /**
606
+ * Default value for event time ISO strings
607
+ */
608
+ const mockEventScheduledTime = new Date(mockEventTimestamp).toISOString();
609
+
562
610
  /**
563
611
  * Mock out the API hit during Tail deletion
564
612
  *
@@ -696,3 +744,9 @@ function generateMockScheduledEvent(
696
744
  scheduledTime: opts?.scheduledTime || mockEventTimestamp,
697
745
  };
698
746
  }
747
+
748
+ function generateMockAlarmEvent(opts?: Partial<AlarmEvent>): AlarmEvent {
749
+ return {
750
+ scheduledTime: opts?.scheduledTime || mockEventScheduledTime,
751
+ };
752
+ }
@@ -56,6 +56,7 @@ describe("User", () => {
56
56
  oauth_token: "test-access-token",
57
57
  refresh_token: "test-refresh-token",
58
58
  expiration_time: expect.any(String),
59
+ scopes: ["account:read"],
59
60
  });
60
61
  });
61
62
  });
@@ -0,0 +1,56 @@
1
+ import { validateDevProps } from "../dev/validate-dev-props";
2
+ import type { DevProps } from "../dev/dev";
3
+
4
+ describe("validateDevProps", () => {
5
+ it("should throw if the user tries to use the service-worker format with an `assets` directory", () => {
6
+ const props = {
7
+ isWorkersSite: false,
8
+ assetPaths: ["assets"],
9
+ entry: { format: "service-worker" },
10
+ bindings: {},
11
+ };
12
+
13
+ expect(() => validateDevProps(props as unknown as DevProps)).toThrowError(
14
+ "You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
15
+ );
16
+ });
17
+
18
+ it("should throw if the user tries to configure [wasm_modules] with an ES module worker", () => {
19
+ const props = {
20
+ isWorkersSite: false,
21
+ assetPaths: [],
22
+ entry: { format: "modules" },
23
+ bindings: { wasm_modules: true },
24
+ };
25
+
26
+ expect(() => validateDevProps(props as unknown as DevProps)).toThrowError(
27
+ "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"
28
+ );
29
+ });
30
+
31
+ it("should throw if the user tries to configure [text_blobs] with an ES module worker", () => {
32
+ const props = {
33
+ isWorkersSite: false,
34
+ assetPaths: [],
35
+ entry: { format: "modules" },
36
+ bindings: { text_blobs: true },
37
+ };
38
+
39
+ expect(() => validateDevProps(props as unknown as DevProps)).toThrowError(
40
+ "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml"
41
+ );
42
+ });
43
+
44
+ it("should throw if the user tries to configure [data_blobs] with an ES module worker", () => {
45
+ const props = {
46
+ isWorkersSite: false,
47
+ assetPaths: [],
48
+ entry: { format: "modules" },
49
+ bindings: { data_blobs: true },
50
+ };
51
+
52
+ expect(() => validateDevProps(props as unknown as DevProps)).toThrowError(
53
+ "You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml"
54
+ );
55
+ });
56
+ });
@@ -0,0 +1,35 @@
1
+ import { version } from "./../../package.json";
2
+ import { mockConsoleMethods } from "./helpers/mock-console";
3
+ import { useMockIsTTY } from "./helpers/mock-istty";
4
+ import { runWrangler } from "./helpers/run-wrangler";
5
+
6
+ describe("version", () => {
7
+ const std = mockConsoleMethods();
8
+ const { setIsTTY } = useMockIsTTY();
9
+
10
+ // We cannot test output of version banner,
11
+ // as it is disabled in jest environments
12
+
13
+ // it("should output version banner", async () => {
14
+ // await runWrangler("-v");
15
+ // expect(std.out).toMatchInlineSnapshot(`
16
+ // " ⛅️ wrangler 2.0.22
17
+ // --------------------"
18
+ // `);
19
+ // });
20
+
21
+ it("should output current version if !isTTY calling -v", async () => {
22
+ setIsTTY(false);
23
+
24
+ await runWrangler("-v");
25
+ expect(std.out).toMatch(version);
26
+ });
27
+
28
+ // This run separately as command handling is different
29
+ it("should output current version if !isTTY calling --version", async () => {
30
+ setIsTTY(false);
31
+
32
+ await runWrangler("--version");
33
+ expect(std.out).toMatch(version);
34
+ });
35
+ });