wrangler 2.0.27 → 2.1.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 +1 -1
- package/miniflare-dist/index.mjs +1141 -369
- package/package.json +6 -4
- package/src/__tests__/api-dev.test.ts +19 -0
- package/src/__tests__/configuration.test.ts +27 -27
- package/src/__tests__/dev.test.tsx +8 -6
- package/src/__tests__/helpers/hello-world-worker.js +5 -0
- package/src/__tests__/helpers/mock-cfetch.ts +4 -4
- package/src/__tests__/helpers/mock-console.ts +11 -2
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
- package/src/__tests__/helpers/mock-known-routes.ts +7 -0
- package/src/__tests__/index.test.ts +37 -37
- package/src/__tests__/init.test.ts +356 -5
- package/src/__tests__/jest.setup.ts +13 -0
- package/src/__tests__/middleware.test.ts +768 -0
- package/src/__tests__/pages.test.ts +829 -104
- package/src/__tests__/paths.test.ts +17 -0
- package/src/__tests__/publish.test.ts +512 -445
- package/src/__tests__/tail.test.ts +79 -72
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/worker-namespace.test.ts +37 -35
- package/src/api/dev.ts +93 -28
- package/src/bundle.ts +239 -12
- package/src/cfetch/internal.ts +64 -3
- package/src/cli.ts +1 -1
- package/src/config/environment.ts +1 -1
- package/src/config/index.ts +4 -4
- package/src/config/validation.ts +3 -3
- package/src/create-worker-upload-form.ts +29 -26
- package/src/dev/dev.tsx +3 -1
- package/src/dev/local.tsx +319 -171
- package/src/dev/remote.tsx +16 -4
- package/src/dev/start-server.ts +416 -0
- package/src/dev/use-esbuild.ts +4 -0
- package/src/dev.tsx +340 -166
- package/src/dialogs.tsx +12 -0
- package/src/{worker-namespace.ts → dispatch-namespace.ts} +18 -18
- package/src/entry.ts +2 -1
- package/src/index.tsx +59 -12
- package/src/init.ts +291 -16
- package/src/metrics/send-event.ts +6 -5
- package/src/miniflare-cli/assets.ts +130 -476
- package/src/miniflare-cli/index.ts +39 -33
- package/src/pages/constants.ts +3 -0
- package/src/pages/dev.tsx +8 -3
- package/src/pages/functions/buildPlugin.ts +2 -1
- package/src/pages/functions/buildWorker.ts +2 -1
- package/src/pages/functions/routes-transformation.test.ts +12 -1
- package/src/pages/functions/routes-transformation.ts +7 -1
- package/src/pages/hash.tsx +13 -0
- package/src/pages/publish.tsx +82 -38
- package/src/pages/upload.tsx +3 -18
- package/src/paths.ts +20 -1
- package/src/publish.ts +49 -8
- package/src/tail/filters.ts +1 -5
- package/src/tail/index.ts +6 -3
- package/src/worker.ts +10 -9
- package/src/zones.ts +91 -0
- package/templates/middleware/common.ts +62 -0
- package/templates/middleware/loader-modules.ts +84 -0
- package/templates/middleware/loader-sw.ts +213 -0
- package/templates/middleware/middleware-pretty-error.ts +40 -0
- package/templates/middleware/middleware-scheduled.ts +14 -0
- package/wrangler-dist/cli.d.ts +22 -8
- package/wrangler-dist/cli.js +71020 -65212
package/src/dev/local.tsx
CHANGED
|
@@ -8,16 +8,27 @@ import { registerWorker } from "../dev-registry";
|
|
|
8
8
|
import useInspector from "../inspect";
|
|
9
9
|
import { logger } from "../logger";
|
|
10
10
|
import { DEFAULT_MODULE_RULES } from "../module-collection";
|
|
11
|
+
import { getBasePath } from "../paths";
|
|
11
12
|
import { waitForPortToBeAvailable } from "../proxy";
|
|
12
13
|
import type { Config } from "../config";
|
|
13
14
|
import type { WorkerRegistry } from "../dev-registry";
|
|
14
15
|
import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
|
|
15
16
|
import type { AssetPaths } from "../sites";
|
|
16
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
CfWorkerInit,
|
|
19
|
+
CfScriptFormat,
|
|
20
|
+
CfWasmModuleBindings,
|
|
21
|
+
CfTextBlobBindings,
|
|
22
|
+
CfDataBlobBindings,
|
|
23
|
+
CfDurableObject,
|
|
24
|
+
CfKvNamespace,
|
|
25
|
+
CfR2Bucket,
|
|
26
|
+
CfVars,
|
|
27
|
+
} from "../worker";
|
|
17
28
|
import type { EsbuildBundle } from "./use-esbuild";
|
|
18
29
|
import type { MiniflareOptions } from "miniflare";
|
|
19
30
|
import type { ChildProcess } from "node:child_process";
|
|
20
|
-
interface LocalProps {
|
|
31
|
+
export interface LocalProps {
|
|
21
32
|
name: string | undefined;
|
|
22
33
|
bundle: EsbuildBundle | undefined;
|
|
23
34
|
format: CfScriptFormat | undefined;
|
|
@@ -25,7 +36,7 @@ interface LocalProps {
|
|
|
25
36
|
compatibilityFlags: string[] | undefined;
|
|
26
37
|
usageModel: "bundled" | "unbound" | undefined;
|
|
27
38
|
bindings: CfWorkerInit["bindings"];
|
|
28
|
-
workerDefinitions: WorkerRegistry;
|
|
39
|
+
workerDefinitions: WorkerRegistry | undefined;
|
|
29
40
|
assetPaths: AssetPaths | undefined;
|
|
30
41
|
port: number;
|
|
31
42
|
ip: string;
|
|
@@ -37,7 +48,7 @@ interface LocalProps {
|
|
|
37
48
|
localProtocol: "http" | "https";
|
|
38
49
|
localUpstream: string | undefined;
|
|
39
50
|
inspect: boolean;
|
|
40
|
-
onReady: (() => void) | undefined;
|
|
51
|
+
onReady: ((ip: string, port: number) => void) | undefined;
|
|
41
52
|
logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
|
|
42
53
|
logPrefix?: string;
|
|
43
54
|
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
|
|
@@ -136,189 +147,58 @@ function useLocalWorker({
|
|
|
136
147
|
|
|
137
148
|
const scriptPath = realpathSync(bundle.path);
|
|
138
149
|
|
|
139
|
-
// the wasm_modules/text_blobs/data_blobs bindings are
|
|
140
|
-
// relative to process.cwd(), but the actual worker bundle
|
|
141
|
-
// is in the temp output directory; so we rewrite the paths to be absolute,
|
|
142
|
-
// letting miniflare resolve them correctly
|
|
143
|
-
|
|
144
|
-
// wasm
|
|
145
|
-
const wasmBindings: Record<string, string> = {};
|
|
146
|
-
for (const [name, filePath] of Object.entries(
|
|
147
|
-
bindings.wasm_modules || {}
|
|
148
|
-
)) {
|
|
149
|
-
wasmBindings[name] = path.join(process.cwd(), filePath);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// text
|
|
153
|
-
const textBlobBindings: Record<string, string> = {};
|
|
154
|
-
for (const [name, filePath] of Object.entries(
|
|
155
|
-
bindings.text_blobs || {}
|
|
156
|
-
)) {
|
|
157
|
-
textBlobBindings[name] = path.join(process.cwd(), filePath);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// data
|
|
161
|
-
const dataBlobBindings: Record<string, string> = {};
|
|
162
|
-
for (const [name, filePath] of Object.entries(
|
|
163
|
-
bindings.data_blobs || {}
|
|
164
|
-
)) {
|
|
165
|
-
dataBlobBindings[name] = path.join(process.cwd(), filePath);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (format === "service-worker") {
|
|
169
|
-
for (const { type, name } of bundle.modules) {
|
|
170
|
-
if (type === "compiled-wasm") {
|
|
171
|
-
// In service-worker format, .wasm modules are referenced by global identifiers,
|
|
172
|
-
// so we convert it here.
|
|
173
|
-
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
174
|
-
// characters with an underscore.
|
|
175
|
-
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
176
|
-
wasmBindings[identifier] = name;
|
|
177
|
-
} else if (type === "text") {
|
|
178
|
-
// In service-worker format, text modules are referenced by global identifiers,
|
|
179
|
-
// so we convert it here.
|
|
180
|
-
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
181
|
-
// characters with an underscore.
|
|
182
|
-
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
183
|
-
textBlobBindings[identifier] = name;
|
|
184
|
-
} else if (type === "buffer") {
|
|
185
|
-
// In service-worker format, data blobs are referenced by global identifiers,
|
|
186
|
-
// so we convert it here.
|
|
187
|
-
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
188
|
-
// characters with an underscore.
|
|
189
|
-
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
190
|
-
dataBlobBindings[identifier] = name;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
150
|
const upstream =
|
|
196
151
|
typeof localUpstream === "string"
|
|
197
152
|
? `${localProtocol}://${localUpstream}`
|
|
198
153
|
: undefined;
|
|
199
154
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
155
|
+
const {
|
|
156
|
+
externalDurableObjects,
|
|
157
|
+
internalDurableObjects,
|
|
158
|
+
wasmBindings,
|
|
159
|
+
textBlobBindings,
|
|
160
|
+
dataBlobBindings,
|
|
161
|
+
} = setupBindings({
|
|
162
|
+
wasm_modules: bindings.wasm_modules,
|
|
163
|
+
text_blobs: bindings.text_blobs,
|
|
164
|
+
data_blobs: bindings.data_blobs,
|
|
165
|
+
durable_objects: bindings.durable_objects,
|
|
166
|
+
format,
|
|
167
|
+
bundle,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const { forkOptions, miniflareCLIPath } = setupMiniflareOptions({
|
|
171
|
+
workerName,
|
|
211
172
|
port,
|
|
212
173
|
scriptPath,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
.concat(DEFAULT_MODULE_RULES)
|
|
218
|
-
.map(({ type, globs: include, fallthrough }) => ({
|
|
219
|
-
type,
|
|
220
|
-
include,
|
|
221
|
-
fallthrough,
|
|
222
|
-
})),
|
|
174
|
+
localProtocol,
|
|
175
|
+
ip,
|
|
176
|
+
format,
|
|
177
|
+
rules,
|
|
223
178
|
compatibilityDate,
|
|
224
179
|
compatibilityFlags,
|
|
225
180
|
usageModel,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
binding.class_name,
|
|
232
|
-
])
|
|
233
|
-
),
|
|
234
|
-
externalDurableObjects: Object.fromEntries(
|
|
235
|
-
externalDurableObjects
|
|
236
|
-
.map((binding) => {
|
|
237
|
-
const service = workerDefinitions[binding.script_name as string];
|
|
238
|
-
if (!service) return [binding.name, undefined];
|
|
239
|
-
|
|
240
|
-
const name = service.durableObjects.find(
|
|
241
|
-
(durableObject) =>
|
|
242
|
-
durableObject.className === binding.class_name
|
|
243
|
-
)?.name;
|
|
244
|
-
if (!name) return [binding.name, undefined];
|
|
245
|
-
|
|
246
|
-
return [
|
|
247
|
-
binding.name,
|
|
248
|
-
{
|
|
249
|
-
name,
|
|
250
|
-
host: service.durableObjectsHost,
|
|
251
|
-
port: service.durableObjectsPort,
|
|
252
|
-
},
|
|
253
|
-
];
|
|
254
|
-
})
|
|
255
|
-
.filter(([_, details]) => !!details)
|
|
256
|
-
),
|
|
257
|
-
...(localPersistencePath
|
|
258
|
-
? {
|
|
259
|
-
cachePersist: path.join(localPersistencePath, "cache"),
|
|
260
|
-
durableObjectsPersist: path.join(localPersistencePath, "do"),
|
|
261
|
-
kvPersist: path.join(localPersistencePath, "kv"),
|
|
262
|
-
r2Persist: path.join(localPersistencePath, "r2"),
|
|
263
|
-
}
|
|
264
|
-
: {
|
|
265
|
-
// We mark these as true, so that they'll
|
|
266
|
-
// persist in the temp directory.
|
|
267
|
-
// This means they'll persist across a dev session,
|
|
268
|
-
// even if we change source and reload,
|
|
269
|
-
// and be deleted when the dev session ends
|
|
270
|
-
cachePersist: true,
|
|
271
|
-
durableObjectsPersist: true,
|
|
272
|
-
kvPersist: true,
|
|
273
|
-
r2Persist: true,
|
|
274
|
-
}),
|
|
275
|
-
|
|
181
|
+
kv_namespaces: bindings?.kv_namespaces,
|
|
182
|
+
r2_buckets: bindings?.r2_buckets,
|
|
183
|
+
internalDurableObjects,
|
|
184
|
+
externalDurableObjects,
|
|
185
|
+
localPersistencePath,
|
|
276
186
|
liveReload,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
: undefined,
|
|
280
|
-
siteInclude: assetPaths?.includePatterns.length
|
|
281
|
-
? assetPaths?.includePatterns
|
|
282
|
-
: undefined,
|
|
283
|
-
siteExclude: assetPaths?.excludePatterns.length
|
|
284
|
-
? assetPaths.excludePatterns
|
|
285
|
-
: undefined,
|
|
286
|
-
bindings: bindings.vars,
|
|
187
|
+
assetPaths,
|
|
188
|
+
vars: bindings?.vars,
|
|
287
189
|
wasmBindings,
|
|
288
190
|
textBlobBindings,
|
|
289
191
|
dataBlobBindings,
|
|
290
|
-
sourceMap: true,
|
|
291
|
-
logUnhandledRejections: true,
|
|
292
192
|
crons,
|
|
293
193
|
upstream,
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
// `wrangler-dist` and that the CLI is found in `miniflare-dist`.
|
|
300
|
-
// If either of those paths change this line needs updating.
|
|
301
|
-
const miniflareCLIPath = path.resolve(
|
|
302
|
-
__dirname,
|
|
303
|
-
"../miniflare-dist/index.mjs"
|
|
304
|
-
);
|
|
305
|
-
const miniflareOptions = JSON.stringify(options, null);
|
|
194
|
+
logLevel,
|
|
195
|
+
logPrefix,
|
|
196
|
+
workerDefinitions,
|
|
197
|
+
enablePagesAssetsServiceBinding,
|
|
198
|
+
});
|
|
306
199
|
|
|
200
|
+
const nodeOptions = setupNodeOptions({ inspect, ip, inspectorPort });
|
|
307
201
|
logger.log("⎔ Starting a local server...");
|
|
308
|
-
const nodeOptions = [
|
|
309
|
-
"--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
|
|
310
|
-
"--no-warnings", // hide annoying Node warnings
|
|
311
|
-
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
312
|
-
];
|
|
313
|
-
if (inspect) {
|
|
314
|
-
nodeOptions.push("--inspect=" + `${ip}:${inspectorPort}`); // start Miniflare listening for a debugger to attach
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const forkOptions = [miniflareOptions];
|
|
318
|
-
|
|
319
|
-
if (enablePagesAssetsServiceBinding) {
|
|
320
|
-
forkOptions.push(JSON.stringify(enablePagesAssetsServiceBinding));
|
|
321
|
-
}
|
|
322
202
|
|
|
323
203
|
const child = (local.current = fork(miniflareCLIPath, forkOptions, {
|
|
324
204
|
cwd: path.dirname(scriptPath),
|
|
@@ -348,7 +228,7 @@ function useLocalWorker({
|
|
|
348
228
|
: {}),
|
|
349
229
|
});
|
|
350
230
|
}
|
|
351
|
-
onReady?.();
|
|
231
|
+
onReady?.(ip, message.mfPort);
|
|
352
232
|
}
|
|
353
233
|
});
|
|
354
234
|
|
|
@@ -420,7 +300,7 @@ function useLocalWorker({
|
|
|
420
300
|
port,
|
|
421
301
|
inspectorPort,
|
|
422
302
|
ip,
|
|
423
|
-
bindings.durable_objects
|
|
303
|
+
bindings.durable_objects,
|
|
424
304
|
bindings.kv_namespaces,
|
|
425
305
|
bindings.r2_buckets,
|
|
426
306
|
bindings.vars,
|
|
@@ -447,3 +327,271 @@ function useLocalWorker({
|
|
|
447
327
|
]);
|
|
448
328
|
return { inspectorUrl };
|
|
449
329
|
}
|
|
330
|
+
|
|
331
|
+
interface SetupBindingsProps {
|
|
332
|
+
wasm_modules: CfWasmModuleBindings | undefined;
|
|
333
|
+
text_blobs: CfTextBlobBindings | undefined;
|
|
334
|
+
data_blobs: CfDataBlobBindings | undefined;
|
|
335
|
+
durable_objects: { bindings: CfDurableObject[] } | undefined;
|
|
336
|
+
bundle: EsbuildBundle;
|
|
337
|
+
format: CfScriptFormat;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function setupBindings({
|
|
341
|
+
wasm_modules,
|
|
342
|
+
text_blobs,
|
|
343
|
+
data_blobs,
|
|
344
|
+
durable_objects,
|
|
345
|
+
format,
|
|
346
|
+
bundle,
|
|
347
|
+
}: SetupBindingsProps) {
|
|
348
|
+
// the wasm_modules/text_blobs/data_blobs bindings are
|
|
349
|
+
// relative to process.cwd(), but the actual worker bundle
|
|
350
|
+
// is in the temp output directory; so we rewrite the paths to be absolute,
|
|
351
|
+
// letting miniflare resolve them correctly
|
|
352
|
+
|
|
353
|
+
// wasm
|
|
354
|
+
const wasmBindings: Record<string, string> = {};
|
|
355
|
+
for (const [name, filePath] of Object.entries(wasm_modules || {})) {
|
|
356
|
+
wasmBindings[name] = path.join(process.cwd(), filePath);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// text
|
|
360
|
+
const textBlobBindings: Record<string, string> = {};
|
|
361
|
+
for (const [name, filePath] of Object.entries(text_blobs || {})) {
|
|
362
|
+
textBlobBindings[name] = path.join(process.cwd(), filePath);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// data
|
|
366
|
+
const dataBlobBindings: Record<string, string> = {};
|
|
367
|
+
for (const [name, filePath] of Object.entries(data_blobs || {})) {
|
|
368
|
+
dataBlobBindings[name] = path.join(process.cwd(), filePath);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (format === "service-worker") {
|
|
372
|
+
for (const { type, name } of bundle.modules) {
|
|
373
|
+
if (type === "compiled-wasm") {
|
|
374
|
+
// In service-worker format, .wasm modules are referenced by global identifiers,
|
|
375
|
+
// so we convert it here.
|
|
376
|
+
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
377
|
+
// characters with an underscore.
|
|
378
|
+
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
379
|
+
wasmBindings[identifier] = name;
|
|
380
|
+
} else if (type === "text") {
|
|
381
|
+
// In service-worker format, text modules are referenced by global identifiers,
|
|
382
|
+
// so we convert it here.
|
|
383
|
+
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
384
|
+
// characters with an underscore.
|
|
385
|
+
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
386
|
+
textBlobBindings[identifier] = name;
|
|
387
|
+
} else if (type === "buffer") {
|
|
388
|
+
// In service-worker format, data blobs are referenced by global identifiers,
|
|
389
|
+
// so we convert it here.
|
|
390
|
+
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
|
|
391
|
+
// characters with an underscore.
|
|
392
|
+
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
393
|
+
dataBlobBindings[identifier] = name;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const internalDurableObjects = (durable_objects?.bindings || []).filter(
|
|
399
|
+
(binding) => !binding.script_name
|
|
400
|
+
);
|
|
401
|
+
const externalDurableObjects = (durable_objects?.bindings || []).filter(
|
|
402
|
+
(binding) => binding.script_name
|
|
403
|
+
);
|
|
404
|
+
return {
|
|
405
|
+
internalDurableObjects,
|
|
406
|
+
externalDurableObjects,
|
|
407
|
+
wasmBindings,
|
|
408
|
+
textBlobBindings,
|
|
409
|
+
dataBlobBindings,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
interface SetupMiniflareOptionsProps {
|
|
414
|
+
workerName: string | undefined;
|
|
415
|
+
port: number;
|
|
416
|
+
scriptPath: string;
|
|
417
|
+
localProtocol: "http" | "https";
|
|
418
|
+
ip: string;
|
|
419
|
+
format: CfScriptFormat;
|
|
420
|
+
rules: Config["rules"];
|
|
421
|
+
compatibilityDate: string;
|
|
422
|
+
compatibilityFlags: string[] | undefined;
|
|
423
|
+
usageModel: "bundled" | "unbound" | undefined;
|
|
424
|
+
kv_namespaces: CfKvNamespace[] | undefined;
|
|
425
|
+
r2_buckets: CfR2Bucket[] | undefined;
|
|
426
|
+
internalDurableObjects: CfDurableObject[];
|
|
427
|
+
externalDurableObjects: CfDurableObject[];
|
|
428
|
+
localPersistencePath: string | null;
|
|
429
|
+
liveReload: boolean;
|
|
430
|
+
assetPaths: AssetPaths | undefined;
|
|
431
|
+
vars: CfVars | undefined;
|
|
432
|
+
wasmBindings: Record<string, string>;
|
|
433
|
+
textBlobBindings: Record<string, string>;
|
|
434
|
+
dataBlobBindings: Record<string, string>;
|
|
435
|
+
crons: Config["triggers"]["crons"];
|
|
436
|
+
upstream: string | undefined;
|
|
437
|
+
logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
|
|
438
|
+
logPrefix: string | undefined;
|
|
439
|
+
workerDefinitions: WorkerRegistry | undefined;
|
|
440
|
+
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export function setupMiniflareOptions({
|
|
444
|
+
workerName,
|
|
445
|
+
port,
|
|
446
|
+
scriptPath,
|
|
447
|
+
localProtocol,
|
|
448
|
+
ip,
|
|
449
|
+
format,
|
|
450
|
+
rules,
|
|
451
|
+
compatibilityDate,
|
|
452
|
+
compatibilityFlags,
|
|
453
|
+
usageModel,
|
|
454
|
+
kv_namespaces,
|
|
455
|
+
r2_buckets,
|
|
456
|
+
internalDurableObjects,
|
|
457
|
+
externalDurableObjects,
|
|
458
|
+
localPersistencePath,
|
|
459
|
+
liveReload,
|
|
460
|
+
assetPaths,
|
|
461
|
+
vars,
|
|
462
|
+
wasmBindings,
|
|
463
|
+
textBlobBindings,
|
|
464
|
+
dataBlobBindings,
|
|
465
|
+
crons,
|
|
466
|
+
upstream,
|
|
467
|
+
logLevel,
|
|
468
|
+
logPrefix,
|
|
469
|
+
workerDefinitions,
|
|
470
|
+
enablePagesAssetsServiceBinding,
|
|
471
|
+
}: SetupMiniflareOptionsProps): MiniflareOptions {
|
|
472
|
+
// TODO: This was already messy with the custom `disableLogs` and `logOptions`.
|
|
473
|
+
// It's now getting _really_ messy now with Pages ASSETS binding outside and the external Durable Objects inside.
|
|
474
|
+
const options = {
|
|
475
|
+
name: workerName,
|
|
476
|
+
port,
|
|
477
|
+
scriptPath,
|
|
478
|
+
https: localProtocol === "https",
|
|
479
|
+
host: ip,
|
|
480
|
+
modules: format === "modules",
|
|
481
|
+
modulesRules: (rules || [])
|
|
482
|
+
.concat(DEFAULT_MODULE_RULES)
|
|
483
|
+
.map(({ type, globs: include, fallthrough }) => ({
|
|
484
|
+
type,
|
|
485
|
+
include,
|
|
486
|
+
fallthrough,
|
|
487
|
+
})),
|
|
488
|
+
compatibilityDate,
|
|
489
|
+
compatibilityFlags,
|
|
490
|
+
usageModel,
|
|
491
|
+
kvNamespaces: kv_namespaces?.map((kv) => kv.binding),
|
|
492
|
+
r2Buckets: r2_buckets?.map((r2) => r2.binding),
|
|
493
|
+
durableObjects: Object.fromEntries(
|
|
494
|
+
internalDurableObjects.map((binding) => [
|
|
495
|
+
binding.name,
|
|
496
|
+
binding.class_name,
|
|
497
|
+
])
|
|
498
|
+
),
|
|
499
|
+
externalDurableObjects: Object.fromEntries(
|
|
500
|
+
externalDurableObjects
|
|
501
|
+
.map((binding) => {
|
|
502
|
+
const service =
|
|
503
|
+
workerDefinitions &&
|
|
504
|
+
workerDefinitions[binding.script_name as string];
|
|
505
|
+
if (!service) return [binding.name, undefined];
|
|
506
|
+
|
|
507
|
+
const name = service.durableObjects.find(
|
|
508
|
+
(durableObject) => durableObject.className === binding.class_name
|
|
509
|
+
)?.name;
|
|
510
|
+
if (!name) return [binding.name, undefined];
|
|
511
|
+
|
|
512
|
+
return [
|
|
513
|
+
binding.name,
|
|
514
|
+
{
|
|
515
|
+
name,
|
|
516
|
+
host: service.durableObjectsHost,
|
|
517
|
+
port: service.durableObjectsPort,
|
|
518
|
+
},
|
|
519
|
+
];
|
|
520
|
+
})
|
|
521
|
+
.filter(([_, details]) => !!details)
|
|
522
|
+
),
|
|
523
|
+
...(localPersistencePath
|
|
524
|
+
? {
|
|
525
|
+
cachePersist: path.join(localPersistencePath, "cache"),
|
|
526
|
+
durableObjectsPersist: path.join(localPersistencePath, "do"),
|
|
527
|
+
kvPersist: path.join(localPersistencePath, "kv"),
|
|
528
|
+
r2Persist: path.join(localPersistencePath, "r2"),
|
|
529
|
+
}
|
|
530
|
+
: {
|
|
531
|
+
// We mark these as true, so that they'll
|
|
532
|
+
// persist in the temp directory.
|
|
533
|
+
// This means they'll persist across a dev session,
|
|
534
|
+
// even if we change source and reload,
|
|
535
|
+
// and be deleted when the dev session ends
|
|
536
|
+
cachePersist: true,
|
|
537
|
+
durableObjectsPersist: true,
|
|
538
|
+
kvPersist: true,
|
|
539
|
+
r2Persist: true,
|
|
540
|
+
}),
|
|
541
|
+
|
|
542
|
+
liveReload,
|
|
543
|
+
sitePath: assetPaths?.assetDirectory
|
|
544
|
+
? path.join(assetPaths.baseDirectory, assetPaths.assetDirectory)
|
|
545
|
+
: undefined,
|
|
546
|
+
siteInclude: assetPaths?.includePatterns.length
|
|
547
|
+
? assetPaths?.includePatterns
|
|
548
|
+
: undefined,
|
|
549
|
+
siteExclude: assetPaths?.excludePatterns.length
|
|
550
|
+
? assetPaths.excludePatterns
|
|
551
|
+
: undefined,
|
|
552
|
+
bindings: vars,
|
|
553
|
+
wasmBindings,
|
|
554
|
+
textBlobBindings,
|
|
555
|
+
dataBlobBindings,
|
|
556
|
+
sourceMap: true,
|
|
557
|
+
logUnhandledRejections: true,
|
|
558
|
+
crons,
|
|
559
|
+
upstream,
|
|
560
|
+
disableLogs: logLevel === "none",
|
|
561
|
+
logOptions: logPrefix ? { prefix: logPrefix } : undefined,
|
|
562
|
+
enablePagesAssetsServiceBinding,
|
|
563
|
+
};
|
|
564
|
+
// The path to the Miniflare CLI assumes that this file is being run from
|
|
565
|
+
// `wrangler-dist` and that the CLI is found in `miniflare-dist`.
|
|
566
|
+
// If either of those paths change this line needs updating.
|
|
567
|
+
const miniflareCLIPath = path.resolve(
|
|
568
|
+
getBasePath(),
|
|
569
|
+
"miniflare-dist/index.mjs"
|
|
570
|
+
);
|
|
571
|
+
const miniflareOptions = JSON.stringify(options, null);
|
|
572
|
+
const forkOptions = [miniflareOptions];
|
|
573
|
+
if (enablePagesAssetsServiceBinding) {
|
|
574
|
+
forkOptions.push(JSON.stringify(enablePagesAssetsServiceBinding));
|
|
575
|
+
}
|
|
576
|
+
return { miniflareCLIPath, forkOptions };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
export function setupNodeOptions({
|
|
580
|
+
inspect,
|
|
581
|
+
ip,
|
|
582
|
+
inspectorPort,
|
|
583
|
+
}: {
|
|
584
|
+
inspect: boolean;
|
|
585
|
+
ip: string;
|
|
586
|
+
inspectorPort: number;
|
|
587
|
+
}) {
|
|
588
|
+
const nodeOptions = [
|
|
589
|
+
"--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
|
|
590
|
+
"--no-warnings", // hide annoying Node warnings
|
|
591
|
+
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
592
|
+
];
|
|
593
|
+
if (inspect) {
|
|
594
|
+
nodeOptions.push("--inspect=" + `${ip}:${inspectorPort}`); // start Miniflare listening for a debugger to attach
|
|
595
|
+
}
|
|
596
|
+
return nodeOptions;
|
|
597
|
+
}
|
package/src/dev/remote.tsx
CHANGED
|
@@ -54,7 +54,7 @@ export function Remote(props: {
|
|
|
54
54
|
zone: string | undefined;
|
|
55
55
|
host: string | undefined;
|
|
56
56
|
routes: Route[] | undefined;
|
|
57
|
-
onReady?: (() => void) | undefined;
|
|
57
|
+
onReady?: ((ip: string, port: number) => void) | undefined;
|
|
58
58
|
sourceMapPath: string | undefined;
|
|
59
59
|
sendMetrics: boolean | undefined;
|
|
60
60
|
}) {
|
|
@@ -81,6 +81,7 @@ export function Remote(props: {
|
|
|
81
81
|
routes: props.routes,
|
|
82
82
|
onReady: props.onReady,
|
|
83
83
|
sendMetrics: props.sendMetrics,
|
|
84
|
+
port: props.port,
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
usePreviewServer({
|
|
@@ -164,8 +165,9 @@ export function useWorker(props: {
|
|
|
164
165
|
zone: string | undefined;
|
|
165
166
|
host: string | undefined;
|
|
166
167
|
routes: Route[] | undefined;
|
|
167
|
-
onReady: (() => void) | undefined;
|
|
168
|
+
onReady: ((ip: string, port: number) => void) | undefined;
|
|
168
169
|
sendMetrics: boolean | undefined;
|
|
170
|
+
port: number;
|
|
169
171
|
}): CfPreviewToken | undefined {
|
|
170
172
|
const {
|
|
171
173
|
name,
|
|
@@ -182,7 +184,7 @@ export function useWorker(props: {
|
|
|
182
184
|
} = props;
|
|
183
185
|
const [session, setSession] = useState<CfPreviewSession | undefined>();
|
|
184
186
|
const [token, setToken] = useState<CfPreviewToken | undefined>();
|
|
185
|
-
|
|
187
|
+
const [restartCounter, setRestartCounter] = useState<number>(0);
|
|
186
188
|
// This is the most reliable way to detect whether
|
|
187
189
|
// something's "happened" in our system; We make a ref and
|
|
188
190
|
// mark it once we log our initial message. Refs are vars!
|
|
@@ -237,6 +239,7 @@ export function useWorker(props: {
|
|
|
237
239
|
props.routes,
|
|
238
240
|
props.zone,
|
|
239
241
|
props.sendMetrics,
|
|
242
|
+
restartCounter,
|
|
240
243
|
]);
|
|
241
244
|
|
|
242
245
|
// This effect uses the session to upload the worker and create a preview
|
|
@@ -314,6 +317,7 @@ export function useWorker(props: {
|
|
|
314
317
|
compatibility_date: compatibilityDate,
|
|
315
318
|
compatibility_flags: compatibilityFlags,
|
|
316
319
|
usage_model: usageModel,
|
|
320
|
+
keep_bindings: true,
|
|
317
321
|
};
|
|
318
322
|
|
|
319
323
|
const workerAccount: CfAccount = {
|
|
@@ -361,7 +365,7 @@ export function useWorker(props: {
|
|
|
361
365
|
}
|
|
362
366
|
*/
|
|
363
367
|
|
|
364
|
-
onReady?.();
|
|
368
|
+
onReady?.(props.host || "localhost", props.port);
|
|
365
369
|
}
|
|
366
370
|
start().catch((err) => {
|
|
367
371
|
// we want to log the error, but not end the process
|
|
@@ -379,6 +383,13 @@ export function useWorker(props: {
|
|
|
379
383
|
logger.error(
|
|
380
384
|
`${errorMessage}\n${solutionMessage}\n${onboardingLink}`
|
|
381
385
|
);
|
|
386
|
+
} else if (err.code === 10049) {
|
|
387
|
+
logger.log("Preview token expired, fetching a new one");
|
|
388
|
+
// code 10049 happens when the preview token expires
|
|
389
|
+
// since we want a new preview token when this happens,
|
|
390
|
+
// lets increment the counter, and trigger a rerun of
|
|
391
|
+
// the useEffect above
|
|
392
|
+
setRestartCounter((prevCount) => prevCount + 1);
|
|
382
393
|
} else {
|
|
383
394
|
logger.error("Error on remote worker:", err);
|
|
384
395
|
}
|
|
@@ -408,6 +419,7 @@ export function useWorker(props: {
|
|
|
408
419
|
session,
|
|
409
420
|
onReady,
|
|
410
421
|
props.sendMetrics,
|
|
422
|
+
props.port,
|
|
411
423
|
]);
|
|
412
424
|
return token;
|
|
413
425
|
}
|