wrangler 2.0.16 → 2.0.19
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/bin/wrangler.js +42 -8
- package/miniflare-dist/index.mjs +1 -0
- package/package.json +65 -63
- package/src/__tests__/configuration.test.ts +11 -7
- package/src/__tests__/helpers/run-in-tmp.ts +22 -23
- package/src/__tests__/https-options.test.ts +51 -18
- package/src/__tests__/index.test.ts +13 -13
- package/src/__tests__/jest.setup.ts +13 -0
- package/src/__tests__/kv.test.ts +33 -2
- package/src/__tests__/metrics.test.ts +415 -0
- package/src/__tests__/pages.test.ts +15 -8
- package/src/__tests__/publish.test.ts +49 -23
- package/src/__tests__/secret.test.ts +84 -78
- package/src/__tests__/tail.test.ts +8 -0
- package/src/__tests__/test-old-node-version.js +31 -0
- package/src/__tests__/user.test.ts +7 -7
- package/src/__tests__/whoami.test.tsx +11 -1
- package/src/api/dev.ts +4 -1
- package/src/cli.ts +1 -1
- package/src/config/config.ts +8 -0
- package/src/config/validation.ts +9 -0
- package/src/config-cache.ts +2 -1
- package/src/dev/local.tsx +31 -25
- package/src/dev/remote.tsx +2 -2
- package/src/dev.tsx +6 -0
- package/src/entry.ts +1 -1
- package/src/{__tests__/helpers/faye-websocket.d.ts → faye-websocket.d.ts} +0 -0
- package/src/global-wrangler-config-path.ts +26 -0
- package/src/https-options.ts +8 -4
- package/src/index.tsx +120 -22
- package/src/kv.ts +23 -1
- package/src/metrics/index.ts +4 -0
- package/src/metrics/metrics-config.ts +222 -0
- package/src/metrics/metrics-dispatcher.ts +93 -0
- package/src/metrics/send-event.ts +80 -0
- package/src/miniflare-cli/index.ts +1 -0
- package/src/package-manager.ts +45 -0
- package/src/pages/build.tsx +2 -0
- package/src/pages/deployments.tsx +2 -0
- package/src/pages/dev.tsx +4 -0
- package/src/pages/projects.tsx +3 -0
- package/src/pages/publish.tsx +3 -0
- package/src/pages/upload.tsx +26 -14
- package/src/publish.ts +28 -15
- package/src/pubsub/pubsub-commands.tsx +43 -0
- package/src/user/user.tsx +29 -20
- package/src/worker-namespace.ts +16 -0
- package/templates/static-asset-facade.js +11 -5
- package/templates/tsconfig.json +2 -2
- package/wrangler-dist/cli.d.ts +298 -0
- package/wrangler-dist/cli.js +2589 -1659
|
@@ -73,9 +73,9 @@ describe("wrangler secret", () => {
|
|
|
73
73
|
mockPutRequest({ name: `secret-name`, text: `hunter2` });
|
|
74
74
|
await runWrangler("secret put secret-name --name script-name");
|
|
75
75
|
expect(std.out).toMatchInlineSnapshot(`
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
"🌀 Creating the secret for the Worker \\"script-name\\"
|
|
77
|
+
✨ Success! Uploaded secret secret-name"
|
|
78
|
+
`);
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
it("should create a secret", async () => {
|
|
@@ -89,9 +89,9 @@ describe("wrangler secret", () => {
|
|
|
89
89
|
await runWrangler("secret put the-key --name script-name");
|
|
90
90
|
|
|
91
91
|
expect(std.out).toMatchInlineSnapshot(`
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
"🌀 Creating the secret for the Worker \\"script-name\\"
|
|
93
|
+
✨ Success! Uploaded secret the-key"
|
|
94
|
+
`);
|
|
95
95
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
96
96
|
});
|
|
97
97
|
|
|
@@ -112,9 +112,9 @@ describe("wrangler secret", () => {
|
|
|
112
112
|
);
|
|
113
113
|
|
|
114
114
|
expect(std.out).toMatchInlineSnapshot(`
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
"🌀 Creating the secret for the Worker \\"script-name-some-env\\"
|
|
116
|
+
✨ Success! Uploaded secret the-key"
|
|
117
|
+
`);
|
|
118
118
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
119
119
|
});
|
|
120
120
|
|
|
@@ -135,9 +135,9 @@ describe("wrangler secret", () => {
|
|
|
135
135
|
);
|
|
136
136
|
|
|
137
137
|
expect(std.out).toMatchInlineSnapshot(`
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
"🌀 Creating the secret for the Worker \\"script-name\\" (some-env)
|
|
139
|
+
✨ Success! Uploaded secret the-key"
|
|
140
|
+
`);
|
|
141
141
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
142
142
|
});
|
|
143
143
|
|
|
@@ -149,15 +149,17 @@ describe("wrangler secret", () => {
|
|
|
149
149
|
error = e as Error;
|
|
150
150
|
}
|
|
151
151
|
expect(std.out).toMatchInlineSnapshot(`
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
"
|
|
153
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
154
|
+
`);
|
|
155
155
|
expect(std.err).toMatchInlineSnapshot(`
|
|
156
|
-
|
|
156
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mRequired Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`[0m
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
expect(error).toMatchInlineSnapshot(
|
|
158
|
+
"
|
|
159
|
+
`);
|
|
160
|
+
expect(error).toMatchInlineSnapshot(
|
|
161
|
+
`[Error: Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`]`
|
|
162
|
+
);
|
|
161
163
|
});
|
|
162
164
|
});
|
|
163
165
|
|
|
@@ -176,9 +178,9 @@ describe("wrangler secret", () => {
|
|
|
176
178
|
await runWrangler("secret put the-key --name script-name");
|
|
177
179
|
|
|
178
180
|
expect(std.out).toMatchInlineSnapshot(`
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
"🌀 Creating the secret for the Worker \\"script-name\\"
|
|
182
|
+
✨ Success! Uploaded secret the-key"
|
|
183
|
+
`);
|
|
182
184
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
183
185
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
184
186
|
});
|
|
@@ -190,9 +192,9 @@ describe("wrangler secret", () => {
|
|
|
190
192
|
await runWrangler("secret put the-key --name script-name");
|
|
191
193
|
|
|
192
194
|
expect(std.out).toMatchInlineSnapshot(`
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
"🌀 Creating the secret for the Worker \\"script-name\\"
|
|
196
|
+
✨ Success! Uploaded secret the-key"
|
|
197
|
+
`);
|
|
196
198
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
197
199
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
198
200
|
});
|
|
@@ -205,9 +207,9 @@ describe("wrangler secret", () => {
|
|
|
205
207
|
).rejects.toThrowErrorMatchingInlineSnapshot(`"Error in stdin stream"`);
|
|
206
208
|
|
|
207
209
|
expect(std.out).toMatchInlineSnapshot(`
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
"
|
|
211
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
212
|
+
`);
|
|
211
213
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
212
214
|
});
|
|
213
215
|
|
|
@@ -244,9 +246,9 @@ describe("wrangler secret", () => {
|
|
|
244
246
|
mockPutRequest({ name: "the-key", text: "the-secret" });
|
|
245
247
|
await runWrangler("secret put the-key --name script-name");
|
|
246
248
|
expect(std.out).toMatchInlineSnapshot(`
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
249
|
+
"🌀 Creating the secret for the Worker \\"script-name\\"
|
|
250
|
+
✨ Success! Uploaded secret the-key"
|
|
251
|
+
`);
|
|
250
252
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
251
253
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
252
254
|
});
|
|
@@ -317,14 +319,14 @@ describe("wrangler secret", () => {
|
|
|
317
319
|
it("should delete a secret", async () => {
|
|
318
320
|
mockDeleteRequest({ scriptName: "script-name", secretName: "the-key" });
|
|
319
321
|
mockConfirm({
|
|
320
|
-
text: "Are you sure you want to permanently delete the
|
|
322
|
+
text: "Are you sure you want to permanently delete the secret the-key on the Worker script-name?",
|
|
321
323
|
result: true,
|
|
322
324
|
});
|
|
323
325
|
await runWrangler("secret delete the-key --name script-name");
|
|
324
326
|
expect(std.out).toMatchInlineSnapshot(`
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
327
|
+
"🌀 Deleting the secret the-key on the Worker script-name
|
|
328
|
+
✨ Success! Deleted secret the-key"
|
|
329
|
+
`);
|
|
328
330
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
329
331
|
});
|
|
330
332
|
|
|
@@ -335,16 +337,16 @@ describe("wrangler secret", () => {
|
|
|
335
337
|
true
|
|
336
338
|
);
|
|
337
339
|
mockConfirm({
|
|
338
|
-
text: "Are you sure you want to permanently delete the
|
|
340
|
+
text: "Are you sure you want to permanently delete the secret the-key on the Worker script-name-some-env?",
|
|
339
341
|
result: true,
|
|
340
342
|
});
|
|
341
343
|
await runWrangler(
|
|
342
344
|
"secret delete the-key --name script-name --env some-env --legacy-env"
|
|
343
345
|
);
|
|
344
346
|
expect(std.out).toMatchInlineSnapshot(`
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
347
|
+
"🌀 Deleting the secret the-key on the Worker script-name-some-env
|
|
348
|
+
✨ Success! Deleted secret the-key"
|
|
349
|
+
`);
|
|
348
350
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
349
351
|
});
|
|
350
352
|
|
|
@@ -354,16 +356,16 @@ describe("wrangler secret", () => {
|
|
|
354
356
|
"some-env"
|
|
355
357
|
);
|
|
356
358
|
mockConfirm({
|
|
357
|
-
text: "Are you sure you want to permanently delete the
|
|
359
|
+
text: "Are you sure you want to permanently delete the secret the-key on the Worker script-name (some-env)?",
|
|
358
360
|
result: true,
|
|
359
361
|
});
|
|
360
362
|
await runWrangler(
|
|
361
363
|
"secret delete the-key --name script-name --env some-env --legacy-env false"
|
|
362
364
|
);
|
|
363
365
|
expect(std.out).toMatchInlineSnapshot(`
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
366
|
+
"🌀 Deleting the secret the-key on the Worker script-name (some-env)
|
|
367
|
+
✨ Success! Deleted secret the-key"
|
|
368
|
+
`);
|
|
367
369
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
368
370
|
});
|
|
369
371
|
|
|
@@ -376,15 +378,17 @@ describe("wrangler secret", () => {
|
|
|
376
378
|
error = e as Error;
|
|
377
379
|
}
|
|
378
380
|
expect(std.out).toMatchInlineSnapshot(`
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
381
|
+
"
|
|
382
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
383
|
+
`);
|
|
382
384
|
expect(std.err).toMatchInlineSnapshot(`
|
|
383
|
-
|
|
385
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mRequired Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`[0m
|
|
384
386
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
expect(error).toMatchInlineSnapshot(
|
|
387
|
+
"
|
|
388
|
+
`);
|
|
389
|
+
expect(error).toMatchInlineSnapshot(
|
|
390
|
+
`[Error: Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`]`
|
|
391
|
+
);
|
|
388
392
|
});
|
|
389
393
|
});
|
|
390
394
|
|
|
@@ -422,13 +426,13 @@ describe("wrangler secret", () => {
|
|
|
422
426
|
mockListRequest({ scriptName: "script-name" });
|
|
423
427
|
await runWrangler("secret list --name script-name");
|
|
424
428
|
expect(std.out).toMatchInlineSnapshot(`
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
429
|
+
"[
|
|
430
|
+
{
|
|
431
|
+
\\"name\\": \\"the-secret-name\\",
|
|
432
|
+
\\"type\\": \\"secret_text\\"
|
|
433
|
+
}
|
|
434
|
+
]"
|
|
435
|
+
`);
|
|
432
436
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
433
437
|
});
|
|
434
438
|
|
|
@@ -438,13 +442,13 @@ describe("wrangler secret", () => {
|
|
|
438
442
|
"secret list --name script-name --env some-env --legacy-env"
|
|
439
443
|
);
|
|
440
444
|
expect(std.out).toMatchInlineSnapshot(`
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
445
|
+
"[
|
|
446
|
+
{
|
|
447
|
+
\\"name\\": \\"the-secret-name\\",
|
|
448
|
+
\\"type\\": \\"secret_text\\"
|
|
449
|
+
}
|
|
450
|
+
]"
|
|
451
|
+
`);
|
|
448
452
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
449
453
|
});
|
|
450
454
|
|
|
@@ -454,13 +458,13 @@ describe("wrangler secret", () => {
|
|
|
454
458
|
"secret list --name script-name --env some-env --legacy-env false"
|
|
455
459
|
);
|
|
456
460
|
expect(std.out).toMatchInlineSnapshot(`
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
461
|
+
"[
|
|
462
|
+
{
|
|
463
|
+
\\"name\\": \\"the-secret-name\\",
|
|
464
|
+
\\"type\\": \\"secret_text\\"
|
|
465
|
+
}
|
|
466
|
+
]"
|
|
467
|
+
`);
|
|
464
468
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
465
469
|
});
|
|
466
470
|
|
|
@@ -472,15 +476,17 @@ describe("wrangler secret", () => {
|
|
|
472
476
|
error = e as Error;
|
|
473
477
|
}
|
|
474
478
|
expect(std.out).toMatchInlineSnapshot(`
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
479
|
+
"
|
|
480
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
481
|
+
`);
|
|
478
482
|
expect(std.err).toMatchInlineSnapshot(`
|
|
479
|
-
|
|
483
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mRequired Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`[0m
|
|
480
484
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
expect(error).toMatchInlineSnapshot(
|
|
485
|
+
"
|
|
486
|
+
`);
|
|
487
|
+
expect(error).toMatchInlineSnapshot(
|
|
488
|
+
`[Error: Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name <worker-name>\`]`
|
|
489
|
+
);
|
|
484
490
|
});
|
|
485
491
|
});
|
|
486
492
|
});
|
|
@@ -27,6 +27,14 @@ describe("tail", () => {
|
|
|
27
27
|
* deletion, and connection.
|
|
28
28
|
*/
|
|
29
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
|
+
|
|
30
38
|
it("creates and then delete tails", async () => {
|
|
31
39
|
const api = mockWebsocketAPIs();
|
|
32
40
|
expect(api.requests.creation.count).toStrictEqual(0);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// this test has to be run with a version of node.js older than 16.7 to pass
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const assert = require("assert");
|
|
7
|
+
|
|
8
|
+
const wranglerProcess = spawn(
|
|
9
|
+
"node",
|
|
10
|
+
[path.join(__dirname, "../../bin/wrangler.js")],
|
|
11
|
+
{ stdio: "pipe" }
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const messageToMatch = "Wrangler requires at least node.js v16.7.0";
|
|
15
|
+
|
|
16
|
+
wranglerProcess.once("exit", (code) => {
|
|
17
|
+
try {
|
|
18
|
+
const errorMessage = wranglerProcess.stderr.read().toString();
|
|
19
|
+
|
|
20
|
+
assert(code === 1, "Expected exit code 1");
|
|
21
|
+
assert(
|
|
22
|
+
errorMessage.includes(messageToMatch),
|
|
23
|
+
`Expected error message to include "${messageToMatch}"`
|
|
24
|
+
);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
console.error("Error:", err);
|
|
27
|
+
throw new Error(
|
|
28
|
+
"This test has to be run with a version of node.js under 16.7 to pass"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import fetchMock from "jest-fetch-mock";
|
|
4
|
+
import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
|
|
5
5
|
import {
|
|
6
6
|
loginOrRefreshIfRequired,
|
|
7
7
|
readAuthConfigFile,
|
|
@@ -18,7 +18,7 @@ import type { Config } from "../config";
|
|
|
18
18
|
import type { UserAuthConfig } from "../user";
|
|
19
19
|
|
|
20
20
|
describe("User", () => {
|
|
21
|
-
runInTempDir(
|
|
21
|
+
runInTempDir();
|
|
22
22
|
const std = mockConsoleMethods();
|
|
23
23
|
const {
|
|
24
24
|
mockOAuthServerCallback,
|
|
@@ -86,7 +86,10 @@ describe("User", () => {
|
|
|
86
86
|
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
87
87
|
|
|
88
88
|
// Make sure that logout removed the config file containing the auth tokens.
|
|
89
|
-
const config = path.join(
|
|
89
|
+
const config = path.join(
|
|
90
|
+
getGlobalWranglerConfigPath(),
|
|
91
|
+
USER_AUTH_CONFIG_FILE
|
|
92
|
+
);
|
|
90
93
|
expect(fs.existsSync(config)).toBeFalsy();
|
|
91
94
|
});
|
|
92
95
|
});
|
|
@@ -94,13 +97,10 @@ describe("User", () => {
|
|
|
94
97
|
// TODO: Improve OAuth mocking to handle `/token` endpoints from different calls
|
|
95
98
|
it("should handle errors for failed token refresh", async () => {
|
|
96
99
|
setIsTTY(false);
|
|
97
|
-
mockOAuthServerCallback();
|
|
98
100
|
writeAuthConfigFile({
|
|
99
101
|
oauth_token: "hunter2",
|
|
100
102
|
refresh_token: "Order 66",
|
|
101
103
|
});
|
|
102
|
-
mockGrantAuthorization({ respondWith: "success" });
|
|
103
|
-
|
|
104
104
|
mockExchangeRefreshTokenForAccessToken({
|
|
105
105
|
respondWith: "badResponse",
|
|
106
106
|
});
|
|
@@ -109,7 +109,7 @@ describe("User", () => {
|
|
|
109
109
|
await expect(
|
|
110
110
|
requireAuth({} as Config)
|
|
111
111
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
112
|
-
`"
|
|
112
|
+
`"In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN environment variable for wrangler to work. Please go to https://developers.cloudflare.com/api/tokens/create/ for instructions on how to create an api token, and assign its value to CLOUDFLARE_API_TOKEN."`
|
|
113
113
|
);
|
|
114
114
|
});
|
|
115
115
|
|
|
@@ -16,7 +16,7 @@ import type { UserInfo } from "../whoami";
|
|
|
16
16
|
describe("getUserInfo()", () => {
|
|
17
17
|
const ENV_COPY = process.env;
|
|
18
18
|
|
|
19
|
-
runInTempDir(
|
|
19
|
+
runInTempDir();
|
|
20
20
|
const std = mockConsoleMethods();
|
|
21
21
|
const { setIsTTY } = useMockIsTTY();
|
|
22
22
|
|
|
@@ -173,6 +173,16 @@ describe("getUserInfo()", () => {
|
|
|
173
173
|
|
|
174
174
|
it("should display a warning message if the config file contains a legacy api_token field", async () => {
|
|
175
175
|
writeAuthConfigFile({ api_token: "API_TOKEN" });
|
|
176
|
+
setMockResponse("/user", () => {
|
|
177
|
+
return { email: "user@example.com" };
|
|
178
|
+
});
|
|
179
|
+
setMockResponse("/accounts", () => {
|
|
180
|
+
return [
|
|
181
|
+
{ name: "Account One", id: "account-1" },
|
|
182
|
+
{ name: "Account Two", id: "account-2" },
|
|
183
|
+
{ name: "Account Three", id: "account-3" },
|
|
184
|
+
];
|
|
185
|
+
});
|
|
176
186
|
await getUserInfo();
|
|
177
187
|
expect(std.warn).toMatchInlineSnapshot(`
|
|
178
188
|
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mIt looks like you have used Wrangler 1's \`config\` command to login with an API token.[0m
|
package/src/api/dev.ts
CHANGED
|
@@ -43,7 +43,10 @@ export async function unstable_dev(script: string, options: DevOptions) {
|
|
|
43
43
|
showInteractiveDevSession: false,
|
|
44
44
|
});
|
|
45
45
|
}).then((devServer) => {
|
|
46
|
-
resolve({
|
|
46
|
+
resolve({
|
|
47
|
+
stop: devServer.stop,
|
|
48
|
+
fetch: devServer.fetch,
|
|
49
|
+
});
|
|
47
50
|
});
|
|
48
51
|
});
|
|
49
52
|
}
|
package/src/cli.ts
CHANGED
package/src/config/config.ts
CHANGED
|
@@ -38,6 +38,14 @@ export interface ConfigFields<Dev extends RawDevConfig> {
|
|
|
38
38
|
*/
|
|
39
39
|
legacy_env: boolean;
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Whether Wrangler should send usage metrics to Cloudflare for this project.
|
|
43
|
+
*
|
|
44
|
+
* When defined this will override any user settings.
|
|
45
|
+
* Otherwise, Wrangler will use the user's preference.
|
|
46
|
+
*/
|
|
47
|
+
send_metrics: boolean | undefined;
|
|
48
|
+
|
|
41
49
|
/**
|
|
42
50
|
* Options to configure the development server that your worker will use.
|
|
43
51
|
*/
|
package/src/config/validation.ts
CHANGED
|
@@ -94,6 +94,14 @@ export function normalizeAndValidateConfig(
|
|
|
94
94
|
"boolean"
|
|
95
95
|
);
|
|
96
96
|
|
|
97
|
+
validateOptionalProperty(
|
|
98
|
+
diagnostics,
|
|
99
|
+
"",
|
|
100
|
+
"send_metrics",
|
|
101
|
+
rawConfig.send_metrics,
|
|
102
|
+
"boolean"
|
|
103
|
+
);
|
|
104
|
+
|
|
97
105
|
// TODO: set the default to false to turn on service environments as the default
|
|
98
106
|
const isLegacyEnv =
|
|
99
107
|
(args as { "legacy-env": boolean | undefined })["legacy-env"] ??
|
|
@@ -173,6 +181,7 @@ export function normalizeAndValidateConfig(
|
|
|
173
181
|
const config: Config = {
|
|
174
182
|
configPath,
|
|
175
183
|
legacy_env: isLegacyEnv,
|
|
184
|
+
send_metrics: rawConfig.send_metrics,
|
|
176
185
|
...activeEnv,
|
|
177
186
|
dev: normalizeAndValidateDev(diagnostics, rawConfig.dev ?? {}),
|
|
178
187
|
migrations: normalizeAndValidateMigrations(
|
package/src/config-cache.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { logger } from "./logger";
|
|
|
6
6
|
|
|
7
7
|
let cacheMessageShown = false;
|
|
8
8
|
|
|
9
|
-
let __cacheFolder: string | null;
|
|
9
|
+
let __cacheFolder: string | null | undefined;
|
|
10
10
|
function getCacheFolder() {
|
|
11
11
|
if (__cacheFolder || __cacheFolder === null) return __cacheFolder;
|
|
12
12
|
|
|
@@ -80,4 +80,5 @@ export function purgeConfigCaches() {
|
|
|
80
80
|
if (cacheFolder) {
|
|
81
81
|
rmSync(cacheFolder, { recursive: true, force: true });
|
|
82
82
|
}
|
|
83
|
+
__cacheFolder = undefined;
|
|
83
84
|
}
|
package/src/dev/local.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fork } from "node:child_process";
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
3
|
import { writeFile } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
@@ -13,7 +13,7 @@ import type { AssetPaths } from "../sites";
|
|
|
13
13
|
import type { CfWorkerInit, CfScriptFormat } from "../worker";
|
|
14
14
|
import type { EsbuildBundle } from "./use-esbuild";
|
|
15
15
|
import type { MiniflareOptions } from "miniflare";
|
|
16
|
-
|
|
16
|
+
import type { ChildProcess } from "node:child_process";
|
|
17
17
|
interface LocalProps {
|
|
18
18
|
name: string | undefined;
|
|
19
19
|
bundle: EsbuildBundle | undefined;
|
|
@@ -67,7 +67,7 @@ function useLocalWorker({
|
|
|
67
67
|
logLevel,
|
|
68
68
|
}: LocalProps) {
|
|
69
69
|
// TODO: pass vars via command line
|
|
70
|
-
const local = useRef<
|
|
70
|
+
const local = useRef<ChildProcess>();
|
|
71
71
|
const removeSignalExitListener = useRef<() => void>();
|
|
72
72
|
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
73
73
|
// if we're using local persistence for data, we should use the cwd
|
|
@@ -187,6 +187,7 @@ function useLocalWorker({
|
|
|
187
187
|
compatibilityDate,
|
|
188
188
|
compatibilityFlags,
|
|
189
189
|
kvNamespaces: bindings.kv_namespaces?.map((kv) => kv.binding),
|
|
190
|
+
r2Buckets: bindings.r2_buckets?.map((r2) => r2.binding),
|
|
190
191
|
durableObjects: Object.fromEntries(
|
|
191
192
|
(bindings.durable_objects?.bindings ?? []).map<[string, string]>(
|
|
192
193
|
(value) => [value.name, value.class_name]
|
|
@@ -194,9 +195,10 @@ function useLocalWorker({
|
|
|
194
195
|
),
|
|
195
196
|
...(localPersistencePath
|
|
196
197
|
? {
|
|
197
|
-
kvPersist: path.join(localPersistencePath, "kv"),
|
|
198
|
-
durableObjectsPersist: path.join(localPersistencePath, "do"),
|
|
199
198
|
cachePersist: path.join(localPersistencePath, "cache"),
|
|
199
|
+
durableObjectsPersist: path.join(localPersistencePath, "do"),
|
|
200
|
+
kvPersist: path.join(localPersistencePath, "kv"),
|
|
201
|
+
r2Persist: path.join(localPersistencePath, "r2"),
|
|
200
202
|
}
|
|
201
203
|
: {
|
|
202
204
|
// We mark these as true, so that they'll
|
|
@@ -204,9 +206,10 @@ function useLocalWorker({
|
|
|
204
206
|
// This means they'll persist across a dev session,
|
|
205
207
|
// even if we change source and reload,
|
|
206
208
|
// and be deleted when the dev session ends
|
|
207
|
-
durableObjectsPersist: true,
|
|
208
209
|
cachePersist: true,
|
|
210
|
+
durableObjectsPersist: true,
|
|
209
211
|
kvPersist: true,
|
|
212
|
+
r2Persist: true,
|
|
210
213
|
}),
|
|
211
214
|
|
|
212
215
|
sitePath: assetPaths?.assetDirectory
|
|
@@ -236,43 +239,45 @@ function useLocalWorker({
|
|
|
236
239
|
__dirname,
|
|
237
240
|
"../miniflare-dist/index.mjs"
|
|
238
241
|
);
|
|
239
|
-
const
|
|
242
|
+
const miniflareOptions = JSON.stringify(options, null);
|
|
240
243
|
|
|
241
244
|
logger.log("⎔ Starting a local server...");
|
|
242
|
-
const
|
|
245
|
+
const nodeOptions = [
|
|
243
246
|
"--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
|
|
244
247
|
"--no-warnings", // hide annoying Node warnings
|
|
245
|
-
miniflareCLIPath,
|
|
246
|
-
optionsArg,
|
|
247
248
|
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
248
249
|
];
|
|
249
250
|
if (inspect) {
|
|
250
|
-
|
|
251
|
+
nodeOptions.push("--inspect"); // start Miniflare listening for a debugger to attach
|
|
251
252
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
const child = (local.current = fork(
|
|
254
|
+
miniflareCLIPath,
|
|
255
|
+
[miniflareOptions],
|
|
256
|
+
{
|
|
257
|
+
cwd: path.dirname(scriptPath),
|
|
258
|
+
execArgv: nodeOptions,
|
|
259
|
+
}
|
|
260
|
+
));
|
|
261
|
+
child.on("message", (message) => {
|
|
262
|
+
if (message === "ready") {
|
|
263
|
+
onReady?.();
|
|
264
|
+
}
|
|
255
265
|
});
|
|
256
|
-
//TODO: instead of being lucky with spawn's timing, have miniflare-cli notify wrangler that it's ready in packages/wrangler/src/miniflare-cli/index.ts, after the mf.startScheduler promise resolves
|
|
257
|
-
if (onReady) {
|
|
258
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
259
|
-
onReady();
|
|
260
|
-
}
|
|
261
266
|
|
|
262
|
-
|
|
267
|
+
child.on("close", (code) => {
|
|
263
268
|
if (code) {
|
|
264
269
|
logger.log(`Miniflare process exited with code ${code}`);
|
|
265
270
|
}
|
|
266
271
|
});
|
|
267
272
|
|
|
268
|
-
|
|
273
|
+
child.stdout?.on("data", (data: Buffer) => {
|
|
269
274
|
process.stdout.write(data);
|
|
270
275
|
});
|
|
271
276
|
|
|
272
277
|
// parse the node inspector url (which may be received in chunks) from stderr
|
|
273
278
|
let stderrData = "";
|
|
274
279
|
let inspectorUrlFound = false;
|
|
275
|
-
|
|
280
|
+
child.stderr?.on("data", (data: Buffer) => {
|
|
276
281
|
if (!inspectorUrlFound) {
|
|
277
282
|
stderrData += data.toString();
|
|
278
283
|
const matches =
|
|
@@ -288,20 +293,20 @@ function useLocalWorker({
|
|
|
288
293
|
process.stderr.write(data);
|
|
289
294
|
});
|
|
290
295
|
|
|
291
|
-
|
|
296
|
+
child.on("exit", (code) => {
|
|
292
297
|
if (code) {
|
|
293
298
|
logger.error(`Miniflare process exited with code ${code}`);
|
|
294
299
|
}
|
|
295
300
|
});
|
|
296
301
|
|
|
297
|
-
|
|
302
|
+
child.on("error", (error: Error) => {
|
|
298
303
|
logger.error(`Miniflare process failed to spawn`);
|
|
299
304
|
logger.error(error);
|
|
300
305
|
});
|
|
301
306
|
|
|
302
307
|
removeSignalExitListener.current = onExit((_code, _signal) => {
|
|
303
308
|
logger.log("⎔ Shutting down local server.");
|
|
304
|
-
|
|
309
|
+
child.kill();
|
|
305
310
|
local.current = undefined;
|
|
306
311
|
});
|
|
307
312
|
}
|
|
@@ -328,6 +333,7 @@ function useLocalWorker({
|
|
|
328
333
|
ip,
|
|
329
334
|
bindings.durable_objects?.bindings,
|
|
330
335
|
bindings.kv_namespaces,
|
|
336
|
+
bindings.r2_buckets,
|
|
331
337
|
bindings.vars,
|
|
332
338
|
bindings.services,
|
|
333
339
|
compatibilityDate,
|
package/src/dev/remote.tsx
CHANGED
|
@@ -53,7 +53,7 @@ export function Remote(props: {
|
|
|
53
53
|
zone: string | undefined;
|
|
54
54
|
host: string | undefined;
|
|
55
55
|
routes: Route[] | undefined;
|
|
56
|
-
onReady?: () => void;
|
|
56
|
+
onReady?: (() => void) | undefined;
|
|
57
57
|
}) {
|
|
58
58
|
const [accountId, setAccountId] = useState(props.accountId);
|
|
59
59
|
const accountChoicesRef = useRef<Promise<ChooseAccountItem[]>>();
|
|
@@ -158,7 +158,7 @@ export function useWorker(props: {
|
|
|
158
158
|
zone: string | undefined;
|
|
159
159
|
host: string | undefined;
|
|
160
160
|
routes: Route[] | undefined;
|
|
161
|
-
onReady
|
|
161
|
+
onReady: (() => void) | undefined;
|
|
162
162
|
}): CfPreviewToken | undefined {
|
|
163
163
|
const {
|
|
164
164
|
name,
|