wrangler 0.0.0-e043479 → 0.0.0-e09abbc

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 (208) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +33 -14
  3. package/bin/wrangler.js +160 -28
  4. package/kv-asset-handler.js +1 -0
  5. package/miniflare-dist/index.mjs +5354 -0
  6. package/package.json +166 -136
  7. package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
  8. package/src/__tests__/config-cache.test.ts +42 -0
  9. package/src/__tests__/configuration.test.ts +3942 -2178
  10. package/src/__tests__/dev.test.tsx +1191 -235
  11. package/src/__tests__/guess-worker-format.test.ts +76 -57
  12. package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
  13. package/src/__tests__/helpers/mock-account-id.ts +26 -22
  14. package/src/__tests__/helpers/mock-bin.ts +20 -20
  15. package/src/__tests__/helpers/mock-cfetch.ts +96 -92
  16. package/src/__tests__/helpers/mock-console.ts +59 -32
  17. package/src/__tests__/helpers/mock-dialogs.ts +121 -33
  18. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  19. package/src/__tests__/helpers/mock-istty.ts +74 -0
  20. package/src/__tests__/helpers/mock-kv.ts +28 -35
  21. package/src/__tests__/helpers/mock-oauth-flow.ts +250 -0
  22. package/src/__tests__/helpers/mock-process.ts +39 -0
  23. package/src/__tests__/helpers/mock-stdin.ts +82 -77
  24. package/src/__tests__/helpers/mock-web-socket.ts +21 -21
  25. package/src/__tests__/helpers/run-in-tmp.ts +29 -20
  26. package/src/__tests__/helpers/run-wrangler.ts +8 -8
  27. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  28. package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
  29. package/src/__tests__/https-options.test.ts +163 -0
  30. package/src/__tests__/index.test.ts +246 -850
  31. package/src/__tests__/init.test.ts +1992 -0
  32. package/src/__tests__/jest.setup.ts +85 -34
  33. package/src/__tests__/kv.test.ts +1402 -1139
  34. package/src/__tests__/logger.test.ts +141 -0
  35. package/src/__tests__/metrics.test.ts +445 -0
  36. package/src/__tests__/package-manager.test.ts +312 -165
  37. package/src/__tests__/pages.test.ts +1261 -0
  38. package/src/__tests__/parse.test.ts +253 -245
  39. package/src/__tests__/publish.test.ts +6611 -2079
  40. package/src/__tests__/pubsub.test.ts +367 -0
  41. package/src/__tests__/r2.test.ts +184 -149
  42. package/src/__tests__/route.test.ts +45 -0
  43. package/src/__tests__/secret.test.ts +474 -407
  44. package/src/__tests__/tail.test.ts +565 -431
  45. package/src/__tests__/test-old-node-version.js +31 -0
  46. package/src/__tests__/user.test.ts +143 -0
  47. package/src/__tests__/whoami.test.tsx +219 -75
  48. package/src/__tests__/worker-namespace.test.ts +327 -0
  49. package/src/abort.d.ts +3 -0
  50. package/src/api/dev.ts +86 -0
  51. package/src/api/index.ts +1 -0
  52. package/src/bundle-reporter.tsx +29 -0
  53. package/src/bundle.ts +196 -93
  54. package/src/cfetch/index.ts +83 -66
  55. package/src/cfetch/internal.ts +100 -84
  56. package/src/cli.ts +22 -14
  57. package/src/config/README.md +7 -7
  58. package/src/config/config.ts +223 -242
  59. package/src/config/diagnostics.ts +61 -61
  60. package/src/config/environment.ts +404 -256
  61. package/src/config/index.ts +218 -32
  62. package/src/config/validation-helpers.ts +436 -222
  63. package/src/config/validation.ts +1642 -907
  64. package/src/config-cache.ts +84 -0
  65. package/src/create-worker-preview.ts +255 -0
  66. package/src/create-worker-upload-form.ts +263 -0
  67. package/src/dev/dev-vars.ts +36 -0
  68. package/src/dev/dev.tsx +452 -0
  69. package/src/dev/local.tsx +373 -0
  70. package/src/dev/remote.tsx +386 -0
  71. package/src/dev/use-esbuild.ts +150 -0
  72. package/src/dev.tsx +576 -943
  73. package/src/dialogs.tsx +115 -57
  74. package/src/durable.ts +102 -0
  75. package/src/entry.ts +308 -37
  76. package/src/environment-variables.ts +25 -23
  77. package/src/errors.ts +11 -0
  78. package/src/faye-websocket.d.ts +6 -0
  79. package/src/generate.ts +33 -0
  80. package/src/git-client.ts +42 -0
  81. package/src/global-wrangler-config-path.ts +26 -0
  82. package/src/https-options.ts +127 -0
  83. package/src/index.tsx +1910 -2241
  84. package/src/init.ts +549 -0
  85. package/src/inspect.ts +603 -550
  86. package/src/intl-polyfill.d.ts +139 -0
  87. package/src/is-interactive.ts +12 -0
  88. package/src/kv.ts +430 -0
  89. package/src/logger.ts +73 -0
  90. package/src/metrics/index.ts +4 -0
  91. package/src/metrics/is-ci.ts +14 -0
  92. package/src/metrics/metrics-config.ts +239 -0
  93. package/src/metrics/metrics-dispatcher.ts +95 -0
  94. package/src/metrics/send-event.ts +92 -0
  95. package/src/miniflare-cli/README.md +30 -0
  96. package/src/miniflare-cli/assets.ts +543 -0
  97. package/src/miniflare-cli/enum-keys.ts +17 -0
  98. package/src/miniflare-cli/index.ts +85 -0
  99. package/src/miniflare-cli/request-context.ts +40 -0
  100. package/src/module-collection.ts +234 -146
  101. package/src/open-in-browser.ts +10 -6
  102. package/src/package-manager.ts +183 -90
  103. package/src/pages/build.tsx +204 -0
  104. package/src/pages/constants.ts +7 -0
  105. package/src/pages/deployments.tsx +106 -0
  106. package/src/pages/dev.tsx +401 -0
  107. package/src/pages/functions/buildPlugin.ts +105 -0
  108. package/src/pages/functions/buildWorker.ts +151 -0
  109. package/src/pages/functions/filepath-routing.test.ts +234 -0
  110. package/src/pages/functions/filepath-routing.ts +189 -0
  111. package/src/pages/functions/identifiers.ts +78 -0
  112. package/src/pages/functions/routes.ts +151 -0
  113. package/src/pages/index.tsx +84 -0
  114. package/src/pages/projects.tsx +163 -0
  115. package/src/pages/publish.tsx +338 -0
  116. package/src/pages/types.ts +40 -0
  117. package/src/pages/upload.tsx +396 -0
  118. package/src/pages/utils.ts +12 -0
  119. package/src/parse.ts +224 -121
  120. package/src/paths.ts +6 -6
  121. package/src/preview.ts +31 -0
  122. package/src/proxy.ts +413 -313
  123. package/src/publish.ts +773 -343
  124. package/src/pubsub/index.ts +286 -0
  125. package/src/pubsub/pubsub-commands.tsx +623 -0
  126. package/src/r2.ts +19 -19
  127. package/src/selfsigned.d.ts +29 -0
  128. package/src/sites.tsx +285 -151
  129. package/src/tail/filters.ts +108 -108
  130. package/src/tail/index.ts +217 -217
  131. package/src/tail/printing.ts +51 -46
  132. package/src/update-check.ts +19 -0
  133. package/src/user/choose-account.tsx +69 -0
  134. package/src/user/env-vars.ts +46 -0
  135. package/src/user/generate-auth-url.ts +33 -0
  136. package/src/user/generate-random-state.ts +16 -0
  137. package/src/user/index.ts +3 -0
  138. package/src/user/user.tsx +1171 -0
  139. package/src/whoami.tsx +63 -41
  140. package/src/worker-namespace.ts +206 -0
  141. package/src/worker.ts +191 -0
  142. package/src/zones.ts +76 -0
  143. package/templates/checked-fetch.js +17 -0
  144. package/templates/gitignore +171 -0
  145. package/templates/new-worker-scheduled.js +17 -0
  146. package/templates/new-worker-scheduled.ts +32 -0
  147. package/templates/new-worker.js +3 -3
  148. package/templates/new-worker.ts +18 -3
  149. package/templates/no-op-worker.js +10 -0
  150. package/templates/pages-shim.ts +9 -0
  151. package/templates/pages-template-plugin.ts +155 -0
  152. package/templates/pages-template-worker.ts +161 -0
  153. package/templates/static-asset-facade.js +38 -36
  154. package/templates/tsconfig.json +95 -95
  155. package/wrangler-dist/cli.d.ts +327 -0
  156. package/wrangler-dist/cli.js +94947 -111199
  157. package/pages/functions/buildWorker.ts +0 -62
  158. package/pages/functions/filepath-routing.test.ts +0 -123
  159. package/pages/functions/filepath-routing.ts +0 -178
  160. package/pages/functions/identifiers.ts +0 -78
  161. package/pages/functions/routes.ts +0 -151
  162. package/pages/functions/template-worker.ts +0 -130
  163. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  164. package/src/__tests__/helpers/mock-user.ts +0 -27
  165. package/src/__tests__/logout.test.ts +0 -50
  166. package/src/__tests__/sentry.test.ts +0 -146
  167. package/src/api/form_data.ts +0 -217
  168. package/src/api/preview.ts +0 -147
  169. package/src/api/worker.ts +0 -186
  170. package/src/guess-worker-format.ts +0 -68
  171. package/src/kv.tsx +0 -339
  172. package/src/pages.tsx +0 -1045
  173. package/src/reporting.ts +0 -115
  174. package/src/user.tsx +0 -1063
  175. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  176. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  177. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  178. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  179. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  180. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  181. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  182. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  183. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  184. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  185. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  186. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  187. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  188. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  189. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  190. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  191. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  192. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  193. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  194. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  195. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  196. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  197. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  198. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  199. package/vendor/wrangler-mime/LICENSE +0 -21
  200. package/vendor/wrangler-mime/Mime.js +0 -97
  201. package/vendor/wrangler-mime/README.md +0 -187
  202. package/vendor/wrangler-mime/cli.js +0 -46
  203. package/vendor/wrangler-mime/index.js +0 -4
  204. package/vendor/wrangler-mime/lite.js +0 -4
  205. package/vendor/wrangler-mime/package.json +0 -52
  206. package/vendor/wrangler-mime/types/other.js +0 -1
  207. package/vendor/wrangler-mime/types/standard.js +0 -1
  208. package/wrangler-dist/cli.js.map +0 -7
