wrangler 0.0.0-e7a0cd5b → 0.0.0-e7cf0caa

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 (237) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +126 -74
  4. package/package.json +27 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +567 -86
  9. package/src/__tests__/d1/d1.test.ts +82 -0
  10. package/src/__tests__/d1/execute.test.ts +66 -0
  11. package/src/__tests__/d1/migrate.test.ts +157 -0
  12. package/src/__tests__/d1/splitter.test.ts +255 -0
  13. package/src/__tests__/delete.test.ts +91 -49
  14. package/src/__tests__/deployments.test.ts +330 -56
  15. package/src/__tests__/dev.test.tsx +198 -90
  16. package/src/__tests__/generate.test.ts +12 -10
  17. package/src/__tests__/guess-worker-format.test.ts +35 -0
  18. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  19. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  20. package/src/__tests__/helpers/mock-console.ts +6 -0
  21. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  22. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  23. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  24. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  25. package/src/__tests__/helpers/mock-kv.ts +29 -16
  26. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  27. package/src/__tests__/helpers/mock-process.ts +8 -13
  28. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  29. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  30. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  31. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  32. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  33. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  34. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  35. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  36. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  37. package/src/__tests__/helpers/msw/index.ts +32 -1
  38. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  39. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  40. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  41. package/src/__tests__/index.test.ts +90 -72
  42. package/src/__tests__/init.test.ts +927 -631
  43. package/src/__tests__/jest.setup.ts +19 -42
  44. package/src/__tests__/kv.test.ts +355 -231
  45. package/src/__tests__/logger.test.ts +68 -2
  46. package/src/__tests__/logout.test.ts +47 -0
  47. package/src/__tests__/metrics.test.ts +94 -51
  48. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  49. package/src/__tests__/middleware.test.ts +212 -122
  50. package/src/__tests__/mtls-certificates.test.ts +588 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +452 -0
  53. package/src/__tests__/pages/pages.test.ts +81 -0
  54. package/src/__tests__/pages/project-create.test.ts +63 -0
  55. package/src/__tests__/pages/project-list.test.ts +110 -0
  56. package/src/__tests__/pages/project-upload.test.ts +500 -0
  57. package/src/__tests__/pages/publish.test.ts +2864 -0
  58. package/src/__tests__/pages-deployment-tail.test.ts +955 -0
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +1615 -852
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +238 -77
  63. package/src/__tests__/r2.test.ts +55 -57
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +267 -109
  66. package/src/__tests__/test-old-node-version.js +3 -3
  67. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  68. package/src/__tests__/tsconfig-sanity.ts +12 -0
  69. package/src/__tests__/tsconfig.json +8 -0
  70. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  71. package/src/__tests__/type-generation.test.ts +43 -26
  72. package/src/__tests__/user.test.ts +35 -72
  73. package/src/__tests__/whoami.test.tsx +8 -114
  74. package/src/__tests__/worker-namespace.test.ts +83 -69
  75. package/src/api/dev.ts +168 -60
  76. package/src/api/index.ts +10 -1
  77. package/src/api/mtls-certificate.ts +148 -0
  78. package/src/api/pages/create-worker-bundle-contents.ts +76 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +355 -0
  81. package/src/bundle.ts +263 -140
  82. package/src/cfetch/index.ts +0 -2
  83. package/src/cfetch/internal.ts +16 -21
  84. package/src/cli.ts +4 -4
  85. package/src/config/config.ts +14 -7
  86. package/src/config/environment.ts +79 -24
  87. package/src/config/index.ts +99 -38
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +248 -19
  90. package/src/create-worker-preview.ts +19 -8
  91. package/src/create-worker-upload-form.ts +60 -22
  92. package/src/d1/backups.tsx +43 -42
  93. package/src/d1/constants.ts +2 -0
  94. package/src/d1/create.tsx +44 -30
  95. package/src/d1/{delete.tsx → delete.ts} +11 -14
  96. package/src/d1/execute.tsx +209 -151
  97. package/src/d1/index.ts +31 -7
  98. package/src/d1/list.tsx +22 -10
  99. package/src/d1/migrations/apply.tsx +212 -0
  100. package/src/d1/migrations/create.tsx +79 -0
  101. package/src/d1/migrations/helpers.ts +172 -0
  102. package/src/d1/migrations/index.ts +3 -0
  103. package/src/d1/migrations/list.tsx +95 -0
  104. package/src/d1/migrations/options.ts +23 -0
  105. package/src/d1/options.ts +12 -2
  106. package/src/d1/splitter.ts +161 -0
  107. package/src/d1/{types.tsx → types.ts} +11 -0
  108. package/src/d1/utils.ts +12 -2
  109. package/src/delete.ts +8 -16
  110. package/src/deployments.ts +340 -46
  111. package/src/deprecated/index.ts +8 -302
  112. package/src/dev/dev.tsx +57 -44
  113. package/src/dev/local.tsx +294 -91
  114. package/src/dev/remote.tsx +32 -3
  115. package/src/dev/start-server.ts +89 -68
  116. package/src/dev/use-esbuild.ts +17 -18
  117. package/src/dev/validate-dev-props.ts +9 -0
  118. package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
  119. package/src/dev.tsx +178 -118
  120. package/src/dialogs.ts +136 -0
  121. package/src/dispatch-namespace.ts +21 -17
  122. package/src/docs/index.ts +97 -0
  123. package/src/entry.ts +19 -11
  124. package/src/environment-variables/factory.ts +88 -0
  125. package/src/environment-variables/misc-variables.ts +30 -0
  126. package/src/generate/index.ts +298 -0
  127. package/src/git-client.ts +15 -4
  128. package/src/{index.tsx → index.ts} +137 -63
  129. package/src/init.ts +249 -187
  130. package/src/inspect.ts +16 -1
  131. package/src/jest.d.ts +4 -0
  132. package/src/kv/index.ts +15 -17
  133. package/src/logger.ts +32 -5
  134. package/src/metrics/metrics-config.ts +3 -3
  135. package/src/metrics/send-event.ts +6 -1
  136. package/src/miniflare-cli/assets.ts +64 -28
  137. package/src/miniflare-cli/index.ts +4 -7
  138. package/src/miniflare-cli/tsconfig.json +9 -0
  139. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  140. package/src/miniflare-cli/types.ts +11 -0
  141. package/src/module-collection.ts +91 -25
  142. package/src/mtls-certificate/cli.ts +155 -0
  143. package/src/pages/build.ts +410 -0
  144. package/src/pages/buildFunctions.ts +140 -0
  145. package/src/pages/deployment-tails.ts +281 -0
  146. package/src/pages/deployments.tsx +11 -33
  147. package/src/pages/{dev.tsx → dev.ts} +147 -124
  148. package/src/pages/errors.ts +1 -0
  149. package/src/pages/functions/buildPlugin.ts +72 -69
  150. package/src/pages/functions/buildWorker.ts +249 -114
  151. package/src/pages/functions/tsconfig.json +8 -0
  152. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  153. package/src/pages/{functions.tsx → functions.ts} +8 -4
  154. package/src/pages/{index.tsx → index.ts} +11 -3
  155. package/src/pages/projects.tsx +12 -22
  156. package/src/pages/prompt-select-project.tsx +31 -0
  157. package/src/pages/publish.tsx +45 -214
  158. package/src/pages/types.ts +6 -9
  159. package/src/pages/upload.tsx +58 -14
  160. package/src/pages/utils.ts +14 -3
  161. package/src/parse.ts +23 -1
  162. package/src/paths.ts +1 -1
  163. package/src/proxy.ts +5 -0
  164. package/src/publish/index.ts +20 -16
  165. package/src/publish/publish.ts +72 -47
  166. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  167. package/src/queues/cli/commands/consumer/add.ts +24 -24
  168. package/src/queues/cli/commands/consumer/index.ts +3 -6
  169. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  170. package/src/queues/cli/commands/create.ts +8 -8
  171. package/src/queues/cli/commands/delete.ts +8 -8
  172. package/src/queues/cli/commands/index.ts +6 -4
  173. package/src/queues/cli/commands/list.ts +8 -8
  174. package/src/queues/client.ts +1 -0
  175. package/src/queues/utils.ts +18 -0
  176. package/src/r2/constants.ts +4 -0
  177. package/src/r2/helpers.ts +1 -0
  178. package/src/r2/index.ts +40 -28
  179. package/src/secret/index.ts +14 -17
  180. package/src/{sites.tsx → sites.ts} +1 -1
  181. package/src/tail/createTail.ts +94 -3
  182. package/src/tail/filters.ts +1 -1
  183. package/src/tail/index.ts +8 -11
  184. package/src/tail/printing.ts +15 -0
  185. package/src/traverse-module-graph.ts +53 -0
  186. package/src/tsconfig-sanity.ts +16 -0
  187. package/src/type-generation.ts +79 -57
  188. package/src/user/access.ts +0 -1
  189. package/src/user/auth-variables.ts +113 -0
  190. package/src/user/choose-account.tsx +1 -31
  191. package/src/user/index.ts +0 -1
  192. package/src/user/{user.tsx → user.ts} +123 -82
  193. package/src/utils/render.ts +93 -0
  194. package/src/{whoami.tsx → whoami.ts} +37 -71
  195. package/src/worker.ts +35 -3
  196. package/src/yargs-types.ts +22 -5
  197. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  198. package/templates/__tests__/tsconfig.json +8 -0
  199. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  200. package/templates/checked-fetch.js +9 -3
  201. package/templates/d1-beta-facade.js +95 -25
  202. package/templates/facade.d.ts +14 -0
  203. package/templates/first-party-worker-module-facade.ts +4 -3
  204. package/templates/format-dev-errors.ts +8 -6
  205. package/templates/gitignore +1 -0
  206. package/templates/init-tests/test-jest-new-worker.js +3 -5
  207. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  208. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  209. package/templates/middleware/loader-modules.ts +2 -2
  210. package/templates/middleware/loader-sw.ts +51 -31
  211. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  212. package/templates/new-worker.ts +3 -0
  213. package/templates/pages-dev-pipeline.ts +4 -1
  214. package/templates/pages-shim.ts +4 -1
  215. package/templates/pages-template-plugin.ts +19 -10
  216. package/templates/serve-static-assets.ts +17 -14
  217. package/templates/service-bindings-module-facade.js +1 -0
  218. package/templates/tsconfig-sanity.ts +11 -0
  219. package/templates/tsconfig.init.json +105 -0
  220. package/templates/tsconfig.json +5 -103
  221. package/templates/tsconfig.tsbuildinfo +1 -0
  222. package/wrangler-dist/cli.d.ts +826 -77
  223. package/wrangler-dist/cli.js +130734 -140838
  224. package/wrangler-dist/wasm-sync.wasm +0 -0
  225. package/src/__tests__/api-devregistry.test.js +0 -57
  226. package/src/__tests__/d1.test.ts +0 -72
  227. package/src/__tests__/dialogs.test.tsx +0 -40
  228. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  229. package/src/__tests__/pages.test.ts +0 -2223
  230. package/src/dialogs.tsx +0 -163
  231. package/src/environment-variables.ts +0 -50
  232. package/src/pages/build.tsx +0 -238
  233. package/src/user/env-vars.ts +0 -46
  234. package/templates/experimental-local-cache-stubs.js +0 -27
  235. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  236. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  237. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,12 +1,11 @@
