wrangler 0.0.0-e2f9bb2 → 0.0.0-e3278fa
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/Cloudflare_CA.pem +18 -0
- package/README.md +3 -1
- package/bin/wrangler.js +36 -4
- package/package.json +12 -7
- package/pages/functions/buildPlugin.ts +13 -0
- package/pages/functions/buildWorker.ts +14 -1
- package/pages/functions/template-plugin.ts +3 -2
- package/src/__tests__/configuration.test.ts +370 -87
- package/src/__tests__/dev.test.tsx +298 -77
- package/src/__tests__/helpers/mock-dialogs.ts +43 -2
- package/src/__tests__/index.test.ts +79 -72
- package/src/__tests__/init.test.ts +718 -123
- package/src/__tests__/jest.setup.ts +8 -0
- package/src/__tests__/kv.test.ts +173 -146
- package/src/__tests__/package-manager.test.ts +154 -7
- package/src/__tests__/pages.test.ts +478 -53
- package/src/__tests__/parse.test.ts +8 -0
- package/src/__tests__/publish.test.ts +1094 -215
- package/src/__tests__/r2.test.ts +55 -36
- package/src/__tests__/secret.test.ts +39 -4
- package/src/__tests__/whoami.test.tsx +34 -0
- package/src/abort.d.ts +3 -0
- package/src/bundle.ts +34 -6
- package/src/cfetch/index.ts +21 -4
- package/src/cfetch/internal.ts +23 -18
- package/src/config/config.ts +2 -2
- package/src/config/environment.ts +40 -14
- package/src/config/index.ts +162 -0
- package/src/config/validation-helpers.ts +10 -1
- package/src/config/validation.ts +180 -65
- package/src/create-worker-preview.ts +32 -22
- package/src/create-worker-upload-form.ts +22 -8
- package/src/dev/dev.tsx +12 -18
- package/src/dev/local.tsx +10 -0
- package/src/dev/remote.tsx +40 -16
- package/src/dialogs.tsx +48 -0
- package/src/durable.ts +102 -0
- package/src/entry.ts +64 -9
- package/src/index.tsx +548 -317
- package/src/inspect.ts +39 -0
- package/src/kv.ts +114 -25
- package/src/open-in-browser.ts +5 -12
- package/src/package-manager.ts +50 -3
- package/src/pages.tsx +434 -207
- package/src/parse.ts +23 -4
- package/src/proxy.ts +59 -35
- package/src/publish.ts +374 -127
- package/src/sites.tsx +61 -28
- package/src/user.tsx +23 -2
- package/src/whoami.tsx +3 -2
- package/src/worker.ts +10 -1
- package/src/zones.ts +73 -0
- package/templates/new-worker-scheduled.js +17 -0
- package/templates/new-worker-scheduled.ts +32 -0
- package/templates/new-worker.ts +16 -1
- package/templates/static-asset-facade.js +0 -4
- package/wrangler-dist/cli.js +96965 -83414
- package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
- package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
- package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
- package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
- package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
- package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
- package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
- package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
- package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
- package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
- package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
- package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
- package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
- package/vendor/wrangler-mime/CHANGELOG.md +0 -289
- package/vendor/wrangler-mime/LICENSE +0 -21
- package/vendor/wrangler-mime/Mime.js +0 -97
- package/vendor/wrangler-mime/README.md +0 -187
- package/vendor/wrangler-mime/cli.js +0 -46
- package/vendor/wrangler-mime/index.js +0 -4
- package/vendor/wrangler-mime/lite.js +0 -4
- package/vendor/wrangler-mime/package.json +0 -52
- package/vendor/wrangler-mime/types/other.js +0 -1
- package/vendor/wrangler-mime/types/standard.js +0 -1
package/src/parse.ts
CHANGED
|
@@ -62,8 +62,6 @@ export class ParseError extends Error implements Message {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
66
|
-
|
|
67
65
|
const TOML_ERROR_NAME = "TomlError";
|
|
68
66
|
const TOML_ERROR_SUFFIX = " at row ";
|
|
69
67
|
|
|
@@ -77,7 +75,9 @@ type TomlError = Error & {
|
|
|
77
75
|
*/
|
|
78
76
|
export function parseTOML(input: string, file?: string): TOML.JsonMap | never {
|
|
79
77
|
try {
|
|
80
|
-
|
|
78
|
+
// Normalize CRLF to LF to avoid hitting https://github.com/iarna/iarna-toml/issues/33.
|
|
79
|
+
const normalizedInput = input.replace(/\r\n/g, "\n");
|
|
80
|
+
return TOML.parse(normalizedInput);
|
|
81
81
|
} catch (err) {
|
|
82
82
|
const { name, message, line, col } = err as TomlError;
|
|
83
83
|
if (name !== TOML_ERROR_NAME) {
|
|
@@ -98,10 +98,29 @@ export function parseTOML(input: string, file?: string): TOML.JsonMap | never {
|
|
|
98
98
|
|
|
99
99
|
const JSON_ERROR_SUFFIX = " in JSON at position ";
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* A minimal type describing a package.json file.
|
|
103
|
+
*/
|
|
104
|
+
export type PackageJSON = {
|
|
105
|
+
devDependencies?: Record<string, unknown>;
|
|
106
|
+
dependencies?: Record<string, unknown>;
|
|
107
|
+
scripts?: Record<string, unknown>;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* A typed version of `parseJSON()`.
|
|
112
|
+
*/
|
|
113
|
+
export function parsePackageJSON<T extends PackageJSON = PackageJSON>(
|
|
114
|
+
input: string,
|
|
115
|
+
file?: string
|
|
116
|
+
): T {
|
|
117
|
+
return parseJSON<T>(input, file);
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
/**
|
|
102
121
|
* A wrapper around `JSON.parse` that throws a `ParseError`.
|
|
103
122
|
*/
|
|
104
|
-
export function parseJSON(input: string, file?: string):
|
|
123
|
+
export function parseJSON<T>(input: string, file?: string): T {
|
|
105
124
|
try {
|
|
106
125
|
return JSON.parse(input);
|
|
107
126
|
} catch (err) {
|
package/src/proxy.ts
CHANGED
|
@@ -2,11 +2,13 @@ import { createServer as createHttpServer } from "node:http";
|
|
|
2
2
|
import { connect } from "node:http2";
|
|
3
3
|
import { createServer as createHttpsServer } from "node:https";
|
|
4
4
|
import WebSocket from "faye-websocket";
|
|
5
|
+
import { createHttpTerminator } from "http-terminator";
|
|
5
6
|
import { useEffect, useRef, useState } from "react";
|
|
6
7
|
import serveStatic from "serve-static";
|
|
7
8
|
import { getHttpsOptions } from "./https-options";
|
|
8
9
|
import { logger } from "./logger";
|
|
9
10
|
import type { CfPreviewToken } from "./create-worker-preview";
|
|
11
|
+
import type { HttpTerminator } from "http-terminator";
|
|
10
12
|
import type {
|
|
11
13
|
IncomingHttpHeaders,
|
|
12
14
|
RequestListener,
|
|
@@ -67,6 +69,11 @@ function rewriteRemoteHostToLocalHostInHeaders(
|
|
|
67
69
|
}
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
type PreviewProxy = {
|
|
73
|
+
server: HttpServer | HttpsServer;
|
|
74
|
+
terminator: HttpTerminator;
|
|
75
|
+
};
|
|
76
|
+
|
|
70
77
|
export function usePreviewServer({
|
|
71
78
|
previewToken,
|
|
72
79
|
publicRoot,
|
|
@@ -81,21 +88,29 @@ export function usePreviewServer({
|
|
|
81
88
|
ip: string;
|
|
82
89
|
}) {
|
|
83
90
|
/** Creates an HTTP/1 proxy that sends requests over HTTP/2. */
|
|
84
|
-
const [
|
|
91
|
+
const [proxy, setProxy] = useState<PreviewProxy>();
|
|
85
92
|
|
|
86
93
|
/**
|
|
87
94
|
* Create the instance of the local proxy server that will pass on
|
|
88
95
|
* requests to the preview worker.
|
|
89
96
|
*/
|
|
90
97
|
useEffect(() => {
|
|
91
|
-
if (
|
|
98
|
+
if (proxy === undefined) {
|
|
92
99
|
createProxyServer(localProtocol)
|
|
93
|
-
.then((
|
|
100
|
+
.then((server) => {
|
|
101
|
+
setProxy({
|
|
102
|
+
server,
|
|
103
|
+
terminator: createHttpTerminator({
|
|
104
|
+
server,
|
|
105
|
+
gracefulTerminationTimeout: 0,
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
})
|
|
94
109
|
.catch(async (err) => {
|
|
95
110
|
logger.error("Failed to create proxy server:", err);
|
|
96
111
|
});
|
|
97
112
|
}
|
|
98
|
-
}, [
|
|
113
|
+
}, [proxy, localProtocol]);
|
|
99
114
|
|
|
100
115
|
/**
|
|
101
116
|
* When we're not connected / getting a fresh token on changes,
|
|
@@ -123,7 +138,7 @@ export function usePreviewServer({
|
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
useEffect(() => {
|
|
126
|
-
if (
|
|
141
|
+
if (proxy === undefined) {
|
|
127
142
|
return;
|
|
128
143
|
}
|
|
129
144
|
|
|
@@ -138,8 +153,8 @@ export function usePreviewServer({
|
|
|
138
153
|
// store the stream in a buffer so we can replay it later
|
|
139
154
|
streamBufferRef.current.push({ stream, headers });
|
|
140
155
|
};
|
|
141
|
-
|
|
142
|
-
cleanupListeners.push(() =>
|
|
156
|
+
proxy.server.on("stream", bufferStream);
|
|
157
|
+
cleanupListeners.push(() => proxy.server.off("stream", bufferStream));
|
|
143
158
|
|
|
144
159
|
const bufferRequestResponse = (
|
|
145
160
|
request: IncomingMessage,
|
|
@@ -149,9 +164,9 @@ export function usePreviewServer({
|
|
|
149
164
|
requestResponseBufferRef.current.push({ request, response });
|
|
150
165
|
};
|
|
151
166
|
|
|
152
|
-
|
|
167
|
+
proxy.server.on("request", bufferRequestResponse);
|
|
153
168
|
cleanupListeners.push(() =>
|
|
154
|
-
|
|
169
|
+
proxy.server.off("request", bufferRequestResponse)
|
|
155
170
|
);
|
|
156
171
|
return () => {
|
|
157
172
|
cleanupListeners.forEach((cleanup) => cleanup());
|
|
@@ -179,8 +194,8 @@ export function usePreviewServer({
|
|
|
179
194
|
port,
|
|
180
195
|
localProtocol
|
|
181
196
|
);
|
|
182
|
-
|
|
183
|
-
cleanupListeners.push(() =>
|
|
197
|
+
proxy.server.on("stream", handleStream);
|
|
198
|
+
cleanupListeners.push(() => proxy.server.off("stream", handleStream));
|
|
184
199
|
|
|
185
200
|
// flush and replay buffered streams
|
|
186
201
|
streamBufferRef.current.forEach((buffer) =>
|
|
@@ -210,6 +225,10 @@ export function usePreviewServer({
|
|
|
210
225
|
const request = message.pipe(remote.request(headers));
|
|
211
226
|
request.on("response", (responseHeaders) => {
|
|
212
227
|
const status = responseHeaders[":status"] ?? 500;
|
|
228
|
+
|
|
229
|
+
// log all requests to terminal
|
|
230
|
+
logger.log(new Date().toLocaleTimeString(), method, url, status);
|
|
231
|
+
|
|
213
232
|
rewriteRemoteHostToLocalHostInHeaders(
|
|
214
233
|
responseHeaders,
|
|
215
234
|
previewToken.host,
|
|
@@ -232,9 +251,9 @@ export function usePreviewServer({
|
|
|
232
251
|
? createHandleAssetsRequest(assetPath, handleRequest)
|
|
233
252
|
: handleRequest;
|
|
234
253
|
|
|
235
|
-
|
|
254
|
+
proxy.server.on("request", actualHandleRequest);
|
|
236
255
|
cleanupListeners.push(() =>
|
|
237
|
-
|
|
256
|
+
proxy.server.off("request", actualHandleRequest)
|
|
238
257
|
);
|
|
239
258
|
|
|
240
259
|
// flush and replay buffered requests
|
|
@@ -266,8 +285,8 @@ export function usePreviewServer({
|
|
|
266
285
|
remoteWebsocketClient.close();
|
|
267
286
|
});
|
|
268
287
|
};
|
|
269
|
-
|
|
270
|
-
cleanupListeners.push(() =>
|
|
288
|
+
proxy.server.on("upgrade", handleUpgrade);
|
|
289
|
+
cleanupListeners.push(() => proxy.server.off("upgrade", handleUpgrade));
|
|
271
290
|
|
|
272
291
|
return () => {
|
|
273
292
|
cleanupListeners.forEach((cleanup) => cleanup());
|
|
@@ -277,7 +296,7 @@ export function usePreviewServer({
|
|
|
277
296
|
publicRoot,
|
|
278
297
|
port,
|
|
279
298
|
localProtocol,
|
|
280
|
-
|
|
299
|
+
proxy,
|
|
281
300
|
// We use a state value as a sigil to trigger reconnecting the server.
|
|
282
301
|
// It's not used inside the effect, so react-hooks/exhaustive-deps
|
|
283
302
|
// doesn't complain if it's not included in the dependency array.
|
|
@@ -289,7 +308,7 @@ export function usePreviewServer({
|
|
|
289
308
|
// containing component is mounted/unmounted.
|
|
290
309
|
useEffect(() => {
|
|
291
310
|
const abortController = new AbortController();
|
|
292
|
-
if (
|
|
311
|
+
if (proxy === undefined) {
|
|
293
312
|
return;
|
|
294
313
|
}
|
|
295
314
|
|
|
@@ -299,8 +318,10 @@ export function usePreviewServer({
|
|
|
299
318
|
abortSignal: abortController.signal,
|
|
300
319
|
})
|
|
301
320
|
.then(() => {
|
|
302
|
-
|
|
303
|
-
|
|
321
|
+
proxy.server.on("listening", () => {
|
|
322
|
+
logger.log(`⬣ Listening at ${localProtocol}://${ip}:${port}`);
|
|
323
|
+
});
|
|
324
|
+
proxy.server.listen(port, ip);
|
|
304
325
|
})
|
|
305
326
|
.catch((err) => {
|
|
306
327
|
if ((err as { code: string }).code !== "ABORT_ERR") {
|
|
@@ -309,10 +330,14 @@ export function usePreviewServer({
|
|
|
309
330
|
});
|
|
310
331
|
|
|
311
332
|
return () => {
|
|
312
|
-
proxyServer.close();
|
|
313
333
|
abortController.abort();
|
|
334
|
+
// Running `proxy.server.close()` does not close open connections, preventing the process from exiting.
|
|
335
|
+
// So we use this `terminator` to close all the connections and force the server to shutdown.
|
|
336
|
+
proxy.terminator
|
|
337
|
+
.terminate()
|
|
338
|
+
.catch(() => logger.error("Failed to terminate the proxy server."));
|
|
314
339
|
};
|
|
315
|
-
}, [port, ip,
|
|
340
|
+
}, [port, ip, proxy, localProtocol]);
|
|
316
341
|
}
|
|
317
342
|
|
|
318
343
|
function createHandleAssetsRequest(
|
|
@@ -349,15 +374,6 @@ async function createProxyServer(
|
|
|
349
374
|
: createHttpServer();
|
|
350
375
|
|
|
351
376
|
return server
|
|
352
|
-
.on("request", function (req, res) {
|
|
353
|
-
// log all requests
|
|
354
|
-
logger.log(
|
|
355
|
-
new Date().toLocaleTimeString(),
|
|
356
|
-
req.method,
|
|
357
|
-
req.url,
|
|
358
|
-
res.statusCode
|
|
359
|
-
);
|
|
360
|
-
})
|
|
361
377
|
.on("upgrade", (req) => {
|
|
362
378
|
// log all websocket connections
|
|
363
379
|
logger.log(
|
|
@@ -409,7 +425,7 @@ export async function waitForPortToBeAvailable(
|
|
|
409
425
|
): Promise<void> {
|
|
410
426
|
return new Promise((resolve, reject) => {
|
|
411
427
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
412
|
-
|
|
428
|
+
options.abortSignal.addEventListener("abort", () => {
|
|
413
429
|
const abortError = new Error("waitForPortToBeAvailable() aborted");
|
|
414
430
|
(abortError as Error & { code: string }).code = "ABORT_ERR";
|
|
415
431
|
doReject(abortError);
|
|
@@ -439,16 +455,24 @@ export async function waitForPortToBeAvailable(
|
|
|
439
455
|
// trying to make a server listen on that port, and retrying
|
|
440
456
|
// until it succeeds.
|
|
441
457
|
const server = createHttpServer();
|
|
458
|
+
const terminator = createHttpTerminator({
|
|
459
|
+
server,
|
|
460
|
+
gracefulTerminationTimeout: 0, // default 1000
|
|
461
|
+
});
|
|
462
|
+
|
|
442
463
|
server.on("error", (err) => {
|
|
443
464
|
// @ts-expect-error non standard property on Error
|
|
444
465
|
if (err.code !== "EADDRINUSE") {
|
|
445
466
|
doReject(err);
|
|
446
467
|
}
|
|
447
468
|
});
|
|
448
|
-
server.listen(port, () =>
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
469
|
+
server.listen(port, () =>
|
|
470
|
+
terminator
|
|
471
|
+
.terminate()
|
|
472
|
+
.then(doResolve, () =>
|
|
473
|
+
logger.error("Failed to terminate the port checker.")
|
|
474
|
+
)
|
|
475
|
+
);
|
|
452
476
|
}
|
|
453
477
|
});
|
|
454
478
|
}
|