@@ -3,297 +3,426 @@ import { Headers, Request } from "undici";
3
3
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
4
4
  import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
5
5
  import { mockConsoleMethods } from "./helpers/mock-console";
6
+ import { useMockIsTTY } from "./helpers/mock-istty";
6
7
  import { runInTempDir } from "./helpers/run-in-tmp";
7
8
  import { runWrangler } from "./helpers/run-wrangler";
8
9
  import type { TailEventMessage, RequestEvent, ScheduledEvent } from "../tail";
9
10
  import type WebSocket from "ws";
10
11
 
11
12
  describe("tail", () => {
12
- runInTempDir();
13
- mockAccountId();
14
- mockApiToken();
15
-
16
- const std = mockConsoleMethods();
17
-
18
- afterEach(() => {
19
- mockWebSockets.forEach((ws) => ws.close());
20
- mockWebSockets.splice(0);
21
- unsetAllMocks();
22
- });
23
-
24
- /**
25
- * Interaction with the tailing API, including tail creation,
26
- * deletion, and connection.
27
- */
28
- describe("API interaction", () => {
29
- it("creates and then delete tails", async () => {
30
- const api = mockWebsocketAPIs();
31
- expect(api.requests.creation.count).toStrictEqual(0);
32
-
33
- await runWrangler("tail test-worker");
34
-
35
- await expect(api.ws.connected).resolves.toBeTruthy();
36
- expect(api.requests.creation.count).toStrictEqual(1);
37
- expect(api.requests.deletion.count).toStrictEqual(0);
38
-
39
- api.ws.close();
40
- expect(api.requests.deletion.count).toStrictEqual(1);
41
- });
42
-
43
- it("creates and then delete tails: legacy envs", async () => {
44
- const api = mockWebsocketAPIs("some-env", true);
45
- expect(api.requests.creation.count).toStrictEqual(0);
46
-
47
- await runWrangler("tail test-worker --env some-env --legacy-env true");
48
-
49
- await expect(api.ws.connected).resolves.toBeTruthy();
50
- expect(api.requests.creation.count).toStrictEqual(1);
51
- expect(api.requests.deletion.count).toStrictEqual(0);
52
-
53
- api.ws.close();
54
- expect(api.requests.deletion.count).toStrictEqual(1);
55
- });
56
-
57
- it("creates and then delete tails: service envs", async () => {
58
- const api = mockWebsocketAPIs("some-env");
59
- expect(api.requests.creation.count).toStrictEqual(0);
60
-
61
- await runWrangler("tail test-worker --env some-env --legacy-env false");
62
-
63
- await expect(api.ws.connected).resolves.toBeTruthy();
64
- expect(api.requests.creation.count).toStrictEqual(1);
65
- expect(api.requests.deletion.count).toStrictEqual(0);
66
-
67
- api.ws.close();
68
- expect(api.requests.deletion.count).toStrictEqual(1);
69
- });
70
-
71
- it("errors when the websocket closes unexpectedly", async () => {
72
- const api = mockWebsocketAPIs();
73
- api.ws.close();
74
-
75
- await expect(runWrangler("tail test-worker")).rejects.toThrow();
76
- });
77
-
78
- it("activates debug mode when the cli arg is passed in", async () => {
79
- const api = mockWebsocketAPIs();
80
- await runWrangler("tail test-worker --debug");
81
- await expect(api.nextMessageJson()).resolves.toHaveProperty(
82
- "debug",
83
- true
84
- );
85
- });
86
- });
87
-
88
- describe("filtering", () => {
89
- it("sends sampling rate filters", async () => {
90
- const api = mockWebsocketAPIs();
91
- const tooHigh = runWrangler("tail test-worker --sampling-rate 10");
92
- await expect(tooHigh).rejects.toThrow();
93
-
94
- const tooLow = runWrangler("tail test-worker --sampling-rate -5");
95
- await expect(tooLow).rejects.toThrow();
96
-
97
- await runWrangler("tail test-worker --sampling-rate 0.25");
98
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
99
- { sampling_rate: 0.25 },
100
- ]);
101
- });
102
-
103
- it("sends single status filters", async () => {
104
- const api = mockWebsocketAPIs();
105
- await runWrangler("tail test-worker --status error");
106
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
107
- { outcome: ["exception", "exceededCpu", "unknown"] },
108
- ]);
109
- });
110
-
111
- it("sends multiple status filters", async () => {
112
- const api = mockWebsocketAPIs();
113
- await runWrangler("tail test-worker --status error --status canceled");
114
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
115
- { outcome: ["exception", "exceededCpu", "unknown", "canceled"] },
116
- ]);
117
- });
118
-
119
- it("sends single HTTP method filters", async () => {
120
- const api = mockWebsocketAPIs();
121
- await runWrangler("tail test-worker --method POST");
122
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
123
- { method: ["POST"] },
124
- ]);
125
- });
126
-
127
- it("sends multiple HTTP method filters", async () => {
128
- const api = mockWebsocketAPIs();
129
- await runWrangler("tail test-worker --method POST --method GET");
130
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
131
- { method: ["POST", "GET"] },
132
- ]);
133
- });
134
-
135
- it("sends header filters without a query", async () => {
136
- const api = mockWebsocketAPIs();
137
- await runWrangler("tail test-worker --header X-CUSTOM-HEADER ");
138
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
139
- { header: { key: "X-CUSTOM-HEADER" } },
140
- ]);
141
- });
142
-
143
- it("sends header filters with a query", async () => {
144
- const api = mockWebsocketAPIs();
145
- await runWrangler(
146
- "tail test-worker --header X-CUSTOM-HEADER:some-value "
147
- );
148
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
149
- { header: { key: "X-CUSTOM-HEADER", query: "some-value" } },
150
- ]);
151
- });
152
-
153
- it("sends single IP filters", async () => {
154
- const api = mockWebsocketAPIs();
155
- const fakeIp = "192.0.2.1";
156
-
157
- await runWrangler(`tail test-worker --ip ${fakeIp}`);
158
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
159
- { client_ip: [fakeIp] },
160
- ]);
161
- });
162
-
163
- it("sends multiple IP filters", async () => {
164
- const api = mockWebsocketAPIs();
165
- const fakeIp = "192.0.2.1";
166
-
167
- await runWrangler(`tail test-worker --ip ${fakeIp} --ip self`);
168
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
169
- { client_ip: [fakeIp, "self"] },
170
- ]);
171
- });
172
-
173
- it("sends search filters", async () => {
174
- const api = mockWebsocketAPIs();
175
- const search = "filterMe";
176
-
177
- await runWrangler(`tail test-worker --search ${search}`);
178
- await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
179
- { query: search },
180
- ]);
181
- });
182
-
183
- it("sends everything but the kitchen sink", async () => {
184
- const api = mockWebsocketAPIs();
185
- const sampling_rate = 0.69;
186
- const status = ["ok", "error"];
187
- const method = ["GET", "POST", "PUT"];
188
- const header = "X-HELLO:world";
189
- const client_ip = ["192.0.2.1", "self"];
190
- const query = "onlyTheseMessagesPlease";
191
-
192
- const cliFilters =
193
- `--sampling-rate ${sampling_rate} ` +
194
- status.map((s) => `--status ${s} `).join("") +
195
- method.map((m) => `--method ${m} `).join("") +
196
- `--header ${header} ` +
197
- client_ip.map((c) => `--ip ${c} `).join("") +
198
- `--search ${query} ` +
199
- `--debug`;
200
-
201
- const expectedWebsocketMessage = {
202
- filters: [
203
- { sampling_rate },
204
- { outcome: ["ok", "exception", "exceededCpu", "unknown"] },
205
- { method },
206
- { header: { key: "X-HELLO", query: "world" } },
207
- { client_ip },
208
- { query },
209
- ],
210
- debug: true,
211
- };
212
-
213
- await runWrangler(`tail test-worker ${cliFilters}`);
214
- await expect(api.nextMessageJson()).resolves.toEqual(
215
- expectedWebsocketMessage
216
- );
217
- });
218
- });
219
-
220
- describe("printing", () => {
221
- it("logs request messages in JSON format", async () => {
222
- const api = mockWebsocketAPIs();
223
- await runWrangler("tail test-worker --format json");
224
-
225
- const event = generateMockRequestEvent();
226
- const message = generateMockEventMessage({ event });
227
- const serializedMessage = serialize(message);
228
-
229
- api.ws.send(serializedMessage);
230
- expect(std.out).toMatch(deserializeToJson(serializedMessage));
231
- });
232
-
233
- it("logs scheduled messages in JSON format", async () => {
234
- const api = mockWebsocketAPIs();
235
- await runWrangler("tail test-worker --format json");
236
-
237
- const event = generateMockScheduledEvent();
238
- const message = generateMockEventMessage({ event });
239
- const serializedMessage = serialize(message);
240
-
241
- api.ws.send(serializedMessage);
242
- expect(std.out).toMatch(deserializeToJson(serializedMessage));
243
- });
244
-
245
- it("logs request messages in pretty format", async () => {
246
- const api = mockWebsocketAPIs();
247
- await runWrangler("tail test-worker --format pretty");
248
-
249
- const event = generateMockRequestEvent();
250
- const message = generateMockEventMessage({ event });
251
- const serializedMessage = serialize(message);
252
-
253
- api.ws.send(serializedMessage);
254
- expect(
255
- std.out
256
- .replace(
257
- new Date(mockEventTimestamp).toLocaleString(),
258
- "[mock event timestamp]"
259
- )
260
- .replace(
261
- mockTailExpiration.toLocaleString(),
262
- "[mock expiration date]"
263
- )
264
- ).toMatchInlineSnapshot(`
265
- "successfully created tail, expires at [mock expiration date]
13
+ runInTempDir();
14
+ mockAccountId();
15
+ mockApiToken();
16
+
17
+ const std = mockConsoleMethods();
18
+
19
+ afterEach(() => {
20
+ mockWebSockets.forEach((ws) => ws.close());
21
+ mockWebSockets.splice(0);
22
+ unsetAllMocks();
23
+ });
24
+
25
+ /**
26
+ * Interaction with the tailing API, including tail creation,
27
+ * deletion, and connection.
28
+ */
29
+ describe("API interaction", () => {
30
+ it("should throw an error if name isn't provided", async () => {
31
+ await expect(
32
+ runWrangler("tail")
33
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
34
+ `"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`wrangler tail <worker-name>\`"`
35
+ );
36
+ });
37
+
38
+ it("creates and then delete tails", async () => {
39
+ const api = mockWebsocketAPIs();
40
+ expect(api.requests.creation.count).toStrictEqual(0);
41
+
42
+ await runWrangler("tail test-worker");
43
+
44
+ await expect(api.ws.connected).resolves.toBeTruthy();
45
+ expect(api.requests.creation.count).toStrictEqual(1);
46
+ expect(api.requests.deletion.count).toStrictEqual(0);
47
+
48
+ api.ws.close();
49
+ expect(api.requests.deletion.count).toStrictEqual(1);
50
+ });
51
+
52
+ it("creates and then delete tails: legacy envs", async () => {
53
+ const api = mockWebsocketAPIs("some-env", true);
54
+ expect(api.requests.creation.count).toStrictEqual(0);
55
+
56
+ await runWrangler("tail test-worker --env some-env --legacy-env true");
57
+
58
+ await expect(api.ws.connected).resolves.toBeTruthy();
59
+ expect(api.requests.creation.count).toStrictEqual(1);
60
+ expect(api.requests.deletion.count).toStrictEqual(0);
61
+
62
+ api.ws.close();
63
+ expect(api.requests.deletion.count).toStrictEqual(1);
64
+ });
65
+
66
+ it("creates and then delete tails: service envs", async () => {
67
+ const api = mockWebsocketAPIs("some-env");
68
+ expect(api.requests.creation.count).toStrictEqual(0);
69
+
70
+ await runWrangler("tail test-worker --env some-env --legacy-env false");
71
+
72
+ await expect(api.ws.connected).resolves.toBeTruthy();
73
+ expect(api.requests.creation.count).toStrictEqual(1);
74
+ expect(api.requests.deletion.count).toStrictEqual(0);
75
+
76
+ api.ws.close();
77
+ expect(api.requests.deletion.count).toStrictEqual(1);
78
+ });
79
+
80
+ it("errors when the websocket closes unexpectedly", async () => {
81
+ const api = mockWebsocketAPIs();
82
+ api.ws.close();
83
+
84
+ await expect(runWrangler("tail test-worker")).rejects.toThrow();
85
+ });
86
+
87
+ it("activates debug mode when the cli arg is passed in", async () => {
88
+ const api = mockWebsocketAPIs();
89
+ await runWrangler("tail test-worker --debug");
90
+ await expect(api.nextMessageJson()).resolves.toHaveProperty(
91
+ "debug",
92
+ true
93
+ );
94
+ });
95
+ });
96
+
97
+ describe("filtering", () => {
98
+ it("sends sampling rate filters", async () => {
99
+ const api = mockWebsocketAPIs();
100
+ const tooHigh = runWrangler("tail test-worker --sampling-rate 10");
101
+ await expect(tooHigh).rejects.toThrow();
102
+
103
+ const tooLow = runWrangler("tail test-worker --sampling-rate -5");
104
+ await expect(tooLow).rejects.toThrow();
105
+
106
+ await runWrangler("tail test-worker --sampling-rate 0.25");
107
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
108
+ { sampling_rate: 0.25 },
109
+ ]);
110
+ });
111
+
112
+ it("sends single status filters", async () => {
113
+ const api = mockWebsocketAPIs();
114
+ await runWrangler("tail test-worker --status error");
115
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
116
+ { outcome: ["exception", "exceededCpu", "unknown"] },
117
+ ]);
118
+ });
119
+
120
+ it("sends multiple status filters", async () => {
121
+ const api = mockWebsocketAPIs();
122
+ await runWrangler("tail test-worker --status error --status canceled");
123
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
124
+ { outcome: ["exception", "exceededCpu", "unknown", "canceled"] },
125
+ ]);
126
+ });
127
+
128
+ it("sends single HTTP method filters", async () => {
129
+ const api = mockWebsocketAPIs();
130
+ await runWrangler("tail test-worker --method POST");
131
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
132
+ { method: ["POST"] },
133
+ ]);
134
+ });
135
+
136
+ it("sends multiple HTTP method filters", async () => {
137
+ const api = mockWebsocketAPIs();
138
+ await runWrangler("tail test-worker --method POST --method GET");
139
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
140
+ { method: ["POST", "GET"] },
141
+ ]);
142
+ });
143
+
144
+ it("sends header filters without a query", async () => {
145
+ const api = mockWebsocketAPIs();
146
+ await runWrangler("tail test-worker --header X-CUSTOM-HEADER");
147
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
148
+ { header: { key: "X-CUSTOM-HEADER" } },
149
+ ]);
150
+ });
151
+
152
+ it("sends header filters with a query", async () => {
153
+ const api = mockWebsocketAPIs();
154
+ await runWrangler("tail test-worker --header X-CUSTOM-HEADER:some-value");
155
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
156
+ { header: { key: "X-CUSTOM-HEADER", query: "some-value" } },
157
+ ]);
158
+ });
159
+
160
+ it("sends single IP filters", async () => {
161
+ const api = mockWebsocketAPIs();
162
+ const fakeIp = "192.0.2.1";
163
+
164
+ await runWrangler(`tail test-worker --ip ${fakeIp}`);
165
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
166
+ { client_ip: [fakeIp] },
167
+ ]);
168
+ });
169
+
170
+ it("sends multiple IP filters", async () => {
171
+ const api = mockWebsocketAPIs();
172
+ const fakeIp = "192.0.2.1";
173
+
174
+ await runWrangler(`tail test-worker --ip ${fakeIp} --ip self`);
175
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
176
+ { client_ip: [fakeIp, "self"] },
177
+ ]);
178
+ });
179
+
180
+ it("sends search filters", async () => {
181
+ const api = mockWebsocketAPIs();
182
+ const search = "filterMe";
183
+
184
+ await runWrangler(`tail test-worker --search ${search}`);
185
+ await expect(api.nextMessageJson()).resolves.toHaveProperty("filters", [
186
+ { query: search },
187
+ ]);
188
+ });
189
+
190
+ it("sends everything but the kitchen sink", async () => {
191
+ const api = mockWebsocketAPIs();
192
+ const sampling_rate = 0.69;
193
+ const status = ["ok", "error"];
194
+ const method = ["GET", "POST", "PUT"];
195
+ const header = "X-HELLO:world";
196
+ const client_ip = ["192.0.2.1", "self"];
197
+ const query = "onlyTheseMessagesPlease";
198
+
199
+ const cliFilters =
200
+ `--sampling-rate ${sampling_rate} ` +
201
+ status.map((s) => `--status ${s} `).join("") +
202
+ method.map((m) => `--method ${m} `).join("") +
203
+ `--header ${header} ` +
204
+ client_ip.map((c) => `--ip ${c} `).join("") +
205
+ `--search ${query} ` +
206
+ `--debug`;
207
+
208
+ const expectedWebsocketMessage = {
209
+ filters: [
210
+ { sampling_rate },
211
+ { outcome: ["ok", "exception", "exceededCpu", "unknown"] },
212
+ { method },
213
+ { header: { key: "X-HELLO", query: "world" } },
214
+ { client_ip },
215
+ { query },
216
+ ],
217
+ debug: true,
218
+ };
219
+
220
+ await runWrangler(`tail test-worker ${cliFilters}`);
221
+ await expect(api.nextMessageJson()).resolves.toEqual(
222
+ expectedWebsocketMessage
223
+ );
224
+ });
225
+ });
226
+
227
+ describe("printing", () => {
228
+ const { setIsTTY } = useMockIsTTY();
229
+
230
+ it("logs request messages in JSON format", async () => {
231
+ const api = mockWebsocketAPIs();
232
+ await runWrangler("tail test-worker --format json");
233
+
234
+ const event = generateMockRequestEvent();
235
+ const message = generateMockEventMessage({ event });
236
+ const serializedMessage = serialize(message);
237
+
238
+ api.ws.send(serializedMessage);
239
+ expect(std.out).toMatch(deserializeToJson(serializedMessage));
240
+ });
241
+
242
+ it("logs scheduled messages in JSON format", async () => {
243
+ const api = mockWebsocketAPIs();
244
+ await runWrangler("tail test-worker --format json");
245
+
246
+ const event = generateMockScheduledEvent();
247
+ const message = generateMockEventMessage({ event });
248
+ const serializedMessage = serialize(message);
249
+
250
+ api.ws.send(serializedMessage);
251
+ expect(std.out).toMatch(deserializeToJson(serializedMessage));
252
+ });
253
+
254
+ it("logs request messages in pretty format", async () => {
255
+ const api = mockWebsocketAPIs();
256
+ await runWrangler("tail test-worker --format pretty");
257
+
258
+ const event = generateMockRequestEvent();
259
+ const message = generateMockEventMessage({ event });
260
+ const serializedMessage = serialize(message);
261
+
262
+ api.ws.send(serializedMessage);
263
+ expect(
264
+ std.out
265
+ .replace(
266
+ new Date(mockEventTimestamp).toLocaleString(),
267
+ "[mock event timestamp]"
268
+ )
269
+ .replace(
270
+ mockTailExpiration.toLocaleString(),
271
+ "[mock expiration date]"
272
+ )
273
+ ).toMatchInlineSnapshot(`
274
+ "Successfully created tail, expires at [mock expiration date]
266
275
  Connected to test-worker, waiting for logs...
267
276
  GET https://example.org/ - Ok @ [mock event timestamp]"
268
277
  `);
269
- });
270
-
271
- it("logs scheduled messages in pretty format", async () => {
272
- const api = mockWebsocketAPIs();
273
- await runWrangler("tail test-worker --format pretty");
274
-
275
- const event = generateMockScheduledEvent();
276
- const message = generateMockEventMessage({ event });
277
- const serializedMessage = serialize(message);
278
-
279
- api.ws.send(serializedMessage);
280
- expect(
281
- std.out
282
- .replace(
283
- new Date(mockEventTimestamp).toLocaleString(),
284
- "[mock timestamp string]"
285
- )
286
- .replace(
287
- mockTailExpiration.toLocaleString(),
288
- "[mock expiration date]"
289
- )
290
- ).toMatchInlineSnapshot(`
291
- "successfully created tail, expires at [mock expiration date]
278
+ });
279
+
280
+ it("logs scheduled messages in pretty format", async () => {
281
+ const api = mockWebsocketAPIs();
282
+ await runWrangler("tail test-worker --format pretty");
283
+
284
+ const event = generateMockScheduledEvent();
285
+ const message = generateMockEventMessage({ event });
286
+ const serializedMessage = serialize(message);
287
+
288
+ api.ws.send(serializedMessage);
289
+ expect(
290
+ std.out
291
+ .replace(
292
+ new Date(mockEventTimestamp).toLocaleString(),
293
+ "[mock timestamp string]"
294
+ )
295
+ .replace(
296
+ mockTailExpiration.toLocaleString(),
297
+ "[mock expiration date]"
298
+ )
299
+ ).toMatchInlineSnapshot(`
300
+ "Successfully created tail, expires at [mock expiration date]
292
301
  Connected to test-worker, waiting for logs...
293
302
  \\"* * * * *\\" @ [mock timestamp string] - Ok"
294
303
  `);
295
- });
296
- });
304
+ });
305
+
306
+ it("should not crash when the tail message has a void event", async () => {
307
+ const api = mockWebsocketAPIs();
308
+ await runWrangler("tail test-worker --format pretty");
309
+
310
+ const message = generateMockEventMessage({ event: null });
311
+ const serializedMessage = serialize(message);
312
+
313
+ api.ws.send(serializedMessage);
314
+ expect(
315
+ std.out
316
+ .replace(
317
+ new Date(mockEventTimestamp).toLocaleString(),
318
+ "[mock timestamp string]"
319
+ )
320
+ .replace(
321
+ mockTailExpiration.toLocaleString(),
322
+ "[mock expiration date]"
323
+ )
324
+ ).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
+ `);
329
+ });
330
+
331
+ it("defaults to logging in pretty format when the output is a TTY", async () => {
332
+ setIsTTY(true);
333
+ const api = mockWebsocketAPIs();
334
+ await runWrangler("tail test-worker");
335
+
336
+ const event = generateMockRequestEvent();
337
+ const message = generateMockEventMessage({ event });
338
+ const serializedMessage = serialize(message);
339
+
340
+ api.ws.send(serializedMessage);
341
+ expect(
342
+ std.out
343
+ .replace(
344
+ new Date(mockEventTimestamp).toLocaleString(),
345
+ "[mock event timestamp]"
346
+ )
347
+ .replace(
348
+ mockTailExpiration.toLocaleString(),
349
+ "[mock expiration date]"
350
+ )
351
+ ).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
+ `);
356
+ });
357
+
358
+ it("defaults to logging in json format when the output is not a TTY", async () => {
359
+ setIsTTY(false);
360
+
361
+ const api = mockWebsocketAPIs();
362
+ await runWrangler("tail test-worker");
363
+
364
+ const event = generateMockRequestEvent();
365
+ const message = generateMockEventMessage({ event });
366
+ const serializedMessage = serialize(message);
367
+
368
+ api.ws.send(serializedMessage);
369
+ expect(std.out).toMatch(deserializeToJson(serializedMessage));
370
+ });
371
+
372
+ it("logs console messages and exceptions", async () => {
373
+ setIsTTY(true);
374
+ const api = mockWebsocketAPIs();
375
+ await runWrangler("tail test-worker");
376
+
377
+ const event = generateMockRequestEvent();
378
+ const message = generateMockEventMessage({
379
+ event,
380
+ logs: [
381
+ { message: ["some string"], level: "log", timestamp: 1234561 },
382
+ {
383
+ message: [{ complex: "object" }],
384
+ level: "log",
385
+ timestamp: 1234562,
386
+ },
387
+ { message: [1234], level: "error", timestamp: 1234563 },
388
+ ],
389
+ exceptions: [
390
+ { name: "Error", message: "some error", timestamp: 1234564 },
391
+ { name: "Error", message: { complex: "error" }, timestamp: 1234564 },
392
+ ],
393
+ });
394
+ const serializedMessage = serialize(message);
395
+
396
+ api.ws.send(serializedMessage);
397
+ expect(
398
+ std.out
399
+ .replace(
400
+ new Date(mockEventTimestamp).toLocaleString(),
401
+ "[mock event timestamp]"
402
+ )
403
+ .replace(
404
+ mockTailExpiration.toLocaleString(),
405
+ "[mock expiration date]"
406
+ )
407
+ ).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
+ `);
415
+ expect(std.err).toMatchInlineSnapshot(`
416
+ "X [ERROR]  Error: some error
417
+
418
+
419
+ X [ERROR]  Error: { complex: 'error' }
420
+
421
+ "
422
+ `);
423
+ expect(std.warn).toMatchInlineSnapshot(`""`);
424
+ });
425
+ });
297
426
  });
298
427
 
299
428
  /* helpers */
@@ -308,32 +437,33 @@ describe("tail", () => {
308
437
  * @returns the same type we expect when deserializing in wrangler
309
438
  */
310
439
  function serialize(message: TailEventMessage): WebSocket.RawData {
311
- if (isScheduled(message.event)) {
312
- // `ScheduledEvent`s work just fine
313
- const stringified = JSON.stringify(message);
314
- return Buffer.from(stringified, "utf-8");
315
- } else {
316
- // Since the "properties" of an `undici.Request` are actually getters,
317
- // which don't serialize properly, we need to hydrate them manually.
318
- // This isn't a problem outside of testing since deserialization
319
- // works just fine and wrangler never _sends_ any event messages,
320
- // it only receives them.
321
- const request = (message.event as RequestEvent).request;
322
- const stringified = JSON.stringify(message, (key, value) => {
323
- if (key !== "request") {
324
- return value;
325
- }
326
-
327
- return {
328
- ...request,
329
- url: request.url,
330
- headers: request.headers,
331
- method: request.method,
332
- };
333
- });
334
-
335
- return Buffer.from(stringified, "utf-8");
336
- }
440
+ if (isScheduled(message.event)) {
441
+ // `ScheduledEvent`s work just fine
442
+ const stringified = JSON.stringify(message);
443
+ return Buffer.from(stringified, "utf-8");
444
+ } else {
445
+ // Since the "properties" of an `undici.Request` are actually getters,
446
+ // which don't serialize properly, we need to hydrate them manually.
447
+ // This isn't a problem outside of testing since deserialization
448
+ // works just fine and wrangler never _sends_ any event messages,
449
+ // it only receives them.
450
+ const request = ((message.event as RequestEvent | undefined | null) || {})
451
+ .request;
452
+ const stringified = JSON.stringify(message, (key, value) => {
453
+ if (key !== "request") {
454
+ return value;
455
+ }
456
+
457
+ return {
458
+ ...request,
459
+ url: request?.url,
460
+ headers: request?.headers,
461
+ method: request?.method,
462
+ };
463
+ });
464
+
465
+ return Buffer.from(stringified, "utf-8");
466
+ }
337
467
  }
338
468
 
339
469
  /**
@@ -343,9 +473,9 @@ function serialize(message: TailEventMessage): WebSocket.RawData {
343
473
  * @returns whether event is a ScheduledEvent (true) or a RequestEvent
344
474
  */
345
475
  function isScheduled(
346
- event: ScheduledEvent | RequestEvent
476
+ event: ScheduledEvent | RequestEvent | undefined | null
347
477
  ): event is ScheduledEvent {
348
- return "cron" in event;
478
+ return Boolean(event && "cron" in event);
349
479
  }
350
480
 
351
481
  /**
@@ -357,7 +487,7 @@ function isScheduled(
357
487
  * @returns a string ready to be printed to the terminal or compared against
358
488
  */
359
489
  function deserializeToJson(message: WebSocket.RawData): string {
360
- return JSON.stringify(JSON.parse(message.toString()), null, 2);
490
+ return JSON.stringify(JSON.parse(message.toString()), null, 2);
361
491
  }
362
492
 
363
493
  /**
@@ -365,12 +495,12 @@ function deserializeToJson(message: WebSocket.RawData): string {
365
495
  * when running `wrangler tail`
366
496
  */
367
497
  type MockAPI = {
368
- requests: {
369
- creation: RequestCounter;
370
- deletion: RequestCounter;
371
- };
372
- ws: MockWebSocket;
373
- nextMessageJson(): Promise<unknown>;
498
+ requests: {
499
+ creation: RequestCounter;
500
+ deletion: RequestCounter;
501
+ };
502
+ ws: MockWebSocket;
503
+ nextMessageJson(): Promise<unknown>;
374
504
  };
375
505
 
376
506
  /**
@@ -379,7 +509,7 @@ type MockAPI = {
379
509
  * the correct API calls without actually sending any web traffic
380
510
  */
381
511
  type RequestCounter = {
382
- count: number;
512
+ count: number;
383
513
  };
384
514
 
385
515
  /**
@@ -389,34 +519,34 @@ type RequestCounter = {
389
519
  * @returns a `RequestCounter` for counting how many times the API is hit
390
520
  */
391
521
  function mockCreateTailRequest(
392
- websocketURL: string,
393
- env?: string,
394
- legacyEnv = false
522
+ websocketURL: string,
523
+ env?: string,
524
+ legacyEnv = false
395
525
  ): RequestCounter {
396
- const requests = { count: 0 };
397
- const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
398
- const environment = env && !legacyEnv ? "/environments/:envName" : "";
399
- setMockResponse(
400
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails`,
401
- "POST",
402
- ([_url, accountId, scriptName, envName]) => {
403
- requests.count++;
404
- expect(accountId).toEqual("some-account-id");
405
- expect(scriptName).toEqual(
406
- legacyEnv && env ? `test-worker-${env}` : "test-worker"
407
- );
408
- if (!legacyEnv) {
409
- expect(envName).toEqual(env);
410
- }
411
- return {
412
- id: "tail-id",
413
- url: websocketURL,
414
- expires_at: mockTailExpiration,
415
- };
416
- }
417
- );
418
-
419
- return requests;
526
+ const requests = { count: 0 };
527
+ const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
528
+ const environment = env && !legacyEnv ? "/environments/:envName" : "";
529
+ setMockResponse(
530
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails`,
531
+ "POST",
532
+ ([_url, accountId, scriptName, envName]) => {
533
+ requests.count++;
534
+ expect(accountId).toEqual("some-account-id");
535
+ expect(scriptName).toEqual(
536
+ legacyEnv && env ? `test-worker-${env}` : "test-worker"
537
+ );
538
+ if (!legacyEnv) {
539
+ expect(envName).toEqual(env);
540
+ }
541
+ return {
542
+ id: "tail-id",
543
+ url: websocketURL,
544
+ expires_at: mockTailExpiration,
545
+ };
546
+ }
547
+ );
548
+
549
+ return requests;
420
550
  }
421
551
 
422
552
  /**
@@ -435,37 +565,37 @@ const mockEventTimestamp = 1645454470467;
435
565
  * @returns a `RequestCounter` for counting how many times the API is hit
436
566
  */
437
567
  function mockDeleteTailRequest(
438
- env?: string,
439
- legacyEnv = false
568
+ env?: string,
569
+ legacyEnv = false
440
570
  ): RequestCounter {
441
- const requests = { count: 0 };
442
- const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
443
- const environment = env && !legacyEnv ? "/environments/:envName" : "";
444
- setMockResponse(
445
- // "/accounts/:accountId/workers/scripts/:worker/tails",
446
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails/:tailId`,
447
- "DELETE",
448
- ([_url, accountId, scriptName, envNameOrTailId, tailId]) => {
449
- requests.count++;
450
- expect(accountId).toEqual("some-account-id");
451
- expect(scriptName).toEqual(
452
- legacyEnv && env ? `test-worker-${env}` : "test-worker"
453
- );
454
- if (!legacyEnv) {
455
- if (env) {
456
- expect(envNameOrTailId).toEqual(env);
457
- expect(tailId).toEqual("tail-id");
458
- } else {
459
- expect(envNameOrTailId).toEqual("tail-id");
460
- }
461
- } else {
462
- expect(envNameOrTailId).toEqual("tail-id");
463
- }
464
- return null;
465
- }
466
- );
467
-
468
- return requests;
571
+ const requests = { count: 0 };
572
+ const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
573
+ const environment = env && !legacyEnv ? "/environments/:envName" : "";
574
+ setMockResponse(
575
+ // "/accounts/:accountId/workers/scripts/:worker/tails",
576
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails/:tailId`,
577
+ "DELETE",
578
+ ([_url, accountId, scriptName, envNameOrTailId, tailId]) => {
579
+ requests.count++;
580
+ expect(accountId).toEqual("some-account-id");
581
+ expect(scriptName).toEqual(
582
+ legacyEnv && env ? `test-worker-${env}` : "test-worker"
583
+ );
584
+ if (!legacyEnv) {
585
+ if (env) {
586
+ expect(envNameOrTailId).toEqual(env);
587
+ expect(tailId).toEqual("tail-id");
588
+ } else {
589
+ expect(envNameOrTailId).toEqual("tail-id");
590
+ }
591
+ } else {
592
+ expect(envNameOrTailId).toEqual("tail-id");
593
+ }
594
+ return null;
595
+ }
596
+ );
597
+
598
+ return requests;
469
599
  }
470
600
 
471
601
  const mockWebSockets: MockWebSocket[] = [];
@@ -478,30 +608,30 @@ const mockWebSockets: MockWebSocket[] = [];
478
608
  * @returns a mocked-out version of the API
479
609
  */
480
610
  function mockWebsocketAPIs(env?: string, legacyEnv = false): MockAPI {
481
- const websocketURL = "ws://localhost:1234";
482
- const api: MockAPI = {
483
- requests: {
484
- deletion: { count: 0 },
485
- creation: { count: 0 },
486
- },
487
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
488
- ws: null!, // will be set in the `beforeEach()` below.
489
-
490
- /**
491
- * Parse the next message received by the mock websocket as JSON
492
- * @returns JSON.parse of the next message received by the websocket
493
- */
494
- async nextMessageJson() {
495
- const message = await api.ws.nextMessage;
496
- return JSON.parse(message as string);
497
- },
498
- };
499
- api.requests.creation = mockCreateTailRequest(websocketURL, env, legacyEnv);
500
- api.requests.deletion = mockDeleteTailRequest(env, legacyEnv);
501
- api.ws = new MockWebSocket(websocketURL);
502
- mockWebSockets.push(api.ws);
503
-
504
- return api;
611
+ const websocketURL = "ws://localhost:1234";
612
+ const api: MockAPI = {
613
+ requests: {
614
+ deletion: { count: 0 },
615
+ creation: { count: 0 },
616
+ },
617
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
618
+ ws: null!, // will be set in the `beforeEach()` below.
619
+
620
+ /**
621
+ * Parse the next message received by the mock websocket as JSON
622
+ * @returns JSON.parse of the next message received by the websocket
623
+ */
624
+ async nextMessageJson() {
625
+ const message = await api.ws.nextMessage;
626
+ return JSON.parse(message as string);
627
+ },
628
+ };
629
+ api.requests.creation = mockCreateTailRequest(websocketURL, env, legacyEnv);
630
+ api.requests.deletion = mockDeleteTailRequest(env, legacyEnv);
631
+ api.ws = new MockWebSocket(websocketURL);
632
+ mockWebSockets.push(api.ws);
633
+
634
+ return api;
505
635
  }
506
636
 
507
637
  /**
@@ -511,16 +641,20 @@ function mockWebsocketAPIs(env?: string, legacyEnv = false): MockAPI {
511
641
  * @param opts Any specific parts of the message to use instead of defaults
512
642
  * @returns a `TailEventMessage` that wrangler can process and display
513
643
  */
514
- function generateMockEventMessage(
515
- opts?: Partial<TailEventMessage>
516
- ): TailEventMessage {
517
- return {
518
- outcome: opts?.outcome || "ok",
519
- exceptions: opts?.exceptions || [],
520
- logs: opts?.logs || [],
521
- eventTimestamp: opts?.eventTimestamp || mockEventTimestamp,
522
- event: opts?.event || generateMockRequestEvent(),
523
- };
644
+ function generateMockEventMessage({
645
+ outcome = "ok",
646
+ exceptions = [],
647
+ logs = [],
648
+ eventTimestamp = mockEventTimestamp,
649
+ event = generateMockRequestEvent(),
650
+ }: Partial<TailEventMessage>): TailEventMessage {
651
+ return {
652
+ outcome,
653
+ exceptions,
654
+ logs,
655
+ eventTimestamp,
656
+ event,
657
+ };
524
658
  }
525
659
 
526
660
  /**
@@ -531,34 +665,34 @@ function generateMockEventMessage(
531
665
  * @returns a `RequestEvent` that can be used within an `EventMessage`
532
666
  */
533
667
  function generateMockRequestEvent(
534
- opts?: Partial<RequestEvent["request"]>
668
+ opts?: Partial<RequestEvent["request"]>
535
669
  ): RequestEvent {
536
- return {
537
- request: Object.assign(
538
- new Request(opts?.url || "https://example.org/", {
539
- method: opts?.method || "GET",
540
- headers:
541
- opts?.headers || new Headers({ "X-EXAMPLE-HEADER": "some_value" }),
542
- }),
543
- {
544
- cf: opts?.cf || {
545
- tlsCipher: "AEAD-ENCRYPT-O-MATIC-SHA",
546
- tlsVersion: "TLSv2.0",
547
- asn: 42069,
548
- colo: "ATL",
549
- httpProtocol: "HTTP/4",
550
- asOrganization: "Cloudflare",
551
- },
552
- }
553
- ),
554
- };
670
+ return {
671
+ request: Object.assign(
672
+ new Request(opts?.url || "https://example.org/", {
673
+ method: opts?.method || "GET",
674
+ headers:
675
+ opts?.headers || new Headers({ "X-EXAMPLE-HEADER": "some_value" }),
676
+ }),
677
+ {
678
+ cf: opts?.cf || {
679
+ tlsCipher: "AEAD-ENCRYPT-O-MATIC-SHA",
680
+ tlsVersion: "TLSv2.0",
681
+ asn: 42069,
682
+ colo: "ATL",
683
+ httpProtocol: "HTTP/4",
684
+ asOrganization: "Cloudflare",
685
+ },
686
+ }
687
+ ),
688
+ };
555
689
  }
556
690
 
557
691
  function generateMockScheduledEvent(
558
- opts?: Partial<ScheduledEvent>
692
+ opts?: Partial<ScheduledEvent>
559
693
  ): ScheduledEvent {
560
- return {
561
- cron: opts?.cron || "* * * * *",
562
- scheduledTime: opts?.scheduledTime || mockEventTimestamp,
563
- };
694
+ return {
695
+ cron: opts?.cron || "* * * * *",
696
+ scheduledTime: opts?.scheduledTime || mockEventTimestamp,
697
+ };
564
698
  }