wrangler 0.0.0-e1c615f → 0.0.0-e22f9d7
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 +3 -2
- package/pages/functions/buildWorker.ts +5 -0
- package/pages/functions/template-worker.ts +9 -2
- package/src/__tests__/dev.test.tsx +3 -2
- package/src/__tests__/kv.test.ts +24 -11
- package/src/__tests__/mock-cfetch.ts +4 -4
- package/src/api/form_data.ts +1 -1
- package/src/api/worker.ts +6 -6
- package/src/cfetch/internal.ts +4 -4
- package/src/config.ts +475 -119
- package/src/dev.tsx +107 -197
- package/src/index.tsx +50 -5
- package/src/inspect.ts +539 -0
- package/src/kv.tsx +18 -9
- package/src/pages.tsx +98 -35
- package/src/proxy.ts +275 -76
- package/src/publish.ts +40 -26
- package/src/sites.tsx +5 -1
- package/src/user.tsx +22 -17
- package/wrangler-dist/cli.js +30051 -29836
- package/wrangler-dist/cli.js.map +3 -3
- package/src/api/inspect.ts +0 -430
package/src/dev.tsx
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
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";
|
|
17
28
|
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
29
|
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
30
|
|
|
30
|
-
type CfScriptFormat =
|
|
31
|
+
type CfScriptFormat = undefined | "modules" | "service-worker";
|
|
31
32
|
|
|
32
33
|
export type DevProps = {
|
|
33
34
|
name?: string;
|
|
34
35
|
entry: string;
|
|
35
36
|
port?: number;
|
|
36
37
|
format: CfScriptFormat;
|
|
37
|
-
accountId:
|
|
38
|
+
accountId: undefined | string;
|
|
38
39
|
initialMode: "local" | "remote";
|
|
39
|
-
jsxFactory:
|
|
40
|
-
jsxFragment:
|
|
40
|
+
jsxFactory: undefined | string;
|
|
41
|
+
jsxFragment: undefined | string;
|
|
41
42
|
bindings: CfWorkerInit["bindings"];
|
|
42
|
-
public:
|
|
43
|
-
site:
|
|
44
|
-
compatibilityDate:
|
|
45
|
-
compatibilityFlags:
|
|
46
|
-
usageModel:
|
|
43
|
+
public: undefined | string;
|
|
44
|
+
site: undefined | string;
|
|
45
|
+
compatibilityDate: undefined | string;
|
|
46
|
+
compatibilityFlags: undefined | string[];
|
|
47
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
47
48
|
buildCommand: {
|
|
48
49
|
command?: undefined | string;
|
|
49
50
|
cwd?: undefined | string;
|
|
@@ -57,7 +58,7 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
57
58
|
"You cannot use the service worker format with a `public` directory."
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
|
-
const port = props.port
|
|
61
|
+
const port = props.port ?? 8787;
|
|
61
62
|
const apiToken = getAPIToken();
|
|
62
63
|
const directory = useTmpDir();
|
|
63
64
|
|
|
@@ -79,9 +80,6 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
// @ts-expect-error whack
|
|
83
|
-
useDevtoolsRefresh(bundle?.id ?? 0);
|
|
84
|
-
|
|
85
83
|
const toggles = useHotkeys(
|
|
86
84
|
{
|
|
87
85
|
local: props.initialMode === "local",
|
|
@@ -102,7 +100,7 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
102
100
|
bindings={props.bindings}
|
|
103
101
|
site={props.site}
|
|
104
102
|
public={props.public}
|
|
105
|
-
port={
|
|
103
|
+
port={port}
|
|
106
104
|
/>
|
|
107
105
|
) : (
|
|
108
106
|
<Remote
|
|
@@ -114,7 +112,7 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
114
112
|
bindings={props.bindings}
|
|
115
113
|
site={props.site}
|
|
116
114
|
public={props.public}
|
|
117
|
-
port={
|
|
115
|
+
port={port}
|
|
118
116
|
compatibilityDate={props.compatibilityDate}
|
|
119
117
|
compatibilityFlags={props.compatibilityFlags}
|
|
120
118
|
usageModel={props.usageModel}
|
|
@@ -133,53 +131,23 @@ function Dev(props: DevProps): JSX.Element {
|
|
|
133
131
|
);
|
|
134
132
|
}
|
|
135
133
|
|
|
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
134
|
function Remote(props: {
|
|
167
|
-
name:
|
|
168
|
-
bundle: EsbuildBundle |
|
|
135
|
+
name: undefined | string;
|
|
136
|
+
bundle: EsbuildBundle | undefined;
|
|
169
137
|
format: CfScriptFormat;
|
|
170
|
-
public:
|
|
171
|
-
site:
|
|
138
|
+
public: undefined | string;
|
|
139
|
+
site: undefined | string;
|
|
172
140
|
port: number;
|
|
173
|
-
accountId:
|
|
174
|
-
apiToken:
|
|
141
|
+
accountId: undefined | string;
|
|
142
|
+
apiToken: undefined | string;
|
|
175
143
|
bindings: CfWorkerInit["bindings"];
|
|
176
|
-
compatibilityDate: string |
|
|
177
|
-
compatibilityFlags:
|
|
178
|
-
usageModel:
|
|
144
|
+
compatibilityDate: string | undefined;
|
|
145
|
+
compatibilityFlags: undefined | string[];
|
|
146
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
179
147
|
}) {
|
|
180
148
|
assert(props.accountId, "accountId is required");
|
|
181
149
|
assert(props.apiToken, "apiToken is required");
|
|
182
|
-
const
|
|
150
|
+
const previewToken = useWorker({
|
|
183
151
|
name: props.name,
|
|
184
152
|
bundle: props.bundle,
|
|
185
153
|
format: props.format,
|
|
@@ -194,18 +162,26 @@ function Remote(props: {
|
|
|
194
162
|
usageModel: props.usageModel,
|
|
195
163
|
});
|
|
196
164
|
|
|
197
|
-
|
|
165
|
+
usePreviewServer({
|
|
166
|
+
previewToken,
|
|
167
|
+
publicRoot: props.public,
|
|
168
|
+
port: props.port,
|
|
169
|
+
});
|
|
198
170
|
|
|
199
|
-
useInspector(
|
|
171
|
+
useInspector({
|
|
172
|
+
inspectorUrl: previewToken ? previewToken.inspectorUrl.href : undefined,
|
|
173
|
+
port: 9229,
|
|
174
|
+
logToTerminal: true,
|
|
175
|
+
});
|
|
200
176
|
return null;
|
|
201
177
|
}
|
|
202
178
|
function Local(props: {
|
|
203
|
-
name:
|
|
204
|
-
bundle: EsbuildBundle |
|
|
179
|
+
name: undefined | string;
|
|
180
|
+
bundle: EsbuildBundle | undefined;
|
|
205
181
|
format: CfScriptFormat;
|
|
206
182
|
bindings: CfWorkerInit["bindings"];
|
|
207
|
-
public:
|
|
208
|
-
site:
|
|
183
|
+
public: undefined | string;
|
|
184
|
+
site: undefined | string;
|
|
209
185
|
port: number;
|
|
210
186
|
}) {
|
|
211
187
|
const { inspectorUrl } = useLocalWorker({
|
|
@@ -215,13 +191,13 @@ function Local(props: {
|
|
|
215
191
|
bindings: props.bindings,
|
|
216
192
|
port: props.port,
|
|
217
193
|
});
|
|
218
|
-
useInspector(inspectorUrl);
|
|
194
|
+
useInspector({ inspectorUrl, port: 9229, logToTerminal: false });
|
|
219
195
|
return null;
|
|
220
196
|
}
|
|
221
197
|
|
|
222
198
|
function useLocalWorker(props: {
|
|
223
|
-
name:
|
|
224
|
-
bundle: EsbuildBundle |
|
|
199
|
+
name: undefined | string;
|
|
200
|
+
bundle: EsbuildBundle | undefined;
|
|
225
201
|
format: CfScriptFormat;
|
|
226
202
|
bindings: CfWorkerInit["bindings"];
|
|
227
203
|
port: number;
|
|
@@ -230,7 +206,7 @@ function useLocalWorker(props: {
|
|
|
230
206
|
const { bundle, format, bindings, port } = props;
|
|
231
207
|
const local = useRef<ReturnType<typeof spawn>>();
|
|
232
208
|
const removeSignalExitListener = useRef<() => void>();
|
|
233
|
-
const [inspectorUrl, setInspectorUrl] = useState<string |
|
|
209
|
+
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
234
210
|
useEffect(() => {
|
|
235
211
|
async function startLocalWorker() {
|
|
236
212
|
if (!bundle) return;
|
|
@@ -289,11 +265,11 @@ function useLocalWorker(props: {
|
|
|
289
265
|
}
|
|
290
266
|
});
|
|
291
267
|
|
|
292
|
-
local.current.stdout
|
|
268
|
+
local.current.stdout?.on("data", (data: Buffer) => {
|
|
293
269
|
console.log(`${data.toString()}`);
|
|
294
270
|
});
|
|
295
271
|
|
|
296
|
-
local.current.stderr
|
|
272
|
+
local.current.stderr?.on("data", (data: Buffer) => {
|
|
297
273
|
console.error(`${data.toString()}`);
|
|
298
274
|
const matches =
|
|
299
275
|
/Debugger listening on (ws:\/\/127\.0\.0\.1:9229\/[A-Za-z0-9-]+)/.exec(
|
|
@@ -346,7 +322,7 @@ function useLocalWorker(props: {
|
|
|
346
322
|
return { inspectorUrl };
|
|
347
323
|
}
|
|
348
324
|
|
|
349
|
-
function useTmpDir(): string |
|
|
325
|
+
function useTmpDir(): string | undefined {
|
|
350
326
|
const [directory, setDirectory] = useState<DirectoryResult>();
|
|
351
327
|
const handleError = useErrorHandler();
|
|
352
328
|
useEffect(() => {
|
|
@@ -384,10 +360,10 @@ function useCustomBuild(
|
|
|
384
360
|
cwd?: undefined | string;
|
|
385
361
|
watch_dir?: undefined | string;
|
|
386
362
|
}
|
|
387
|
-
):
|
|
388
|
-
const [entry, setEntry] = useState<string |
|
|
363
|
+
): undefined | string {
|
|
364
|
+
const [entry, setEntry] = useState<string | undefined>(
|
|
389
365
|
// if there's no build command, just return the expected entry
|
|
390
|
-
props.command
|
|
366
|
+
props.command || expectedEntry
|
|
391
367
|
);
|
|
392
368
|
const { command, cwd, watch_dir } = props;
|
|
393
369
|
useEffect(() => {
|
|
@@ -456,16 +432,16 @@ type EsbuildBundle = {
|
|
|
456
432
|
};
|
|
457
433
|
|
|
458
434
|
function useEsbuild(props: {
|
|
459
|
-
entry:
|
|
460
|
-
destination: string |
|
|
461
|
-
staticRoot:
|
|
462
|
-
jsxFactory: string |
|
|
463
|
-
jsxFragment: string |
|
|
464
|
-
}): EsbuildBundle |
|
|
435
|
+
entry: undefined | string;
|
|
436
|
+
destination: string | undefined;
|
|
437
|
+
staticRoot: undefined | string;
|
|
438
|
+
jsxFactory: string | undefined;
|
|
439
|
+
jsxFragment: string | undefined;
|
|
440
|
+
}): EsbuildBundle | undefined {
|
|
465
441
|
const { entry, destination, staticRoot, jsxFactory, jsxFragment } = props;
|
|
466
442
|
const [bundle, setBundle] = useState<EsbuildBundle>();
|
|
467
443
|
useEffect(() => {
|
|
468
|
-
let result: esbuild.BuildResult;
|
|
444
|
+
let result: esbuild.BuildResult | undefined;
|
|
469
445
|
async function build() {
|
|
470
446
|
if (!destination || !entry) return;
|
|
471
447
|
const moduleCollector = makeModuleCollector();
|
|
@@ -491,25 +467,37 @@ function useEsbuild(props: {
|
|
|
491
467
|
else {
|
|
492
468
|
// nothing really changes here, so let's increment the id
|
|
493
469
|
// to change the return object's identity
|
|
494
|
-
setBundle((previousBundle) =>
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
470
|
+
setBundle((previousBundle) => {
|
|
471
|
+
if (previousBundle === undefined) {
|
|
472
|
+
assert.fail(
|
|
473
|
+
"Rebuild triggered with no previous build available"
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
return { ...previousBundle, id: previousBundle.id + 1 };
|
|
477
|
+
});
|
|
498
478
|
}
|
|
499
479
|
},
|
|
500
480
|
},
|
|
501
481
|
});
|
|
502
482
|
|
|
503
|
-
|
|
483
|
+
// result.metafile is defined because of the `metafile: true` option above.
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
485
|
+
const metafile = result.metafile!;
|
|
486
|
+
const outputEntry = Object.entries(metafile.outputs).find(
|
|
504
487
|
([_path, { entryPoint }]) => entryPoint === entry
|
|
505
488
|
); // assumedly only one entry point
|
|
506
489
|
|
|
490
|
+
if (outputEntry === undefined) {
|
|
491
|
+
throw new Error(
|
|
492
|
+
`Cannot find entry-point "${entry}" in generated bundle.`
|
|
493
|
+
);
|
|
494
|
+
}
|
|
507
495
|
setBundle({
|
|
508
496
|
id: 0,
|
|
509
497
|
entry,
|
|
510
|
-
path:
|
|
511
|
-
type:
|
|
512
|
-
exports:
|
|
498
|
+
path: outputEntry[0],
|
|
499
|
+
type: outputEntry[1].exports.length > 0 ? "esm" : "commonjs",
|
|
500
|
+
exports: outputEntry[1].exports,
|
|
513
501
|
modules: moduleCollector.modules,
|
|
514
502
|
});
|
|
515
503
|
}
|
|
@@ -520,26 +508,26 @@ function useEsbuild(props: {
|
|
|
520
508
|
// so this is a no-op error handler
|
|
521
509
|
});
|
|
522
510
|
return () => {
|
|
523
|
-
result?.stop();
|
|
511
|
+
result?.stop?.();
|
|
524
512
|
};
|
|
525
513
|
}, [entry, destination, staticRoot, jsxFactory, jsxFragment]);
|
|
526
514
|
return bundle;
|
|
527
515
|
}
|
|
528
516
|
|
|
529
517
|
function useWorker(props: {
|
|
530
|
-
name:
|
|
531
|
-
bundle: EsbuildBundle |
|
|
518
|
+
name: undefined | string;
|
|
519
|
+
bundle: EsbuildBundle | undefined;
|
|
532
520
|
format: CfScriptFormat;
|
|
533
521
|
modules: CfModule[];
|
|
534
522
|
accountId: string;
|
|
535
523
|
apiToken: string;
|
|
536
524
|
bindings: CfWorkerInit["bindings"];
|
|
537
|
-
sitesFolder:
|
|
525
|
+
sitesFolder: undefined | string;
|
|
538
526
|
port: number;
|
|
539
|
-
compatibilityDate: string |
|
|
540
|
-
compatibilityFlags: string[] |
|
|
541
|
-
usageModel:
|
|
542
|
-
}): CfPreviewToken |
|
|
527
|
+
compatibilityDate: string | undefined;
|
|
528
|
+
compatibilityFlags: string[] | undefined;
|
|
529
|
+
usageModel: undefined | "bundled" | "unbound";
|
|
530
|
+
}): CfPreviewToken | undefined {
|
|
543
531
|
const {
|
|
544
532
|
name,
|
|
545
533
|
bundle,
|
|
@@ -554,7 +542,7 @@ function useWorker(props: {
|
|
|
554
542
|
usageModel,
|
|
555
543
|
port,
|
|
556
544
|
} = props;
|
|
557
|
-
const [token, setToken] = useState<CfPreviewToken>();
|
|
545
|
+
const [token, setToken] = useState<CfPreviewToken | undefined>();
|
|
558
546
|
|
|
559
547
|
// This is the most reliable way to detect whether
|
|
560
548
|
// something's "happened" in our system; We make a ref and
|
|
@@ -563,6 +551,8 @@ function useWorker(props: {
|
|
|
563
551
|
|
|
564
552
|
useEffect(() => {
|
|
565
553
|
async function start() {
|
|
554
|
+
setToken(undefined); // reset token in case we're re-running
|
|
555
|
+
|
|
566
556
|
if (!bundle) return;
|
|
567
557
|
if (format === "modules" && bundle.type === "commonjs") {
|
|
568
558
|
console.error("⎔ Cannot use modules with a commonjs bundle.");
|
|
@@ -576,7 +566,6 @@ function useWorker(props: {
|
|
|
576
566
|
}
|
|
577
567
|
|
|
578
568
|
if (!startedRef.current) {
|
|
579
|
-
console.log("⎔ Starting server...");
|
|
580
569
|
startedRef.current = true;
|
|
581
570
|
} else {
|
|
582
571
|
console.log("⎔ Detected changes, restarting server...");
|
|
@@ -654,85 +643,6 @@ function useWorker(props: {
|
|
|
654
643
|
return token;
|
|
655
644
|
}
|
|
656
645
|
|
|
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
646
|
function sleep(period: number) {
|
|
737
647
|
return new Promise((resolve) => setTimeout(resolve, period));
|
|
738
648
|
}
|
|
@@ -740,7 +650,7 @@ const SLEEP_DURATION = 2000;
|
|
|
740
650
|
// really need a first class api for this
|
|
741
651
|
const hostNameRegex = /userHostname="(.*)"/g;
|
|
742
652
|
async function findTunnelHostname() {
|
|
743
|
-
let hostName: string;
|
|
653
|
+
let hostName: string | undefined;
|
|
744
654
|
while (!hostName) {
|
|
745
655
|
try {
|
|
746
656
|
const resp = await fetch("http://localhost:8789/metrics");
|
|
@@ -866,7 +776,7 @@ function ErrorFallback(props: { error: Error }) {
|
|
|
866
776
|
return (
|
|
867
777
|
<>
|
|
868
778
|
<Text>Something went wrong:</Text>
|
|
869
|
-
<Text>{props.error.
|
|
779
|
+
<Text>{props.error.stack}</Text>
|
|
870
780
|
</>
|
|
871
781
|
);
|
|
872
782
|
}
|
package/src/index.tsx
CHANGED
|
@@ -435,6 +435,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
435
435
|
type: "string",
|
|
436
436
|
// TODO: get choices for the toml file?
|
|
437
437
|
})
|
|
438
|
+
.option("compatibility-date", {
|
|
439
|
+
describe: "Date to use for compatibility checks",
|
|
440
|
+
type: "string",
|
|
441
|
+
})
|
|
442
|
+
.option("compatibility-flags", {
|
|
443
|
+
describe: "Flags to use for compatibility checks",
|
|
444
|
+
type: "array",
|
|
445
|
+
alias: "compatibility-flag",
|
|
446
|
+
})
|
|
447
|
+
.option("latest", {
|
|
448
|
+
describe: "Use the latest version of the worker runtime",
|
|
449
|
+
type: "boolean",
|
|
450
|
+
default: true,
|
|
451
|
+
})
|
|
438
452
|
.option("ip", {
|
|
439
453
|
describe: "IP address to listen on",
|
|
440
454
|
type: "string",
|
|
@@ -520,7 +534,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
520
534
|
if ("durable_objects" in envRootObj) {
|
|
521
535
|
if (!(args.name || config.name)) {
|
|
522
536
|
console.warn(
|
|
523
|
-
'A worker with durable objects
|
|
537
|
+
'A worker with durable objects needs to be named, or it may not work as expected. Add a "name" into wrangler.toml, or pass it in the command line with --name.'
|
|
524
538
|
);
|
|
525
539
|
}
|
|
526
540
|
// TODO: if not already published, publish a draft worker
|
|
@@ -539,8 +553,15 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
539
553
|
site={args.site || config.site?.bucket}
|
|
540
554
|
port={args.port || config.dev?.port}
|
|
541
555
|
public={args["experimental-public"]}
|
|
542
|
-
compatibilityDate={
|
|
543
|
-
|
|
556
|
+
compatibilityDate={
|
|
557
|
+
args["compatibility-date"] ||
|
|
558
|
+
config.compatibility_date ||
|
|
559
|
+
new Date().toISOString().substring(0, 10)
|
|
560
|
+
}
|
|
561
|
+
compatibilityFlags={
|
|
562
|
+
(args["compatibility-flags"] as string[]) ||
|
|
563
|
+
config.compatibility_flags
|
|
564
|
+
}
|
|
544
565
|
usageModel={config.usage_model}
|
|
545
566
|
bindings={{
|
|
546
567
|
kv_namespaces: envRootObj.kv_namespaces?.map(
|
|
@@ -592,6 +613,20 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
592
613
|
describe: "name to use when uploading",
|
|
593
614
|
type: "string",
|
|
594
615
|
})
|
|
616
|
+
.option("compatibility-date", {
|
|
617
|
+
describe: "Date to use for compatibility checks",
|
|
618
|
+
type: "string",
|
|
619
|
+
})
|
|
620
|
+
.option("compatibility-flags", {
|
|
621
|
+
describe: "Flags to use for compatibility checks",
|
|
622
|
+
type: "array",
|
|
623
|
+
alias: "compatibility-flag",
|
|
624
|
+
})
|
|
625
|
+
.option("latest", {
|
|
626
|
+
describe: "Use the latest version of the worker runtime",
|
|
627
|
+
type: "boolean",
|
|
628
|
+
default: false,
|
|
629
|
+
})
|
|
595
630
|
.option("experimental-public", {
|
|
596
631
|
describe: "Static assets to be served",
|
|
597
632
|
type: "string",
|
|
@@ -645,6 +680,12 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
645
680
|
|
|
646
681
|
const config = args.config as Config;
|
|
647
682
|
|
|
683
|
+
if (args.latest) {
|
|
684
|
+
console.warn(
|
|
685
|
+
"⚠️ Using the latest version of the Workers runtime. To silence this warning, please choose a specific version of the runtime with --compatibility-date, or add a compatibility_date to your wrangler.toml.\n"
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
|
|
648
689
|
// -- snip, extract --
|
|
649
690
|
if (!args.local) {
|
|
650
691
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
@@ -668,6 +709,10 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
668
709
|
name: args.name,
|
|
669
710
|
script: args.script,
|
|
670
711
|
env: args.env,
|
|
712
|
+
compatibilityDate: args.latest
|
|
713
|
+
? new Date().toISOString().substring(0, 10)
|
|
714
|
+
: args["compatibility-date"],
|
|
715
|
+
compatibilityFlags: args["compatibility-flags"] as string[],
|
|
671
716
|
triggers: args.triggers,
|
|
672
717
|
jsxFactory: args["jsx-factory"],
|
|
673
718
|
jsxFragment: args["jsx-fragment"],
|
|
@@ -1810,11 +1855,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1810
1855
|
)
|
|
1811
1856
|
.command(
|
|
1812
1857
|
"delete <filename>",
|
|
1813
|
-
"
|
|
1858
|
+
"Delete multiple key-value pairs from a namespace",
|
|
1814
1859
|
(yargs) => {
|
|
1815
1860
|
return yargs
|
|
1816
1861
|
.positional("filename", {
|
|
1817
|
-
describe: `The JSON file of
|
|
1862
|
+
describe: `The JSON file of keys to delete, in the form ["key1", "key2", ...]`,
|
|
1818
1863
|
type: "string",
|
|
1819
1864
|
})
|
|
1820
1865
|
.option("binding", {
|