wrangler 0.0.0-e3cab74 → 0.0.0-e452a04
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/package.json +6 -4
- package/src/__tests__/configuration.test.ts +141 -109
- package/src/__tests__/dev.test.tsx +375 -83
- package/src/__tests__/dev2.test.tsx +152 -0
- package/src/__tests__/guess-worker-format.test.ts +9 -17
- package/src/__tests__/helpers/mock-account-id.ts +18 -4
- package/src/__tests__/helpers/mock-cfetch.ts +3 -3
- package/src/__tests__/helpers/mock-console.ts +17 -9
- package/src/__tests__/helpers/mock-stdin.ts +103 -0
- package/src/__tests__/https-options.test.ts +127 -0
- package/src/__tests__/index.test.ts +125 -0
- package/src/__tests__/jest.setup.ts +16 -4
- package/src/__tests__/kv.test.ts +321 -54
- package/src/__tests__/pages.test.ts +44 -0
- package/src/__tests__/publish.test.ts +299 -453
- package/src/__tests__/route.test.ts +45 -0
- package/src/__tests__/secret.test.ts +167 -68
- package/src/bundle.ts +20 -11
- package/src/cfetch/internal.ts +2 -0
- package/src/config/config.ts +53 -39
- package/src/config/validation-helpers.ts +30 -12
- package/src/config/validation.ts +49 -39
- package/src/{api/preview.ts → create-worker-preview.ts} +39 -20
- package/src/{api/form_data.ts → create-worker-upload-form.ts} +1 -1
- package/src/dev/dev.tsx +357 -0
- package/src/dev/local.tsx +241 -0
- package/src/dev/remote.tsx +201 -0
- package/src/dev/use-esbuild.ts +100 -0
- package/src/entry.ts +111 -9
- package/src/https-options.ts +122 -0
- package/src/index.tsx +447 -445
- package/src/inspect.ts +9 -1
- package/src/{kv.tsx → kv/index.tsx} +92 -28
- package/src/module-collection.ts +85 -2
- package/src/open-in-browser.ts +14 -2
- package/src/pages.tsx +1 -1
- package/src/proxy.ts +102 -40
- package/src/publish.ts +37 -53
- package/src/reporting.ts +25 -9
- package/src/selfsigned.d.ts +29 -0
- package/src/sites.tsx +3 -6
- package/src/user.tsx +21 -5
- package/src/{api/worker.ts → worker.ts} +1 -24
- package/wrangler-dist/cli.js +2815 -2690
- package/wrangler-dist/cli.js.map +3 -3
- package/src/dev.tsx +0 -961
- package/src/guess-worker-format.ts +0 -68
|
@@ -1,31 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import patchConsole from "patch-console";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
4
|
+
import Dev from "../dev/dev";
|
|
5
|
+
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
6
|
+
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
|
|
5
7
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
8
|
+
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
6
9
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
7
10
|
import writeWranglerToml from "./helpers/write-wrangler-toml";
|
|
8
|
-
import type { DevProps } from "../dev";
|
|
9
11
|
|
|
10
12
|
describe("Dev component", () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
mockAccountId();
|
|
14
|
+
mockApiToken();
|
|
15
|
+
runInTempDir();
|
|
14
16
|
const std = mockConsoleMethods();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const { lastFrame } = renderDev({
|
|
20
|
-
format: "service-worker",
|
|
21
|
-
accountId: "some-account-id",
|
|
22
|
-
public: "some/public/path",
|
|
23
|
-
});
|
|
24
|
-
expect(lastFrame()?.split("\n").slice(0, 2).join("\n"))
|
|
25
|
-
.toMatchInlineSnapshot(`
|
|
26
|
-
"Something went wrong:
|
|
27
|
-
Error: You cannot use the service worker format with a \`public\` directory."
|
|
28
|
-
`);
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
(Dev as jest.Mock).mockClear();
|
|
19
|
+
patchConsole(() => {});
|
|
20
|
+
unsetAllMocks();
|
|
29
21
|
});
|
|
30
22
|
|
|
31
23
|
describe("entry-points", () => {
|
|
@@ -42,72 +34,372 @@ describe("Dev component", () => {
|
|
|
42
34
|
expect(std.err).toMatchInlineSnapshot(`
|
|
43
35
|
"Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler dev path/to/script\`) or the \`main\` config field.
|
|
44
36
|
|
|
45
|
-
[32m%s[0m
|
|
46
|
-
|
|
37
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
38
|
+
`);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("host", () => {
|
|
43
|
+
it("should resolve a host to its zone", async () => {
|
|
44
|
+
writeWranglerToml({
|
|
45
|
+
main: "index.js",
|
|
46
|
+
});
|
|
47
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
48
|
+
mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
|
|
49
|
+
await runWrangler("dev --host some-host.com");
|
|
50
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
51
|
+
host: "some-host.com",
|
|
52
|
+
id: "some-zone-id",
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should read wrangler.toml's dev.host", async () => {
|
|
57
|
+
writeWranglerToml({
|
|
58
|
+
main: "index.js",
|
|
59
|
+
dev: {
|
|
60
|
+
host: "some-host.com",
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
64
|
+
mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
|
|
65
|
+
await runWrangler("dev");
|
|
66
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
|
|
67
|
+
"some-host.com"
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should read --route", async () => {
|
|
72
|
+
writeWranglerToml({
|
|
73
|
+
main: "index.js",
|
|
74
|
+
});
|
|
75
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
76
|
+
mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
|
|
77
|
+
await runWrangler("dev --route http://some-host.com/some/path/*");
|
|
78
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
|
|
79
|
+
"some-host.com"
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should read wrangler.toml's routes", async () => {
|
|
84
|
+
writeWranglerToml({
|
|
85
|
+
main: "index.js",
|
|
86
|
+
routes: [
|
|
87
|
+
"http://some-host.com/some/path/*",
|
|
88
|
+
"http://some-other-host.com/path/*",
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
92
|
+
mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
|
|
93
|
+
await runWrangler("dev");
|
|
94
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
|
|
95
|
+
"some-host.com"
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("should read wrangler.toml's environment specific routes", async () => {
|
|
100
|
+
writeWranglerToml({
|
|
101
|
+
main: "index.js",
|
|
102
|
+
routes: [
|
|
103
|
+
"http://a-host.com/some/path/*",
|
|
104
|
+
"http://another-host.com/path/*",
|
|
105
|
+
],
|
|
106
|
+
env: {
|
|
107
|
+
staging: {
|
|
108
|
+
routes: [
|
|
109
|
+
"http://some-host.com/some/path/*",
|
|
110
|
+
"http://some-other-host.com/path/*",
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
116
|
+
mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
|
|
117
|
+
await runWrangler("dev --env staging");
|
|
118
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
|
|
119
|
+
"some-host.com"
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("given a long host, it should use the longest subdomain that resolves to a zone", async () => {
|
|
124
|
+
writeWranglerToml({
|
|
125
|
+
main: "index.js",
|
|
126
|
+
});
|
|
127
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
128
|
+
mockGetZones("111.222.333.some-host.com", []);
|
|
129
|
+
mockGetZones("222.333.some-host.com", []);
|
|
130
|
+
mockGetZones("333.some-host.com", [{ id: "some-zone-id" }]);
|
|
131
|
+
await runWrangler("dev --host 111.222.333.some-host.com");
|
|
132
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
133
|
+
host: "111.222.333.some-host.com",
|
|
134
|
+
id: "some-zone-id",
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("should, in order, use args.host/config.dev.host/args.routes/config.route/config.routes", async () => {
|
|
139
|
+
// This test might seem like it's testing implementation details, but let's be specific and consider it a spec
|
|
140
|
+
|
|
141
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
142
|
+
|
|
143
|
+
// config.routes
|
|
144
|
+
mockGetZones("5.some-host.com", [{ id: "some-zone-id-5" }]);
|
|
145
|
+
writeWranglerToml({
|
|
146
|
+
main: "index.js",
|
|
147
|
+
routes: ["http://5.some-host.com/some/path/*"],
|
|
148
|
+
});
|
|
149
|
+
await runWrangler("dev");
|
|
150
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
151
|
+
host: "5.some-host.com",
|
|
152
|
+
id: "some-zone-id-5",
|
|
153
|
+
});
|
|
154
|
+
(Dev as jest.Mock).mockClear();
|
|
155
|
+
|
|
156
|
+
// config.route
|
|
157
|
+
mockGetZones("4.some-host.com", [{ id: "some-zone-id-4" }]);
|
|
158
|
+
writeWranglerToml({
|
|
159
|
+
main: "index.js",
|
|
160
|
+
route: "https://4.some-host.com/some/path/*",
|
|
161
|
+
routes: ["http://5.some-host.com/some/path/*"],
|
|
162
|
+
});
|
|
163
|
+
await runWrangler("dev");
|
|
164
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
165
|
+
host: "4.some-host.com",
|
|
166
|
+
id: "some-zone-id-4",
|
|
167
|
+
});
|
|
168
|
+
(Dev as jest.Mock).mockClear();
|
|
169
|
+
|
|
170
|
+
// --routes
|
|
171
|
+
mockGetZones("3.some-host.com", [{ id: "some-zone-id-3" }]);
|
|
172
|
+
writeWranglerToml({
|
|
173
|
+
main: "index.js",
|
|
174
|
+
route: "https://4.some-host.com/some/path/*",
|
|
175
|
+
routes: ["http://5.some-host.com/some/path/*"],
|
|
176
|
+
});
|
|
177
|
+
await runWrangler("dev --routes http://3.some-host.com/some/path/*");
|
|
178
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
179
|
+
host: "3.some-host.com",
|
|
180
|
+
id: "some-zone-id-3",
|
|
181
|
+
});
|
|
182
|
+
(Dev as jest.Mock).mockClear();
|
|
183
|
+
|
|
184
|
+
// config.dev.host
|
|
185
|
+
mockGetZones("2.some-host.com", [{ id: "some-zone-id-2" }]);
|
|
186
|
+
writeWranglerToml({
|
|
187
|
+
main: "index.js",
|
|
188
|
+
dev: {
|
|
189
|
+
host: `2.some-host.com`,
|
|
190
|
+
},
|
|
191
|
+
route: "4.some-host.com/some/path/*",
|
|
192
|
+
routes: ["5.some-host.com/some/path/*"],
|
|
193
|
+
});
|
|
194
|
+
await runWrangler("dev --routes http://3.some-host.com/some/path/*");
|
|
195
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
196
|
+
host: "2.some-host.com",
|
|
197
|
+
id: "some-zone-id-2",
|
|
198
|
+
});
|
|
199
|
+
(Dev as jest.Mock).mockClear();
|
|
200
|
+
|
|
201
|
+
// --host
|
|
202
|
+
mockGetZones("1.some-host.com", [{ id: "some-zone-id-1" }]);
|
|
203
|
+
writeWranglerToml({
|
|
204
|
+
main: "index.js",
|
|
205
|
+
dev: {
|
|
206
|
+
host: `2.some-host.com`,
|
|
207
|
+
},
|
|
208
|
+
route: "4.some-host.com/some/path/*",
|
|
209
|
+
routes: ["5.some-host.com/some/path/*"],
|
|
210
|
+
});
|
|
211
|
+
await runWrangler(
|
|
212
|
+
"dev --routes http://3.some-host.com/some/path/* --host 1.some-host.com"
|
|
213
|
+
);
|
|
214
|
+
expect((Dev as jest.Mock).mock.calls[0][0].zone).toEqual({
|
|
215
|
+
host: "1.some-host.com",
|
|
216
|
+
id: "some-zone-id-1",
|
|
217
|
+
});
|
|
218
|
+
(Dev as jest.Mock).mockClear();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("should error if a host can't resolve to a zone", async () => {
|
|
222
|
+
writeWranglerToml({
|
|
223
|
+
main: "index.js",
|
|
224
|
+
});
|
|
225
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
226
|
+
mockGetZones("some-host.com", []);
|
|
227
|
+
await expect(
|
|
228
|
+
runWrangler("dev --host some-host.com")
|
|
229
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
230
|
+
`"Could not find zone for some-host.com"`
|
|
231
|
+
);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe("custom builds", () => {
|
|
236
|
+
it("should run a custom build before starting `dev`", async () => {
|
|
237
|
+
writeWranglerToml({
|
|
238
|
+
build: {
|
|
239
|
+
command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
await runWrangler("dev index.js");
|
|
244
|
+
|
|
245
|
+
expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(
|
|
246
|
+
`"export default { fetch(){ return new Response(123) } }"`
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// and the command would pass through
|
|
250
|
+
expect((Dev as jest.Mock).mock.calls[0][0].buildCommand).toEqual({
|
|
251
|
+
command:
|
|
252
|
+
"node -e \"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\"",
|
|
253
|
+
cwd: undefined,
|
|
254
|
+
watch_dir: undefined,
|
|
255
|
+
});
|
|
256
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
257
|
+
`"running: node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\""`
|
|
258
|
+
);
|
|
259
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
260
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
if (process.platform !== "win32") {
|
|
264
|
+
it("should run a custom build of multiple steps combined by && before starting `dev`", async () => {
|
|
265
|
+
writeWranglerToml({
|
|
266
|
+
build: {
|
|
267
|
+
command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
await runWrangler("dev index.js");
|
|
272
|
+
|
|
273
|
+
expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(`
|
|
274
|
+
"export default { fetch(){ return new Response(123) } }
|
|
275
|
+
"
|
|
276
|
+
`);
|
|
277
|
+
|
|
278
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
279
|
+
`"running: echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js"`
|
|
280
|
+
);
|
|
281
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
282
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
it("should throw an error if the entry doesn't exist after the build finishes", async () => {
|
|
287
|
+
writeWranglerToml({
|
|
288
|
+
main: "index.js",
|
|
289
|
+
build: {
|
|
290
|
+
command: `node -e "console.log('custom build');"`,
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
await expect(
|
|
295
|
+
runWrangler("dev")
|
|
296
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
297
|
+
`"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\""`
|
|
298
|
+
);
|
|
299
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
300
|
+
`"running: node -e \\"console.log('custom build');\\""`
|
|
301
|
+
);
|
|
302
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
303
|
+
"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
|
|
304
|
+
|
|
305
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
306
|
+
`);
|
|
307
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe("upstream-protocol", () => {
|
|
312
|
+
it("should default upstream-protocol to `https`", async () => {
|
|
313
|
+
writeWranglerToml({
|
|
314
|
+
main: "index.js",
|
|
315
|
+
});
|
|
316
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
317
|
+
await runWrangler("dev");
|
|
318
|
+
expect((Dev as jest.Mock).mock.calls[0][0].upstreamProtocol).toEqual(
|
|
319
|
+
"https"
|
|
320
|
+
);
|
|
321
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
322
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
323
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it("should warn if `--upstream-protocol=http` is used", async () => {
|
|
327
|
+
writeWranglerToml({
|
|
328
|
+
main: "index.js",
|
|
329
|
+
});
|
|
330
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
331
|
+
await runWrangler("dev --upstream-protocol=http");
|
|
332
|
+
expect((Dev as jest.Mock).mock.calls[0][0].upstreamProtocol).toEqual(
|
|
333
|
+
"http"
|
|
334
|
+
);
|
|
335
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
336
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
337
|
+
"Setting upstream-protocol to http is not currently implemented.
|
|
338
|
+
If this is required in your project, please add your use case to the following issue:
|
|
339
|
+
https://github.com/cloudflare/wrangler2/issues/583."
|
|
47
340
|
`);
|
|
341
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
describe("local-protocol", () => {
|
|
346
|
+
it("should default local-protocol to `http`", async () => {
|
|
347
|
+
writeWranglerToml({
|
|
348
|
+
main: "index.js",
|
|
349
|
+
});
|
|
350
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
351
|
+
await runWrangler("dev");
|
|
352
|
+
expect((Dev as jest.Mock).mock.calls[0][0].localProtocol).toEqual("http");
|
|
353
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
354
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
355
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it("should use to `local_protocol` from `wrangler.toml`, if available", async () => {
|
|
359
|
+
writeWranglerToml({
|
|
360
|
+
main: "index.js",
|
|
361
|
+
dev: {
|
|
362
|
+
local_protocol: "https",
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
366
|
+
await runWrangler("dev");
|
|
367
|
+
expect((Dev as jest.Mock).mock.calls[0][0].localProtocol).toEqual(
|
|
368
|
+
"https"
|
|
369
|
+
);
|
|
370
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
371
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
372
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
it("should use --local-protocol command line arg, if provided", async () => {
|
|
376
|
+
// Here we show that the command line overrides the wrangler.toml by
|
|
377
|
+
// setting the config to https, and then setting it back to http on the command line.
|
|
378
|
+
writeWranglerToml({
|
|
379
|
+
main: "index.js",
|
|
380
|
+
dev: {
|
|
381
|
+
local_protocol: "https",
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
385
|
+
await runWrangler("dev --local-protocol=http");
|
|
386
|
+
expect((Dev as jest.Mock).mock.calls[0][0].localProtocol).toEqual("http");
|
|
387
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
388
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
389
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
48
390
|
});
|
|
49
391
|
});
|
|
50
392
|
});
|
|
51
393
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
format,
|
|
63
|
-
accountId,
|
|
64
|
-
legacyEnv = true,
|
|
65
|
-
initialMode = "local",
|
|
66
|
-
jsxFactory,
|
|
67
|
-
jsxFragment,
|
|
68
|
-
rules = [],
|
|
69
|
-
bindings = {
|
|
70
|
-
kv_namespaces: [],
|
|
71
|
-
vars: {},
|
|
72
|
-
durable_objects: { bindings: [] },
|
|
73
|
-
r2_buckets: [],
|
|
74
|
-
wasm_modules: {},
|
|
75
|
-
text_blobs: {},
|
|
76
|
-
unsafe: [],
|
|
77
|
-
},
|
|
78
|
-
public: publicDir,
|
|
79
|
-
assetPaths,
|
|
80
|
-
compatibilityDate,
|
|
81
|
-
compatibilityFlags,
|
|
82
|
-
usageModel,
|
|
83
|
-
buildCommand = {},
|
|
84
|
-
enableLocalPersistence = false,
|
|
85
|
-
env,
|
|
86
|
-
zone,
|
|
87
|
-
}: Partial<DevProps>) {
|
|
88
|
-
return render(
|
|
89
|
-
<Dev
|
|
90
|
-
name={name}
|
|
91
|
-
entry={entry}
|
|
92
|
-
env={env}
|
|
93
|
-
rules={rules}
|
|
94
|
-
port={port}
|
|
95
|
-
inspectorPort={inspectorPort}
|
|
96
|
-
legacyEnv={legacyEnv}
|
|
97
|
-
buildCommand={buildCommand}
|
|
98
|
-
format={format}
|
|
99
|
-
initialMode={initialMode}
|
|
100
|
-
jsxFactory={jsxFactory}
|
|
101
|
-
jsxFragment={jsxFragment}
|
|
102
|
-
accountId={accountId}
|
|
103
|
-
assetPaths={assetPaths}
|
|
104
|
-
public={publicDir}
|
|
105
|
-
compatibilityDate={compatibilityDate}
|
|
106
|
-
compatibilityFlags={compatibilityFlags}
|
|
107
|
-
usageModel={usageModel}
|
|
108
|
-
bindings={bindings}
|
|
109
|
-
enableLocalPersistence={enableLocalPersistence}
|
|
110
|
-
zone={zone}
|
|
111
|
-
/>
|
|
394
|
+
function mockGetZones(domain: string, zones: { id: string }[] = []) {
|
|
395
|
+
const removeMock = setMockResponse(
|
|
396
|
+
"/zones",
|
|
397
|
+
"GET",
|
|
398
|
+
(_urlPieces, _init, queryParams) => {
|
|
399
|
+
expect([...queryParams.entries()]).toEqual([["name", domain]]);
|
|
400
|
+
// Because the API URL `/zones` is the same for each request, we can get into a situation where earlier mocks get triggered for later requests. So, we simply clear the mock on every trigger.
|
|
401
|
+
removeMock();
|
|
402
|
+
return zones;
|
|
403
|
+
}
|
|
112
404
|
);
|
|
113
405
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import TestRenderer from "react-test-renderer";
|
|
4
|
+
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
5
|
+
import { unsetAllMocks } from "./helpers/mock-cfetch";
|
|
6
|
+
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
7
|
+
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
8
|
+
import type { DevProps, default as DevType } from "../dev/dev";
|
|
9
|
+
|
|
10
|
+
function sleep(period = 100): Promise<void> {
|
|
11
|
+
return new Promise((resolve) => setTimeout(resolve, period));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// we use this ["mock"] form to avoid esbuild-jest from rewriting it
|
|
15
|
+
jest["mock"]("../proxy", () => {
|
|
16
|
+
return {
|
|
17
|
+
usePreviewServer() {},
|
|
18
|
+
waitForPortToBeAvailable() {},
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
jest["mock"]("../inspect", () => {
|
|
22
|
+
return () => {};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const Dev: typeof DevType = jest.requireActual("../dev/dev").DevImplementation;
|
|
26
|
+
|
|
27
|
+
mockAccountId();
|
|
28
|
+
mockApiToken();
|
|
29
|
+
runInTempDir();
|
|
30
|
+
mockConsoleMethods();
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
unsetAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("dev", () => {
|
|
36
|
+
it("should render", async () => {
|
|
37
|
+
fs.writeFileSync("./index.js", `export default {}`);
|
|
38
|
+
|
|
39
|
+
const testRenderer = await renderDev({
|
|
40
|
+
entry: {
|
|
41
|
+
file: "./index.js",
|
|
42
|
+
directory: process.cwd(),
|
|
43
|
+
format: "modules",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
expect(testRenderer.toJSON()).toMatchInlineSnapshot(`
|
|
47
|
+
<ink-box
|
|
48
|
+
style={
|
|
49
|
+
Object {
|
|
50
|
+
"borderStyle": "round",
|
|
51
|
+
"flexDirection": "row",
|
|
52
|
+
"flexGrow": 0,
|
|
53
|
+
"flexShrink": 1,
|
|
54
|
+
"marginBottom": 0,
|
|
55
|
+
"marginLeft": 0,
|
|
56
|
+
"marginRight": 0,
|
|
57
|
+
"marginTop": 0,
|
|
58
|
+
"paddingBottom": 0,
|
|
59
|
+
"paddingLeft": 1,
|
|
60
|
+
"paddingRight": 1,
|
|
61
|
+
"paddingTop": 0,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
>
|
|
65
|
+
<ink-text
|
|
66
|
+
internal_transform={[Function]}
|
|
67
|
+
style={
|
|
68
|
+
Object {
|
|
69
|
+
"flexDirection": "row",
|
|
70
|
+
"flexGrow": 0,
|
|
71
|
+
"flexShrink": 1,
|
|
72
|
+
"textWrap": "wrap",
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
>
|
|
76
|
+
B to open a browser, D to open Devtools, L to turn off local mode, X to exit
|
|
77
|
+
</ink-text>
|
|
78
|
+
</ink-box>
|
|
79
|
+
`);
|
|
80
|
+
await TestRenderer.act(async () => {
|
|
81
|
+
// TODO: get rid of these sleep statements
|
|
82
|
+
await sleep(50);
|
|
83
|
+
testRenderer.unmount();
|
|
84
|
+
await sleep(50);
|
|
85
|
+
});
|
|
86
|
+
await sleep(50);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
async function renderDev({
|
|
91
|
+
name,
|
|
92
|
+
entry = { file: "index.js", directory: "", format: "modules" },
|
|
93
|
+
port,
|
|
94
|
+
inspectorPort = 9229,
|
|
95
|
+
accountId,
|
|
96
|
+
legacyEnv = true,
|
|
97
|
+
initialMode = "local",
|
|
98
|
+
jsxFactory,
|
|
99
|
+
jsxFragment,
|
|
100
|
+
localProtocol = "http",
|
|
101
|
+
upstreamProtocol = "https",
|
|
102
|
+
rules = [],
|
|
103
|
+
bindings = {
|
|
104
|
+
kv_namespaces: [],
|
|
105
|
+
vars: {},
|
|
106
|
+
durable_objects: { bindings: [] },
|
|
107
|
+
r2_buckets: [],
|
|
108
|
+
wasm_modules: undefined,
|
|
109
|
+
text_blobs: undefined,
|
|
110
|
+
unsafe: [],
|
|
111
|
+
},
|
|
112
|
+
public: publicDir,
|
|
113
|
+
assetPaths,
|
|
114
|
+
compatibilityDate,
|
|
115
|
+
compatibilityFlags,
|
|
116
|
+
usageModel,
|
|
117
|
+
buildCommand = {},
|
|
118
|
+
enableLocalPersistence = false,
|
|
119
|
+
env,
|
|
120
|
+
zone,
|
|
121
|
+
}: Partial<DevProps>): Promise<TestRenderer.ReactTestRenderer> {
|
|
122
|
+
let instance: TestRenderer.ReactTestRenderer | undefined;
|
|
123
|
+
await TestRenderer.act(async () => {
|
|
124
|
+
instance = TestRenderer.create(
|
|
125
|
+
<Dev
|
|
126
|
+
name={name}
|
|
127
|
+
entry={entry}
|
|
128
|
+
env={env}
|
|
129
|
+
rules={rules}
|
|
130
|
+
port={port}
|
|
131
|
+
inspectorPort={inspectorPort}
|
|
132
|
+
legacyEnv={legacyEnv}
|
|
133
|
+
buildCommand={buildCommand}
|
|
134
|
+
initialMode={initialMode}
|
|
135
|
+
localProtocol={localProtocol}
|
|
136
|
+
upstreamProtocol={upstreamProtocol}
|
|
137
|
+
jsxFactory={jsxFactory}
|
|
138
|
+
jsxFragment={jsxFragment}
|
|
139
|
+
accountId={accountId}
|
|
140
|
+
assetPaths={assetPaths}
|
|
141
|
+
public={publicDir}
|
|
142
|
+
compatibilityDate={compatibilityDate}
|
|
143
|
+
compatibilityFlags={compatibilityFlags}
|
|
144
|
+
usageModel={usageModel}
|
|
145
|
+
bindings={bindings}
|
|
146
|
+
enableLocalPersistence={enableLocalPersistence}
|
|
147
|
+
zone={zone}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
return instance as TestRenderer.ReactTestRenderer;
|
|
152
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writeFile } from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import guessWorkerFormat from "../
|
|
3
|
+
import guessWorkerFormat from "../entry";
|
|
4
4
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
5
5
|
|
|
6
6
|
describe("guess worker format", () => {
|
|
@@ -10,10 +10,8 @@ describe("guess worker format", () => {
|
|
|
10
10
|
// Note that this isn't actually a valid worker, because it's missing
|
|
11
11
|
// a fetch handler. Regardless, our heuristic is simply to check for exports.
|
|
12
12
|
const guess = await guessWorkerFormat(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
directory: process.cwd(),
|
|
16
|
-
},
|
|
13
|
+
path.join(process.cwd(), "./index.ts"),
|
|
14
|
+
process.cwd(),
|
|
17
15
|
undefined
|
|
18
16
|
);
|
|
19
17
|
expect(guess).toBe("modules");
|
|
@@ -25,10 +23,8 @@ describe("guess worker format", () => {
|
|
|
25
23
|
// a fetch listener. Regardless, our heuristic is simply to check for
|
|
26
24
|
// the lack of exports.
|
|
27
25
|
const guess = await guessWorkerFormat(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
directory: process.cwd(),
|
|
31
|
-
},
|
|
26
|
+
path.join(process.cwd(), "./index.ts"),
|
|
27
|
+
process.cwd(),
|
|
32
28
|
undefined
|
|
33
29
|
);
|
|
34
30
|
expect(guess).toBe("service-worker");
|
|
@@ -38,10 +34,8 @@ describe("guess worker format", () => {
|
|
|
38
34
|
await writeFile("./index.ts", "export default {};");
|
|
39
35
|
await expect(
|
|
40
36
|
guessWorkerFormat(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
directory: process.cwd(),
|
|
44
|
-
},
|
|
37
|
+
path.join(process.cwd(), "./index.ts"),
|
|
38
|
+
process.cwd(),
|
|
45
39
|
"service-worker"
|
|
46
40
|
)
|
|
47
41
|
).rejects.toThrow(
|
|
@@ -53,10 +47,8 @@ describe("guess worker format", () => {
|
|
|
53
47
|
await writeFile("./index.ts", "");
|
|
54
48
|
await expect(
|
|
55
49
|
guessWorkerFormat(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
directory: process.cwd(),
|
|
59
|
-
},
|
|
50
|
+
path.join(process.cwd(), "./index.ts"),
|
|
51
|
+
process.cwd(),
|
|
60
52
|
"modules"
|
|
61
53
|
)
|
|
62
54
|
).rejects.toThrow(
|