wrangler 2.4.4 → 2.6.0
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 +20 -8
- package/miniflare-dist/index.mjs +90 -41
- package/package.json +3 -3
- package/src/__tests__/configuration.test.ts +211 -0
- package/src/__tests__/delete.test.ts +81 -48
- package/src/__tests__/dev.test.tsx +25 -8
- package/src/__tests__/helpers/mock-oauth-flow.ts +5 -1
- package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
- package/src/__tests__/init.test.ts +18 -3
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +88 -43
- package/src/__tests__/pages-deployment-tail.test.ts +165 -101
- package/src/__tests__/publish.test.ts +94 -7
- package/src/__tests__/pubsub.test.ts +208 -88
- package/src/__tests__/queues.test.ts +155 -67
- package/src/__tests__/tail.test.ts +207 -108
- package/src/__tests__/type-generation.test.ts +7 -0
- package/src/__tests__/user.test.ts +43 -69
- package/src/config/environment.ts +16 -0
- package/src/config/index.ts +31 -8
- package/src/config/validation.ts +49 -0
- package/src/create-worker-upload-form.ts +9 -0
- package/src/d1/backups.tsx +7 -2
- package/src/d1/delete.tsx +4 -4
- package/src/d1/index.ts +2 -0
- package/src/d1/migrations/apply.tsx +6 -5
- package/src/d1/migrations/helpers.ts +4 -2
- package/src/d1/migrations/list.tsx +2 -2
- package/src/d1/migrations/options.ts +18 -0
- package/src/dev/dev.tsx +46 -22
- package/src/dev/local.tsx +63 -29
- package/src/dev/start-server.ts +18 -21
- package/src/dev.tsx +33 -13
- package/src/git-client.ts +15 -4
- package/src/index.tsx +1 -0
- package/src/init.ts +8 -0
- package/src/miniflare-cli/assets.ts +55 -28
- package/src/miniflare-cli/index.ts +2 -1
- package/src/pages/dev.tsx +7 -0
- package/src/proxy.ts +5 -0
- package/src/publish/publish.ts +1 -0
- package/src/secret/index.ts +1 -0
- package/src/type-generation.ts +10 -2
- package/src/worker.ts +6 -0
- package/wrangler-dist/cli.d.ts +15 -0
- package/wrangler-dist/cli.js +2045 -636
package/src/dev/local.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { realpathSync } from "node:fs";
|
|
|
4
4
|
import { readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
+
import getPort from "get-port";
|
|
7
8
|
import { npxImport } from "npx-import";
|
|
8
9
|
import { useState, useEffect, useRef } from "react";
|
|
9
10
|
import onExit from "signal-exit";
|
|
@@ -11,6 +12,7 @@ import { performApiFetch } from "../cfetch/internal";
|
|
|
11
12
|
import { registerWorker } from "../dev-registry";
|
|
12
13
|
import useInspector from "../inspect";
|
|
13
14
|
import { logger } from "../logger";
|
|
15
|
+
import generateASSETSBinding from "../miniflare-cli/assets";
|
|
14
16
|
import {
|
|
15
17
|
DEFAULT_MODULE_RULES,
|
|
16
18
|
ModuleTypeToRuleType,
|
|
@@ -57,8 +59,8 @@ export interface LocalProps {
|
|
|
57
59
|
bindings: CfWorkerInit["bindings"];
|
|
58
60
|
workerDefinitions: WorkerRegistry | undefined;
|
|
59
61
|
assetPaths: AssetPaths | undefined;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
initialPort: number;
|
|
63
|
+
initialIp: string;
|
|
62
64
|
rules: Config["rules"];
|
|
63
65
|
inspectorPort: number;
|
|
64
66
|
localPersistencePath: string | null;
|
|
@@ -109,12 +111,11 @@ function useLocalWorker({
|
|
|
109
111
|
bindings,
|
|
110
112
|
workerDefinitions,
|
|
111
113
|
assetPaths,
|
|
112
|
-
|
|
113
|
-
inspectorPort,
|
|
114
|
+
initialPort,
|
|
114
115
|
rules,
|
|
115
116
|
localPersistencePath,
|
|
116
117
|
liveReload,
|
|
117
|
-
|
|
118
|
+
initialIp,
|
|
118
119
|
crons,
|
|
119
120
|
queueConsumers,
|
|
120
121
|
localProtocol,
|
|
@@ -134,6 +135,11 @@ function useLocalWorker({
|
|
|
134
135
|
const removeExperimentalLocalSignalExitListener = useRef<() => void>();
|
|
135
136
|
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
136
137
|
|
|
138
|
+
// Our inspector proxy server will be binding to `LocalProps`'s `inspectorPort`.
|
|
139
|
+
// If we attempted to bind Node.js/workerd to the same inspector port, we'd get a port already in use error.
|
|
140
|
+
// Therefore, generate a new random port for our runtime's to bind their inspector service to.
|
|
141
|
+
const runtimeInspectorPortRef = useRef<number>();
|
|
142
|
+
|
|
137
143
|
useEffect(() => {
|
|
138
144
|
if (bindings.services && bindings.services.length > 0) {
|
|
139
145
|
logger.warn(
|
|
@@ -159,13 +165,6 @@ function useLocalWorker({
|
|
|
159
165
|
async function startLocalWorker() {
|
|
160
166
|
if (!bundle || !format) return;
|
|
161
167
|
|
|
162
|
-
// port for the worker
|
|
163
|
-
await waitForPortToBeAvailable(port, {
|
|
164
|
-
retryPeriod: 200,
|
|
165
|
-
timeout: 2000,
|
|
166
|
-
abortSignal: abortController.signal,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
168
|
// In local mode, we want to copy all referenced modules into
|
|
170
169
|
// the output bundle directory before starting up
|
|
171
170
|
for (const module of bundle.modules) {
|
|
@@ -197,12 +196,15 @@ function useLocalWorker({
|
|
|
197
196
|
bundle,
|
|
198
197
|
});
|
|
199
198
|
|
|
199
|
+
runtimeInspectorPortRef.current ??= await getPort();
|
|
200
|
+
const runtimeInspectorPort = runtimeInspectorPortRef.current;
|
|
201
|
+
|
|
200
202
|
const { forkOptions, miniflareCLIPath, options } = setupMiniflareOptions({
|
|
201
203
|
workerName,
|
|
202
|
-
port,
|
|
204
|
+
port: initialPort,
|
|
203
205
|
scriptPath,
|
|
204
206
|
localProtocol,
|
|
205
|
-
ip,
|
|
207
|
+
ip: initialIp,
|
|
206
208
|
format,
|
|
207
209
|
rules,
|
|
208
210
|
compatibilityDate,
|
|
@@ -236,11 +238,12 @@ function useLocalWorker({
|
|
|
236
238
|
format,
|
|
237
239
|
bundle,
|
|
238
240
|
log,
|
|
241
|
+
enablePagesAssetsServiceBinding,
|
|
239
242
|
kvNamespaces: bindings?.kv_namespaces,
|
|
240
243
|
r2Buckets: bindings?.r2_buckets,
|
|
241
244
|
authenticatedAccountId: accountId,
|
|
242
245
|
kvRemote: experimentalLocalRemoteKv,
|
|
243
|
-
inspectorPort,
|
|
246
|
+
inspectorPort: runtimeInspectorPort,
|
|
244
247
|
});
|
|
245
248
|
|
|
246
249
|
const current = experimentalLocalRef.current;
|
|
@@ -268,7 +271,7 @@ function useLocalWorker({
|
|
|
268
271
|
try {
|
|
269
272
|
// fetch the inspector JSON response from the DevTools Inspector protocol
|
|
270
273
|
const inspectorJSONArr = (await (
|
|
271
|
-
await fetch(`http://127.0.0.1:${
|
|
274
|
+
await fetch(`http://127.0.0.1:${runtimeInspectorPort}/json`)
|
|
272
275
|
).json()) as InspectorJSON;
|
|
273
276
|
|
|
274
277
|
const foundInspectorURL = inspectorJSONArr?.find((inspectorJSON) =>
|
|
@@ -295,7 +298,19 @@ function useLocalWorker({
|
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
300
|
|
|
298
|
-
|
|
301
|
+
// Wait for the Worker port to be available. We don't want to do this in experimental local
|
|
302
|
+
// mode, as we only `dispose()` the Miniflare 3 instance, and shutdown the server when
|
|
303
|
+
// unmounting the component, not when props change. If we did, we'd just timeout every time.
|
|
304
|
+
await waitForPortToBeAvailable(initialPort, {
|
|
305
|
+
retryPeriod: 200,
|
|
306
|
+
timeout: 2000,
|
|
307
|
+
abortSignal: abortController.signal,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const nodeOptions = setupNodeOptions({
|
|
311
|
+
inspect,
|
|
312
|
+
inspectorPort: runtimeInspectorPort,
|
|
313
|
+
});
|
|
299
314
|
logger.log("⎔ Starting a local server...");
|
|
300
315
|
|
|
301
316
|
const child = (local.current = fork(miniflareCLIPath, forkOptions, {
|
|
@@ -316,21 +331,21 @@ function useLocalWorker({
|
|
|
316
331
|
await registerWorker(workerName, {
|
|
317
332
|
protocol: localProtocol,
|
|
318
333
|
mode: "local",
|
|
319
|
-
port,
|
|
320
|
-
host:
|
|
334
|
+
port: message.port,
|
|
335
|
+
host: initialIp,
|
|
321
336
|
durableObjects: internalDurableObjects.map((binding) => ({
|
|
322
337
|
name: binding.name,
|
|
323
338
|
className: binding.class_name,
|
|
324
339
|
})),
|
|
325
340
|
...(message.durableObjectsPort
|
|
326
341
|
? {
|
|
327
|
-
durableObjectsHost:
|
|
342
|
+
durableObjectsHost: initialIp,
|
|
328
343
|
durableObjectsPort: message.durableObjectsPort,
|
|
329
344
|
}
|
|
330
345
|
: {}),
|
|
331
346
|
});
|
|
332
347
|
}
|
|
333
|
-
onReady?.(
|
|
348
|
+
onReady?.(initialIp, message.port);
|
|
334
349
|
}
|
|
335
350
|
});
|
|
336
351
|
|
|
@@ -382,7 +397,13 @@ function useLocalWorker({
|
|
|
382
397
|
}
|
|
383
398
|
|
|
384
399
|
startLocalWorker().catch((err) => {
|
|
385
|
-
|
|
400
|
+
if (err.code === "ERR_RUNTIME_FAILURE") {
|
|
401
|
+
// Don't log a full verbose stack-trace when Miniflare 3's workerd instance fails to start.
|
|
402
|
+
// workerd will log its own errors, and our stack trace won't have any useful information.
|
|
403
|
+
logger.error(err.message);
|
|
404
|
+
} else {
|
|
405
|
+
logger.error("local worker:", err);
|
|
406
|
+
}
|
|
386
407
|
});
|
|
387
408
|
|
|
388
409
|
return () => {
|
|
@@ -399,9 +420,8 @@ function useLocalWorker({
|
|
|
399
420
|
bundle,
|
|
400
421
|
workerName,
|
|
401
422
|
format,
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
ip,
|
|
423
|
+
initialPort,
|
|
424
|
+
initialIp,
|
|
405
425
|
queueConsumers,
|
|
406
426
|
bindings.queues,
|
|
407
427
|
bindings.durable_objects,
|
|
@@ -729,11 +749,9 @@ export function setupMiniflareOptions({
|
|
|
729
749
|
|
|
730
750
|
export function setupNodeOptions({
|
|
731
751
|
inspect,
|
|
732
|
-
ip,
|
|
733
752
|
inspectorPort,
|
|
734
753
|
}: {
|
|
735
754
|
inspect: boolean;
|
|
736
|
-
ip: string;
|
|
737
755
|
inspectorPort: number;
|
|
738
756
|
}) {
|
|
739
757
|
const nodeOptions = [
|
|
@@ -742,7 +760,7 @@ export function setupNodeOptions({
|
|
|
742
760
|
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
743
761
|
];
|
|
744
762
|
if (inspect) {
|
|
745
|
-
nodeOptions.push("--inspect=" +
|
|
763
|
+
nodeOptions.push("--inspect=" + `127.0.0.1:${inspectorPort}`); // start Miniflare listening for a debugger to attach
|
|
746
764
|
}
|
|
747
765
|
return nodeOptions;
|
|
748
766
|
}
|
|
@@ -757,6 +775,8 @@ export interface SetupMiniflare3Options {
|
|
|
757
775
|
// Miniflare's logger
|
|
758
776
|
log: Miniflare3LogType;
|
|
759
777
|
|
|
778
|
+
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
|
|
779
|
+
|
|
760
780
|
// Miniflare 3 accepts namespace/bucket names in addition to binding names.
|
|
761
781
|
// This means multiple workers persisting to the same location can have
|
|
762
782
|
// different binding names for the same namespace/bucket. Therefore, we need
|
|
@@ -794,6 +814,7 @@ export async function transformMf2OptionsToMf3Options({
|
|
|
794
814
|
format,
|
|
795
815
|
bundle,
|
|
796
816
|
log,
|
|
817
|
+
enablePagesAssetsServiceBinding,
|
|
797
818
|
kvNamespaces,
|
|
798
819
|
r2Buckets,
|
|
799
820
|
authenticatedAccountId,
|
|
@@ -829,6 +850,19 @@ export async function transformMf2OptionsToMf3Options({
|
|
|
829
850
|
log,
|
|
830
851
|
};
|
|
831
852
|
|
|
853
|
+
if (enablePagesAssetsServiceBinding !== undefined) {
|
|
854
|
+
options.serviceBindings = {
|
|
855
|
+
...options.serviceBindings,
|
|
856
|
+
ASSETS: (await generateASSETSBinding({
|
|
857
|
+
log,
|
|
858
|
+
...enablePagesAssetsServiceBinding,
|
|
859
|
+
tre: true,
|
|
860
|
+
// We can get rid of this `any` easily once we do experimental-local/tre by default
|
|
861
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
862
|
+
})) as any,
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
832
866
|
if (format === "modules") {
|
|
833
867
|
// Manually specify all modules from the bundle. If we didn't do this,
|
|
834
868
|
// Miniflare 3 would try collect them automatically again itself.
|
|
@@ -882,5 +916,5 @@ export async function getMiniflare3(): Promise<
|
|
|
882
916
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
883
917
|
typeof import("@miniflare/tre")
|
|
884
918
|
> {
|
|
885
|
-
return (miniflare3Module ??= await npxImport("@miniflare/tre@3.0.0-next.
|
|
919
|
+
return (miniflare3Module ??= await npxImport("@miniflare/tre@3.0.0-next.8"));
|
|
886
920
|
}
|
package/src/dev/start-server.ts
CHANGED
|
@@ -112,8 +112,8 @@ export async function startDevServer(
|
|
|
112
112
|
compatibilityFlags: props.compatibilityFlags,
|
|
113
113
|
bindings: props.bindings,
|
|
114
114
|
assetPaths: props.assetPaths,
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
initialPort: props.initialPort,
|
|
116
|
+
initialIp: props.initialIp,
|
|
117
117
|
rules: props.rules,
|
|
118
118
|
inspectorPort: props.inspectorPort,
|
|
119
119
|
localPersistencePath: props.localPersistencePath,
|
|
@@ -149,8 +149,8 @@ export async function startDevServer(
|
|
|
149
149
|
bindings: props.bindings,
|
|
150
150
|
assetPaths: props.assetPaths,
|
|
151
151
|
isWorkersSite: props.isWorkersSite,
|
|
152
|
-
port: props.
|
|
153
|
-
ip: props.
|
|
152
|
+
port: props.initialPort,
|
|
153
|
+
ip: props.initialIp,
|
|
154
154
|
localProtocol: props.localProtocol,
|
|
155
155
|
inspectorPort: props.inspectorPort,
|
|
156
156
|
inspect: props.inspect,
|
|
@@ -294,12 +294,12 @@ export async function startLocalServer({
|
|
|
294
294
|
bindings,
|
|
295
295
|
workerDefinitions,
|
|
296
296
|
assetPaths,
|
|
297
|
-
|
|
297
|
+
initialPort,
|
|
298
298
|
inspectorPort,
|
|
299
299
|
rules,
|
|
300
300
|
localPersistencePath,
|
|
301
301
|
liveReload,
|
|
302
|
-
|
|
302
|
+
initialIp,
|
|
303
303
|
crons,
|
|
304
304
|
queueConsumers,
|
|
305
305
|
localProtocol,
|
|
@@ -325,14 +325,11 @@ export async function startLocalServer({
|
|
|
325
325
|
if (!bundle || !format) return;
|
|
326
326
|
|
|
327
327
|
// port for the worker
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
abortSignal: abortController.signal,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
328
|
+
await waitForPortToBeAvailable(initialPort, {
|
|
329
|
+
retryPeriod: 200,
|
|
330
|
+
timeout: 2000,
|
|
331
|
+
abortSignal: abortController.signal,
|
|
332
|
+
});
|
|
336
333
|
|
|
337
334
|
if (bindings.services && bindings.services.length > 0) {
|
|
338
335
|
logger.warn(
|
|
@@ -373,10 +370,10 @@ export async function startLocalServer({
|
|
|
373
370
|
|
|
374
371
|
const { forkOptions, miniflareCLIPath, options } = setupMiniflareOptions({
|
|
375
372
|
workerName,
|
|
376
|
-
port,
|
|
373
|
+
port: initialPort,
|
|
377
374
|
scriptPath,
|
|
378
375
|
localProtocol,
|
|
379
|
-
ip,
|
|
376
|
+
ip: initialIp,
|
|
380
377
|
format,
|
|
381
378
|
rules,
|
|
382
379
|
compatibilityDate,
|
|
@@ -429,7 +426,7 @@ export async function startLocalServer({
|
|
|
429
426
|
return;
|
|
430
427
|
}
|
|
431
428
|
|
|
432
|
-
const nodeOptions = setupNodeOptions({ inspect,
|
|
429
|
+
const nodeOptions = setupNodeOptions({ inspect, inspectorPort });
|
|
433
430
|
logger.log("⎔ Starting a local server...");
|
|
434
431
|
|
|
435
432
|
const child = (local = fork(miniflareCLIPath, forkOptions, {
|
|
@@ -446,21 +443,21 @@ export async function startLocalServer({
|
|
|
446
443
|
await registerWorker(workerName, {
|
|
447
444
|
protocol: localProtocol,
|
|
448
445
|
mode: "local",
|
|
449
|
-
port: message.
|
|
450
|
-
host:
|
|
446
|
+
port: message.port,
|
|
447
|
+
host: initialIp,
|
|
451
448
|
durableObjects: internalDurableObjects.map((binding) => ({
|
|
452
449
|
name: binding.name,
|
|
453
450
|
className: binding.class_name,
|
|
454
451
|
})),
|
|
455
452
|
...(message.durableObjectsPort
|
|
456
453
|
? {
|
|
457
|
-
durableObjectsHost:
|
|
454
|
+
durableObjectsHost: initialIp,
|
|
458
455
|
durableObjectsPort: message.durableObjectsPort,
|
|
459
456
|
}
|
|
460
457
|
: {}),
|
|
461
458
|
});
|
|
462
459
|
}
|
|
463
|
-
onReady?.(
|
|
460
|
+
onReady?.(initialIp, message.port);
|
|
464
461
|
}
|
|
465
462
|
});
|
|
466
463
|
|
package/src/dev.tsx
CHANGED
|
@@ -14,7 +14,7 @@ import { getEntry } from "./entry";
|
|
|
14
14
|
import { logger } from "./logger";
|
|
15
15
|
import * as metrics from "./metrics";
|
|
16
16
|
import { getAssetPaths, getSiteAssetPaths } from "./sites";
|
|
17
|
-
import { getAccountFromCache } from "./user";
|
|
17
|
+
import { getAccountFromCache, loginOrRefreshIfRequired } from "./user";
|
|
18
18
|
import { collectKeyValues } from "./utils/collectKeyValues";
|
|
19
19
|
import { identifyD1BindingsAsBeta } from "./worker";
|
|
20
20
|
import { getHostFromRoute, getZoneForRoute, getZoneIdFromHost } from "./zones";
|
|
@@ -328,6 +328,15 @@ export function devOptions(yargs: Argv<CommonYargsOptions>): Argv<DevArgs> {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
|
|
331
|
+
if (!args.local) {
|
|
332
|
+
const isLoggedIn = await loginOrRefreshIfRequired();
|
|
333
|
+
if (!isLoggedIn) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
"You must be logged in to use wrangler dev in remote mode. Try logging in, or run wrangler dev --local."
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
331
340
|
let watcher;
|
|
332
341
|
try {
|
|
333
342
|
const devInstance = await startDev(args);
|
|
@@ -467,11 +476,13 @@ export async function startDev(args: StartDevOptions) {
|
|
|
467
476
|
accountId={configParam.account_id || getAccountFromCache()?.id}
|
|
468
477
|
assetPaths={assetPaths}
|
|
469
478
|
assetsConfig={configParam.assets}
|
|
470
|
-
|
|
471
|
-
|
|
479
|
+
initialPort={
|
|
480
|
+
args.port ?? configParam.dev.port ?? (await getLocalPort())
|
|
481
|
+
}
|
|
482
|
+
initialIp={args.ip || configParam.dev.ip}
|
|
472
483
|
inspectorPort={
|
|
473
|
-
args.inspectorPort
|
|
474
|
-
configParam.dev.inspector_port
|
|
484
|
+
args.inspectorPort ??
|
|
485
|
+
configParam.dev.inspector_port ??
|
|
475
486
|
(await getInspectorPort())
|
|
476
487
|
}
|
|
477
488
|
isWorkersSite={Boolean(args.site || configParam.site)}
|
|
@@ -584,14 +595,11 @@ export async function startApiDev(args: StartDevOptions) {
|
|
|
584
595
|
assetPaths: assetPaths,
|
|
585
596
|
assetsConfig: configParam.assets,
|
|
586
597
|
//port can be 0, which means to use a random port
|
|
587
|
-
port
|
|
588
|
-
|
|
589
|
-
? args.port
|
|
590
|
-
: args.port || configParam.dev.port || (await getLocalPort()),
|
|
591
|
-
ip: args.ip || configParam.dev.ip,
|
|
598
|
+
initialPort: args.port ?? configParam.dev.port ?? (await getLocalPort()),
|
|
599
|
+
initialIp: args.ip || configParam.dev.ip,
|
|
592
600
|
inspectorPort:
|
|
593
|
-
args["inspector-port"]
|
|
594
|
-
configParam.dev.inspector_port
|
|
601
|
+
args["inspector-port"] ??
|
|
602
|
+
configParam.dev.inspector_port ??
|
|
595
603
|
(await getInspectorPort()),
|
|
596
604
|
isWorkersSite: Boolean(args.site || configParam.site),
|
|
597
605
|
compatibilityDate: getDevCompatibilityDate(
|
|
@@ -893,10 +901,22 @@ async function getBindings(
|
|
|
893
901
|
],
|
|
894
902
|
dispatch_namespaces: configParam.dispatch_namespaces,
|
|
895
903
|
services: configParam.services,
|
|
904
|
+
analytics_engine_datasets: configParam.analytics_engine_datasets,
|
|
896
905
|
unsafe: configParam.unsafe?.bindings,
|
|
897
906
|
logfwdr: configParam.logfwdr,
|
|
898
907
|
d1_databases: identifyD1BindingsAsBeta([
|
|
899
|
-
...configParam.d1_databases
|
|
908
|
+
...(configParam.d1_databases ?? []).map((d1Db) => {
|
|
909
|
+
if (!d1Db.preview_database_id) {
|
|
910
|
+
throw new Error(
|
|
911
|
+
`In development, you should use a separate D1 database than the one you'd use in production. Please create a new D1 database with "wrangler d1 create <name>" and add its id as preview_database_id to the d1_database "${d1Db.binding}" in your wrangler.toml`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
return {
|
|
916
|
+
...d1Db,
|
|
917
|
+
database_id: d1Db.preview_database_id,
|
|
918
|
+
};
|
|
919
|
+
}),
|
|
900
920
|
...(args.d1Databases || []),
|
|
901
921
|
]),
|
|
902
922
|
};
|
package/src/git-client.ts
CHANGED
|
@@ -42,10 +42,21 @@ export async function getGitVersioon(): Promise<string | null> {
|
|
|
42
42
|
*/
|
|
43
43
|
export async function initializeGit(cwd: string) {
|
|
44
44
|
try {
|
|
45
|
-
//
|
|
46
|
-
await execa("git", [
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
// Get the default init branch name
|
|
46
|
+
const { stdout: defaultBranchName } = await execa("git", [
|
|
47
|
+
"config",
|
|
48
|
+
"--get",
|
|
49
|
+
"init.defaultBranch",
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
// Try to create the repository with the HEAD branch of defaultBranchName ?? `main`.
|
|
53
|
+
await execa(
|
|
54
|
+
"git",
|
|
55
|
+
["init", "--initial-branch", defaultBranchName.trim() ?? "main"],
|
|
56
|
+
{
|
|
57
|
+
cwd,
|
|
58
|
+
}
|
|
59
|
+
);
|
|
49
60
|
} catch {
|
|
50
61
|
// Unable to create the repo with a HEAD branch name, so just fall back to the default.
|
|
51
62
|
await execa("git", ["init"], {
|
package/src/index.tsx
CHANGED
|
@@ -543,6 +543,7 @@ export function createCLIParser(argv: string[]) {
|
|
|
543
543
|
r2_buckets: config.r2_buckets,
|
|
544
544
|
d1_databases: config.d1_databases,
|
|
545
545
|
services: config.services,
|
|
546
|
+
analytics_engine_datasets: config.analytics_engine_datasets,
|
|
546
547
|
dispatch_namespaces: config.dispatch_namespaces,
|
|
547
548
|
logfwdr: config.logfwdr,
|
|
548
549
|
unsafe: { bindings: config.unsafe?.bindings },
|
package/src/init.ts
CHANGED
|
@@ -862,6 +862,14 @@ async function getWorkerConfig(
|
|
|
862
862
|
];
|
|
863
863
|
}
|
|
864
864
|
break;
|
|
865
|
+
case "analytics_engine":
|
|
866
|
+
{
|
|
867
|
+
configObj.analytics_engine_datasets = [
|
|
868
|
+
...(configObj.analytics_engine_datasets ?? []),
|
|
869
|
+
{ binding: binding.name, dataset: binding.dataset },
|
|
870
|
+
];
|
|
871
|
+
}
|
|
872
|
+
break;
|
|
865
873
|
case "namespace":
|
|
866
874
|
{
|
|
867
875
|
configObj.dispatch_namespaces = [
|
|
@@ -3,54 +3,69 @@ import { join } from "node:path";
|
|
|
3
3
|
import { createMetadataObject } from "@cloudflare/pages-shared/metadata-generator/createMetadataObject";
|
|
4
4
|
import { parseHeaders } from "@cloudflare/pages-shared/metadata-generator/parseHeaders";
|
|
5
5
|
import { parseRedirects } from "@cloudflare/pages-shared/metadata-generator/parseRedirects";
|
|
6
|
-
import { fetch as miniflareFetch } from "@miniflare/core";
|
|
7
|
-
import {
|
|
8
|
-
Response as MiniflareResponse,
|
|
9
|
-
Request as MiniflareRequest,
|
|
10
|
-
} from "@miniflare/core";
|
|
11
6
|
import { watch } from "chokidar";
|
|
12
7
|
import { getType } from "mime";
|
|
13
8
|
import { hashFile } from "../pages/hash";
|
|
14
9
|
import type { Metadata } from "@cloudflare/pages-shared/asset-server/metadata";
|
|
15
|
-
import type {
|
|
16
|
-
fetch,
|
|
17
|
-
Request,
|
|
18
|
-
} from "@cloudflare/pages-shared/environment-polyfills/types";
|
|
19
10
|
import type {
|
|
20
11
|
ParsedRedirects,
|
|
21
12
|
ParsedHeaders,
|
|
22
13
|
} from "@cloudflare/pages-shared/metadata-generator/types";
|
|
23
|
-
import type {
|
|
24
|
-
|
|
14
|
+
import type {
|
|
15
|
+
RequestInfo as TreRequestInfo,
|
|
16
|
+
RequestInit as TreRequestInit,
|
|
17
|
+
} from "@miniflare/tre";
|
|
18
|
+
|
|
19
|
+
interface Logger {
|
|
20
|
+
log: (message: string) => void;
|
|
21
|
+
warn: (message: string) => void;
|
|
22
|
+
error: (error: Error) => void;
|
|
23
|
+
}
|
|
25
24
|
|
|
26
25
|
export interface Options {
|
|
27
|
-
log:
|
|
26
|
+
log: Logger;
|
|
28
27
|
proxyPort?: number;
|
|
29
28
|
directory?: string;
|
|
29
|
+
tre: boolean;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export default async function generateASSETSBinding(options: Options) {
|
|
33
33
|
const assetsFetch =
|
|
34
34
|
options.directory !== undefined
|
|
35
|
-
? await generateAssetsFetch(options.directory, options.log)
|
|
35
|
+
? await generateAssetsFetch(options.directory, options.log, options.tre)
|
|
36
36
|
: invalidAssetsFetch;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
const miniflare = options.tre
|
|
39
|
+
? await import("@miniflare/tre")
|
|
40
|
+
: await import("@miniflare/core");
|
|
41
|
+
|
|
42
|
+
const Request = miniflare.Request;
|
|
43
|
+
const Response = miniflare.Response;
|
|
44
|
+
// WebSockets won't work with `--experimental-local` until we expose something like `upgradingFetch` from `@miniflare/tre`.
|
|
45
|
+
const fetch = (
|
|
46
|
+
options.tre
|
|
47
|
+
? miniflare.fetch
|
|
48
|
+
: (await import("@miniflare/web-sockets")).upgradingFetch
|
|
49
|
+
) as (request: Request) => Promise<Response>;
|
|
50
|
+
|
|
51
|
+
return async function (miniflareRequest: Request) {
|
|
39
52
|
if (options.proxyPort) {
|
|
40
53
|
try {
|
|
41
54
|
const url = new URL(miniflareRequest.url);
|
|
42
55
|
url.host = `localhost:${options.proxyPort}`;
|
|
43
|
-
|
|
56
|
+
const proxyRequest = new Request(url, miniflareRequest);
|
|
57
|
+
if (proxyRequest.headers.get("Upgrade") === "websocket") {
|
|
58
|
+
proxyRequest.headers.delete("Sec-WebSocket-Accept");
|
|
59
|
+
proxyRequest.headers.delete("Sec-WebSocket-Key");
|
|
60
|
+
}
|
|
61
|
+
return await fetch(proxyRequest as Request);
|
|
44
62
|
} catch (thrown) {
|
|
45
63
|
options.log.error(new Error(`Could not proxy request: ${thrown}`));
|
|
46
64
|
|
|
47
65
|
// TODO: Pretty error page
|
|
48
|
-
return new
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
status: 502,
|
|
52
|
-
}
|
|
53
|
-
);
|
|
66
|
+
return new Response(`[wrangler] Could not proxy request: ${thrown}`, {
|
|
67
|
+
status: 502,
|
|
68
|
+
});
|
|
54
69
|
}
|
|
55
70
|
} else {
|
|
56
71
|
try {
|
|
@@ -59,21 +74,33 @@ export default async function generateASSETSBinding(options: Options) {
|
|
|
59
74
|
options.log.error(new Error(`Could not serve static asset: ${thrown}`));
|
|
60
75
|
|
|
61
76
|
// TODO: Pretty error page
|
|
62
|
-
return new
|
|
77
|
+
return new Response(
|
|
63
78
|
`[wrangler] Could not serve static asset: ${thrown}`,
|
|
64
79
|
{ status: 502 }
|
|
65
80
|
);
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
|
-
}
|
|
83
|
+
};
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
async function generateAssetsFetch(
|
|
72
87
|
directory: string,
|
|
73
|
-
log:
|
|
88
|
+
log: Logger,
|
|
89
|
+
tre: boolean
|
|
74
90
|
): Promise<typeof fetch> {
|
|
75
91
|
// Defer importing miniflare until we really need it
|
|
76
|
-
|
|
92
|
+
if (tre) {
|
|
93
|
+
await import(
|
|
94
|
+
"@cloudflare/pages-shared/environment-polyfills/miniflare-tre"
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
await import("@cloudflare/pages-shared/environment-polyfills/miniflare");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const miniflare = tre
|
|
101
|
+
? await import("@miniflare/tre")
|
|
102
|
+
: await import("@miniflare/core");
|
|
103
|
+
const Request = miniflare.Request;
|
|
77
104
|
|
|
78
105
|
const { generateHandler, parseQualityWeightedList } = await import(
|
|
79
106
|
"@cloudflare/pages-shared/asset-server/handler"
|
|
@@ -202,10 +229,10 @@ async function generateAssetsFetch(
|
|
|
202
229
|
});
|
|
203
230
|
};
|
|
204
231
|
|
|
205
|
-
return async (input:
|
|
206
|
-
const request = new
|
|
232
|
+
return (async (input: TreRequestInfo, init?: TreRequestInit) => {
|
|
233
|
+
const request = new Request(input, init);
|
|
207
234
|
return await generateResponse(request as unknown as Request);
|
|
208
|
-
};
|
|
235
|
+
}) as typeof fetch;
|
|
209
236
|
}
|
|
210
237
|
|
|
211
238
|
const invalidAssetsFetch: typeof fetch = () => {
|
|
@@ -120,6 +120,7 @@ async function main() {
|
|
|
120
120
|
log: config.log,
|
|
121
121
|
proxyPort: opts.proxyPort,
|
|
122
122
|
directory: opts.directory,
|
|
123
|
+
tre: false,
|
|
123
124
|
};
|
|
124
125
|
|
|
125
126
|
config.serviceBindings = {
|
|
@@ -196,7 +197,7 @@ async function main() {
|
|
|
196
197
|
process.send &&
|
|
197
198
|
process.send(
|
|
198
199
|
JSON.stringify({
|
|
199
|
-
|
|
200
|
+
port: mfPort,
|
|
200
201
|
ready: true,
|
|
201
202
|
durableObjectsPort: durableObjectsMfPort,
|
|
202
203
|
})
|
package/src/pages/dev.tsx
CHANGED
|
@@ -134,6 +134,11 @@ export function Options(yargs: Argv) {
|
|
|
134
134
|
type: "boolean",
|
|
135
135
|
hidden: true,
|
|
136
136
|
},
|
|
137
|
+
"experimental-local": {
|
|
138
|
+
describe: "Run on my machine using the Cloudflare Workers runtime",
|
|
139
|
+
type: "boolean",
|
|
140
|
+
default: false,
|
|
141
|
+
},
|
|
137
142
|
config: {
|
|
138
143
|
describe: "Pages does not support wrangler.toml",
|
|
139
144
|
type: "string",
|
|
@@ -168,6 +173,7 @@ export const Handler = async ({
|
|
|
168
173
|
persist,
|
|
169
174
|
persistTo,
|
|
170
175
|
"node-compat": nodeCompat,
|
|
176
|
+
"experimental-local": experimentalLocal,
|
|
171
177
|
config: config,
|
|
172
178
|
_: [_pages, _dev, ...remaining],
|
|
173
179
|
logLevel,
|
|
@@ -476,6 +482,7 @@ export const Handler = async ({
|
|
|
476
482
|
compatibilityDate,
|
|
477
483
|
compatibilityFlags,
|
|
478
484
|
nodeCompat,
|
|
485
|
+
experimentalLocal,
|
|
479
486
|
vars: Object.fromEntries(
|
|
480
487
|
bindings
|
|
481
488
|
.map((binding) => binding.toString().split("="))
|
package/src/proxy.ts
CHANGED
|
@@ -651,6 +651,11 @@ export async function waitForPortToBeAvailable(
|
|
|
651
651
|
}
|
|
652
652
|
|
|
653
653
|
function checkPort() {
|
|
654
|
+
if (port === 0) {
|
|
655
|
+
doResolve();
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
|
|
654
659
|
// Testing whether a port is 'available' involves simply
|
|
655
660
|
// trying to make a server listen on that port, and retrying
|
|
656
661
|
// until it succeeds.
|