wrangler 0.0.0-e5d3690 → 0.0.0-e88a54e
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 +2 -2
- package/miniflare-dist/index.mjs +79 -0
- package/miniflare-dist/index.mjs.map +7 -0
- package/package.json +32 -16
- package/pages/functions/buildWorker.ts +1 -1
- package/pages/functions/filepath-routing.test.ts +212 -28
- package/pages/functions/filepath-routing.ts +83 -130
- package/pages/functions/routes.ts +11 -18
- package/pages/functions/template-worker.ts +3 -9
- package/src/__tests__/configuration.test.ts +2796 -0
- package/src/__tests__/dev.test.tsx +488 -59
- package/src/__tests__/dev2.test.tsx +154 -0
- package/src/__tests__/guess-worker-format.test.ts +58 -0
- package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
- package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
- package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
- package/src/__tests__/helpers/mock-account-id.ts +48 -0
- package/src/__tests__/helpers/mock-bin.ts +36 -0
- package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +48 -14
- package/src/__tests__/helpers/mock-console.ts +70 -0
- package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
- package/src/__tests__/helpers/mock-kv.ts +33 -0
- package/src/__tests__/helpers/mock-stdin.ts +103 -0
- package/src/__tests__/helpers/mock-web-socket.ts +29 -0
- package/src/__tests__/helpers/run-in-tmp.ts +32 -0
- package/src/__tests__/helpers/run-wrangler.ts +16 -0
- package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
- package/src/__tests__/https-options.test.ts +127 -0
- package/src/__tests__/index.test.ts +777 -75
- package/src/__tests__/jest.setup.ts +53 -6
- package/src/__tests__/kv.test.ts +674 -491
- package/src/__tests__/logout.test.ts +52 -0
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/pages.test.ts +44 -0
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +2327 -295
- package/src/__tests__/r2.test.ts +198 -0
- package/src/__tests__/route.test.ts +45 -0
- package/src/__tests__/secret.test.ts +425 -0
- package/src/__tests__/sentry.test.ts +146 -0
- package/src/__tests__/tail.test.ts +564 -0
- package/src/__tests__/whoami.test.tsx +26 -56
- package/src/bundle.ts +142 -0
- package/src/cfetch/index.ts +13 -19
- package/src/cfetch/internal.ts +91 -23
- package/src/cli.ts +10 -0
- package/src/config/README.md +107 -0
- package/src/config/config.ts +218 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +366 -0
- package/src/config/index.ts +62 -0
- package/src/config/validation-helpers.ts +486 -0
- package/src/config/validation.ts +1090 -0
- package/src/{api/preview.ts → create-worker-preview.ts} +61 -23
- package/src/create-worker-upload-form.ts +217 -0
- package/src/dev/dev.tsx +364 -0
- package/src/dev/local.tsx +232 -0
- package/src/dev/remote.tsx +203 -0
- package/src/dev/use-esbuild.ts +100 -0
- package/src/dialogs.tsx +2 -2
- package/src/entry.ts +208 -0
- package/src/environment-variables.ts +33 -0
- package/src/https-options.ts +122 -0
- package/src/index.tsx +1175 -777
- package/src/inspect.ts +95 -21
- package/src/{kv.tsx → kv.ts} +104 -61
- package/src/miniflare-cli/README.md +30 -0
- package/src/miniflare-cli/enum-keys.ts +17 -0
- package/src/miniflare-cli/index.ts +37 -0
- package/src/module-collection.ts +229 -35
- package/src/open-in-browser.ts +25 -0
- package/src/package-manager.ts +126 -0
- package/src/pages.tsx +39 -32
- package/src/parse.ts +183 -0
- package/src/paths.ts +26 -0
- package/src/proxy.ts +177 -39
- package/src/publish.ts +274 -309
- package/src/r2.ts +50 -0
- package/src/reporting.ts +131 -0
- package/src/selfsigned.d.ts +29 -0
- package/src/sites.tsx +95 -58
- package/src/tail/filters.ts +279 -0
- package/src/tail/index.ts +299 -0
- package/src/tail/printing.ts +62 -0
- package/src/user.tsx +233 -134
- package/src/{api/worker.ts → worker.ts} +45 -37
- package/templates/new-worker.js +15 -0
- package/templates/new-worker.ts +15 -0
- package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
- package/templates/tsconfig.json +105 -0
- package/wrangler-dist/cli.js +130352 -112740
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/run-in-tmp.ts +0 -19
- package/src/__tests__/run-wrangler.ts +0 -32
- package/src/api/form_data.ts +0 -131
- package/src/config.ts +0 -646
- package/src/dev.tsx +0 -779
- package/src/tail.tsx +0 -73
package/src/inspect.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import { createServer } from "http";
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { URL } from "node:url";
|
|
4
|
+
|
|
6
5
|
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
7
7
|
import { version } from "../package.json";
|
|
8
|
-
|
|
8
|
+
import { waitForPortToBeAvailable } from "./proxy";
|
|
9
9
|
import type Protocol from "devtools-protocol";
|
|
10
|
+
import type { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
11
|
+
import type { MessageEvent } from "ws";
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* `useInspector` is a hook for debugging Workers applications
|
|
@@ -152,7 +154,14 @@ export default function useInspector(props: InspectorProps) {
|
|
|
152
154
|
* of the component lifecycle. Convenient.
|
|
153
155
|
*/
|
|
154
156
|
useEffect(() => {
|
|
155
|
-
|
|
157
|
+
async function startInspectorProxy() {
|
|
158
|
+
await waitForPortToBeAvailable(props.port, {
|
|
159
|
+
retryPeriod: 200,
|
|
160
|
+
timeout: 2000,
|
|
161
|
+
});
|
|
162
|
+
server.listen(props.port);
|
|
163
|
+
}
|
|
164
|
+
startInspectorProxy().catch((err) => console.error(err));
|
|
156
165
|
return () => {
|
|
157
166
|
server.close();
|
|
158
167
|
// Also disconnect any open websockets/devtools connections
|
|
@@ -315,9 +324,14 @@ export default function useInspector(props: InspectorProps) {
|
|
|
315
324
|
};
|
|
316
325
|
}, [
|
|
317
326
|
props.inspectorUrl,
|
|
318
|
-
retryRemoteWebSocketConnectionSigil,
|
|
319
327
|
props.logToTerminal,
|
|
320
328
|
wsServer,
|
|
329
|
+
// We use a state value as a sigil to trigger a retry of the
|
|
330
|
+
// remote websocket connection. It's not used inside the effect,
|
|
331
|
+
// so react-hooks/exhaustive-deps doesn't complain if it's not
|
|
332
|
+
// included in the dependency array. But its presence is critical,
|
|
333
|
+
// so do NOT remove it from the dependency list.
|
|
334
|
+
retryRemoteWebSocketConnectionSigil,
|
|
321
335
|
]);
|
|
322
336
|
|
|
323
337
|
/**
|
|
@@ -361,7 +375,10 @@ export default function useInspector(props: InspectorProps) {
|
|
|
361
375
|
);
|
|
362
376
|
remoteWebSocket.send(event.data);
|
|
363
377
|
} catch (e) {
|
|
364
|
-
if (
|
|
378
|
+
if (
|
|
379
|
+
(e as Error).message !==
|
|
380
|
+
"WebSocket is not open: readyState 0 (CONNECTING)"
|
|
381
|
+
) {
|
|
365
382
|
/**
|
|
366
383
|
* ^ this just means we haven't opened a websocket yet
|
|
367
384
|
* usually happens until there's at least one request
|
|
@@ -432,6 +449,33 @@ function randomId(): string {
|
|
|
432
449
|
* we're just doing a little bit of the work of the devtools console,
|
|
433
450
|
* directly in the terminal.
|
|
434
451
|
*/
|
|
452
|
+
|
|
453
|
+
export const mapConsoleAPIMessageTypeToConsoleMethod: {
|
|
454
|
+
[key in Protocol.Runtime.ConsoleAPICalledEvent["type"]]: Exclude<
|
|
455
|
+
keyof Console,
|
|
456
|
+
"Console"
|
|
457
|
+
>;
|
|
458
|
+
} = {
|
|
459
|
+
log: "log",
|
|
460
|
+
debug: "debug",
|
|
461
|
+
info: "info",
|
|
462
|
+
warning: "warn",
|
|
463
|
+
error: "error",
|
|
464
|
+
dir: "dir",
|
|
465
|
+
dirxml: "dirxml",
|
|
466
|
+
table: "table",
|
|
467
|
+
trace: "trace",
|
|
468
|
+
clear: "clear",
|
|
469
|
+
count: "count",
|
|
470
|
+
assert: "assert",
|
|
471
|
+
profile: "profile",
|
|
472
|
+
profileEnd: "profileEnd",
|
|
473
|
+
timeEnd: "timeEnd",
|
|
474
|
+
startGroup: "group",
|
|
475
|
+
startGroupCollapsed: "groupCollapsed",
|
|
476
|
+
endGroup: "groupEnd",
|
|
477
|
+
};
|
|
478
|
+
|
|
435
479
|
function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
436
480
|
const args: string[] = [];
|
|
437
481
|
for (const ro of evt.args) {
|
|
@@ -449,7 +493,11 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
449
493
|
break;
|
|
450
494
|
case "object":
|
|
451
495
|
if (!ro.preview) {
|
|
452
|
-
args.push(
|
|
496
|
+
args.push(
|
|
497
|
+
ro.subtype === "null"
|
|
498
|
+
? "null"
|
|
499
|
+
: ro.description ?? "<no-description>"
|
|
500
|
+
);
|
|
453
501
|
} else {
|
|
454
502
|
args.push(ro.preview.description ?? "<no-description>");
|
|
455
503
|
|
|
@@ -467,6 +515,7 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
467
515
|
);
|
|
468
516
|
|
|
469
517
|
break;
|
|
518
|
+
case "weakmap":
|
|
470
519
|
case "map":
|
|
471
520
|
args.push(
|
|
472
521
|
"{\n" +
|
|
@@ -484,6 +533,7 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
484
533
|
);
|
|
485
534
|
|
|
486
535
|
break;
|
|
536
|
+
case "weakset":
|
|
487
537
|
case "set":
|
|
488
538
|
args.push(
|
|
489
539
|
"{ " +
|
|
@@ -497,27 +547,33 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
497
547
|
(ro.preview.overflow ? ", ..." : "") +
|
|
498
548
|
" }"
|
|
499
549
|
);
|
|
500
|
-
|
|
501
550
|
break;
|
|
502
|
-
case "null":
|
|
503
|
-
args.push("null");
|
|
504
|
-
break;
|
|
505
|
-
case "node":
|
|
506
551
|
case "regexp":
|
|
552
|
+
break;
|
|
507
553
|
case "date":
|
|
508
|
-
|
|
509
|
-
case "weakset":
|
|
510
|
-
case "iterator":
|
|
554
|
+
break;
|
|
511
555
|
case "generator":
|
|
512
|
-
|
|
513
|
-
|
|
556
|
+
args.push(ro.preview.properties[0].value || "");
|
|
557
|
+
break;
|
|
514
558
|
case "promise":
|
|
559
|
+
if (ro.preview.properties[0].value === "pending") {
|
|
560
|
+
args.push(`{<${ro.preview.properties[0].value}>}`);
|
|
561
|
+
} else {
|
|
562
|
+
args.push(
|
|
563
|
+
`{<${ro.preview.properties[0].value}>: ${ro.preview.properties[1].value}}`
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
break;
|
|
567
|
+
case "node":
|
|
568
|
+
case "iterator":
|
|
569
|
+
case "proxy":
|
|
515
570
|
case "typedarray":
|
|
516
571
|
case "arraybuffer":
|
|
517
572
|
case "dataview":
|
|
518
573
|
case "webassemblymemory":
|
|
519
574
|
case "wasmvalue":
|
|
520
575
|
break;
|
|
576
|
+
case "error":
|
|
521
577
|
default:
|
|
522
578
|
// just a pojo
|
|
523
579
|
args.push(
|
|
@@ -539,5 +595,23 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
539
595
|
}
|
|
540
596
|
}
|
|
541
597
|
|
|
542
|
-
|
|
598
|
+
const method = mapConsoleAPIMessageTypeToConsoleMethod[evt.type];
|
|
599
|
+
|
|
600
|
+
if (method in console) {
|
|
601
|
+
switch (method) {
|
|
602
|
+
case "dir":
|
|
603
|
+
console.dir(args);
|
|
604
|
+
break;
|
|
605
|
+
case "table":
|
|
606
|
+
console.table(args);
|
|
607
|
+
break;
|
|
608
|
+
default:
|
|
609
|
+
// eslint-disable-next-line prefer-spread
|
|
610
|
+
console[method].apply(console, args);
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
} else {
|
|
614
|
+
console.warn(`Unsupported console method: ${method}`);
|
|
615
|
+
console.log("console event:", evt);
|
|
616
|
+
}
|
|
543
617
|
}
|
package/src/{kv.tsx → kv.ts}
RENAMED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { URLSearchParams } from "node:url";
|
|
2
|
+
import { fetchListResult, fetchResult, fetchKVGetValue } from "./cfetch";
|
|
2
3
|
import type { Config } from "./config";
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
/** The largest number of kv items we can pass to the API in a single request. */
|
|
6
|
+
const API_MAX = 10000;
|
|
7
|
+
// The const below are halved from the API's true capacity to help avoid
|
|
8
|
+
// hammering it with large requests.
|
|
9
|
+
const BATCH_KEY_MAX = API_MAX / 2;
|
|
4
10
|
|
|
5
11
|
type KvArgs = {
|
|
6
12
|
binding?: string;
|
|
7
13
|
"namespace-id"?: string;
|
|
8
|
-
env?: string;
|
|
9
14
|
preview?: boolean;
|
|
10
|
-
config?: Config;
|
|
11
15
|
};
|
|
12
16
|
|
|
13
17
|
/**
|
|
@@ -91,67 +95,130 @@ export async function listNamespaceKeys(
|
|
|
91
95
|
);
|
|
92
96
|
}
|
|
93
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Information about a key-value pair, including its "metadata" fields.
|
|
100
|
+
*/
|
|
101
|
+
export interface KeyValue {
|
|
102
|
+
key: string;
|
|
103
|
+
value: string;
|
|
104
|
+
expiration?: number;
|
|
105
|
+
expiration_ttl?: number;
|
|
106
|
+
metadata?: object;
|
|
107
|
+
base64?: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const KeyValueKeys = new Set([
|
|
111
|
+
"key",
|
|
112
|
+
"value",
|
|
113
|
+
"expiration",
|
|
114
|
+
"expiration_ttl",
|
|
115
|
+
"metadata",
|
|
116
|
+
"base64",
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Is the given object a valid `KeyValue` type?
|
|
121
|
+
*/
|
|
122
|
+
export function isKeyValue(keyValue: object): keyValue is KeyValue {
|
|
123
|
+
const props = Object.keys(keyValue);
|
|
124
|
+
if (!props.includes("key") || !props.includes("value")) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get all the properties on the `keyValue` that are not expected.
|
|
132
|
+
*/
|
|
133
|
+
export function unexpectedKeyValueProps(keyValue: KeyValue): string[] {
|
|
134
|
+
const props = Object.keys(keyValue);
|
|
135
|
+
return props.filter((prop) => !KeyValueKeys.has(prop));
|
|
136
|
+
}
|
|
137
|
+
|
|
94
138
|
export async function putKeyValue(
|
|
95
139
|
accountId: string,
|
|
96
140
|
namespaceId: string,
|
|
97
|
-
|
|
98
|
-
value: string,
|
|
99
|
-
args?: { expiration?: number; expiration_ttl?: number }
|
|
141
|
+
keyValue: KeyValue
|
|
100
142
|
) {
|
|
101
143
|
let searchParams: URLSearchParams | undefined;
|
|
102
|
-
if (
|
|
144
|
+
if (keyValue.expiration || keyValue.expiration_ttl) {
|
|
103
145
|
searchParams = new URLSearchParams();
|
|
104
|
-
if (
|
|
105
|
-
searchParams.set("expiration", `${
|
|
146
|
+
if (keyValue.expiration) {
|
|
147
|
+
searchParams.set("expiration", `${keyValue.expiration}`);
|
|
106
148
|
}
|
|
107
|
-
if (
|
|
108
|
-
searchParams.set("expiration_ttl", `${
|
|
149
|
+
if (keyValue.expiration_ttl) {
|
|
150
|
+
searchParams.set("expiration_ttl", `${keyValue.expiration_ttl}`);
|
|
109
151
|
}
|
|
110
152
|
}
|
|
111
153
|
return await fetchResult(
|
|
112
|
-
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`,
|
|
113
|
-
{ method: "PUT", body: value },
|
|
154
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${keyValue.key}`,
|
|
155
|
+
{ method: "PUT", body: keyValue.value },
|
|
114
156
|
searchParams
|
|
115
157
|
);
|
|
116
158
|
}
|
|
117
159
|
|
|
160
|
+
export async function getKeyValue(
|
|
161
|
+
accountId: string,
|
|
162
|
+
namespaceId: string,
|
|
163
|
+
key: string
|
|
164
|
+
): Promise<string> {
|
|
165
|
+
return await fetchKVGetValue(accountId, namespaceId, key);
|
|
166
|
+
}
|
|
167
|
+
|
|
118
168
|
export async function putBulkKeyValue(
|
|
119
169
|
accountId: string,
|
|
120
170
|
namespaceId: string,
|
|
121
|
-
|
|
171
|
+
keyValues: KeyValue[],
|
|
172
|
+
progressCallback: (index: number, total: number) => void
|
|
122
173
|
) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
method: "PUT",
|
|
127
|
-
body: keyvalueStr,
|
|
128
|
-
headers: { "Content-Type": "application/json" },
|
|
174
|
+
for (let index = 0; index < keyValues.length; index += BATCH_KEY_MAX) {
|
|
175
|
+
if (progressCallback && keyValues.length > BATCH_KEY_MAX) {
|
|
176
|
+
progressCallback(index, keyValues.length);
|
|
129
177
|
}
|
|
130
|
-
|
|
178
|
+
|
|
179
|
+
await fetchResult(
|
|
180
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/bulk`,
|
|
181
|
+
{
|
|
182
|
+
method: "PUT",
|
|
183
|
+
body: JSON.stringify(keyValues.slice(index, index + BATCH_KEY_MAX)),
|
|
184
|
+
headers: { "Content-Type": "application/json" },
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
if (progressCallback && keyValues.length > BATCH_KEY_MAX) {
|
|
189
|
+
progressCallback(keyValues.length, keyValues.length);
|
|
190
|
+
}
|
|
131
191
|
}
|
|
132
192
|
|
|
133
193
|
export async function deleteBulkKeyValue(
|
|
134
194
|
accountId: string,
|
|
135
195
|
namespaceId: string,
|
|
136
|
-
|
|
196
|
+
keys: string[],
|
|
197
|
+
progressCallback: (index: number, total: number) => void
|
|
137
198
|
) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
method: "DELETE",
|
|
142
|
-
body: keyStr,
|
|
143
|
-
headers: { "Content-Type": "application/json" },
|
|
199
|
+
for (let index = 0; index < keys.length; index += BATCH_KEY_MAX) {
|
|
200
|
+
if (progressCallback && keys.length > BATCH_KEY_MAX) {
|
|
201
|
+
progressCallback(index, keys.length);
|
|
144
202
|
}
|
|
145
|
-
|
|
203
|
+
|
|
204
|
+
await fetchResult(
|
|
205
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/bulk`,
|
|
206
|
+
{
|
|
207
|
+
method: "DELETE",
|
|
208
|
+
body: JSON.stringify(keys.slice(index, index + BATCH_KEY_MAX)),
|
|
209
|
+
headers: { "Content-Type": "application/json" },
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
if (progressCallback && keys.length > BATCH_KEY_MAX) {
|
|
214
|
+
progressCallback(keys.length, keys.length);
|
|
215
|
+
}
|
|
146
216
|
}
|
|
147
217
|
|
|
148
|
-
export function getNamespaceId(
|
|
149
|
-
preview,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
"namespace-id": namespaceId,
|
|
153
|
-
env,
|
|
154
|
-
}: KvArgs): string {
|
|
218
|
+
export function getNamespaceId(
|
|
219
|
+
{ preview, binding, "namespace-id": namespaceId }: KvArgs,
|
|
220
|
+
config: Config
|
|
221
|
+
): string {
|
|
155
222
|
// nice
|
|
156
223
|
if (namespaceId) {
|
|
157
224
|
return namespaceId;
|
|
@@ -159,7 +226,7 @@ export function getNamespaceId({
|
|
|
159
226
|
|
|
160
227
|
// begin pre-flight checks
|
|
161
228
|
|
|
162
|
-
// `--binding` is only valid if there's a wrangler configuration
|
|
229
|
+
// `--binding` is only valid if there's a wrangler configuration.
|
|
163
230
|
if (binding && !config) {
|
|
164
231
|
throw new Error("--binding specified, but no config file was found.");
|
|
165
232
|
}
|
|
@@ -172,30 +239,6 @@ export function getNamespaceId({
|
|
|
172
239
|
);
|
|
173
240
|
}
|
|
174
241
|
|
|
175
|
-
// they want to use an environment, actually
|
|
176
|
-
if (env) {
|
|
177
|
-
if (!config.env || !config.env[env]) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`Failed to find environment "${env}" in configuration file!`
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// TODO: either a bespoke arg type for this function to avoid `undefined`s or an `EnvOrConfig` type
|
|
184
|
-
return getNamespaceId({
|
|
185
|
-
binding,
|
|
186
|
-
"namespace-id": namespaceId,
|
|
187
|
-
env: undefined,
|
|
188
|
-
preview,
|
|
189
|
-
config: {
|
|
190
|
-
env: undefined,
|
|
191
|
-
build: undefined,
|
|
192
|
-
name: undefined,
|
|
193
|
-
account_id: undefined,
|
|
194
|
-
...config.env[env],
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
242
|
// there's no KV namespaces
|
|
200
243
|
if (!config.kv_namespaces || config.kv_namespaces.length === 0) {
|
|
201
244
|
throw new Error(
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Custom Miniflare CLI
|
|
2
|
+
|
|
3
|
+
This directory contains a simple wrapper around the programmatic Miniflare API,
|
|
4
|
+
which Wrangler spawns when running `wrangler dev` in local mode.
|
|
5
|
+
|
|
6
|
+
## Building
|
|
7
|
+
|
|
8
|
+
This CLI is built at the same time as Wrangler by running
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
npm run -w wrangler build
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The output of the build is `miniflare-dist/index.mjs`.
|
|
15
|
+
|
|
16
|
+
## Running
|
|
17
|
+
|
|
18
|
+
The CLI expects a single command line argument which is the Miniflare options formatted as a string of JSON.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
node --no-warnings ./packages/wrangler/miniflare-dist/index.mjs '{"watch": true, "script": ""}' --log VERBOSE
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The `--log` argument is optional and takes one of Miniflare's LogLevels: "NONE", "ERROR", "WARN", "INFO", "DEBUG", "VERBOSE".
|
|
25
|
+
It defaults to `INFO`.
|
|
26
|
+
|
|
27
|
+
## Debugging
|
|
28
|
+
|
|
29
|
+
Simply place a breakpoint in the code and run the above command in the VS Code "JavaScript Debug Terminal".
|
|
30
|
+
The code will stop at the breakpoint as expected.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type EnumKeys<Enum> = Exclude<keyof Enum, number>;
|
|
2
|
+
|
|
3
|
+
export const enumObject = <Enum extends Record<string, number | string>>(
|
|
4
|
+
e: Enum
|
|
5
|
+
) => {
|
|
6
|
+
const copy = { ...e } as { [K in EnumKeys<Enum>]: Enum[K] };
|
|
7
|
+
Object.values(e).forEach(
|
|
8
|
+
(value) => typeof value === "number" && delete copy[value]
|
|
9
|
+
);
|
|
10
|
+
return copy;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const enumKeys = <Enum extends Record<string, number | string>>(
|
|
14
|
+
e: Enum
|
|
15
|
+
) => {
|
|
16
|
+
return Object.keys(enumObject(e)) as EnumKeys<Enum>[];
|
|
17
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Log, LogLevel, Miniflare } from "miniflare";
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { hideBin } from "yargs/helpers";
|
|
4
|
+
import { enumKeys } from "./enum-keys";
|
|
5
|
+
|
|
6
|
+
async function main() {
|
|
7
|
+
const args = await yargs(hideBin(process.argv))
|
|
8
|
+
.help(false)
|
|
9
|
+
.version(false)
|
|
10
|
+
.option("log", {
|
|
11
|
+
choices: enumKeys(LogLevel),
|
|
12
|
+
}).argv;
|
|
13
|
+
|
|
14
|
+
const logLevel = LogLevel[args.log ?? "INFO"];
|
|
15
|
+
const config = {
|
|
16
|
+
...JSON.parse((args._[0] as string) ?? "{}"),
|
|
17
|
+
log: new Log(logLevel),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
if (logLevel > LogLevel.INFO) {
|
|
21
|
+
console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mf = new Miniflare(config);
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// Start Miniflare development server
|
|
28
|
+
await mf.startServer();
|
|
29
|
+
} catch (e) {
|
|
30
|
+
mf.log.error(e as Error);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
// Unmount any mounted workers
|
|
33
|
+
await mf.dispose();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await main();
|