wrangler 2.0.26 → 2.0.29
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 +1 -1
- package/miniflare-dist/index.mjs +54 -46
- package/package.json +6 -4
- package/src/__tests__/api-dev.test.ts +19 -0
- package/src/__tests__/configuration.test.ts +33 -29
- package/src/__tests__/dev.test.tsx +8 -6
- package/src/__tests__/generate.test.ts +2 -4
- package/src/__tests__/helpers/hello-world-worker.js +5 -0
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
- package/src/__tests__/helpers/mock-known-routes.ts +7 -0
- package/src/__tests__/index.test.ts +30 -30
- package/src/__tests__/jest.setup.ts +17 -0
- package/src/__tests__/metrics.test.ts +1 -1
- package/src/__tests__/pages.test.ts +829 -103
- package/src/__tests__/paths.test.ts +17 -0
- package/src/__tests__/publish.test.ts +59 -18
- package/src/__tests__/r2.test.ts +4 -3
- package/src/__tests__/tail.test.ts +34 -0
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/user.test.ts +11 -0
- package/src/__tests__/worker-namespace.test.ts +37 -35
- package/src/api/dev.ts +74 -28
- package/src/bundle.ts +14 -11
- package/src/cfetch/internal.ts +81 -3
- package/src/cli.ts +1 -1
- package/src/config/environment.ts +1 -1
- package/src/config/index.ts +4 -4
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +11 -5
- package/src/config-cache.ts +2 -1
- package/src/create-worker-upload-form.ts +29 -26
- package/src/dev/local.tsx +317 -169
- package/src/dev/remote.tsx +10 -1
- package/src/dev/start-server.ts +412 -0
- package/src/dev.tsx +341 -157
- package/src/{worker-namespace.ts → dispatch-namespace.ts} +18 -18
- package/src/entry.ts +2 -1
- package/src/generate.ts +1 -1
- package/src/index.tsx +54 -8
- package/src/init.ts +5 -5
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/metrics/metrics-config.ts +1 -1
- package/src/metrics/send-event.ts +6 -5
- package/src/miniflare-cli/assets.ts +4 -65
- package/src/miniflare-cli/index.ts +36 -32
- package/src/pages/constants.ts +3 -0
- package/src/pages/dev.tsx +10 -15
- package/src/pages/functions/buildPlugin.ts +2 -1
- package/src/pages/functions/buildWorker.ts +2 -1
- package/src/pages/functions/routes-transformation.test.ts +12 -1
- package/src/pages/functions/routes-transformation.ts +7 -1
- package/src/pages/publish.tsx +82 -38
- package/src/paths.ts +20 -1
- package/src/proxy.ts +10 -0
- package/src/publish.ts +19 -4
- package/src/r2.ts +4 -4
- package/src/user/user.tsx +6 -4
- package/src/whoami.tsx +5 -5
- package/src/worker.ts +10 -9
- package/src/zones.ts +91 -0
- package/wrangler-dist/cli.d.ts +22 -8
- package/wrangler-dist/cli.js +7757 -2315
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { getBasePath } from "../paths";
|
|
3
|
+
|
|
4
|
+
describe("paths", () => {
|
|
5
|
+
describe("getBasePath()", () => {
|
|
6
|
+
it("should return the path to the wrangler package", () => {
|
|
7
|
+
expect(getBasePath()).toMatch(/packages[/\\]wrangler$/);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("should use the __RELATIVE_PACKAGE_PATH__ as defined on the global context to compute the base path", () => {
|
|
11
|
+
(
|
|
12
|
+
global as unknown as { __RELATIVE_PACKAGE_PATH__: string }
|
|
13
|
+
).__RELATIVE_PACKAGE_PATH__ = "/foo/bar";
|
|
14
|
+
expect(getBasePath()).toEqual(path.resolve("/foo/bar"));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
} from "./helpers/mock-cfetch";
|
|
14
14
|
import { mockConsoleMethods, normalizeSlashes } from "./helpers/mock-console";
|
|
15
15
|
import { mockConfirm } from "./helpers/mock-dialogs";
|
|
16
|
+
import { mockGetZoneFromHostRequest } from "./helpers/mock-get-zone-from-host";
|
|
16
17
|
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
18
|
+
import { mockCollectKnownRoutesRequest } from "./helpers/mock-known-routes";
|
|
17
19
|
import { mockKeyListRequest } from "./helpers/mock-kv";
|
|
18
20
|
import { mockGetMemberships, mockOAuthFlow } from "./helpers/mock-oauth-flow";
|
|
19
21
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
@@ -3615,6 +3617,32 @@ addEventListener('fetch', event => {});`
|
|
|
3615
3617
|
"
|
|
3616
3618
|
`);
|
|
3617
3619
|
});
|
|
3620
|
+
|
|
3621
|
+
it("can be overridden with cli args", async () => {
|
|
3622
|
+
writeWranglerToml({
|
|
3623
|
+
main: "index.js",
|
|
3624
|
+
define: {
|
|
3625
|
+
abc: "123",
|
|
3626
|
+
},
|
|
3627
|
+
});
|
|
3628
|
+
fs.writeFileSync(
|
|
3629
|
+
"index.js",
|
|
3630
|
+
`
|
|
3631
|
+
console.log(abc);
|
|
3632
|
+
`
|
|
3633
|
+
);
|
|
3634
|
+
mockSubDomainRequest();
|
|
3635
|
+
mockUploadWorkerRequest();
|
|
3636
|
+
await runWrangler("publish --dry-run --outdir dist --define abc:789");
|
|
3637
|
+
expect(fs.readFileSync("dist/index.js", "utf-8")).toMatchInlineSnapshot(`
|
|
3638
|
+
"(() => {
|
|
3639
|
+
// index.js
|
|
3640
|
+
console.log(789);
|
|
3641
|
+
})();
|
|
3642
|
+
//# sourceMappingURL=index.js.map
|
|
3643
|
+
"
|
|
3644
|
+
`);
|
|
3645
|
+
});
|
|
3618
3646
|
});
|
|
3619
3647
|
|
|
3620
3648
|
describe("custom builds", () => {
|
|
@@ -5232,6 +5260,29 @@ addEventListener('fetch', event => {});`
|
|
|
5232
5260
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
5233
5261
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
5234
5262
|
});
|
|
5263
|
+
|
|
5264
|
+
it("should read vars passed as cli arguments", async () => {
|
|
5265
|
+
writeWranglerToml();
|
|
5266
|
+
writeWorkerSource();
|
|
5267
|
+
mockSubDomainRequest();
|
|
5268
|
+
mockUploadWorkerRequest();
|
|
5269
|
+
await runWrangler("publish index.js --var TEXT:sometext --var COUNT:1");
|
|
5270
|
+
expect(std).toMatchInlineSnapshot(`
|
|
5271
|
+
Object {
|
|
5272
|
+
"debug": "",
|
|
5273
|
+
"err": "",
|
|
5274
|
+
"out": "Your worker has access to the following bindings:
|
|
5275
|
+
- Vars:
|
|
5276
|
+
- TEXT: \\"(hidden)\\"
|
|
5277
|
+
- COUNT: \\"(hidden)\\"
|
|
5278
|
+
Total Upload: 0xx KiB / gzip: 0xx KiB
|
|
5279
|
+
Uploaded test-name (TIMINGS)
|
|
5280
|
+
Published test-name (TIMINGS)
|
|
5281
|
+
https://test-name.test-sub-domain.workers.dev",
|
|
5282
|
+
"warn": "",
|
|
5283
|
+
}
|
|
5284
|
+
`);
|
|
5285
|
+
});
|
|
5235
5286
|
});
|
|
5236
5287
|
|
|
5237
5288
|
describe("[r2_buckets]", () => {
|
|
@@ -5514,10 +5565,10 @@ addEventListener('fetch', event => {});`
|
|
|
5514
5565
|
});
|
|
5515
5566
|
});
|
|
5516
5567
|
|
|
5517
|
-
describe("[
|
|
5518
|
-
it("should support bindings to a
|
|
5568
|
+
describe("[dispatch_namespaces]", () => {
|
|
5569
|
+
it("should support bindings to a dispatch namespace", async () => {
|
|
5519
5570
|
writeWranglerToml({
|
|
5520
|
-
|
|
5571
|
+
dispatch_namespaces: [
|
|
5521
5572
|
{
|
|
5522
5573
|
binding: "foo",
|
|
5523
5574
|
namespace: "Foo",
|
|
@@ -5538,7 +5589,7 @@ addEventListener('fetch', event => {});`
|
|
|
5538
5589
|
await runWrangler("publish index.js");
|
|
5539
5590
|
expect(std.out).toMatchInlineSnapshot(`
|
|
5540
5591
|
"Your worker has access to the following bindings:
|
|
5541
|
-
-
|
|
5592
|
+
- dispatch namespaces:
|
|
5542
5593
|
- foo: Foo
|
|
5543
5594
|
Total Upload: 0xx KiB / gzip: 0xx KiB
|
|
5544
5595
|
Uploaded test-name (TIMINGS)
|
|
@@ -5549,7 +5600,7 @@ addEventListener('fetch', event => {});`
|
|
|
5549
5600
|
expect(std.warn).toMatchInlineSnapshot(`
|
|
5550
5601
|
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mProcessing wrangler.toml configuration:[0m
|
|
5551
5602
|
|
|
5552
|
-
- \\"
|
|
5603
|
+
- \\"dispatch_namespaces\\" fields are experimental and may change or break at any time.
|
|
5553
5604
|
|
|
5554
5605
|
"
|
|
5555
5606
|
`);
|
|
@@ -6487,6 +6538,9 @@ function mockUploadWorkerRequest(
|
|
|
6487
6538
|
} else {
|
|
6488
6539
|
expect(metadata.body_part).toEqual("index.js");
|
|
6489
6540
|
}
|
|
6541
|
+
|
|
6542
|
+
expect(metadata.keep_bindings).toEqual(["plain_text", "json"]);
|
|
6543
|
+
|
|
6490
6544
|
if ("expectedBindings" in options) {
|
|
6491
6545
|
expect(metadata.bindings).toEqual(expectedBindings);
|
|
6492
6546
|
}
|
|
@@ -6622,19 +6676,6 @@ function mockUnauthorizedPublishRoutesRequest({
|
|
|
6622
6676
|
);
|
|
6623
6677
|
}
|
|
6624
6678
|
|
|
6625
|
-
function mockCollectKnownRoutesRequest(
|
|
6626
|
-
routes: { pattern: string; script: string }[]
|
|
6627
|
-
) {
|
|
6628
|
-
setMockResponse(`/zones/:zoneId/workers/routes`, "GET", () => routes);
|
|
6629
|
-
}
|
|
6630
|
-
|
|
6631
|
-
function mockGetZoneFromHostRequest(host: string, zone: string) {
|
|
6632
|
-
setMockResponse("/zones", (_uri, _init, queryParams) => {
|
|
6633
|
-
expect(queryParams.get("name")).toEqual(host);
|
|
6634
|
-
return [{ id: zone }];
|
|
6635
|
-
});
|
|
6636
|
-
}
|
|
6637
|
-
|
|
6638
6679
|
function mockPublishRoutesFallbackRequest(route: {
|
|
6639
6680
|
pattern: string;
|
|
6640
6681
|
script: string;
|
package/src/__tests__/r2.test.ts
CHANGED
|
@@ -82,10 +82,11 @@ describe("wrangler", () => {
|
|
|
82
82
|
function mockCreateRequest(expectedBucketName: string) {
|
|
83
83
|
const requests = { count: 0 };
|
|
84
84
|
setMockResponse(
|
|
85
|
-
"/accounts/:accountId/r2/buckets
|
|
86
|
-
"
|
|
87
|
-
([_url, accountId,
|
|
85
|
+
"/accounts/:accountId/r2/buckets",
|
|
86
|
+
"POST",
|
|
87
|
+
([_url, accountId], { body }) => {
|
|
88
88
|
expect(accountId).toEqual("some-account-id");
|
|
89
|
+
const bucketName = JSON.parse(body as string).name;
|
|
89
90
|
expect(bucketName).toEqual(expectedBucketName);
|
|
90
91
|
requests.count += 1;
|
|
91
92
|
}
|
|
@@ -3,7 +3,9 @@ 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 { mockGetZoneFromHostRequest } from "./helpers/mock-get-zone-from-host";
|
|
6
7
|
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
8
|
+
import { mockCollectKnownRoutesRequest } from "./helpers/mock-known-routes";
|
|
7
9
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
8
10
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
9
11
|
import type {
|
|
@@ -53,6 +55,38 @@ describe("tail", () => {
|
|
|
53
55
|
api.ws.close();
|
|
54
56
|
expect(api.requests.deletion.count).toStrictEqual(1);
|
|
55
57
|
});
|
|
58
|
+
it("should connect to the worker assigned to a given route", async () => {
|
|
59
|
+
const api = mockWebsocketAPIs();
|
|
60
|
+
expect(api.requests.creation.count).toStrictEqual(0);
|
|
61
|
+
|
|
62
|
+
mockGetZoneFromHostRequest("example.com", "test-zone");
|
|
63
|
+
mockCollectKnownRoutesRequest([
|
|
64
|
+
{
|
|
65
|
+
pattern: "example.com/*",
|
|
66
|
+
script: "test-worker",
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
await runWrangler("tail example.com/*");
|
|
70
|
+
|
|
71
|
+
await expect(api.ws.connected).resolves.toBeTruthy();
|
|
72
|
+
expect(api.requests.creation.count).toStrictEqual(1);
|
|
73
|
+
expect(api.requests.deletion.count).toStrictEqual(0);
|
|
74
|
+
|
|
75
|
+
api.ws.close();
|
|
76
|
+
expect(api.requests.deletion.count).toStrictEqual(1);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should error if a given route is not assigned to the user's zone", async () => {
|
|
80
|
+
mockGetZoneFromHostRequest("example.com", "test-zone");
|
|
81
|
+
mockCollectKnownRoutesRequest([]);
|
|
82
|
+
|
|
83
|
+
await expect(runWrangler("tail example.com/*")).rejects.toThrow();
|
|
84
|
+
});
|
|
85
|
+
it("should error if a given route is not within the user's zone", async () => {
|
|
86
|
+
mockGetZoneFromHostRequest("example.com");
|
|
87
|
+
|
|
88
|
+
await expect(runWrangler("tail example.com/*")).rejects.toThrow();
|
|
89
|
+
});
|
|
56
90
|
|
|
57
91
|
it("creates and then delete tails: legacy envs", async () => {
|
|
58
92
|
const api = mockWebsocketAPIs("some-env", true);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// this test has to be run with a version of node.js older than 16.
|
|
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.
|
|
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.
|
|
28
|
+
"This test has to be run with a version of node.js under 16.13 to pass"
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fetchMock from "jest-fetch-mock";
|
|
4
4
|
import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
|
|
5
|
+
import { CI } from "../is-ci";
|
|
5
6
|
import {
|
|
6
7
|
loginOrRefreshIfRequired,
|
|
7
8
|
readAuthConfigFile,
|
|
@@ -18,6 +19,7 @@ import type { Config } from "../config";
|
|
|
18
19
|
import type { UserAuthConfig } from "../user";
|
|
19
20
|
|
|
20
21
|
describe("User", () => {
|
|
22
|
+
let isCISpy: jest.SpyInstance;
|
|
21
23
|
runInTempDir();
|
|
22
24
|
const std = mockConsoleMethods();
|
|
23
25
|
const {
|
|
@@ -30,6 +32,10 @@ describe("User", () => {
|
|
|
30
32
|
|
|
31
33
|
const { setIsTTY } = useMockIsTTY();
|
|
32
34
|
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
isCISpy = jest.spyOn(CI, "isCI").mockReturnValue(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
33
39
|
describe("login", () => {
|
|
34
40
|
it("should login a user when `wrangler login` is run", async () => {
|
|
35
41
|
mockOAuthServerCallback();
|
|
@@ -132,6 +138,11 @@ describe("User", () => {
|
|
|
132
138
|
expect(std.err).toContain("");
|
|
133
139
|
});
|
|
134
140
|
|
|
141
|
+
it("should revert to non-interactive mode if in CI", async () => {
|
|
142
|
+
isCISpy.mockReturnValue(true);
|
|
143
|
+
await expect(loginOrRefreshIfRequired()).resolves.toEqual(false);
|
|
144
|
+
});
|
|
145
|
+
|
|
135
146
|
it("should revert to non-interactive mode if isTTY throws an error", async () => {
|
|
136
147
|
setIsTTY({
|
|
137
148
|
stdin() {
|
|
@@ -4,7 +4,7 @@ import { mockConsoleMethods } from "./helpers/mock-console";
|
|
|
4
4
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
5
5
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
6
6
|
|
|
7
|
-
describe("
|
|
7
|
+
describe("dispatch-namespace", () => {
|
|
8
8
|
runInTempDir();
|
|
9
9
|
const std = mockConsoleMethods();
|
|
10
10
|
mockAccountId();
|
|
@@ -14,8 +14,8 @@ describe("worker-namespace", () => {
|
|
|
14
14
|
unsetAllMocks();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it("should should display a list of available subcommands, for
|
|
18
|
-
await runWrangler("
|
|
17
|
+
it("should should display a list of available subcommands, for dispatch-namespace with no subcommand", async () => {
|
|
18
|
+
await runWrangler("dispatch-namespace");
|
|
19
19
|
|
|
20
20
|
// wait a tick for the help menu to be printed
|
|
21
21
|
await new Promise((resolve) => setImmediate(resolve));
|
|
@@ -24,16 +24,16 @@ describe("worker-namespace", () => {
|
|
|
24
24
|
Object {
|
|
25
25
|
"debug": "",
|
|
26
26
|
"err": "",
|
|
27
|
-
"out": "wrangler
|
|
27
|
+
"out": "wrangler dispatch-namespace
|
|
28
28
|
|
|
29
|
-
📦 Interact with a
|
|
29
|
+
📦 Interact with a dispatch namespace
|
|
30
30
|
|
|
31
31
|
Commands:
|
|
32
|
-
wrangler
|
|
33
|
-
wrangler
|
|
34
|
-
wrangler
|
|
35
|
-
wrangler
|
|
36
|
-
wrangler
|
|
32
|
+
wrangler dispatch-namespace list List all dispatch namespaces
|
|
33
|
+
wrangler dispatch-namespace get <name> Get information about a dispatch namespace
|
|
34
|
+
wrangler dispatch-namespace create <name> Create a dispatch namespace
|
|
35
|
+
wrangler dispatch-namespace delete <name> Delete a dispatch namespace
|
|
36
|
+
wrangler dispatch-namespace rename <old-name> <new-name> Rename a dispatch namespace
|
|
37
37
|
|
|
38
38
|
Flags:
|
|
39
39
|
-c, --config Path to .toml configuration file [string]
|
|
@@ -73,19 +73,19 @@ describe("worker-namespace", () => {
|
|
|
73
73
|
|
|
74
74
|
it("should display help for create", async () => {
|
|
75
75
|
await expect(
|
|
76
|
-
runWrangler("
|
|
76
|
+
runWrangler("dispatch-namespace create")
|
|
77
77
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
78
78
|
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
79
79
|
);
|
|
80
80
|
|
|
81
81
|
expect(std.out).toMatchInlineSnapshot(`
|
|
82
82
|
"
|
|
83
|
-
wrangler
|
|
83
|
+
wrangler dispatch-namespace create <name>
|
|
84
84
|
|
|
85
|
-
Create a
|
|
85
|
+
Create a dispatch namespace
|
|
86
86
|
|
|
87
87
|
Positionals:
|
|
88
|
-
name Name of the
|
|
88
|
+
name Name of the dispatch namespace [string] [required]
|
|
89
89
|
|
|
90
90
|
Flags:
|
|
91
91
|
-c, --config Path to .toml configuration file [string]
|
|
@@ -97,11 +97,11 @@ describe("worker-namespace", () => {
|
|
|
97
97
|
it("should attempt to create the given namespace", async () => {
|
|
98
98
|
const namespaceName = "my-namespace";
|
|
99
99
|
const requests = mockCreateRequest(namespaceName);
|
|
100
|
-
await runWrangler(`
|
|
100
|
+
await runWrangler(`dispatch-namespace create ${namespaceName}`);
|
|
101
101
|
expect(requests.count).toEqual(1);
|
|
102
102
|
|
|
103
103
|
expect(std.out).toMatchInlineSnapshot(
|
|
104
|
-
`"Created
|
|
104
|
+
`"Created dispatch namespace \\"my-namespace\\" with ID \\"some-namespace-id\\""`
|
|
105
105
|
);
|
|
106
106
|
});
|
|
107
107
|
});
|
|
@@ -125,19 +125,19 @@ describe("worker-namespace", () => {
|
|
|
125
125
|
|
|
126
126
|
it("should display help for delete", async () => {
|
|
127
127
|
await expect(
|
|
128
|
-
runWrangler("
|
|
128
|
+
runWrangler("dispatch-namespace create")
|
|
129
129
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
130
130
|
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
131
131
|
);
|
|
132
132
|
|
|
133
133
|
expect(std.out).toMatchInlineSnapshot(`
|
|
134
134
|
"
|
|
135
|
-
wrangler
|
|
135
|
+
wrangler dispatch-namespace create <name>
|
|
136
136
|
|
|
137
|
-
Create a
|
|
137
|
+
Create a dispatch namespace
|
|
138
138
|
|
|
139
139
|
Positionals:
|
|
140
|
-
name Name of the
|
|
140
|
+
name Name of the dispatch namespace [string] [required]
|
|
141
141
|
|
|
142
142
|
Flags:
|
|
143
143
|
-c, --config Path to .toml configuration file [string]
|
|
@@ -149,11 +149,11 @@ describe("worker-namespace", () => {
|
|
|
149
149
|
it("should try to delete the given namespace", async () => {
|
|
150
150
|
const namespaceName = "my-namespace";
|
|
151
151
|
const requests = mockDeleteRequest(namespaceName);
|
|
152
|
-
await runWrangler(`
|
|
152
|
+
await runWrangler(`dispatch-namespace delete ${namespaceName}`);
|
|
153
153
|
expect(requests.count).toBe(1);
|
|
154
154
|
|
|
155
155
|
expect(std.out).toMatchInlineSnapshot(
|
|
156
|
-
`"Deleted
|
|
156
|
+
`"Deleted dispatch namespace \\"my-namespace\\""`
|
|
157
157
|
);
|
|
158
158
|
});
|
|
159
159
|
});
|
|
@@ -183,19 +183,19 @@ describe("worker-namespace", () => {
|
|
|
183
183
|
|
|
184
184
|
it("should display help for get", async () => {
|
|
185
185
|
await expect(
|
|
186
|
-
runWrangler("
|
|
186
|
+
runWrangler("dispatch-namespace get")
|
|
187
187
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
188
188
|
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
189
189
|
);
|
|
190
190
|
|
|
191
191
|
expect(std.out).toMatchInlineSnapshot(`
|
|
192
192
|
"
|
|
193
|
-
wrangler
|
|
193
|
+
wrangler dispatch-namespace get <name>
|
|
194
194
|
|
|
195
|
-
Get information about a
|
|
195
|
+
Get information about a dispatch namespace
|
|
196
196
|
|
|
197
197
|
Positionals:
|
|
198
|
-
name Name of the
|
|
198
|
+
name Name of the dispatch namespace [string] [required]
|
|
199
199
|
|
|
200
200
|
Flags:
|
|
201
201
|
-c, --config Path to .toml configuration file [string]
|
|
@@ -207,7 +207,7 @@ describe("worker-namespace", () => {
|
|
|
207
207
|
it("should attempt to get info for the given namespace", async () => {
|
|
208
208
|
const namespaceName = "my-namespace";
|
|
209
209
|
const requests = mockInfoRequest(namespaceName);
|
|
210
|
-
await runWrangler(`
|
|
210
|
+
await runWrangler(`dispatch-namespace get ${namespaceName}`);
|
|
211
211
|
expect(requests.count).toBe(1);
|
|
212
212
|
|
|
213
213
|
expect(std.out).toMatchInlineSnapshot(`
|
|
@@ -248,7 +248,7 @@ describe("worker-namespace", () => {
|
|
|
248
248
|
|
|
249
249
|
it("should list all namespaces", async () => {
|
|
250
250
|
const requests = mockListRequest();
|
|
251
|
-
await runWrangler("
|
|
251
|
+
await runWrangler("dispatch-namespace list");
|
|
252
252
|
expect(requests.count).toBe(1);
|
|
253
253
|
expect(std.out).toMatchInlineSnapshot(`
|
|
254
254
|
"[
|
|
@@ -291,20 +291,20 @@ describe("worker-namespace", () => {
|
|
|
291
291
|
|
|
292
292
|
it("should display help for rename", async () => {
|
|
293
293
|
await expect(
|
|
294
|
-
runWrangler("
|
|
294
|
+
runWrangler("dispatch-namespace rename")
|
|
295
295
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
296
296
|
`"Not enough non-option arguments: got 0, need at least 2"`
|
|
297
297
|
);
|
|
298
298
|
|
|
299
299
|
expect(std.out).toMatchInlineSnapshot(`
|
|
300
300
|
"
|
|
301
|
-
wrangler
|
|
301
|
+
wrangler dispatch-namespace rename <old-name> <new-name>
|
|
302
302
|
|
|
303
|
-
Rename a
|
|
303
|
+
Rename a dispatch namespace
|
|
304
304
|
|
|
305
305
|
Positionals:
|
|
306
|
-
old-name Name of the
|
|
307
|
-
new-name New name of the
|
|
306
|
+
old-name Name of the dispatch namespace [string] [required]
|
|
307
|
+
new-name New name of the dispatch namespace [string] [required]
|
|
308
308
|
|
|
309
309
|
Flags:
|
|
310
310
|
-c, --config Path to .toml configuration file [string]
|
|
@@ -317,10 +317,12 @@ describe("worker-namespace", () => {
|
|
|
317
317
|
const namespaceName = "my-namespace";
|
|
318
318
|
const newName = "new-namespace";
|
|
319
319
|
const requests = mockRenameRequest(namespaceName);
|
|
320
|
-
await runWrangler(
|
|
320
|
+
await runWrangler(
|
|
321
|
+
`dispatch-namespace rename ${namespaceName} ${newName}`
|
|
322
|
+
);
|
|
321
323
|
expect(requests.count).toBe(1);
|
|
322
324
|
expect(std.out).toMatchInlineSnapshot(
|
|
323
|
-
`"Renamed
|
|
325
|
+
`"Renamed dispatch namespace \\"my-namespace\\" to \\"new-namespace\\""`
|
|
324
326
|
);
|
|
325
327
|
});
|
|
326
328
|
});
|
package/src/api/dev.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { startDev } from "../dev";
|
|
1
|
+
import { startApiDev, startDev } from "../dev";
|
|
2
2
|
import { logger } from "../logger";
|
|
3
3
|
|
|
4
4
|
import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
|
|
5
5
|
import type { RequestInit, Response } from "undici";
|
|
6
6
|
|
|
7
7
|
interface DevOptions {
|
|
8
|
+
config?: string;
|
|
8
9
|
env?: string;
|
|
9
10
|
ip?: string;
|
|
10
11
|
port?: number;
|
|
@@ -20,7 +21,7 @@ interface DevOptions {
|
|
|
20
21
|
experimentalEnableLocalPersistence?: boolean;
|
|
21
22
|
liveReload?: boolean;
|
|
22
23
|
watch?: boolean;
|
|
23
|
-
vars
|
|
24
|
+
vars?: {
|
|
24
25
|
[key: string]: unknown;
|
|
25
26
|
};
|
|
26
27
|
kv?: {
|
|
@@ -48,46 +49,91 @@ interface DevOptions {
|
|
|
48
49
|
_?: (string | number)[]; //yargs wants this
|
|
49
50
|
$0?: string; //yargs wants this
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
interface DevApiOptions {
|
|
54
|
+
testMode?: boolean;
|
|
55
|
+
disableExperimentalWarning?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface UnstableDev {
|
|
59
|
+
stop: () => Promise<void>;
|
|
60
|
+
fetch: (init?: RequestInit) => Promise<Response | undefined>;
|
|
61
|
+
waitUntilExit: () => Promise<void>;
|
|
62
|
+
}
|
|
51
63
|
/**
|
|
52
64
|
* unstable_dev starts a wrangler dev server, and returns a promise that resolves with utility functions to interact with it.
|
|
53
65
|
* @param {string} script
|
|
54
66
|
* @param {DevOptions} options
|
|
67
|
+
* @param {DevApiOptions} apiOptions
|
|
68
|
+
* @returns {Promise<UnstableDev>}
|
|
55
69
|
*/
|
|
56
70
|
export async function unstable_dev(
|
|
57
71
|
script: string,
|
|
58
|
-
options
|
|
59
|
-
|
|
72
|
+
options?: DevOptions,
|
|
73
|
+
apiOptions?: DevApiOptions
|
|
60
74
|
) {
|
|
75
|
+
const { testMode = true, disableExperimentalWarning = false } =
|
|
76
|
+
apiOptions || {};
|
|
61
77
|
if (!disableExperimentalWarning) {
|
|
62
78
|
logger.warn(
|
|
63
79
|
`unstable_dev() is experimental\nunstable_dev()'s behaviour will likely change in future releases`
|
|
64
80
|
);
|
|
65
81
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
//due to Pages adoption of unstable_dev, we can't *just* disable rebuilds and watching. instead, we'll have two versions of startDev, which will converge.
|
|
83
|
+
if (testMode) {
|
|
84
|
+
//in testMode, we can run multiple wranglers in parallel, but rebuilds might not work out of the box
|
|
85
|
+
return new Promise<UnstableDev>((resolve) => {
|
|
86
|
+
//lmao
|
|
87
|
+
return new Promise<Awaited<ReturnType<typeof startApiDev>>>((ready) => {
|
|
88
|
+
// once the devServer is ready for requests, we resolve the inner promise
|
|
89
|
+
// (where we've named the resolve function "ready")
|
|
90
|
+
const devServer = startApiDev({
|
|
91
|
+
script: script,
|
|
92
|
+
inspect: false,
|
|
93
|
+
logLevel: "none",
|
|
94
|
+
showInteractiveDevSession: false,
|
|
95
|
+
_: [],
|
|
96
|
+
$0: "",
|
|
97
|
+
...options,
|
|
98
|
+
local: true,
|
|
99
|
+
onReady: () => ready(devServer),
|
|
100
|
+
});
|
|
101
|
+
}).then((devServer) => {
|
|
102
|
+
// now that the inner promise has resolved, we can resolve the outer promise
|
|
103
|
+
// with an object that lets you fetch and stop the dev server
|
|
104
|
+
resolve({
|
|
105
|
+
stop: devServer.stop,
|
|
106
|
+
fetch: devServer.fetch,
|
|
107
|
+
//no-op, does nothing in tests
|
|
108
|
+
waitUntilExit: async () => {
|
|
109
|
+
return;
|
|
110
|
+
},
|
|
111
|
+
});
|
|
84
112
|
});
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
//outside of test mode, rebuilds work fine, but only one instance of wrangler will work at a time
|
|
116
|
+
return new Promise<UnstableDev>((resolve) => {
|
|
117
|
+
//lmao
|
|
118
|
+
return new Promise<Awaited<ReturnType<typeof startDev>>>((ready) => {
|
|
119
|
+
const devServer = startDev({
|
|
120
|
+
script: script,
|
|
121
|
+
inspect: false,
|
|
122
|
+
logLevel: "none",
|
|
123
|
+
showInteractiveDevSession: false,
|
|
124
|
+
_: [],
|
|
125
|
+
$0: "",
|
|
126
|
+
...options,
|
|
127
|
+
local: true,
|
|
128
|
+
onReady: () => ready(devServer),
|
|
129
|
+
});
|
|
130
|
+
}).then((devServer) => {
|
|
131
|
+
resolve({
|
|
132
|
+
stop: devServer.stop,
|
|
133
|
+
fetch: devServer.fetch,
|
|
134
|
+
waitUntilExit: devServer.devReactElement.waitUntilExit,
|
|
135
|
+
});
|
|
90
136
|
});
|
|
91
137
|
});
|
|
92
|
-
}
|
|
138
|
+
}
|
|
93
139
|
}
|