1
1
  import MockWebSocket from "jest-websocket-mock";
2
+ import { rest } from "msw";
2
3
  import { Headers, Request } from "undici";
3
4
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
4
- import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
5
5
  import { mockConsoleMethods } from "./helpers/mock-console";
6
- import { mockGetZoneFromHostRequest } from "./helpers/mock-get-zone-from-host";
6
+ import { mockConfirm, clearDialogs } from "./helpers/mock-dialogs";
7
7
  import { useMockIsTTY } from "./helpers/mock-istty";
8
- import { mockCollectKnownRoutesRequest } from "./helpers/mock-known-routes";
9
- import { msw, mswSucessScriptHandlers } from "./helpers/msw";
8
+ import { createFetchResult, msw, mswSucessScriptHandlers } from "./helpers/msw";
10
9
  import { runInTempDir } from "./helpers/run-in-tmp";
11
10
  import { runWrangler } from "./helpers/run-wrangler";
12
11
  import type {
@@ -14,9 +13,11 @@ import type {
14
13
  RequestEvent,
15
14
  ScheduledEvent,
16
15
  AlarmEvent,
16
+ EmailEvent,
17
17
  } from "../tail/createTail";
18
18
  import type { RequestInit } from "undici";
19
19
  import type WebSocket from "ws";
20
+
20
21
  describe("tail", () => {
21
22
  beforeEach(() => msw.use(...mswSucessScriptHandlers));
22
23
  runInTempDir();
@@ -28,7 +29,7 @@ describe("tail", () => {
28
29
  afterEach(() => {
29
30
  mockWebSockets.forEach((ws) => ws.close());
30
31
  mockWebSockets.splice(0);
31
- unsetAllMocks();
32
+ clearDialogs();
32
33
  });
33
34
 
34
35
  /**
@@ -46,6 +47,10 @@ describe("tail", () => {
46
47
  });
47
48
  it("warns about durable object restarts for tty", async () => {
48
49
  setIsTTY(true);
50
+ mockConfirm({
51
+ text: "Would you like to continue?",
52
+ result: false,
53
+ });
49
54
  const api = mockWebsocketAPIs();
50
55
  expect(api.requests.creation.length).toStrictEqual(0);
51
56
  await runWrangler("tail durable-object--websocket--response");
@@ -67,38 +72,101 @@ describe("tail", () => {
67
72
  expect(api.requests.creation.length).toStrictEqual(1);
68
73
  expect(api.requests.deletion.count).toStrictEqual(0);
69
74
 
70
- api.ws.close();
75
+ await api.closeHelper();
71
76
  expect(api.requests.deletion.count).toStrictEqual(1);
72
77
  });
73
78
  it("should connect to the worker assigned to a given route", async () => {
74
79
  const api = mockWebsocketAPIs();
75
80
  expect(api.requests.creation.length).toStrictEqual(0);
76
81
 
77
- mockGetZoneFromHostRequest("example.com", "test-zone");
78
- mockCollectKnownRoutesRequest([
79
- {
80
- pattern: "example.com/*",
81
- script: "test-worker",
82
- },
83
- ]);
82
+ msw.use(
83
+ rest.get(`*/zones`, (req, res, ctx) => {
84
+ expect(req.url.searchParams.get("name")).toBe("example.com");
85
+ return res.once(
86
+ ctx.status(200),
87
+ ctx.json({
88
+ success: true,
89
+ errors: [],
90
+ messages: [],
91
+ result: [{ id: "test-zone" }],
92
+ })
93
+ );
94
+ })
95
+ );
96
+ msw.use(
97
+ rest.get(`*/zones/:zoneId/workers/routes`, (req, res, ctx) => {
98
+ return res.once(
99
+ ctx.status(200),
100
+ ctx.json({
101
+ success: true,
102
+ errors: [],
103
+ messages: [],
104
+ result: [
105
+ {
106
+ pattern: "example.com/*",
107
+ script: "test-worker",
108
+ },
109
+ ],
110
+ })
111
+ );
112
+ })
113
+ );
84
114
  await runWrangler("tail example.com/*");
85
115
 
86
116
  await expect(api.ws.connected).resolves.toBeTruthy();
87
117
  expect(api.requests.creation.length).toStrictEqual(1);
88
118
  expect(api.requests.deletion.count).toStrictEqual(0);
89
119
 
90
- api.ws.close();
120
+ await api.closeHelper();
91
121
  expect(api.requests.deletion.count).toStrictEqual(1);
92
122
  });
93
123
 
94
124
  it("should error if a given route is not assigned to the user's zone", async () => {
95
- mockGetZoneFromHostRequest("example.com", "test-zone");
96
- mockCollectKnownRoutesRequest([]);
125
+ msw.use(
126
+ rest.get(`*/zones`, (req, res, ctx) => {
127
+ expect(req.url.searchParams.get("name")).toBe("example.com");
128
+ return res.once(
129
+ ctx.status(200),
130
+ ctx.json({
131
+ success: true,
132
+ errors: [],
133
+ messages: [],
134
+ result: [{ id: "test-zone" }],
135
+ })
136
+ );
137
+ })
138
+ );
139
+ msw.use(
140
+ rest.get(`*/zones/:zoneId/workers/routes`, (req, res, ctx) => {
141
+ return res.once(
142
+ ctx.status(200),
143
+ ctx.json({
144
+ success: true,
145
+ errors: [],
146
+ messages: [],
147
+ result: [],
148
+ })
149
+ );
150
+ })
151
+ );
97
152
 
98
153
  await expect(runWrangler("tail example.com/*")).rejects.toThrow();
99
154
  });
100
155
  it("should error if a given route is not within the user's zone", async () => {
101
- mockGetZoneFromHostRequest("example.com");
156
+ msw.use(
157
+ rest.get(`*/zones`, (req, res, ctx) => {
158
+ expect(req.url.searchParams.get("name")).toBe("example.com");
159
+ return res.once(
160
+ ctx.status(200),
161
+ ctx.json({
162
+ success: true,
163
+ errors: [],
164
+ messages: [],
165
+ result: [],
166
+ })
167
+ );
168
+ })
169
+ );
102
170
 
103
171
  await expect(runWrangler("tail example.com/*")).rejects.toThrow();
104
172
  });
@@ -113,7 +181,7 @@ describe("tail", () => {
113
181
  expect(api.requests.creation.length).toStrictEqual(1);
114
182
  expect(api.requests.deletion.count).toStrictEqual(0);
115
183
 
116
- api.ws.close();
184
+ await api.closeHelper();
117
185
  expect(api.requests.deletion.count).toStrictEqual(1);
118
186
  });
119
187
 
@@ -127,13 +195,13 @@ describe("tail", () => {
127
195
  expect(api.requests.creation.length).toStrictEqual(1);
128
196
  expect(api.requests.deletion.count).toStrictEqual(0);
129
197
 
130
- api.ws.close();
198
+ await api.closeHelper();
131
199
  expect(api.requests.deletion.count).toStrictEqual(1);
132
200
  });
133
201
 
134
202
  it("errors when the websocket closes unexpectedly", async () => {
135
203
  const api = mockWebsocketAPIs();
136
- api.ws.close();
204
+ await api.closeHelper();
137
205
 
138
206
  await expect(runWrangler("tail test-worker")).rejects.toThrow();
139
207
  });
@@ -158,57 +226,72 @@ describe("tail", () => {
158
226
  await expect(tooLow).rejects.toThrow();
159
227
 
160
228
  await runWrangler("tail test-worker --sampling-rate 0.25");
161
- expect(api.requests.creation[0].body).toEqual(
162
- `{"filters":[{"sampling_rate":0.25}]}`
163
- );
229
+
230
+ expect(api.requests.creation[0]).toEqual({
231
+ filters: [{ sampling_rate: 0.25 }],
232
+ });
164
233
  });
165
234
 
166
235
  it("sends single status filters", async () => {
167
236
  const api = mockWebsocketAPIs();
168
237
  await runWrangler("tail test-worker --status error");
169
- expect(api.requests.creation[0].body).toEqual(
170
- `{"filters":[{"outcome":["exception","exceededCpu","exceededMemory","unknown"]}]}`
171
- );
238
+ expect(api.requests.creation[0]).toEqual({
239
+ filters: [
240
+ {
241
+ outcome: ["exception", "exceededCpu", "exceededMemory", "unknown"],
242
+ },
243
+ ],
244
+ });
172
245
  });
173
246
 
174
247
  it("sends multiple status filters", async () => {
175
248
  const api = mockWebsocketAPIs();
176
249
  await runWrangler("tail test-worker --status error --status canceled");
177
- expect(api.requests.creation[0].body).toEqual(
178
- `{"filters":[{"outcome":["exception","exceededCpu","exceededMemory","unknown","canceled"]}]}`
179
- );
250
+ expect(api.requests.creation[0]).toEqual({
251
+ filters: [
252
+ {
253
+ outcome: [
254
+ "exception",
255
+ "exceededCpu",
256
+ "exceededMemory",
257
+ "unknown",
258
+ "canceled",
259
+ ],
260
+ },
261
+ ],
262
+ });
180
263
  });
181
264
 
182
265
  it("sends single HTTP method filters", async () => {
183
266
  const api = mockWebsocketAPIs();
184
267
  await runWrangler("tail test-worker --method POST");
185
- expect(api.requests.creation[0].body).toEqual(
186
- `{"filters":[{"method":["POST"]}]}`
187
- );
268
+ expect(api.requests.creation[0]).toEqual({
269
+ filters: [{ method: ["POST"] }],
270
+ });
188
271
  });
189
272
 
190
273
  it("sends multiple HTTP method filters", async () => {
191
274
  const api = mockWebsocketAPIs();
192
275
  await runWrangler("tail test-worker --method POST --method GET");
193
- expect(api.requests.creation[0].body).toEqual(
194
- `{"filters":[{"method":["POST","GET"]}]}`
195
- );
276
+ expect(api.requests.creation[0]).toEqual({
277
+ filters: [{ method: ["POST", "GET"] }],
278
+ });
196
279
  });
197
280
 
198
281
  it("sends header filters without a query", async () => {
199
282
  const api = mockWebsocketAPIs();
200
283
  await runWrangler("tail test-worker --header X-CUSTOM-HEADER");
201
- expect(api.requests.creation[0].body).toEqual(
202
- `{"filters":[{"header":{"key":"X-CUSTOM-HEADER"}}]}`
203
- );
284
+ expect(api.requests.creation[0]).toEqual({
285
+ filters: [{ header: { key: "X-CUSTOM-HEADER" } }],
286
+ });
204
287
  });
205
288
 
206
289
  it("sends header filters with a query", async () => {
207
290
  const api = mockWebsocketAPIs();
208
291
  await runWrangler("tail test-worker --header X-CUSTOM-HEADER:some-value");
209
- expect(api.requests.creation[0].body).toEqual(
210
- `{"filters":[{"header":{"key":"X-CUSTOM-HEADER","query":"some-value"}}]}`
211
- );
292
+ expect(api.requests.creation[0]).toEqual({
293
+ filters: [{ header: { key: "X-CUSTOM-HEADER", query: "some-value" } }],
294
+ });
212
295
  });
213
296
 
214
297
  it("sends single IP filters", async () => {
@@ -216,9 +299,9 @@ describe("tail", () => {
216
299
  const fakeIp = "192.0.2.1";
217
300
 
218
301
  await runWrangler(`tail test-worker --ip ${fakeIp}`);
219
- expect(api.requests.creation[0].body).toEqual(
220
- `{"filters":[{"client_ip":["${fakeIp}"]}]}`
221
- );
302
+ expect(api.requests.creation[0]).toEqual({
303
+ filters: [{ client_ip: [fakeIp] }],
304
+ });
222
305
  });
223
306
 
224
307
  it("sends multiple IP filters", async () => {
@@ -226,9 +309,9 @@ describe("tail", () => {
226
309
  const fakeIp = "192.0.2.1";
227
310
 
228
311
  await runWrangler(`tail test-worker --ip ${fakeIp} --ip self`);
229
- expect(api.requests.creation[0].body).toEqual(
230
- `{"filters":[{"client_ip":["${fakeIp}","self"]}]}`
231
- );
312
+ expect(api.requests.creation[0]).toEqual({
313
+ filters: [{ client_ip: [fakeIp, "self"] }],
314
+ });
232
315
  });
233
316
 
234
317
  it("sends search filters", async () => {
@@ -236,9 +319,9 @@ describe("tail", () => {
236
319
  const search = "filterMe";
237
320
 
238
321
  await runWrangler(`tail test-worker --search ${search}`);
239
- expect(api.requests.creation[0].body).toEqual(
240
- `{"filters":[{"query":"${search}"}]}`
241
- );
322
+ expect(api.requests.creation[0]).toEqual({
323
+ filters: [{ query: search }],
324
+ });
242
325
  });
243
326
 
244
327
  it("sends everything but the kitchen sink", async () => {
@@ -259,10 +342,27 @@ describe("tail", () => {
259
342
  `--search ${query} ` +
260
343
  `--debug`;
261
344
 
262
- const expectedWebsocketMessage = `{"filters":[{"sampling_rate":0.69},{"outcome":["ok","exception","exceededCpu","exceededMemory","unknown"]},{"method":["GET","POST","PUT"]},{"header":{"key":"X-HELLO","query":"world"}},{"client_ip":["192.0.2.1","self"]},{"query":"onlyTheseMessagesPlease"}]}`;
345
+ const expectedWebsocketMessage = {
346
+ filters: [
347
+ { sampling_rate: 0.69 },
348
+ {
349
+ outcome: [
350
+ "ok",
351
+ "exception",
352
+ "exceededCpu",
353
+ "exceededMemory",
354
+ "unknown",
355
+ ],
356
+ },
357
+ { method: ["GET", "POST", "PUT"] },
358
+ { header: { key: "X-HELLO", query: "world" } },
359
+ { client_ip: ["192.0.2.1", "self"] },
360
+ { query: "onlyTheseMessagesPlease" },
361
+ ],
362
+ };
263
363
 
264
364
  await runWrangler(`tail test-worker ${cliFilters}`);
265
- expect(api.requests.creation[0].body).toEqual(expectedWebsocketMessage);
365
+ expect(api.requests.creation[0]).toEqual(expectedWebsocketMessage);
266
366
  });
267
367
  });
268
368
 
@@ -305,6 +405,18 @@ describe("tail", () => {
305
405
  expect(std.out).toMatch(deserializeToJson(serializedMessage));
306
406
  });
307
407
 
408
+ it("logs email messages in json format", async () => {
409
+ const api = mockWebsocketAPIs();
410
+ await runWrangler("tail test-worker --format json");
411
+
412
+ const event = generateMockEmailEvent();
413
+ const message = generateMockEventMessage({ event });
414
+ const serializedMessage = serialize(message);
415
+
416
+ api.ws.send(serializedMessage);
417
+ expect(std.out).toMatch(deserializeToJson(serializedMessage));
418
+ });
419
+
308
420
  it("logs request messages in pretty format", async () => {
309
421
  const api = mockWebsocketAPIs();
310
422
  await runWrangler("tail test-worker --format pretty");
@@ -320,10 +432,7 @@ describe("tail", () => {
320
432
  new Date(mockEventTimestamp).toLocaleString(),
321
433
  "[mock event timestamp]"
322
434
  )
323
- .replace(
324
- mockTailExpiration.toLocaleString(),
325
- "[mock expiration date]"
326
- )
435
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
327
436
  ).toMatchInlineSnapshot(`
328
437
  "Successfully created tail, expires at [mock expiration date]
329
438
  Connected to test-worker, waiting for logs...
@@ -346,10 +455,7 @@ describe("tail", () => {
346
455
  new Date(mockEventTimestamp).toLocaleString(),
347
456
  "[mock timestamp string]"
348
457
  )
349
- .replace(
350
- mockTailExpiration.toLocaleString(),
351
- "[mock expiration date]"
352
- )
458
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
353
459
  ).toMatchInlineSnapshot(`
354
460
  "Successfully created tail, expires at [mock expiration date]
355
461
  Connected to test-worker, waiting for logs...
@@ -372,14 +478,34 @@ describe("tail", () => {
372
478
  new Date(mockEventScheduledTime).toLocaleString(),
373
479
  "[mock scheduled time]"
374
480
  )
481
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
482
+ ).toMatchInlineSnapshot(`
483
+ "Successfully created tail, expires at [mock expiration date]
484
+ Connected to test-worker, waiting for logs...
485
+ Alarm @ [mock scheduled time] - Ok"
486
+ `);
487
+ });
488
+
489
+ it("logs email messages in pretty format", async () => {
490
+ const api = mockWebsocketAPIs();
491
+ await runWrangler("tail test-worker --format pretty");
492
+
493
+ const event = generateMockEmailEvent();
494
+ const message = generateMockEventMessage({ event });
495
+ const serializedMessage = serialize(message);
496
+
497
+ api.ws.send(serializedMessage);
498
+ expect(
499
+ std.out
375
500
  .replace(
376
- mockTailExpiration.toLocaleString(),
377
- "[mock expiration date]"
501
+ new Date(mockEventTimestamp).toLocaleString(),
502
+ "[mock event timestamp]"
378
503
  )
504
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
379
505
  ).toMatchInlineSnapshot(`
380
506
  "Successfully created tail, expires at [mock expiration date]
381
507
  Connected to test-worker, waiting for logs...
382
- Alarm @ [mock scheduled time] - Ok"
508
+ Email from:${mockEmailEventFrom} to:${mockEmailEventTo} size:${mockEmailEventSize} @ [mock event timestamp] - Ok"
383
509
  `);
384
510
  });
385
511
 
@@ -393,14 +519,11 @@ describe("tail", () => {
393
519
  api.ws.send(serializedMessage);
394
520
  expect(
395
521
  std.out
396
- .replace(
397
- mockTailExpiration.toLocaleString(),
398
- "[mock expiration date]"
399
- )
400
522
  .replace(
401
523
  new Date(mockEventTimestamp).toLocaleString(),
402
524
  "[mock timestamp string]"
403
525
  )
526
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
404
527
  ).toMatchInlineSnapshot(`
405
528
  "Successfully created tail, expires at [mock expiration date]
406
529
  Connected to test-worker, waiting for logs...
@@ -424,10 +547,7 @@ describe("tail", () => {
424
547
  new Date(mockEventTimestamp).toLocaleString(),
425
548
  "[mock event timestamp]"
426
549
  )
427
- .replace(
428
- mockTailExpiration.toLocaleString(),
429
- "[mock expiration date]"
430
- )
550
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
431
551
  ).toMatchInlineSnapshot(`
432
552
  "Successfully created tail, expires at [mock expiration date]
433
553
  Connected to test-worker, waiting for logs...
@@ -480,10 +600,7 @@ describe("tail", () => {
480
600
  new Date(mockEventTimestamp).toLocaleString(),
481
601
  "[mock event timestamp]"
482
602
  )
483
- .replace(
484
- mockTailExpiration.toLocaleString(),
485
- "[mock expiration date]"
486
- )
603
+ .replace(mockTailExpiration.toISOString(), "[mock expiration date]")
487
604
  ).toMatchInlineSnapshot(`
488
605
  "Successfully created tail, expires at [mock expiration date]
489
606
  Connected to test-worker, waiting for logs...
@@ -553,7 +670,13 @@ function serialize(message: TailEventMessage): WebSocket.RawData {
553
670
  * @returns true if `event` is a RequestEvent
554
671
  */
555
672
  function isRequest(
556
- event: ScheduledEvent | RequestEvent | AlarmEvent | undefined | null
673
+ event:
674
+ | ScheduledEvent
675
+ | RequestEvent
676
+ | AlarmEvent
677
+ | EmailEvent
678
+ | undefined
679
+ | null
557
680
  ): event is RequestEvent {
558
681
  return Boolean(event && "request" in event);
559
682
  }
@@ -581,6 +704,7 @@ type MockAPI = {
581
704
  };
582
705
  ws: MockWebSocket;
583
706
  nextMessageJson(): Promise<unknown>;
707
+ closeHelper: () => Promise<void>;
584
708
  };
585
709
 
586
710
  /**
@@ -607,22 +731,28 @@ function mockCreateTailRequest(
607
731
  const requests: RequestInit[] = [];
608
732
  const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
609
733
  const environment = env && !legacyEnv ? "/environments/:envName" : "";
610
- setMockResponse(
611
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails`,
612
- "POST",
613
- ([_url, accountId, scriptName, envName], req) => {
614
- requests.push(req);
615
- expect(accountId).toEqual("some-account-id");
616
- expect(scriptName).toEqual(expectedScriptName);
617
- if (!legacyEnv) {
618
- expect(envName).toEqual(env);
734
+ msw.use(
735
+ rest.post(
736
+ `*/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails`,
737
+ async (req, res, ctx) => {
738
+ const request = await req.json();
739
+ requests.push(request);
740
+ expect(req.params.accountId).toEqual("some-account-id");
741
+ expect(req.params.scriptName).toEqual(expectedScriptName);
742
+ if (!legacyEnv) {
743
+ expect(req.params.envName).toEqual(env);
744
+ }
745
+ return res.once(
746
+ ctx.json(
747
+ createFetchResult({
748
+ url: websocketURL,
749
+ id: "tail-id",
750
+ expires_at: mockTailExpiration,
751
+ })
752
+ )
753
+ );
619
754
  }
620
- return {
621
- id: "tail-id",
622
- url: websocketURL,
623
- expires_at: mockTailExpiration,
624
- };
625
- }
755
+ )
626
756
  );
627
757
 
628
758
  return requests;
@@ -643,6 +773,21 @@ const mockEventTimestamp = 1645454470467;
643
773
  */
644
774
  const mockEventScheduledTime = new Date(mockEventTimestamp).toISOString();
645
775
 
776
+ /**
777
+ * Default value for email event from
778
+ */
779
+ const mockEmailEventFrom = "from@example.com";
780
+
781
+ /**
782
+ * Default value for email event to
783
+ */
784
+ const mockEmailEventTo = "to@example.com";
785
+
786
+ /**
787
+ * Default value for email event mail size
788
+ */
789
+ const mockEmailEventSize = 45416;
790
+
646
791
  /**
647
792
  * Mock out the API hit during Tail deletion
648
793
  *
@@ -656,26 +801,22 @@ function mockDeleteTailRequest(
656
801
  const requests = { count: 0 };
657
802
  const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
658
803
  const environment = env && !legacyEnv ? "/environments/:envName" : "";
659
- setMockResponse(
660
- // "/accounts/:accountId/workers/scripts/:worker/tails",
661
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails/:tailId`,
662
- "DELETE",
663
- ([_url, accountId, scriptName, envNameOrTailId, tailId]) => {
664
- requests.count++;
665
- expect(accountId).toEqual("some-account-id");
666
- expect(scriptName).toEqual(expectedScriptName);
667
- if (!legacyEnv) {
668
- if (env) {
669
- expect(envNameOrTailId).toEqual(env);
670
- expect(tailId).toEqual("tail-id");
671
- } else {
672
- expect(envNameOrTailId).toEqual("tail-id");
804
+ msw.use(
805
+ rest.delete(
806
+ `*/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails/:tailId`,
807
+ async (req, res, ctx) => {
808
+ requests.count++;
809
+ expect(req.params.accountId).toEqual("some-account-id");
810
+ expect(req.params.scriptName).toEqual(expectedScriptName);
811
+ if (!legacyEnv) {
812
+ if (env) {
813
+ expect(req.params.tailId).toEqual("tail-id");
814
+ }
673
815
  }
674
- } else {
675
- expect(envNameOrTailId).toEqual("tail-id");
816
+ expect(req.params.tailId).toEqual("tail-id");
817
+ return res(ctx.json(createFetchResult(null)));
676
818
  }
677
- return null;
678
- }
819
+ )
679
820
  );
680
821
 
681
822
  return requests;
@@ -712,6 +853,15 @@ function mockWebsocketAPIs(
712
853
  const message = await api.ws.nextMessage;
713
854
  return JSON.parse(message as string);
714
855
  },
856
+ /**
857
+ * Close the mock websocket and clean up the API.
858
+ * The setTimeout forces a cycle to allow for closing and cleanup
859
+ * @returns a Promise that resolves when the websocket is closed
860
+ */
861
+ async closeHelper() {
862
+ api.ws.close();
863
+ await new Promise((resolve) => setTimeout(resolve, 0));
864
+ },
715
865
  };
716
866
  api.requests.creation = mockCreateTailRequest(
717
867
  websocketURL,
@@ -798,3 +948,11 @@ function generateMockAlarmEvent(opts?: Partial<AlarmEvent>): AlarmEvent {
798
948
  scheduledTime: opts?.scheduledTime || mockEventScheduledTime,
799
949
  };
800
950
  }
951
+
952
+ function generateMockEmailEvent(opts?: Partial<EmailEvent>): EmailEvent {
953
+ return {
954
+ mailFrom: opts?.mailFrom || mockEmailEventFrom,
955
+ rcptTo: opts?.rcptTo || mockEmailEventTo,
956
+ rawSize: opts?.rawSize || mockEmailEventSize,
957
+ };
958
+ }
@@ -1,4 +1,4 @@
1
- // this test has to be run with a version of node.js older than 16.13 to pass
1
+ // this test has to be run with a version of Node.js older than 16.13 to pass
2
2
 
3
3
  const { spawn } = require("child_process");
4
4
  const path = require("path");
@@ -11,7 +11,7 @@ const wranglerProcess = spawn(
11
11
  { stdio: "pipe" }
12
12
  );
13
13
 
14
- const messageToMatch = "Wrangler requires at least node.js v16.13.0";
14
+ const messageToMatch = "Wrangler requires at least Node.js v16.13.0";
15
15
 
16
16
  wranglerProcess.once("exit", (code) => {
17
17
  try {
@@ -25,7 +25,7 @@ wranglerProcess.once("exit", (code) => {
25
25
  } catch (err) {
26
26
  console.error("Error:", err);
27
27
  throw new Error(
28
- "This test has to be run with a version of node.js under 16.13 to pass"
28
+ "This test has to be run with a version of Node.js under 16.13 to pass"
29
29
  );
30
30
  }
31
31
  });