wrangler 0.0.0-e1c615f → 0.0.0-e5d3690
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 +9 -5
- package/pages/functions/buildWorker.ts +5 -0
- package/pages/functions/filepath-routing.ts +15 -8
- package/pages/functions/routes.ts +1 -1
- package/pages/functions/template-worker.ts +18 -19
- package/src/__tests__/dev.test.tsx +5 -4
- package/src/__tests__/index.test.ts +2 -0
- package/src/__tests__/kv.test.ts +173 -72
- package/src/__tests__/mock-cfetch.ts +8 -6
- package/src/__tests__/publish.test.ts +672 -0
- package/src/__tests__/whoami.test.tsx +130 -0
- package/src/api/form_data.ts +1 -1
- package/src/api/worker.ts +6 -6
- package/src/cfetch/index.ts +10 -2
- package/src/cfetch/internal.ts +10 -8
- package/src/config.ts +633 -118
- package/src/dev.tsx +119 -214
- package/src/index.tsx +268 -222
- package/src/inspect.ts +543 -0
- package/src/kv.tsx +18 -9
- package/src/pages.tsx +117 -45
- package/src/proxy.ts +275 -76
- package/src/publish.ts +78 -46
- package/src/sites.tsx +167 -38
- package/src/user.tsx +56 -59
- package/src/whoami.tsx +69 -0
- package/wrangler-dist/cli.js +31405 -30705
- package/wrangler-dist/cli.js.map +3 -3
- package/src/api/inspect.ts +0 -430
package/src/dev.tsx
CHANGED
|
@@ -1,49 +1,51 @@
|
|
|
1
1
|
import esbuild from "esbuild";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
7
|
import { Box, Text, useApp, useInput } from "ink";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import { watch } from "chokidar";
|
|
9
|
+
import clipboardy from "clipboardy";
|
|
10
|
+
import commandExists from "command-exists";
|
|
11
|
+
import { execa } from "execa";
|
|
12
|
+
import fetch from "node-fetch";
|
|
10
13
|
import open from "open";
|
|
11
|
-
import {
|
|
14
|
+
import React, { useState, useEffect, useRef } from "react";
|
|
15
|
+
import { withErrorBoundary, useErrorHandler } from "react-error-boundary";
|
|
16
|
+
import onExit from "signal-exit";
|
|
17
|
+
import tmp from "tmp-promise";
|
|
18
|
+
import type { DirectoryResult } from "tmp-promise";
|
|
19
|
+
|
|
20
|
+
import type { CfPreviewToken } from "./api/preview";
|
|
12
21
|
import type { CfModule } from "./api/worker";
|
|
13
22
|
import { createWorker } from "./api/worker";
|
|
14
23
|
import type { CfWorkerInit } from "./api/worker";
|
|
15
|
-
|
|
16
|
-
import
|
|
24
|
+
|
|
25
|
+
import useInspector from "./inspect";
|
|
26
|
+
import makeModuleCollector from "./module-collection";
|
|
27
|
+
import { usePreviewServer } from "./proxy";
|
|
28
|
+
import type { AssetPaths } from "./sites";
|
|
17
29
|
import { syncAssets } from "./sites";
|
|
18
|
-
import clipboardy from "clipboardy";
|
|
19
|
-
import http from "node:http";
|
|
20
|
-
import commandExists from "command-exists";
|
|
21
|
-
import assert from "assert";
|
|
22
30
|
import { getAPIToken } from "./user";
|
|
23
|
-
import fetch from "node-fetch";
|
|
24
|
-
import makeModuleCollector from "./module-collection";
|
|
25
|
-
import { withErrorBoundary, useErrorHandler } from "react-error-boundary";
|
|
26
|
-
import { createHttpProxy } from "./proxy";
|
|
27
|
-
import { execa } from "execa";
|
|
28
|
-
import { watch } from "chokidar";
|
|
29
31
|
|
|
30
|
-
type CfScriptFormat =
|
|
32
|
+
type CfScriptFormat = undefined | "modules" | "service-worker";
|
|
31
33
|
|
|
32
34
|
export type DevProps = {
|
|
33
35
|
name?: string;
|
|
34
36
|
entry: string;
|
|
35
37
|
port?: number;
|
|
36
38
|
format: CfScriptFormat;
|
|
37
|
-
accountId:
|
|
39
|
+
accountId: undefined | string;
|
|
38
40
|
initialMode: "local" | "remote";
|
|
39
|
-
jsxFactory:
|
|
40
|
-
jsxFragment:
|
|
41
|
+
jsxFactory: undefined | string;
|
|
42
|
+
jsxFragment: undefined | string;
|
|
41
43
|
bindings: CfWorkerInit["bindings"];
|
|
42
|
-
public:
|
|
43
|
-
|
|
44
|
-
compatibilityDate:
|
|
45
|
-
compatibilityFlags:
|
|
46
|
-
usageModel:
|
|
44
|
+
public: undefined | string;
|
|
45
|
+
assetPaths: undefined | AssetPaths;
|
|
46
|
+
compatibilityDate: undefined | string;
|
|
47
|
+
compatibilityFlags: undefined | string[];
|
|
48
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
47
49
|
buildCommand: {
|
|
48
50
|
command?: undefined | string;
|
|
49
51
|
cwd?: undefined | string;
|
|
@@ -57,7 +59,7 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
57
59
|
"You cannot use the service worker format with a `public` directory."
|
|
58
60
|
);
|
|
59
61
|
}
|
|
60
|
-
const port = props.port
|
|
62
|
+
const port = props.port ?? 8787;
|
|
61
63
|
const apiToken = getAPIToken();
|
|
62
64
|
const directory = useTmpDir();
|
|
63
65
|
|
|
@@ -79,9 +81,6 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
79
81
|
);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
// @ts-expect-error whack
|
|
83
|
-
useDevtoolsRefresh(bundle?.id ?? 0);
|
|
84
|
-
|
|
85
84
|
const toggles = useHotkeys(
|
|
86
85
|
{
|
|
87
86
|
local: props.initialMode === "local",
|
|
@@ -100,9 +99,9 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
100
99
|
bundle={bundle}
|
|
101
100
|
format={props.format}
|
|
102
101
|
bindings={props.bindings}
|
|
103
|
-
site={props.
|
|
102
|
+
site={props.assetPaths}
|
|
104
103
|
public={props.public}
|
|
105
|
-
port={
|
|
104
|
+
port={port}
|
|
106
105
|
/>
|
|
107
106
|
) : (
|
|
108
107
|
<Remote
|
|
@@ -112,9 +111,9 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
112
111
|
accountId={props.accountId}
|
|
113
112
|
apiToken={apiToken}
|
|
114
113
|
bindings={props.bindings}
|
|
115
|
-
|
|
114
|
+
assetPaths={props.assetPaths}
|
|
116
115
|
public={props.public}
|
|
117
|
-
port={
|
|
116
|
+
port={port}
|
|
118
117
|
compatibilityDate={props.compatibilityDate}
|
|
119
118
|
compatibilityFlags={props.compatibilityFlags}
|
|
120
119
|
usageModel={props.usageModel}
|
|
@@ -133,53 +132,23 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
133
132
|
);
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
function useDevtoolsRefresh(bundleId: number) {
|
|
137
|
-
// TODO: this is a hack while we figure out
|
|
138
|
-
// a better cleaner solution to get devtools to reconnect
|
|
139
|
-
// without having to do a full refresh
|
|
140
|
-
const ref = useRef();
|
|
141
|
-
// @ts-expect-error whack
|
|
142
|
-
ref.current = bundleId;
|
|
143
|
-
|
|
144
|
-
useEffect(() => {
|
|
145
|
-
const server = http.createServer((req, res) => {
|
|
146
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
147
|
-
res.setHeader("Access-Control-Request-Method", "*");
|
|
148
|
-
res.setHeader("Access-Control-Allow-Methods", "OPTIONS, GET");
|
|
149
|
-
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
150
|
-
if (req.method === "OPTIONS") {
|
|
151
|
-
res.writeHead(200);
|
|
152
|
-
res.end();
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
156
|
-
res.end(JSON.stringify({ value: ref.current }));
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
server.listen(3142);
|
|
160
|
-
return () => {
|
|
161
|
-
server.close();
|
|
162
|
-
};
|
|
163
|
-
}, []);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
135
|
function Remote(props: {
|
|
167
|
-
name:
|
|
168
|
-
bundle: EsbuildBundle |
|
|
136
|
+
name: undefined | string;
|
|
137
|
+
bundle: EsbuildBundle | undefined;
|
|
169
138
|
format: CfScriptFormat;
|
|
170
|
-
public:
|
|
171
|
-
|
|
139
|
+
public: undefined | string;
|
|
140
|
+
assetPaths: undefined | AssetPaths;
|
|
172
141
|
port: number;
|
|
173
|
-
accountId:
|
|
174
|
-
apiToken:
|
|
142
|
+
accountId: undefined | string;
|
|
143
|
+
apiToken: undefined | string;
|
|
175
144
|
bindings: CfWorkerInit["bindings"];
|
|
176
|
-
compatibilityDate: string |
|
|
177
|
-
compatibilityFlags:
|
|
178
|
-
usageModel:
|
|
145
|
+
compatibilityDate: string | undefined;
|
|
146
|
+
compatibilityFlags: undefined | string[];
|
|
147
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
179
148
|
}) {
|
|
180
149
|
assert(props.accountId, "accountId is required");
|
|
181
150
|
assert(props.apiToken, "apiToken is required");
|
|
182
|
-
const
|
|
151
|
+
const previewToken = useWorker({
|
|
183
152
|
name: props.name,
|
|
184
153
|
bundle: props.bundle,
|
|
185
154
|
format: props.format,
|
|
@@ -187,25 +156,33 @@ function Remote(props: {
|
|
|
187
156
|
accountId: props.accountId,
|
|
188
157
|
apiToken: props.apiToken,
|
|
189
158
|
bindings: props.bindings,
|
|
190
|
-
|
|
159
|
+
assetPaths: props.assetPaths,
|
|
191
160
|
port: props.port,
|
|
192
161
|
compatibilityDate: props.compatibilityDate,
|
|
193
162
|
compatibilityFlags: props.compatibilityFlags,
|
|
194
163
|
usageModel: props.usageModel,
|
|
195
164
|
});
|
|
196
165
|
|
|
197
|
-
|
|
166
|
+
usePreviewServer({
|
|
167
|
+
previewToken,
|
|
168
|
+
publicRoot: props.public,
|
|
169
|
+
port: props.port,
|
|
170
|
+
});
|
|
198
171
|
|
|
199
|
-
useInspector(
|
|
172
|
+
useInspector({
|
|
173
|
+
inspectorUrl: previewToken ? previewToken.inspectorUrl.href : undefined,
|
|
174
|
+
port: 9229,
|
|
175
|
+
logToTerminal: true,
|
|
176
|
+
});
|
|
200
177
|
return null;
|
|
201
178
|
}
|
|
202
179
|
function Local(props: {
|
|
203
|
-
name:
|
|
204
|
-
bundle: EsbuildBundle |
|
|
180
|
+
name: undefined | string;
|
|
181
|
+
bundle: EsbuildBundle | undefined;
|
|
205
182
|
format: CfScriptFormat;
|
|
206
183
|
bindings: CfWorkerInit["bindings"];
|
|
207
|
-
public:
|
|
208
|
-
site:
|
|
184
|
+
public: undefined | string;
|
|
185
|
+
site: undefined | AssetPaths;
|
|
209
186
|
port: number;
|
|
210
187
|
}) {
|
|
211
188
|
const { inspectorUrl } = useLocalWorker({
|
|
@@ -215,13 +192,13 @@ function Local(props: {
|
|
|
215
192
|
bindings: props.bindings,
|
|
216
193
|
port: props.port,
|
|
217
194
|
});
|
|
218
|
-
useInspector(inspectorUrl);
|
|
195
|
+
useInspector({ inspectorUrl, port: 9229, logToTerminal: false });
|
|
219
196
|
return null;
|
|
220
197
|
}
|
|
221
198
|
|
|
222
199
|
function useLocalWorker(props: {
|
|
223
|
-
name:
|
|
224
|
-
bundle: EsbuildBundle |
|
|
200
|
+
name: undefined | string;
|
|
201
|
+
bundle: EsbuildBundle | undefined;
|
|
225
202
|
format: CfScriptFormat;
|
|
226
203
|
bindings: CfWorkerInit["bindings"];
|
|
227
204
|
port: number;
|
|
@@ -230,7 +207,7 @@ function useLocalWorker(props: {
|
|
|
230
207
|
const { bundle, format, bindings, port } = props;
|
|
231
208
|
const local = useRef<ReturnType<typeof spawn>>();
|
|
232
209
|
const removeSignalExitListener = useRef<() => void>();
|
|
233
|
-
const [inspectorUrl, setInspectorUrl] = useState<string |
|
|
210
|
+
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
234
211
|
useEffect(() => {
|
|
235
212
|
async function startLocalWorker() {
|
|
236
213
|
if (!bundle) return;
|
|
@@ -289,11 +266,11 @@ function useLocalWorker(props: {
|
|
|
289
266
|
}
|
|
290
267
|
});
|
|
291
268
|
|
|
292
|
-
local.current.stdout
|
|
269
|
+
local.current.stdout?.on("data", (data: Buffer) => {
|
|
293
270
|
console.log(`${data.toString()}`);
|
|
294
271
|
});
|
|
295
272
|
|
|
296
|
-
local.current.stderr
|
|
273
|
+
local.current.stderr?.on("data", (data: Buffer) => {
|
|
297
274
|
console.error(`${data.toString()}`);
|
|
298
275
|
const matches =
|
|
299
276
|
/Debugger listening on (ws:\/\/127\.0\.0\.1:9229\/[A-Za-z0-9-]+)/.exec(
|
|
@@ -346,7 +323,7 @@ function useLocalWorker(props: {
|
|
|
346
323
|
return { inspectorUrl };
|
|
347
324
|
}
|
|
348
325
|
|
|
349
|
-
function useTmpDir(): string |
|
|
326
|
+
function useTmpDir(): string | undefined {
|
|
350
327
|
const [directory, setDirectory] = useState<DirectoryResult>();
|
|
351
328
|
const handleError = useErrorHandler();
|
|
352
329
|
useEffect(() => {
|
|
@@ -384,10 +361,10 @@ function useCustomBuild(
|
|
|
384
361
|
cwd?: undefined | string;
|
|
385
362
|
watch_dir?: undefined | string;
|
|
386
363
|
}
|
|
387
|
-
):
|
|
388
|
-
const [entry, setEntry] = useState<string |
|
|
364
|
+
): undefined | string {
|
|
365
|
+
const [entry, setEntry] = useState<string | undefined>(
|
|
389
366
|
// if there's no build command, just return the expected entry
|
|
390
|
-
props.command
|
|
367
|
+
props.command || expectedEntry
|
|
391
368
|
);
|
|
392
369
|
const { command, cwd, watch_dir } = props;
|
|
393
370
|
useEffect(() => {
|
|
@@ -456,16 +433,16 @@ type EsbuildBundle = {
|
|
|
456
433
|
};
|
|
457
434
|
|
|
458
435
|
function useEsbuild(props: {
|
|
459
|
-
entry:
|
|
460
|
-
destination: string |
|
|
461
|
-
staticRoot:
|
|
462
|
-
jsxFactory: string |
|
|
463
|
-
jsxFragment: string |
|
|
464
|
-
}): EsbuildBundle |
|
|
436
|
+
entry: undefined | string;
|
|
437
|
+
destination: string | undefined;
|
|
438
|
+
staticRoot: undefined | string;
|
|
439
|
+
jsxFactory: string | undefined;
|
|
440
|
+
jsxFragment: string | undefined;
|
|
441
|
+
}): EsbuildBundle | undefined {
|
|
465
442
|
const { entry, destination, staticRoot, jsxFactory, jsxFragment } = props;
|
|
466
443
|
const [bundle, setBundle] = useState<EsbuildBundle>();
|
|
467
444
|
useEffect(() => {
|
|
468
|
-
let result: esbuild.BuildResult;
|
|
445
|
+
let result: esbuild.BuildResult | undefined;
|
|
469
446
|
async function build() {
|
|
470
447
|
if (!destination || !entry) return;
|
|
471
448
|
const moduleCollector = makeModuleCollector();
|
|
@@ -491,25 +468,37 @@ function useEsbuild(props: {
|
|
|
491
468
|
else {
|
|
492
469
|
// nothing really changes here, so let's increment the id
|
|
493
470
|
// to change the return object's identity
|
|
494
|
-
setBundle((previousBundle) =>
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
471
|
+
setBundle((previousBundle) => {
|
|
472
|
+
if (previousBundle === undefined) {
|
|
473
|
+
assert.fail(
|
|
474
|
+
"Rebuild triggered with no previous build available"
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
return { ...previousBundle, id: previousBundle.id + 1 };
|
|
478
|
+
});
|
|
498
479
|
}
|
|
499
480
|
},
|
|
500
481
|
},
|
|
501
482
|
});
|
|
502
483
|
|
|
503
|
-
|
|
484
|
+
// result.metafile is defined because of the `metafile: true` option above.
|
|
485
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
486
|
+
const metafile = result.metafile!;
|
|
487
|
+
const outputEntry = Object.entries(metafile.outputs).find(
|
|
504
488
|
([_path, { entryPoint }]) => entryPoint === entry
|
|
505
489
|
); // assumedly only one entry point
|
|
506
490
|
|
|
491
|
+
if (outputEntry === undefined) {
|
|
492
|
+
throw new Error(
|
|
493
|
+
`Cannot find entry-point "${entry}" in generated bundle.`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
507
496
|
setBundle({
|
|
508
497
|
id: 0,
|
|
509
498
|
entry,
|
|
510
|
-
path:
|
|
511
|
-
type:
|
|
512
|
-
exports:
|
|
499
|
+
path: outputEntry[0],
|
|
500
|
+
type: outputEntry[1].exports.length > 0 ? "esm" : "commonjs",
|
|
501
|
+
exports: outputEntry[1].exports,
|
|
513
502
|
modules: moduleCollector.modules,
|
|
514
503
|
});
|
|
515
504
|
}
|
|
@@ -520,26 +509,26 @@ function useEsbuild(props: {
|
|
|
520
509
|
// so this is a no-op error handler
|
|
521
510
|
});
|
|
522
511
|
return () => {
|
|
523
|
-
result?.stop();
|
|
512
|
+
result?.stop?.();
|
|
524
513
|
};
|
|
525
514
|
}, [entry, destination, staticRoot, jsxFactory, jsxFragment]);
|
|
526
515
|
return bundle;
|
|
527
516
|
}
|
|
528
517
|
|
|
529
518
|
function useWorker(props: {
|
|
530
|
-
name:
|
|
531
|
-
bundle: EsbuildBundle |
|
|
519
|
+
name: undefined | string;
|
|
520
|
+
bundle: EsbuildBundle | undefined;
|
|
532
521
|
format: CfScriptFormat;
|
|
533
522
|
modules: CfModule[];
|
|
534
523
|
accountId: string;
|
|
535
524
|
apiToken: string;
|
|
536
525
|
bindings: CfWorkerInit["bindings"];
|
|
537
|
-
|
|
526
|
+
assetPaths: undefined | AssetPaths;
|
|
538
527
|
port: number;
|
|
539
|
-
compatibilityDate: string |
|
|
540
|
-
compatibilityFlags: string[] |
|
|
541
|
-
usageModel:
|
|
542
|
-
}): CfPreviewToken |
|
|
528
|
+
compatibilityDate: string | undefined;
|
|
529
|
+
compatibilityFlags: string[] | undefined;
|
|
530
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
531
|
+
}): CfPreviewToken | undefined {
|
|
543
532
|
const {
|
|
544
533
|
name,
|
|
545
534
|
bundle,
|
|
@@ -548,13 +537,13 @@ function useWorker(props: {
|
|
|
548
537
|
accountId,
|
|
549
538
|
apiToken,
|
|
550
539
|
bindings,
|
|
551
|
-
|
|
540
|
+
assetPaths,
|
|
552
541
|
compatibilityDate,
|
|
553
542
|
compatibilityFlags,
|
|
554
543
|
usageModel,
|
|
555
544
|
port,
|
|
556
545
|
} = props;
|
|
557
|
-
const [token, setToken] = useState<CfPreviewToken>();
|
|
546
|
+
const [token, setToken] = useState<CfPreviewToken | undefined>();
|
|
558
547
|
|
|
559
548
|
// This is the most reliable way to detect whether
|
|
560
549
|
// something's "happened" in our system; We make a ref and
|
|
@@ -563,6 +552,8 @@ function useWorker(props: {
|
|
|
563
552
|
|
|
564
553
|
useEffect(() => {
|
|
565
554
|
async function start() {
|
|
555
|
+
setToken(undefined); // reset token in case we're re-running
|
|
556
|
+
|
|
566
557
|
if (!bundle) return;
|
|
567
558
|
if (format === "modules" && bundle.type === "commonjs") {
|
|
568
559
|
console.error("⎔ Cannot use modules with a commonjs bundle.");
|
|
@@ -576,24 +567,17 @@ function useWorker(props: {
|
|
|
576
567
|
}
|
|
577
568
|
|
|
578
569
|
if (!startedRef.current) {
|
|
579
|
-
console.log("⎔ Starting server...");
|
|
580
570
|
startedRef.current = true;
|
|
581
571
|
} else {
|
|
582
572
|
console.log("⎔ Detected changes, restarting server...");
|
|
583
573
|
}
|
|
584
574
|
|
|
585
|
-
const assets =
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
undefined // TODO: env
|
|
592
|
-
)
|
|
593
|
-
: {
|
|
594
|
-
manifest: undefined,
|
|
595
|
-
namespace: undefined,
|
|
596
|
-
}; // TODO: cancellable?
|
|
575
|
+
const assets = await syncAssets(
|
|
576
|
+
accountId,
|
|
577
|
+
path.basename(bundle.path),
|
|
578
|
+
assetPaths,
|
|
579
|
+
true
|
|
580
|
+
); // TODO: cancellable?
|
|
597
581
|
|
|
598
582
|
const content = await readFile(bundle.path, "utf-8");
|
|
599
583
|
const init: CfWorkerInit = {
|
|
@@ -644,7 +628,7 @@ function useWorker(props: {
|
|
|
644
628
|
accountId,
|
|
645
629
|
apiToken,
|
|
646
630
|
port,
|
|
647
|
-
|
|
631
|
+
assetPaths,
|
|
648
632
|
compatibilityDate,
|
|
649
633
|
compatibilityFlags,
|
|
650
634
|
usageModel,
|
|
@@ -654,85 +638,6 @@ function useWorker(props: {
|
|
|
654
638
|
return token;
|
|
655
639
|
}
|
|
656
640
|
|
|
657
|
-
function useProxy({
|
|
658
|
-
token,
|
|
659
|
-
publicRoot,
|
|
660
|
-
port,
|
|
661
|
-
}: {
|
|
662
|
-
token: CfPreviewToken | void;
|
|
663
|
-
publicRoot: void | string;
|
|
664
|
-
port: number;
|
|
665
|
-
}) {
|
|
666
|
-
useEffect(() => {
|
|
667
|
-
if (!token) return;
|
|
668
|
-
// TODO(soon): since headers are added in callbacks, the server
|
|
669
|
-
// does not need to restart when changes are made.
|
|
670
|
-
const host = token.host;
|
|
671
|
-
const proxy = createHttpProxy({
|
|
672
|
-
host,
|
|
673
|
-
assetPath: typeof publicRoot === "string" ? publicRoot : null,
|
|
674
|
-
onRequest: (headers) => {
|
|
675
|
-
headers["cf-workers-preview-token"] = token.value;
|
|
676
|
-
},
|
|
677
|
-
onResponse: (headers) => {
|
|
678
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
679
|
-
// Rewrite the remote host to the local host.
|
|
680
|
-
if (typeof value === "string" && value.includes(host)) {
|
|
681
|
-
headers[name] = value
|
|
682
|
-
.replaceAll(`https://${host}`, `http://localhost:${port}`)
|
|
683
|
-
.replaceAll(host, `localhost:${port}`);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
},
|
|
687
|
-
});
|
|
688
|
-
|
|
689
|
-
console.log(`⬣ Listening at http://localhost:${port}`);
|
|
690
|
-
|
|
691
|
-
const server = proxy.listen(port);
|
|
692
|
-
|
|
693
|
-
// TODO(soon): refactor logging format into its own function
|
|
694
|
-
proxy.on("request", function (req, res) {
|
|
695
|
-
// log all requests
|
|
696
|
-
console.log(
|
|
697
|
-
new Date().toLocaleTimeString(),
|
|
698
|
-
req.method,
|
|
699
|
-
req.url,
|
|
700
|
-
res.statusCode
|
|
701
|
-
);
|
|
702
|
-
});
|
|
703
|
-
proxy.on("upgrade", (req) => {
|
|
704
|
-
console.log(
|
|
705
|
-
new Date().toLocaleTimeString(),
|
|
706
|
-
req.method,
|
|
707
|
-
req.url,
|
|
708
|
-
101,
|
|
709
|
-
"(WebSocket)"
|
|
710
|
-
);
|
|
711
|
-
});
|
|
712
|
-
proxy.on("error", (err) => {
|
|
713
|
-
console.error(new Date().toLocaleTimeString(), err);
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
return () => {
|
|
717
|
-
proxy.close();
|
|
718
|
-
server.close();
|
|
719
|
-
};
|
|
720
|
-
}, [token, publicRoot, port]);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
function useInspector(inspectorUrl: string | void) {
|
|
724
|
-
useEffect(() => {
|
|
725
|
-
if (!inspectorUrl) return;
|
|
726
|
-
|
|
727
|
-
const inspector = new DtInspector(inspectorUrl);
|
|
728
|
-
const abortController = inspector.proxyTo(9229);
|
|
729
|
-
return () => {
|
|
730
|
-
inspector.close();
|
|
731
|
-
abortController.abort();
|
|
732
|
-
};
|
|
733
|
-
}, [inspectorUrl]);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
641
|
function sleep(period: number) {
|
|
737
642
|
return new Promise((resolve) => setTimeout(resolve, period));
|
|
738
643
|
}
|
|
@@ -740,7 +645,7 @@ const SLEEP_DURATION = 2000;
|
|
|
740
645
|
// really need a first class api for this
|
|
741
646
|
const hostNameRegex = /userHostname="(.*)"/g;
|
|
742
647
|
async function findTunnelHostname() {
|
|
743
|
-
let hostName: string;
|
|
648
|
+
let hostName: string | undefined;
|
|
744
649
|
while (!hostName) {
|
|
745
650
|
try {
|
|
746
651
|
const resp = await fetch("http://localhost:8789/metrics");
|
|
@@ -866,7 +771,7 @@ function ErrorFallback(props: { error: Error }) {
|
|
|
866
771
|
return (
|
|
867
772
|
<>
|
|
868
773
|
<Text>Something went wrong:</Text>
|
|
869
|
-
<Text>{props.error.
|
|
774
|
+
<Text>{props.error.stack}</Text>
|
|
870
775
|
</>
|
|
871
776
|
);
|
|
872
777
|
}
|