wrangler 2.0.29 → 2.1.2
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.
- package/miniflare-dist/index.mjs +1136 -372
- package/package.json +3 -2
- package/src/__tests__/helpers/mock-cfetch.ts +39 -19
- package/src/__tests__/helpers/mock-console.ts +11 -2
- package/src/__tests__/helpers/msw/handlers/index.ts +13 -0
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
- package/src/__tests__/helpers/msw/handlers/oauth.ts +36 -0
- package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
- package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
- package/src/__tests__/helpers/msw/index.ts +4 -0
- package/src/__tests__/index.test.ts +9 -7
- package/src/__tests__/init.test.ts +356 -5
- package/src/__tests__/jest.setup.ts +16 -0
- package/src/__tests__/middleware.test.ts +768 -0
- package/src/__tests__/pages.test.ts +11 -12
- package/src/__tests__/publish.test.ts +516 -438
- package/src/__tests__/r2.test.ts +128 -93
- package/src/__tests__/secret.test.ts +78 -0
- package/src/__tests__/tail.test.ts +47 -74
- package/src/__tests__/whoami.test.tsx +49 -64
- package/src/api/dev.ts +23 -4
- package/src/bundle.ts +225 -1
- package/src/dev/dev.tsx +3 -1
- package/src/dev/local.tsx +2 -2
- package/src/dev/remote.tsx +6 -3
- package/src/dev/start-server.ts +11 -7
- package/src/dev/use-esbuild.ts +4 -0
- package/src/dev.tsx +6 -16
- package/src/dialogs.tsx +12 -0
- package/src/index.tsx +95 -4
- package/src/init.ts +286 -11
- package/src/miniflare-cli/assets.ts +130 -415
- package/src/miniflare-cli/index.ts +3 -1
- package/src/pages/dev.tsx +5 -1
- package/src/pages/hash.tsx +13 -0
- package/src/pages/upload.tsx +3 -18
- package/src/publish.ts +38 -4
- package/src/tail/filters.ts +1 -5
- package/src/tail/index.ts +6 -3
- package/templates/middleware/common.ts +62 -0
- package/templates/middleware/loader-modules.ts +84 -0
- package/templates/middleware/loader-sw.ts +213 -0
- package/templates/middleware/middleware-pretty-error.ts +40 -0
- package/templates/middleware/middleware-scheduled.ts +14 -0
- package/wrangler-dist/cli.js +65900 -65432
package/src/__tests__/r2.test.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { rest } from "msw";
|
|
2
3
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
3
|
-
import {
|
|
4
|
-
setMockFetchR2Objects,
|
|
5
|
-
setMockResponse,
|
|
6
|
-
unsetAllMocks,
|
|
7
|
-
} from "./helpers/mock-cfetch";
|
|
8
4
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
5
|
+
import { msw } from "./helpers/msw";
|
|
9
6
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
10
7
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
11
8
|
import type { R2BucketInfo } from "../r2";
|
|
@@ -16,10 +13,6 @@ describe("wrangler", () => {
|
|
|
16
13
|
runInTempDir();
|
|
17
14
|
const std = mockConsoleMethods();
|
|
18
15
|
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
unsetAllMocks();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
16
|
describe("r2", () => {
|
|
24
17
|
describe("bucket", () => {
|
|
25
18
|
it("should show the correct help when an invalid command is passed", async () => {
|
|
@@ -50,26 +43,41 @@ describe("wrangler", () => {
|
|
|
50
43
|
});
|
|
51
44
|
|
|
52
45
|
describe("list", () => {
|
|
53
|
-
|
|
54
|
-
const requests = { count: 0 };
|
|
55
|
-
setMockResponse(
|
|
56
|
-
"/accounts/:accountId/r2/buckets",
|
|
57
|
-
([_url, accountId], init) => {
|
|
58
|
-
requests.count++;
|
|
59
|
-
expect(accountId).toEqual("some-account-id");
|
|
60
|
-
expect(init).toEqual({});
|
|
61
|
-
return { buckets };
|
|
62
|
-
}
|
|
63
|
-
);
|
|
64
|
-
return requests;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
it("should list buckets", async () => {
|
|
46
|
+
it("should list buckets & check request inputs", async () => {
|
|
68
47
|
const expectedBuckets: R2BucketInfo[] = [
|
|
69
|
-
{ name: "bucket-1", creation_date: "01-01-2001" },
|
|
70
|
-
{ name: "bucket-2", creation_date: "01-01-2001" },
|
|
48
|
+
{ name: "bucket-1-local-once", creation_date: "01-01-2001" },
|
|
49
|
+
{ name: "bucket-2-local-once", creation_date: "01-01-2001" },
|
|
71
50
|
];
|
|
72
|
-
|
|
51
|
+
msw.use(
|
|
52
|
+
rest.get(
|
|
53
|
+
"*/accounts/:accountId/r2/buckets",
|
|
54
|
+
async (request, response, context) => {
|
|
55
|
+
const { accountId } = request.params;
|
|
56
|
+
expect(accountId).toEqual("some-account-id");
|
|
57
|
+
expect(await request.text()).toEqual("");
|
|
58
|
+
return response.once(
|
|
59
|
+
context.status(200),
|
|
60
|
+
context.json({
|
|
61
|
+
success: true,
|
|
62
|
+
errors: [],
|
|
63
|
+
messages: [],
|
|
64
|
+
result: {
|
|
65
|
+
buckets: [
|
|
66
|
+
{
|
|
67
|
+
name: "bucket-1-local-once",
|
|
68
|
+
creation_date: "01-01-2001",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "bucket-2-local-once",
|
|
72
|
+
creation_date: "01-01-2001",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
);
|
|
73
81
|
await runWrangler("r2 bucket list");
|
|
74
82
|
|
|
75
83
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
@@ -79,21 +87,6 @@ describe("wrangler", () => {
|
|
|
79
87
|
});
|
|
80
88
|
|
|
81
89
|
describe("create", () => {
|
|
82
|
-
function mockCreateRequest(expectedBucketName: string) {
|
|
83
|
-
const requests = { count: 0 };
|
|
84
|
-
setMockResponse(
|
|
85
|
-
"/accounts/:accountId/r2/buckets",
|
|
86
|
-
"POST",
|
|
87
|
-
([_url, accountId], { body }) => {
|
|
88
|
-
expect(accountId).toEqual("some-account-id");
|
|
89
|
-
const bucketName = JSON.parse(body as string).name;
|
|
90
|
-
expect(bucketName).toEqual(expectedBucketName);
|
|
91
|
-
requests.count += 1;
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
return requests;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
90
|
it("should error if no bucket name is given", async () => {
|
|
98
91
|
await expect(
|
|
99
92
|
runWrangler("r2 bucket create")
|
|
@@ -148,32 +141,35 @@ describe("wrangler", () => {
|
|
|
148
141
|
`);
|
|
149
142
|
});
|
|
150
143
|
|
|
151
|
-
it("should create a bucket", async () => {
|
|
152
|
-
|
|
144
|
+
it("should create a bucket & check request inputs", async () => {
|
|
145
|
+
msw.use(
|
|
146
|
+
rest.post(
|
|
147
|
+
"*/accounts/:accountId/r2/buckets",
|
|
148
|
+
async (request, response, context) => {
|
|
149
|
+
const { accountId } = request.params;
|
|
150
|
+
expect(accountId).toEqual("some-account-id");
|
|
151
|
+
expect(await request.json()).toEqual({ name: "testBucket" });
|
|
152
|
+
response.once(
|
|
153
|
+
context.status(200),
|
|
154
|
+
context.json({
|
|
155
|
+
success: true,
|
|
156
|
+
errors: [],
|
|
157
|
+
messages: [],
|
|
158
|
+
result: {},
|
|
159
|
+
})
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
);
|
|
153
164
|
await runWrangler("r2 bucket create testBucket");
|
|
154
165
|
expect(std.out).toMatchInlineSnapshot(`
|
|
155
166
|
"Creating bucket testBucket.
|
|
156
167
|
Created bucket testBucket."
|
|
157
168
|
`);
|
|
158
|
-
expect(requests.count).toEqual(1);
|
|
159
169
|
});
|
|
160
170
|
});
|
|
161
171
|
|
|
162
172
|
describe("delete", () => {
|
|
163
|
-
function mockDeleteRequest(expectedBucketName: string) {
|
|
164
|
-
const requests = { count: 0 };
|
|
165
|
-
setMockResponse(
|
|
166
|
-
"/accounts/:accountId/r2/buckets/:bucketName",
|
|
167
|
-
"DELETE",
|
|
168
|
-
([_url, accountId, bucketName]) => {
|
|
169
|
-
expect(accountId).toEqual("some-account-id");
|
|
170
|
-
expect(bucketName).toEqual(expectedBucketName);
|
|
171
|
-
requests.count += 1;
|
|
172
|
-
}
|
|
173
|
-
);
|
|
174
|
-
return requests;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
173
|
it("should error if no bucket name is given", async () => {
|
|
178
174
|
await expect(
|
|
179
175
|
runWrangler("r2 bucket delete")
|
|
@@ -228,23 +224,42 @@ describe("wrangler", () => {
|
|
|
228
224
|
`);
|
|
229
225
|
});
|
|
230
226
|
|
|
231
|
-
it("should delete a bucket specified by name", async () => {
|
|
232
|
-
|
|
227
|
+
it("should delete a bucket specified by name & check requests inputs", async () => {
|
|
228
|
+
msw.use(
|
|
229
|
+
rest.delete(
|
|
230
|
+
"*/accounts/:accountId/r2/buckets/:bucketName",
|
|
231
|
+
async (request, response, context) => {
|
|
232
|
+
const { accountId, bucketName } = request.params;
|
|
233
|
+
expect(accountId).toEqual("some-account-id");
|
|
234
|
+
expect(bucketName).toEqual("some-bucket");
|
|
235
|
+
expect(await request.text()).toEqual("");
|
|
236
|
+
expect(request.headers.get("authorization")).toEqual(
|
|
237
|
+
"Bearer some-api-token"
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
return response.once(
|
|
241
|
+
context.status(200),
|
|
242
|
+
context.json({
|
|
243
|
+
success: true,
|
|
244
|
+
errors: [],
|
|
245
|
+
messages: [],
|
|
246
|
+
result: null,
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
);
|
|
233
252
|
await runWrangler(`r2 bucket delete some-bucket`);
|
|
234
|
-
expect(
|
|
253
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
254
|
+
"Deleting bucket some-bucket.
|
|
255
|
+
Deleted bucket some-bucket."
|
|
256
|
+
`);
|
|
235
257
|
});
|
|
236
258
|
});
|
|
237
259
|
});
|
|
238
260
|
|
|
239
261
|
describe("r2 object", () => {
|
|
240
262
|
it("should download R2 object from bucket", async () => {
|
|
241
|
-
setMockFetchR2Objects({
|
|
242
|
-
accountId: "some-account-id",
|
|
243
|
-
bucketName: "bucketName-object-test",
|
|
244
|
-
objectName: "wormhole-img.png",
|
|
245
|
-
mockResponse: "R2-objects-test-data",
|
|
246
|
-
});
|
|
247
|
-
|
|
248
263
|
await runWrangler(
|
|
249
264
|
`r2 object get bucketName-object-test/wormhole-img.png --file ./wormhole-img.png`
|
|
250
265
|
);
|
|
@@ -256,11 +271,6 @@ describe("wrangler", () => {
|
|
|
256
271
|
});
|
|
257
272
|
|
|
258
273
|
it("should upload R2 object from bucket", async () => {
|
|
259
|
-
setMockFetchR2Objects({
|
|
260
|
-
accountId: "some-account-id",
|
|
261
|
-
bucketName: "bucketName-object-test",
|
|
262
|
-
objectName: "wormhole-img.png",
|
|
263
|
-
});
|
|
264
274
|
fs.writeFileSync("wormhole-img.png", "passageway");
|
|
265
275
|
await runWrangler(
|
|
266
276
|
`r2 object put bucketName-object-test/wormhole-img.png --file ./wormhole-img.png`
|
|
@@ -272,15 +282,52 @@ describe("wrangler", () => {
|
|
|
272
282
|
`);
|
|
273
283
|
});
|
|
274
284
|
|
|
275
|
-
it("should pass all fetch option flags into requestInit", async () => {
|
|
285
|
+
it("should pass all fetch option flags into requestInit & check request inputs", async () => {
|
|
286
|
+
msw.use(
|
|
287
|
+
rest.put(
|
|
288
|
+
"*/accounts/:accountId/r2/buckets/:bucketName/objects/:objectName",
|
|
289
|
+
(request, response, context) => {
|
|
290
|
+
const { accountId, bucketName, objectName } = request.params;
|
|
291
|
+
expect(accountId).toEqual("some-account-id");
|
|
292
|
+
expect(bucketName).toEqual("bucketName-object-test");
|
|
293
|
+
expect(objectName).toEqual("wormhole-img.png");
|
|
294
|
+
const headersObject = request.headers.all();
|
|
295
|
+
delete headersObject["user-agent"];
|
|
296
|
+
expect(headersObject).toMatchInlineSnapshot(`
|
|
297
|
+
Object {
|
|
298
|
+
"accept": "*/*",
|
|
299
|
+
"accept-encoding": "gzip,deflate",
|
|
300
|
+
"authorization": "Bearer some-api-token",
|
|
301
|
+
"cache-control": "cache-control-mock",
|
|
302
|
+
"connection": "close",
|
|
303
|
+
"content-disposition": "content-disposition-mock",
|
|
304
|
+
"content-encoding": "content-encoding-mock",
|
|
305
|
+
"content-language": "content-lang-mock",
|
|
306
|
+
"content-length": "10",
|
|
307
|
+
"content-type": "content-type-mock",
|
|
308
|
+
"expires": "expire-time-mock",
|
|
309
|
+
"host": "api.cloudflare.com",
|
|
310
|
+
}
|
|
311
|
+
`);
|
|
312
|
+
response.once(
|
|
313
|
+
context.status(200),
|
|
314
|
+
context.json({
|
|
315
|
+
success: true,
|
|
316
|
+
errors: [],
|
|
317
|
+
messages: [],
|
|
318
|
+
result: {
|
|
319
|
+
accountId: "some-account-id",
|
|
320
|
+
bucketName: "bucketName-object-test",
|
|
321
|
+
objectName: "wormhole-img.png",
|
|
322
|
+
},
|
|
323
|
+
})
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
);
|
|
276
328
|
fs.writeFileSync("wormhole-img.png", "passageway");
|
|
277
|
-
setMockFetchR2Objects({
|
|
278
|
-
accountId: "some-account-id",
|
|
279
|
-
bucketName: "bucketName-object-test",
|
|
280
|
-
objectName: "wormhole-img.png",
|
|
281
|
-
});
|
|
282
329
|
const flags =
|
|
283
|
-
"--ct content-type --cd content-disposition --ce content-encoding --cl content-lang --cc cache-control --e expire-time";
|
|
330
|
+
"--ct content-type-mock --cd content-disposition-mock --ce content-encoding-mock --cl content-lang-mock --cc cache-control-mock --e expire-time-mock";
|
|
284
331
|
|
|
285
332
|
await runWrangler(
|
|
286
333
|
`r2 object put bucketName-object-test/wormhole-img.png ${flags} --file wormhole-img.png`
|
|
@@ -293,12 +340,6 @@ describe("wrangler", () => {
|
|
|
293
340
|
});
|
|
294
341
|
|
|
295
342
|
it("should delete R2 object from bucket", async () => {
|
|
296
|
-
setMockFetchR2Objects({
|
|
297
|
-
accountId: "some-account-id",
|
|
298
|
-
bucketName: "bucketName-object-test",
|
|
299
|
-
objectName: "wormhole-img.png",
|
|
300
|
-
});
|
|
301
|
-
|
|
302
343
|
await runWrangler(
|
|
303
344
|
`r2 object delete bucketName-object-test/wormhole-img.png`
|
|
304
345
|
);
|
|
@@ -311,12 +352,6 @@ describe("wrangler", () => {
|
|
|
311
352
|
|
|
312
353
|
it("should not allow `--pipe` & `--file` to run together", async () => {
|
|
313
354
|
fs.writeFileSync("wormhole-img.png", "passageway");
|
|
314
|
-
setMockFetchR2Objects({
|
|
315
|
-
accountId: "some-account-id",
|
|
316
|
-
bucketName: "bucketName-object-test",
|
|
317
|
-
objectName: "wormhole-img.png",
|
|
318
|
-
});
|
|
319
|
-
|
|
320
355
|
await expect(
|
|
321
356
|
runWrangler(
|
|
322
357
|
`r2 object put bucketName-object-test/wormhole-img.png --pipe --file wormhole-img.png`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
2
3
|
import * as TOML from "@iarna/toml";
|
|
3
4
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
4
5
|
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
|
|
@@ -95,6 +96,83 @@ describe("wrangler secret", () => {
|
|
|
95
96
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
96
97
|
});
|
|
97
98
|
|
|
99
|
+
it("should create secret:bulk", async () => {
|
|
100
|
+
writeFileSync(
|
|
101
|
+
"secret.json",
|
|
102
|
+
JSON.stringify({
|
|
103
|
+
"secret-name-1": "secret_text",
|
|
104
|
+
"secret-name-2": "secret_text",
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// User counter to pass different secrets to the request mock
|
|
109
|
+
let counter = 0;
|
|
110
|
+
setMockResponse(
|
|
111
|
+
`/accounts/:accountId/workers/scripts/:scriptName/secrets`,
|
|
112
|
+
"PUT",
|
|
113
|
+
([_url, accountId]) => {
|
|
114
|
+
expect(accountId).toEqual("some-account-id");
|
|
115
|
+
counter++;
|
|
116
|
+
|
|
117
|
+
return { name: `secret-name-${counter}`, type: "secret_text" };
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
await runWrangler("secret:bulk ./secret.json --name script-name");
|
|
122
|
+
|
|
123
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
124
|
+
"🌀 Creating the secrets for the Worker \\"script-name\\"
|
|
125
|
+
✨ Successfully created secret for key: secret-name-1
|
|
126
|
+
✨ Successfully created secret for key: secret-name-2
|
|
127
|
+
✨ Finished processing secrets JSON file"
|
|
128
|
+
`);
|
|
129
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should handle failed secret:bulk", async () => {
|
|
133
|
+
writeFileSync(
|
|
134
|
+
"secret.json",
|
|
135
|
+
JSON.stringify({
|
|
136
|
+
"secret-name-1": "secret_text",
|
|
137
|
+
"secret-name-2": "secret_text",
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// User counter to pass different secrets to the request mock
|
|
142
|
+
let counter = 0;
|
|
143
|
+
setMockResponse(
|
|
144
|
+
`/accounts/:accountId/workers/scripts/:scriptName/secrets`,
|
|
145
|
+
"PUT",
|
|
146
|
+
([_url, accountId]) => {
|
|
147
|
+
expect(accountId).toEqual("some-account-id");
|
|
148
|
+
counter++;
|
|
149
|
+
|
|
150
|
+
return Promise.reject(
|
|
151
|
+
new Error(`Failed to create secret ${counter}`)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
await runWrangler("secret:bulk ./secret.json --name script-name");
|
|
157
|
+
|
|
158
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
159
|
+
"🌀 Creating the secrets for the Worker \\"script-name\\"
|
|
160
|
+
✨ Finished processing secrets JSON file"
|
|
161
|
+
`);
|
|
162
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
163
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1m🚨 Error uploading secret for key: secret-name-1:[0m
|
|
164
|
+
|
|
165
|
+
Failed to create secret 1
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
[31mX [41;31m[[41;97mERROR[41;31m][0m [1m🚨 Error uploading secret for key: secret-name-2:[0m
|
|
169
|
+
|
|
170
|
+
Failed to create secret 2
|
|
171
|
+
|
|
172
|
+
"
|
|
173
|
+
`);
|
|
174
|
+
});
|
|
175
|
+
|
|
98
176
|
it("should create a secret: legacy envs", async () => {
|
|
99
177
|
mockPrompt({
|
|
100
178
|
text: "Enter a secret value:",
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ScheduledEvent,
|
|
15
15
|
AlarmEvent,
|
|
16
16
|
} from "../tail";
|
|
17
|
+
import type { RequestInit } from "undici";
|
|
17
18
|
import type WebSocket from "ws";
|
|
18
19
|
|
|
19
20
|
describe("tail", () => {
|
|
@@ -44,12 +45,12 @@ describe("tail", () => {
|
|
|
44
45
|
|
|
45
46
|
it("creates and then delete tails", async () => {
|
|
46
47
|
const api = mockWebsocketAPIs();
|
|
47
|
-
expect(api.requests.creation.
|
|
48
|
+
expect(api.requests.creation.length).toStrictEqual(0);
|
|
48
49
|
|
|
49
50
|
await runWrangler("tail test-worker");
|
|
50
51
|
|
|
51
52
|
await expect(api.ws.connected).resolves.toBeTruthy();
|
|
52
|
-
expect(api.requests.creation.
|
|
53
|
+
expect(api.requests.creation.length).toStrictEqual(1);
|
|
53
54
|
expect(api.requests.deletion.count).toStrictEqual(0);
|
|
54
55
|
|
|
55
56
|
api.ws.close();
|
|
@@ -57,7 +58,7 @@ describe("tail", () => {
|
|
|
57
58
|
});
|
|
58
59
|
it("should connect to the worker assigned to a given route", async () => {
|
|
59
60
|
const api = mockWebsocketAPIs();
|
|
60
|
-
expect(api.requests.creation.
|
|
61
|
+
expect(api.requests.creation.length).toStrictEqual(0);
|
|
61
62
|
|
|
62
63
|
mockGetZoneFromHostRequest("example.com", "test-zone");
|
|
63
64
|
mockCollectKnownRoutesRequest([
|
|
@@ -69,7 +70,7 @@ describe("tail", () => {
|
|
|
69
70
|
await runWrangler("tail example.com/*");
|
|
70
71
|
|
|
71
72
|
await expect(api.ws.connected).resolves.toBeTruthy();
|
|
72
|
-
expect(api.requests.creation.
|
|
73
|
+
expect(api.requests.creation.length).toStrictEqual(1);
|
|
73
74
|
expect(api.requests.deletion.count).toStrictEqual(0);
|
|
74
75
|
|
|
75
76
|
api.ws.close();
|
|
@@ -90,12 +91,12 @@ describe("tail", () => {
|
|
|
90
91
|
|
|
91
92
|
it("creates and then delete tails: legacy envs", async () => {
|
|
92
93
|
const api = mockWebsocketAPIs("some-env", true);
|
|
93
|
-
expect(api.requests.creation.
|
|
94
|
+
expect(api.requests.creation.length).toStrictEqual(0);
|
|
94
95
|
|
|
95
96
|
await runWrangler("tail test-worker --env some-env --legacy-env true");
|
|
96
97
|
|
|
97
98
|
await expect(api.ws.connected).resolves.toBeTruthy();
|
|
98
|
-
expect(api.requests.creation.
|
|
99
|
+
expect(api.requests.creation.length).toStrictEqual(1);
|
|
99
100
|
expect(api.requests.deletion.count).toStrictEqual(0);
|
|
100
101
|
|
|
101
102
|
api.ws.close();
|
|
@@ -104,12 +105,12 @@ describe("tail", () => {
|
|
|
104
105
|
|
|
105
106
|
it("creates and then delete tails: service envs", async () => {
|
|
106
107
|
const api = mockWebsocketAPIs("some-env");
|
|
107
|
-
expect(api.requests.creation.
|
|
108
|
+
expect(api.requests.creation.length).toStrictEqual(0);
|
|
108
109
|
|
|
109
110
|
await runWrangler("tail test-worker --env some-env --legacy-env false");
|
|
110
111
|
|
|
111
112
|
await expect(api.ws.connected).resolves.toBeTruthy();
|
|
112
|
-
expect(api.requests.creation.
|
|
113
|
+
expect(api.requests.creation.length).toStrictEqual(1);
|
|
113
114
|
expect(api.requests.deletion.count).toStrictEqual(0);
|
|
114
115
|
|
|
115
116
|
api.ws.close();
|
|
@@ -143,65 +144,57 @@ describe("tail", () => {
|
|
|
143
144
|
await expect(tooLow).rejects.toThrow();
|
|
144
145
|
|
|
145
146
|
await runWrangler("tail test-worker --sampling-rate 0.25");
|
|
146
|
-
|
|
147
|
-
{
|
|
148
|
-
|
|
147
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
148
|
+
`{"filters":[{"sampling_rate":0.25}]}`
|
|
149
|
+
);
|
|
149
150
|
});
|
|
150
151
|
|
|
151
152
|
it("sends single status filters", async () => {
|
|
152
153
|
const api = mockWebsocketAPIs();
|
|
153
154
|
await runWrangler("tail test-worker --status error");
|
|
154
|
-
|
|
155
|
-
{
|
|
156
|
-
|
|
155
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
156
|
+
`{"filters":[{"outcome":["exception","exceededCpu","exceededMemory","unknown"]}]}`
|
|
157
|
+
);
|
|
157
158
|
});
|
|
158
159
|
|
|
159
160
|
it("sends multiple status filters", async () => {
|
|
160
161
|
const api = mockWebsocketAPIs();
|
|
161
162
|
await runWrangler("tail test-worker --status error --status canceled");
|
|
162
|
-
|
|
163
|
-
{
|
|
164
|
-
|
|
165
|
-
"exception",
|
|
166
|
-
"exceededCpu",
|
|
167
|
-
"exceededMemory",
|
|
168
|
-
"unknown",
|
|
169
|
-
"canceled",
|
|
170
|
-
],
|
|
171
|
-
},
|
|
172
|
-
]);
|
|
163
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
164
|
+
`{"filters":[{"outcome":["exception","exceededCpu","exceededMemory","unknown","canceled"]}]}`
|
|
165
|
+
);
|
|
173
166
|
});
|
|
174
167
|
|
|
175
168
|
it("sends single HTTP method filters", async () => {
|
|
176
169
|
const api = mockWebsocketAPIs();
|
|
177
170
|
await runWrangler("tail test-worker --method POST");
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
|
|
171
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
172
|
+
`{"filters":[{"method":["POST"]}]}`
|
|
173
|
+
);
|
|
181
174
|
});
|
|
182
175
|
|
|
183
176
|
it("sends multiple HTTP method filters", async () => {
|
|
184
177
|
const api = mockWebsocketAPIs();
|
|
185
178
|
await runWrangler("tail test-worker --method POST --method GET");
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
|
|
179
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
180
|
+
`{"filters":[{"method":["POST","GET"]}]}`
|
|
181
|
+
);
|
|
189
182
|
});
|
|
190
183
|
|
|
191
184
|
it("sends header filters without a query", async () => {
|
|
192
185
|
const api = mockWebsocketAPIs();
|
|
193
186
|
await runWrangler("tail test-worker --header X-CUSTOM-HEADER");
|
|
194
|
-
|
|
195
|
-
{
|
|
196
|
-
|
|
187
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
188
|
+
`{"filters":[{"header":{"key":"X-CUSTOM-HEADER"}}]}`
|
|
189
|
+
);
|
|
197
190
|
});
|
|
198
191
|
|
|
199
192
|
it("sends header filters with a query", async () => {
|
|
200
193
|
const api = mockWebsocketAPIs();
|
|
201
194
|
await runWrangler("tail test-worker --header X-CUSTOM-HEADER:some-value");
|
|
202
|
-
|
|
203
|
-
{
|
|
204
|
-
|
|
195
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
196
|
+
`{"filters":[{"header":{"key":"X-CUSTOM-HEADER","query":"some-value"}}]}`
|
|
197
|
+
);
|
|
205
198
|
});
|
|
206
199
|
|
|
207
200
|
it("sends single IP filters", async () => {
|
|
@@ -209,9 +202,9 @@ describe("tail", () => {
|
|
|
209
202
|
const fakeIp = "192.0.2.1";
|
|
210
203
|
|
|
211
204
|
await runWrangler(`tail test-worker --ip ${fakeIp}`);
|
|
212
|
-
|
|
213
|
-
{
|
|
214
|
-
|
|
205
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
206
|
+
`{"filters":[{"client_ip":["${fakeIp}"]}]}`
|
|
207
|
+
);
|
|
215
208
|
});
|
|
216
209
|
|
|
217
210
|
it("sends multiple IP filters", async () => {
|
|
@@ -219,9 +212,9 @@ describe("tail", () => {
|
|
|
219
212
|
const fakeIp = "192.0.2.1";
|
|
220
213
|
|
|
221
214
|
await runWrangler(`tail test-worker --ip ${fakeIp} --ip self`);
|
|
222
|
-
|
|
223
|
-
{
|
|
224
|
-
|
|
215
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
216
|
+
`{"filters":[{"client_ip":["${fakeIp}","self"]}]}`
|
|
217
|
+
);
|
|
225
218
|
});
|
|
226
219
|
|
|
227
220
|
it("sends search filters", async () => {
|
|
@@ -229,9 +222,9 @@ describe("tail", () => {
|
|
|
229
222
|
const search = "filterMe";
|
|
230
223
|
|
|
231
224
|
await runWrangler(`tail test-worker --search ${search}`);
|
|
232
|
-
|
|
233
|
-
{
|
|
234
|
-
|
|
225
|
+
expect(api.requests.creation[0].body).toEqual(
|
|
226
|
+
`{"filters":[{"query":"${search}"}]}`
|
|
227
|
+
);
|
|
235
228
|
});
|
|
236
229
|
|
|
237
230
|
it("sends everything but the kitchen sink", async () => {
|
|
@@ -252,30 +245,10 @@ describe("tail", () => {
|
|
|
252
245
|
`--search ${query} ` +
|
|
253
246
|
`--debug`;
|
|
254
247
|
|
|
255
|
-
const expectedWebsocketMessage = {
|
|
256
|
-
filters: [
|
|
257
|
-
{ sampling_rate },
|
|
258
|
-
{
|
|
259
|
-
outcome: [
|
|
260
|
-
"ok",
|
|
261
|
-
"exception",
|
|
262
|
-
"exceededCpu",
|
|
263
|
-
"exceededMemory",
|
|
264
|
-
"unknown",
|
|
265
|
-
],
|
|
266
|
-
},
|
|
267
|
-
{ method },
|
|
268
|
-
{ header: { key: "X-HELLO", query: "world" } },
|
|
269
|
-
{ client_ip },
|
|
270
|
-
{ query },
|
|
271
|
-
],
|
|
272
|
-
debug: true,
|
|
273
|
-
};
|
|
248
|
+
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"}]}`;
|
|
274
249
|
|
|
275
250
|
await runWrangler(`tail test-worker ${cliFilters}`);
|
|
276
|
-
|
|
277
|
-
expectedWebsocketMessage
|
|
278
|
-
);
|
|
251
|
+
expect(api.requests.creation[0].body).toEqual(expectedWebsocketMessage);
|
|
279
252
|
});
|
|
280
253
|
});
|
|
281
254
|
|
|
@@ -589,7 +562,7 @@ function deserializeToJson(message: WebSocket.RawData): string {
|
|
|
589
562
|
*/
|
|
590
563
|
type MockAPI = {
|
|
591
564
|
requests: {
|
|
592
|
-
creation:
|
|
565
|
+
creation: RequestInit[];
|
|
593
566
|
deletion: RequestCounter;
|
|
594
567
|
};
|
|
595
568
|
ws: MockWebSocket;
|
|
@@ -615,15 +588,15 @@ function mockCreateTailRequest(
|
|
|
615
588
|
websocketURL: string,
|
|
616
589
|
env?: string,
|
|
617
590
|
legacyEnv = false
|
|
618
|
-
):
|
|
619
|
-
const requests =
|
|
591
|
+
): RequestInit[] {
|
|
592
|
+
const requests: RequestInit[] = [];
|
|
620
593
|
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
|
|
621
594
|
const environment = env && !legacyEnv ? "/environments/:envName" : "";
|
|
622
595
|
setMockResponse(
|
|
623
596
|
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/tails`,
|
|
624
597
|
"POST",
|
|
625
|
-
([_url, accountId, scriptName, envName]) => {
|
|
626
|
-
requests.
|
|
598
|
+
([_url, accountId, scriptName, envName], req) => {
|
|
599
|
+
requests.push(req);
|
|
627
600
|
expect(accountId).toEqual("some-account-id");
|
|
628
601
|
expect(scriptName).toEqual(
|
|
629
602
|
legacyEnv && env ? `test-worker-${env}` : "test-worker"
|
|
@@ -710,7 +683,7 @@ function mockWebsocketAPIs(env?: string, legacyEnv = false): MockAPI {
|
|
|
710
683
|
const api: MockAPI = {
|
|
711
684
|
requests: {
|
|
712
685
|
deletion: { count: 0 },
|
|
713
|
-
creation:
|
|
686
|
+
creation: [],
|
|
714
687
|
},
|
|
715
688
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
716
689
|
ws: null!, // will be set in the `beforeEach()` below.
|