devflare 1.0.0-next.34 → 1.0.0-next.36

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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/LLM.md +2 -0
  3. package/README.md +5 -4
  4. package/bin/devflare.js +1 -1
  5. package/dist/{account-p9eywryw.js → account-4tgh03a8.js} +4 -6
  6. package/dist/bridge/client.d.ts +1 -1
  7. package/dist/bridge/v2/control-messages.d.ts +1 -6
  8. package/dist/bridge/v2/control-messages.d.ts.map +1 -1
  9. package/dist/bridge/v2/wire.d.ts +4 -4
  10. package/dist/bridge/v2/wire.d.ts.map +1 -1
  11. package/dist/browser.js +2340 -19
  12. package/dist/{build-8bn7frg8.js → build-rh7ghrgw.js} +7 -10
  13. package/dist/cli/index.js +1377 -6
  14. package/dist/cloudflare/index.js +2 -3
  15. package/dist/config-entry.js +1 -9
  16. package/dist/{config-gphd6wx7.js → config-ghk2bxj3.js} +3 -6
  17. package/dist/{deploy-vpcp41fw.js → deploy-6hzv76sh.js} +13 -17
  18. package/dist/{dev-9scy9gap.js → dev-mkhjdwh7.js} +971 -73
  19. package/dist/{doctor-swfeeqny.js → doctor-0ng5qrr1.js} +2 -3
  20. package/dist/{index-e7xn30bh.js → index-0cc05hzv.js} +1 -1
  21. package/dist/{index-t0r7evpw.js → index-293aqfy4.js} +7 -9
  22. package/dist/{index-3t0e51a0.js → index-2yv7w548.js} +1 -1
  23. package/dist/{index-ksqth51q.js → index-a8pnvg3r.js} +1 -1
  24. package/dist/{index-bhxj7ff6.js → index-e251zhns.js} +943 -117
  25. package/dist/{index-2xz4etye.js → index-hvtd936d.js} +3 -0
  26. package/dist/{index-13sfensw.js → index-kcp7y951.js} +2 -13
  27. package/dist/{index-w8c8tjc5.js → index-mek9msfv.js} +1 -4
  28. package/dist/{index-dem45895.js → index-mjvybn39.js} +1 -1
  29. package/dist/{index-x0wpeb3x.js → index-phcrvs6d.js} +112 -2
  30. package/dist/{index-b20xx2vk.js → index-se4kw8tm.js} +4 -6
  31. package/dist/{index-pd97hk2j.js → index-x8s9rwfh.js} +466 -19
  32. package/dist/index.js +1 -42
  33. package/dist/{login-7vyzeqy4.js → login-4h1sfsed.js} +4 -6
  34. package/dist/{previews-jfbectpc.js → previews-qr7c5j8h.js} +10 -14
  35. package/dist/{productions-49ct4kjm.js → productions-xpmd6bw8.js} +6 -9
  36. package/dist/{remote-6876k6mz.js → remote-kqcvhnfx.js} +100 -5
  37. package/dist/runtime/index.js +0 -63
  38. package/dist/{secrets-9ne7armr.js → secrets-6wbdsdek.js} +3 -5
  39. package/dist/sveltekit/index.js +0 -263
  40. package/dist/test/index.js +2 -4626
  41. package/dist/{types-zekmbebk.js → types-ahnnpphq.js} +6 -8
  42. package/dist/vite/index.js +7 -9
  43. package/dist/{worker-706g8qeh.js → worker-1yg72jxg.js} +6 -9
  44. package/package.json +5 -3
  45. package/dist/index-1trss579.js +0 -2299
  46. package/dist/index-34dejneh.js +0 -214
  47. package/dist/index-3z20d3kd.js +0 -1380
  48. package/dist/index-4xmtkg9g.js +0 -109
  49. package/dist/index-62b3gt2g.js +0 -12
  50. package/dist/index-97rfy7n2.js +0 -413
  51. package/dist/index-c4zd39tc.js +0 -155
  52. package/dist/index-dgx495pv.js +0 -1036
  53. package/dist/index-dm9q84c7.js +0 -360
  54. package/dist/index-pmnb7eke.js +0 -109
  55. package/dist/index-t23wq5js.js +0 -111
  56. package/dist/index-wxdcrzcp.js +0 -475
  57. package/dist/index-x2fd1361.js +0 -133
  58. package/dist/index-za0r01bx.js +0 -588
@@ -1,9 +1,20 @@
1
+ import {
2
+ buildLocalSecretWrappedBindingConfig
3
+ } from "./index-kcp7y951.js";
4
+ import {
5
+ bundleWorkerEntry,
6
+ createDOBundler
7
+ } from "./index-mjvybn39.js";
1
8
  import {
2
9
  detectViteProject,
3
10
  resolveViteMode,
4
11
  stopSpawnedProcessTree,
5
12
  waitForViteReady
6
13
  } from "./index-zdd0d9qa.js";
14
+ import {
15
+ clearLocalSendEmailBindings,
16
+ setLocalSendEmailBindings
17
+ } from "./index-n4xkaymm.js";
7
18
  import {
8
19
  createCliTheme,
9
20
  cyanBold,
@@ -12,25 +23,11 @@ import {
12
23
  yellow
13
24
  } from "./index-maw0jjnn.js";
14
25
  import"./index-3t6rypgc.js";
15
- import {
16
- bundleWorkflowEntrypointScript
17
- } from "./index-pmnb7eke.js";
18
- import {
19
- bundleWorkerEntry,
20
- createDOBundler
21
- } from "./index-dem45895.js";
22
26
  import {
23
27
  DEFAULT_EMAIL_ENTRY_FILES,
24
28
  DEFAULT_FETCH_ENTRY_FILES,
25
29
  DEFAULT_QUEUE_ENTRY_FILES,
26
30
  DEFAULT_SCHEDULED_ENTRY_FILES,
27
- hasWorkerSurfacePaths,
28
- prepareComposedWorkerEntrypoint,
29
- resolveEffectiveViteProject,
30
- resolveWorkerSurfacePaths,
31
- writeGeneratedViteConfig
32
- } from "./index-bhxj7ff6.js";
33
- import {
34
31
  buildAiSearchInstancesConfig,
35
32
  buildAiSearchNamespacesConfig,
36
33
  buildArtifactsConfig,
@@ -50,55 +47,46 @@ import {
50
47
  buildWorkflowsConfig,
51
48
  discoverRoutes,
52
49
  getRouteDirectoryCandidate,
53
- resolveServiceBindings
54
- } from "./index-dgx495pv.js";
50
+ hasWorkerSurfacePaths,
51
+ prepareComposedWorkerEntrypoint,
52
+ resolveEffectiveViteProject,
53
+ resolveServiceBindings,
54
+ resolveWorkerSurfacePaths,
55
+ writeGeneratedViteConfig
56
+ } from "./index-e251zhns.js";
55
57
  import"./index-by27mzra.js";
56
- import"./index-5dkjffqz.js";
57
- import"./index-7m557715.js";
58
- import"./index-p93cngdp.js";
59
58
  import {
60
- GATEWAY_RUNTIME_JS,
61
- createMiniflareLog,
62
- isIgnorableMiniflareDisposeError
63
- } from "./index-za0r01bx.js";
64
- import {
65
- buildLocalBindingShimServiceConfig
66
- } from "./index-dm9q84c7.js";
67
- import {
68
- buildLocalSecretWrappedBindingConfig
69
- } from "./index-13sfensw.js";
70
- import {
71
- clearLocalSendEmailBindings,
72
- setLocalSendEmailBindings
73
- } from "./index-n4xkaymm.js";
59
+ DEFAULT_WORKFLOW_PATTERN,
60
+ findFiles
61
+ } from "./index-5dkjffqz.js";
74
62
  import {
75
63
  applyLocalDevVarsToConfig
76
- } from "./index-w8c8tjc5.js";
64
+ } from "./index-mek9msfv.js";
77
65
  import {
66
+ EnvVarResolutionError,
67
+ getDevflareDotenvPaths,
78
68
  getLocalD1DatabaseIdentifier,
79
69
  getLocalKVNamespaceIdentifier,
80
70
  getSingleBrowserBindingName,
81
71
  loadConfig,
72
+ normalizeWorkflowBinding,
73
+ resolveConfigEnvVars,
82
74
  resolveConfigPath
83
- } from "./index-pd97hk2j.js";
75
+ } from "./index-x8s9rwfh.js";
84
76
  import"./index-h7r11y4a.js";
85
77
  import"./index-04wh9bxx.js";
86
- import {
87
- EnvVarResolutionError,
88
- getDevflareDotenvPaths,
89
- resolveConfigEnvVars
90
- } from "./index-wxdcrzcp.js";
91
- import"./index-34dejneh.js";
78
+ import"./index-7m557715.js";
79
+ import"./index-p93cngdp.js";
92
80
  import {
93
81
  __require
94
82
  } from "./index-37x76zdn.js";
95
83
 
96
84
  // src/cli/commands/dev.ts
97
85
  import { createConsola } from "consola";
98
- import { relative, resolve as resolve7 } from "pathe";
86
+ import { relative as relative2, resolve as resolve8 } from "pathe";
99
87
 
100
88
  // src/dev-server/server.ts
101
- import { dirname as dirname2, resolve as resolve6 } from "pathe";
89
+ import { dirname as dirname3, resolve as resolve7 } from "pathe";
102
90
 
103
91
  // src/cli/wrangler-auth.ts
104
92
  import { exec } from "node:child_process";
@@ -173,9 +161,106 @@ async function checkRemoteBindingRequirements(config) {
173
161
  };
174
162
  }
175
163
 
164
+ // src/workflows/local-workflow-entrypoints.ts
165
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
166
+ import { join, relative, resolve } from "pathe";
167
+ function findExportedClasses(code) {
168
+ const classes = [];
169
+ const classPattern = /export\s+class\s+(\w+)/g;
170
+ let match;
171
+ while ((match = classPattern.exec(code)) !== null) {
172
+ classes.push(match[1]);
173
+ }
174
+ return classes;
175
+ }
176
+ function toImportSpecifier(fromDir, filePath) {
177
+ const relativePath = relative(fromDir, filePath).replace(/\\/g, "/");
178
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
179
+ }
180
+ async function discoverWorkflowClasses(config, configDir) {
181
+ const classToFilePath = new Map;
182
+ const workflowPatternConfig = config.files?.workflows;
183
+ const workflowPattern = typeof workflowPatternConfig === "string" ? workflowPatternConfig : DEFAULT_WORKFLOW_PATTERN;
184
+ if (workflowPatternConfig === false) {
185
+ return classToFilePath;
186
+ }
187
+ const files = await findFiles(workflowPattern, { cwd: configDir });
188
+ for (const filePath of files) {
189
+ try {
190
+ const code = await readFile(filePath, "utf-8");
191
+ for (const className of findExportedClasses(code)) {
192
+ classToFilePath.set(className, filePath);
193
+ }
194
+ } catch {}
195
+ }
196
+ return classToFilePath;
197
+ }
198
+ async function resolveLocalWorkflowEntrypoints(config, configDir) {
199
+ const workflows = config.bindings?.workflows;
200
+ if (!workflows || Object.keys(workflows).length === 0) {
201
+ return [];
202
+ }
203
+ const classToFilePath = await discoverWorkflowClasses(config, configDir);
204
+ const entrypoints = [];
205
+ for (const [bindingName, binding] of Object.entries(workflows)) {
206
+ const normalized = normalizeWorkflowBinding(binding);
207
+ if (normalized.scriptName) {
208
+ continue;
209
+ }
210
+ const scriptPath = classToFilePath.get(normalized.className);
211
+ if (!scriptPath) {
212
+ throw new Error(`Workflow binding ${bindingName} (className: '${normalized.className}') not found.
213
+ ` + `Either set files.workflows to match the workflow source file, or set scriptName when the workflow lives in another worker.`);
214
+ }
215
+ entrypoints.push({
216
+ bindingName,
217
+ className: normalized.className,
218
+ scriptPath
219
+ });
220
+ }
221
+ return entrypoints;
222
+ }
223
+ function buildWorkflowVirtualEntry(entrypoints, entryDir) {
224
+ const imports = entrypoints.map((entrypoint, index) => {
225
+ const importName = `__DevflareWorkflow${index}`;
226
+ const importPath = toImportSpecifier(entryDir, entrypoint.scriptPath);
227
+ return {
228
+ importName,
229
+ className: entrypoint.className,
230
+ line: `import { ${entrypoint.className} as ${importName} } from '${importPath}'`
231
+ };
232
+ });
233
+ const exports = imports.map((entrypoint) => {
234
+ return `export { ${entrypoint.importName} as ${entrypoint.className} }`;
235
+ });
236
+ return [...imports.map((entrypoint) => entrypoint.line), "", ...exports].join(`
237
+ `);
238
+ }
239
+ async function bundleWorkflowEntrypointScript(config, configDir, options = {}) {
240
+ const entrypoints = await resolveLocalWorkflowEntrypoints(config, configDir);
241
+ if (entrypoints.length === 0) {
242
+ return "";
243
+ }
244
+ const entryDir = resolve(configDir, ".devflare", "workflow-entrypoints");
245
+ const entryPath = join(entryDir, "__entry.ts");
246
+ const outFile = join(entryDir, "index.js");
247
+ await mkdir(entryDir, { recursive: true });
248
+ await writeFile(entryPath, buildWorkflowVirtualEntry(entrypoints, entryDir));
249
+ await bundleWorkerEntry({
250
+ cwd: configDir,
251
+ inputFile: entryPath,
252
+ outFile,
253
+ rolldownOptions: config.rolldown?.options,
254
+ sourcemap: config.rolldown?.sourcemap,
255
+ minify: config.rolldown?.minify,
256
+ logger: options.logger
257
+ });
258
+ return await readFile(outFile, "utf-8");
259
+ }
260
+
176
261
  // src/dev-server/d1-migrations.ts
177
262
  import { createHash } from "node:crypto";
178
- import { resolve } from "pathe";
263
+ import { resolve as resolve2 } from "pathe";
179
264
  var MIGRATION_RETRY_DELAYS_MS = [500, 1000, 1500, 2000];
180
265
  function collectMigrationStatements(sql) {
181
266
  const cleanedSql = sql.split(`
@@ -238,7 +323,7 @@ async function runD1Migrations(options) {
238
323
  return;
239
324
  }
240
325
  const { existsSync, readdirSync, readFileSync, statSync } = await import("node:fs");
241
- const migrationsDir = resolve(cwd, "migrations");
326
+ const migrationsDir = resolve2(cwd, "migrations");
242
327
  if (!existsSync(migrationsDir)) {
243
328
  logger?.debug("No migrations/ directory found, skipping D1 migrations");
244
329
  return;
@@ -248,7 +333,7 @@ async function runD1Migrations(options) {
248
333
  if (sharedFiles.length > 0) {
249
334
  sharedFileEntries = [];
250
335
  for (const file of sharedFiles) {
251
- const sql = readFileSync(resolve(migrationsDir, file), "utf-8");
336
+ const sql = readFileSync(resolve2(migrationsDir, file), "utf-8");
252
337
  const fileStatements = collectMigrationStatements(sql);
253
338
  sharedFileEntries.push({
254
339
  filename: file,
@@ -259,7 +344,7 @@ async function runD1Migrations(options) {
259
344
  }
260
345
  }
261
346
  for (const [bindingName] of Object.entries(config.bindings.d1)) {
262
- const perBindingDir = resolve(migrationsDir, bindingName);
347
+ const perBindingDir = resolve2(migrationsDir, bindingName);
263
348
  const hasPerBindingDir = existsSync(perBindingDir) && statSync(perBindingDir).isDirectory();
264
349
  let files = [];
265
350
  let sourceLabel = "";
@@ -270,7 +355,7 @@ async function runD1Migrations(options) {
270
355
  continue;
271
356
  }
272
357
  for (const file of perBindingFiles) {
273
- const sql = readFileSync(resolve(perBindingDir, file), "utf-8");
358
+ const sql = readFileSync(resolve2(perBindingDir, file), "utf-8");
274
359
  const fileStatements = collectMigrationStatements(sql);
275
360
  files.push({
276
361
  filename: file,
@@ -303,6 +388,819 @@ async function runD1Migrations(options) {
303
388
  }
304
389
  }
305
390
 
391
+ // src/dev-server/miniflare-log.ts
392
+ var ANSI_ESCAPE_REGEX = /\u001B\[[0-9;]*m/g;
393
+ var COMPATIBILITY_DATE_FALLBACK_REGEX = /^The latest compatibility date supported by the installed Cloudflare Workers Runtime is "([^"]+)", but you've requested "([^"]+)"\. Falling back to "([^"]+)"\.\.\.$/;
394
+ var MINIFLARE_LOG_LEVEL_FALLBACKS = {
395
+ WARN: 2,
396
+ DEBUG: 4
397
+ };
398
+ function normalizeMiniflareMessage(message) {
399
+ return message.replace(ANSI_ESCAPE_REGEX, "").replace(/\s+/g, " ").trim();
400
+ }
401
+ function formatCompatibilityDateFallbackNotice(message) {
402
+ const normalizedMessage = normalizeMiniflareMessage(message);
403
+ const match = COMPATIBILITY_DATE_FALLBACK_REGEX.exec(normalizedMessage);
404
+ if (!match) {
405
+ return null;
406
+ }
407
+ const [, _supportedDate, requestedDate, fallbackDate] = match;
408
+ return `Using latest supported Cloudflare Workers Runtime compatibility date ${fallbackDate} (requested ${requestedDate})`;
409
+ }
410
+ function resolveMiniflareLogLevel(logLevel, levelName) {
411
+ return logLevel?.[levelName] ?? MINIFLARE_LOG_LEVEL_FALLBACKS[levelName];
412
+ }
413
+ function createMiniflareLog(BaseLog, logLevel, levelName, logger) {
414
+ if (!BaseLog) {
415
+ return;
416
+ }
417
+ return createCompatibilityAwareMiniflareLog(BaseLog, resolveMiniflareLogLevel(logLevel, levelName), logger);
418
+ }
419
+ function createCompatibilityAwareMiniflareLog(BaseLog, level, logger) {
420
+ const log = new BaseLog(level);
421
+ const originalWarn = log.warn.bind(log);
422
+ const originalInfo = log.info.bind(log);
423
+ log.warn = (message) => {
424
+ const notice = formatCompatibilityDateFallbackNotice(message);
425
+ if (!notice) {
426
+ originalWarn(message);
427
+ return;
428
+ }
429
+ if (logger) {
430
+ logger.info(notice);
431
+ return;
432
+ }
433
+ originalInfo(notice);
434
+ };
435
+ return log;
436
+ }
437
+
438
+ // src/shims/local-media-bindings.ts
439
+ var LOCAL_MEDIA_BINDING_SCRIPT = `
440
+ import { RpcTarget, WorkerEntrypoint } from 'cloudflare:workers'
441
+
442
+ function emptyStream() {
443
+ return new ReadableStream({
444
+ start(controller) {
445
+ controller.close()
446
+ }
447
+ })
448
+ }
449
+
450
+ function normalizeContentType(value, fallback) {
451
+ if (typeof value !== 'string' || value.length === 0) return fallback
452
+ if (value.includes('/')) return value
453
+ if (value === 'jpg') return 'image/jpeg'
454
+ if (value === 'jpeg') return 'image/jpeg'
455
+ if (value === 'png') return 'image/png'
456
+ if (value === 'webp') return 'image/webp'
457
+ if (value === 'avif') return 'image/avif'
458
+ if (value === 'mp4') return 'video/mp4'
459
+ return value
460
+ }
461
+
462
+ async function readBytes(stream) {
463
+ return await new Response(stream || emptyStream()).arrayBuffer()
464
+ }
465
+
466
+ function streamFromBytes(bytes) {
467
+ return new Response(bytes.slice(0)).body || emptyStream()
468
+ }
469
+
470
+ function createBodyReader(bytes) {
471
+ return function takeBody() {
472
+ return streamFromBytes(bytes)
473
+ }
474
+ }
475
+
476
+ class LocalImageResult extends RpcTarget {
477
+ constructor(takeBody, contentType) {
478
+ super()
479
+ this.takeBody = takeBody
480
+ this.contentTypeValue = contentType
481
+ }
482
+
483
+ response() {
484
+ return new Response(this.takeBody(), {
485
+ headers: { 'Content-Type': this.contentTypeValue }
486
+ })
487
+ }
488
+
489
+ contentType() {
490
+ return this.contentTypeValue
491
+ }
492
+
493
+ image() {
494
+ return this.takeBody()
495
+ }
496
+ }
497
+
498
+ class LocalImageTransformer extends RpcTarget {
499
+ constructor(bytes) {
500
+ super()
501
+ this.takeBody = createBodyReader(bytes)
502
+ }
503
+
504
+ transform() {
505
+ return this
506
+ }
507
+
508
+ draw() {
509
+ return this
510
+ }
511
+
512
+ async output(options = {}) {
513
+ return new LocalImageResult(
514
+ this.takeBody,
515
+ normalizeContentType(options.format, 'image/png')
516
+ )
517
+ }
518
+ }
519
+
520
+ function createHostedImagesBinding() {
521
+ const unsupported = () => {
522
+ throw new Error('Devflare local Images hosted API is not implemented. Use the transform/info APIs locally, or connect to Cloudflare for hosted image storage.')
523
+ }
524
+ return {
525
+ image() {
526
+ return {
527
+ details: unsupported,
528
+ bytes: unsupported,
529
+ update: unsupported,
530
+ delete: unsupported
531
+ }
532
+ },
533
+ upload: unsupported,
534
+ list: unsupported
535
+ }
536
+ }
537
+
538
+ export class LocalImagesBinding extends WorkerEntrypoint {
539
+ async info(stream) {
540
+ const bytes = await readBytes(stream)
541
+ return {
542
+ format: 'image/png',
543
+ fileSize: bytes.byteLength,
544
+ width: 1,
545
+ height: 1
546
+ }
547
+ }
548
+
549
+ async input(stream) {
550
+ return new LocalImageTransformer(await readBytes(stream))
551
+ }
552
+
553
+ get hosted() {
554
+ return createHostedImagesBinding()
555
+ }
556
+ }
557
+
558
+ class LocalMediaResult extends RpcTarget {
559
+ constructor(takeBody, contentType) {
560
+ super()
561
+ this.takeBody = takeBody
562
+ this.contentTypeValue = contentType
563
+ }
564
+
565
+ async media() {
566
+ return this.takeBody()
567
+ }
568
+
569
+ async response() {
570
+ return new Response(this.takeBody(), {
571
+ headers: { 'Content-Type': this.contentTypeValue }
572
+ })
573
+ }
574
+
575
+ async contentType() {
576
+ return this.contentTypeValue
577
+ }
578
+ }
579
+
580
+ class LocalMediaTransformationGenerator extends RpcTarget {
581
+ constructor(takeBody) {
582
+ super()
583
+ this.takeBody = takeBody
584
+ }
585
+
586
+ output(options = {}) {
587
+ return new LocalMediaResult(
588
+ this.takeBody,
589
+ normalizeContentType(options.format, 'video/mp4')
590
+ )
591
+ }
592
+ }
593
+
594
+ class LocalMediaTransformer extends RpcTarget {
595
+ constructor(bytes) {
596
+ super()
597
+ this.takeBody = createBodyReader(bytes)
598
+ }
599
+
600
+ transform() {
601
+ return new LocalMediaTransformationGenerator(this.takeBody)
602
+ }
603
+
604
+ output(options = {}) {
605
+ return new LocalMediaResult(
606
+ this.takeBody,
607
+ normalizeContentType(options.format, 'video/mp4')
608
+ )
609
+ }
610
+ }
611
+
612
+ export class LocalMediaBinding extends WorkerEntrypoint {
613
+ async input(stream) {
614
+ return new LocalMediaTransformer(await readBytes(stream))
615
+ }
616
+ }
617
+
618
+ export default {
619
+ fetch() {
620
+ return new Response('Devflare local Images/Media binding')
621
+ }
622
+ }
623
+ `;
624
+ function toLocalShimWorkerName(kind, bindingName, index) {
625
+ const slug = bindingName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || kind;
626
+ return `devflare-local-${kind}-${index}-${slug}`;
627
+ }
628
+ function getEntrypoint(kind) {
629
+ return kind === "images" ? "LocalImagesBinding" : "LocalMediaBinding";
630
+ }
631
+ function buildLocalBindingShimServiceConfig(config) {
632
+ const entries = [
633
+ ...Object.keys(config.bindings?.images ?? {}).map((bindingName) => ({
634
+ bindingName,
635
+ kind: "images"
636
+ })),
637
+ ...Object.keys(config.bindings?.media ?? {}).map((bindingName) => ({
638
+ bindingName,
639
+ kind: "media"
640
+ }))
641
+ ];
642
+ return {
643
+ localBindingNames: entries.map((entry) => entry.bindingName),
644
+ serviceBindings: Object.fromEntries(entries.map((entry, index) => {
645
+ const workerName = toLocalShimWorkerName(entry.kind, entry.bindingName, index);
646
+ return [
647
+ entry.bindingName,
648
+ {
649
+ name: workerName,
650
+ entrypoint: getEntrypoint(entry.kind)
651
+ }
652
+ ];
653
+ })),
654
+ workers: entries.map((entry, index) => ({
655
+ name: toLocalShimWorkerName(entry.kind, entry.bindingName, index),
656
+ modules: true,
657
+ script: LOCAL_MEDIA_BINDING_SCRIPT,
658
+ compatibilityDate: config.compatibilityDate ?? "2025-01-01",
659
+ ...config.compatibilityFlags && { compatibilityFlags: config.compatibilityFlags }
660
+ }))
661
+ };
662
+ }
663
+
664
+ // src/bridge/gateway-runtime.ts
665
+ var GATEWAY_RUNTIME_JS = `
666
+ const RAW_EMAIL = 'EmailMessage::raw'
667
+
668
+ function arrayBufferToBase64(buffer) {
669
+ const bytes = new Uint8Array(buffer)
670
+ let binary = ''
671
+ for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i])
672
+ return btoa(binary)
673
+ }
674
+
675
+ function base64ToArrayBuffer(base64) {
676
+ const binary = atob(base64)
677
+ const bytes = new Uint8Array(binary.length)
678
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
679
+ return bytes.buffer
680
+ }
681
+
682
+ function serializeR2Object(obj) {
683
+ if (!obj) return null
684
+ return {
685
+ __type: 'R2Object',
686
+ key: obj.key,
687
+ version: obj.version,
688
+ size: obj.size,
689
+ etag: obj.etag,
690
+ httpEtag: obj.httpEtag,
691
+ checksums: obj.checksums,
692
+ uploaded: obj.uploaded?.toISOString(),
693
+ httpMetadata: obj.httpMetadata,
694
+ customMetadata: obj.customMetadata,
695
+ range: obj.range,
696
+ storageClass: obj.storageClass
697
+ }
698
+ }
699
+
700
+ function serializeR2ObjectBody(obj, bodyData) {
701
+ if (!obj) return null
702
+ return {
703
+ __type: 'R2ObjectBody',
704
+ key: obj.key,
705
+ version: obj.version,
706
+ size: obj.size,
707
+ etag: obj.etag,
708
+ httpEtag: obj.httpEtag,
709
+ checksums: obj.checksums,
710
+ uploaded: obj.uploaded?.toISOString(),
711
+ httpMetadata: obj.httpMetadata,
712
+ customMetadata: obj.customMetadata,
713
+ range: obj.range,
714
+ storageClass: obj.storageClass,
715
+ bodyData
716
+ }
717
+ }
718
+
719
+ function serializeR2Objects(result) {
720
+ if (!result) return null
721
+ return {
722
+ objects: result.objects.map(serializeR2Object),
723
+ truncated: result.truncated,
724
+ cursor: result.cursor,
725
+ delimitedPrefixes: result.delimitedPrefixes
726
+ }
727
+ }
728
+
729
+ async function serializeResponse(response) {
730
+ let body = null
731
+ if (response.body) {
732
+ const bytes = await response.arrayBuffer()
733
+ if (bytes.byteLength > 0) {
734
+ body = { type: 'bytes', data: arrayBufferToBase64(bytes) }
735
+ }
736
+ }
737
+ return {
738
+ status: response.status,
739
+ statusText: response.statusText,
740
+ headers: [...response.headers.entries()],
741
+ body
742
+ }
743
+ }
744
+
745
+ function deserializeRequest(serializedReq) {
746
+ return new Request(serializedReq.url, {
747
+ method: serializedReq.method,
748
+ headers: serializedReq.headers,
749
+ body: serializedReq.body?.type === 'bytes'
750
+ ? base64ToArrayBuffer(serializedReq.body.data)
751
+ : undefined,
752
+ redirect: serializedReq.redirect
753
+ })
754
+ }
755
+
756
+ function createEmailMessageRaw(raw) {
757
+ if (typeof raw === 'string' || raw instanceof ReadableStream) {
758
+ return raw
759
+ }
760
+ if (raw instanceof ArrayBuffer || raw instanceof Uint8Array) {
761
+ return new Response(raw).body
762
+ }
763
+ throw new Error('Unsupported EmailMessage raw payload')
764
+ }
765
+
766
+ function isDurableObjectNamespace(binding) {
767
+ return !!binding
768
+ && typeof binding.idFromName === 'function'
769
+ && typeof binding.idFromString === 'function'
770
+ && typeof binding.newUniqueId === 'function'
771
+ }
772
+
773
+ /**
774
+ * Resolve a (possibly jurisdiction-scoped) DurableObjectNamespace.
775
+ * Forwards the jurisdiction faithfully when the binding supports it
776
+ * (real Cloudflare), and degrades to the plain binding otherwise
777
+ * (miniflare/workerd local emulation, which does not pin jurisdictions).
778
+ */
779
+ function resolveDoNamespace(binding, jurisdiction) {
780
+ if (jurisdiction && typeof binding.jurisdiction === 'function') {
781
+ return binding.jurisdiction(jurisdiction)
782
+ }
783
+ return binding
784
+ }
785
+
786
+ /**
787
+ * Execute an RPC method against the gateway's bindings.
788
+ *
789
+ * Method format: "binding.operation". Operations must be namespaced by
790
+ * binding kind (e.g. "kv.get", "r2.head", "d1.stmt.first", "do.fetch",
791
+ * "service.fetch", "queue.send", "email.send", "ai.run"). Bare verbs and the legacy
792
+ * "stmt.*" / "stub.*" sub-prefixes were removed in B3-final and now throw.
793
+ * Method vocabulary must stay in sync with the canonical server in
794
+ * src/bridge/server.ts.
795
+ */
796
+ async function executeRpcMethod(method, params, env, _ctx) {
797
+ const parts = method.split('.')
798
+ if (parts.length < 2) throw new Error('Invalid method format: ' + method)
799
+
800
+ const bindingName = parts[0]
801
+ const operation = parts.slice(1).join('.')
802
+ const binding = env[bindingName]
803
+
804
+ if (!binding) throw new Error('Binding not found: ' + bindingName)
805
+
806
+ const isNamespaced =
807
+ operation.indexOf('kv.') === 0 ||
808
+ operation.indexOf('r2.') === 0 ||
809
+ operation.indexOf('d1.') === 0 ||
810
+ operation.indexOf('do.') === 0 ||
811
+ operation.indexOf('service.') === 0 ||
812
+ operation.indexOf('queue.') === 0 ||
813
+ operation.indexOf('email.') === 0 ||
814
+ operation.indexOf('ai.') === 0 ||
815
+ operation.indexOf('workflow.') === 0 ||
816
+ operation.indexOf('var.') === 0
817
+ if (!isNamespaced) {
818
+ throw new Error(createUnsupportedBridgeOperationErrorMessage(bindingName, operation))
819
+ }
820
+
821
+ // KV
822
+ if (operation === 'kv.get') return binding.get(params[0], params[1])
823
+ if (operation === 'kv.put') return binding.put(params[0], params[1], params[2])
824
+ if (operation === 'kv.delete') return binding.delete(params[0])
825
+ if (operation === 'kv.list') return binding.list(params[0])
826
+ if (operation === 'kv.getWithMetadata') return binding.getWithMetadata(params[0], params[1])
827
+
828
+ // DO get (returns DOStub reference)
829
+ if (operation === 'do.get') {
830
+ return { __type: 'DOStub', binding: bindingName, id: params[0] }
831
+ }
832
+
833
+ // R2
834
+ if (operation === 'r2.head') return serializeR2Object(await binding.head(params[0]))
835
+ if (operation === 'r2.get') {
836
+ const obj = await binding.get(params[0], params[1])
837
+ if (!obj) return null
838
+ const body = await obj.arrayBuffer()
839
+ return serializeR2ObjectBody(obj, arrayBufferToBase64(body))
840
+ }
841
+ if (operation === 'r2.put') {
842
+ let value = params[1]
843
+ if (value && typeof value === 'object') {
844
+ if (value.__type === 'ArrayBuffer' || value.__type === 'Uint8Array') {
845
+ value = base64ToArrayBuffer(value.data)
846
+ }
847
+ }
848
+ return serializeR2Object(await binding.put(params[0], value, params[2]))
849
+ }
850
+ if (operation === 'r2.delete') return binding.delete(params[0])
851
+ if (operation === 'r2.list') return serializeR2Objects(await binding.list(params[0]))
852
+
853
+ // D1
854
+ if (operation === 'd1.exec') return binding.exec(params[0])
855
+ if (operation === 'd1.batch') {
856
+ const statements = params[0].map((s) => binding.prepare(s.sql).bind(...(s.bindings || [])))
857
+ return binding.batch(statements)
858
+ }
859
+ if (operation.indexOf('d1.stmt.') === 0) {
860
+ const mode = operation.split('.')[2]
861
+ const [sql, ...rest] = params
862
+ let bindings = rest
863
+ let extraParam
864
+ if (mode === 'first' || mode === 'raw') {
865
+ extraParam = rest[rest.length - 1]
866
+ bindings = rest.slice(0, -1)
867
+ }
868
+ let stmt = binding.prepare(sql)
869
+ if (bindings.length > 0) stmt = stmt.bind(...bindings)
870
+ if (mode === 'first') {
871
+ if (typeof extraParam === 'string' && extraParam.length > 0) return stmt.first(extraParam)
872
+ return stmt.first()
873
+ }
874
+ if (mode === 'all') return stmt.all()
875
+ if (mode === 'run') return stmt.run()
876
+ if (mode === 'raw') return stmt.raw(extraParam)
877
+ throw new Error('Unknown stmt mode: ' + mode)
878
+ }
879
+
880
+ // Durable Objects
881
+ if (operation === 'do.idFromName') {
882
+ const ns = resolveDoNamespace(binding, params[1])
883
+ const id = ns.idFromName(params[0])
884
+ return { __type: 'DOId', hex: id.toString() }
885
+ }
886
+ if (operation === 'do.idFromString') {
887
+ const id = binding.idFromString(params[0])
888
+ return { __type: 'DOId', hex: id.toString() }
889
+ }
890
+ if (operation === 'do.newUniqueId') {
891
+ const ns = resolveDoNamespace(binding, params[1])
892
+ const id = ns.newUniqueId(params[0])
893
+ return { __type: 'DOId', hex: id.toString() }
894
+ }
895
+ if (operation === 'do.fetch') {
896
+ const [, serializedId, serializedReq] = params
897
+ const id = binding.idFromString(serializedId.hex)
898
+ const stub = binding.get(id)
899
+ const response = await stub.fetch(new Request(serializedReq.url, {
900
+ method: serializedReq.method,
901
+ headers: serializedReq.headers,
902
+ body: serializedReq.body?.type === 'bytes'
903
+ ? base64ToArrayBuffer(serializedReq.body.data)
904
+ : undefined
905
+ }))
906
+ return serializeResponse(response)
907
+ }
908
+ if (operation === 'do.rpc') {
909
+ const [, serializedId, methodName, args] = params
910
+ const id = binding.idFromString(serializedId.hex)
911
+ const stub = binding.get(id)
912
+ const response = await stub.fetch(new Request('http://do/_rpc', {
913
+ method: 'POST',
914
+ headers: { 'Content-Type': 'application/json' },
915
+ body: JSON.stringify({ method: methodName, params: args })
916
+ }))
917
+ const result = await response.json()
918
+ if (!result.ok) throw new Error(result.error?.message || 'RPC failed')
919
+ return result.result
920
+ }
921
+
922
+ // Service Bindings
923
+ if (operation === 'service.fetch') {
924
+ if (!binding || typeof binding.fetch !== 'function') {
925
+ throw new Error('Service binding ' + bindingName + ' does not support fetch()')
926
+ }
927
+ const response = await binding.fetch(deserializeRequest(params[0]))
928
+ return serializeResponse(response)
929
+ }
930
+ if (operation === 'service.rpc') {
931
+ const methodName = params[0]
932
+ if (typeof methodName !== 'string') {
933
+ throw new Error('Service binding ' + bindingName + ' RPC method name must be a string')
934
+ }
935
+ const args = Array.isArray(params[1]) ? params[1] : []
936
+ const method = binding && binding[methodName]
937
+ if (typeof method !== 'function') {
938
+ throw new Error('Service binding ' + bindingName + ' does not support ' + methodName + '()')
939
+ }
940
+ return method.apply(binding, args)
941
+ }
942
+
943
+ // Queues
944
+ if (operation === 'queue.send') return binding.send(params[0], params[1])
945
+ if (operation === 'queue.sendBatch') return binding.sendBatch(params[0], params[1])
946
+
947
+ // Send Email
948
+ if (operation === 'email.send') {
949
+ if (binding && typeof binding.send === 'function') {
950
+ const message = params[0]
951
+ if (message && typeof message === 'object' && 'from' in message && 'to' in message && 'raw' in message) {
952
+ return binding.send({
953
+ from: message.from,
954
+ to: message.to,
955
+ [RAW_EMAIL]: createEmailMessageRaw(message.raw)
956
+ })
957
+ }
958
+ return binding.send(message)
959
+ }
960
+ return { ok: true, simulated: true }
961
+ }
962
+
963
+ // Workflows
964
+ if (operation === 'workflow.create') {
965
+ return serializeWorkflowInstance(await binding.create(params[0]))
966
+ }
967
+ if (operation === 'workflow.get') {
968
+ return serializeWorkflowInstance(await binding.get(params[0]))
969
+ }
970
+ if (operation === 'workflow.status') {
971
+ return (await binding.get(params[0])).status()
972
+ }
973
+ if (operation === 'workflow.pause') {
974
+ return (await binding.get(params[0])).pause()
975
+ }
976
+ if (operation === 'workflow.resume') {
977
+ return (await binding.get(params[0])).resume()
978
+ }
979
+ if (operation === 'workflow.terminate') {
980
+ return (await binding.get(params[0])).terminate()
981
+ }
982
+ if (operation === 'workflow.restart') {
983
+ return (await binding.get(params[0])).restart()
984
+ }
985
+ if (operation === 'workflow.sendEvent') {
986
+ return (await binding.get(params[0])).sendEvent(params[1])
987
+ }
988
+
989
+ // AI / generic run()
990
+ if (operation === 'ai.run') {
991
+ if (typeof binding.run !== 'function') {
992
+ throw new Error('Binding ' + bindingName + ' does not support run(): ' + method)
993
+ }
994
+ return binding.run(params[0], params[1])
995
+ }
996
+
997
+ throw new Error('Unknown operation: ' + method)
998
+ }
999
+
1000
+ function createUnsupportedBridgeOperationErrorMessage(bindingName, operation) {
1001
+ const base = "[devflare][bridge] Unsupported bridge operation '" + operation + "' for binding '" + bindingName + "'."
1002
+ if (operation === 'fetch') {
1003
+ return base + ' Devflare could not dispatch fetch() for this binding through the local bridge. '
1004
+ + 'Expected Cloudflare API: env.' + bindingName + '.fetch(request). '
1005
+ + 'If this came from SvelteKit platform.env, make sure the binding is declared as a service binding; '
1006
+ + 'this is a Devflare local bridge issue when service bindings fall back to a bare fetch operation.'
1007
+ }
1008
+ if (operation === 'toString') {
1009
+ return base + ' A platform.env value was coerced to a string through the bridge. '
1010
+ + 'For SvelteKit local dev, declared vars should be plain string values and missing env names should read as undefined.'
1011
+ }
1012
+ return base + ' Bare verbs and the legacy stmt.*/stub.* sub-prefixes are not supported; '
1013
+ + 'use the namespaced form (e.g. kv.get, r2.put, d1.stmt.first, do.fetch, service.fetch).'
1014
+ }
1015
+
1016
+ function serializeWorkflowInstance(instance) {
1017
+ return {
1018
+ __type: 'WorkflowInstance',
1019
+ id: instance.id
1020
+ }
1021
+ }
1022
+
1023
+ // ---------------------------------------------------------------------------
1024
+ // WebSocket bridge (shared with src/bridge/server.ts in shape)
1025
+ // ---------------------------------------------------------------------------
1026
+ // NOTE: wsProxies is intentionally created per handleBridgeWebSocket call so
1027
+ // state never leaks across connections or across gateway-script regenerations.
1028
+
1029
+ async function handleBridgeRpcCall(msg, ws, env, ctx) {
1030
+ try {
1031
+ const result = await executeRpcMethod(msg.method, msg.params, env, ctx)
1032
+ ws.send(JSON.stringify({ t: 'rpc.ok', id: msg.id, result }))
1033
+ } catch (error) {
1034
+ ws.send(JSON.stringify({
1035
+ t: 'rpc.err',
1036
+ id: msg.id,
1037
+ error: {
1038
+ code: error?.code || 'INTERNAL_ERROR',
1039
+ message: error?.message || String(error)
1040
+ }
1041
+ }))
1042
+ }
1043
+ }
1044
+
1045
+ async function handleBridgeWsOpen(msg, ws, env, wsProxies) {
1046
+ try {
1047
+ const binding = env[msg.target.binding]
1048
+ const id = binding.idFromString(msg.target.id)
1049
+ const stub = binding.get(id)
1050
+
1051
+ const headers = new Headers(msg.target.headers || [])
1052
+ headers.set('Upgrade', 'websocket')
1053
+
1054
+ const response = await stub.fetch(new Request(msg.target.url, { method: 'GET', headers }))
1055
+ const doWs = response.webSocket
1056
+
1057
+ if (!doWs) {
1058
+ ws.send(JSON.stringify({
1059
+ t: 'rpc.err',
1060
+ id: 'ws_' + msg.wid,
1061
+ error: { code: 'WS_FAILED', message: 'No WebSocket returned' }
1062
+ }))
1063
+ return
1064
+ }
1065
+
1066
+ doWs.accept()
1067
+ wsProxies.set(msg.wid, { doWs })
1068
+
1069
+ doWs.addEventListener('message', (event) => {
1070
+ const isText = typeof event.data === 'string'
1071
+ const data = isText ? event.data : arrayBufferToBase64(event.data)
1072
+ ws.send(JSON.stringify({ t: 'ws.data', wid: msg.wid, data, isText }))
1073
+ })
1074
+
1075
+ doWs.addEventListener('close', (event) => {
1076
+ ws.send(JSON.stringify({ t: 'ws.close', wid: msg.wid, code: event.code, reason: event.reason }))
1077
+ wsProxies.delete(msg.wid)
1078
+ })
1079
+
1080
+ ws.send(JSON.stringify({ t: 'ws.opened', wid: msg.wid }))
1081
+ } catch (error) {
1082
+ ws.send(JSON.stringify({
1083
+ t: 'rpc.err',
1084
+ id: 'ws_' + msg.wid,
1085
+ error: { code: 'WS_FAILED', message: error.message }
1086
+ }))
1087
+ }
1088
+ }
1089
+
1090
+ function handleBridgeWsClose(msg, wsProxies) {
1091
+ const proxy = wsProxies.get(msg.wid)
1092
+ if (proxy) {
1093
+ proxy.doWs.close(msg.code, msg.reason)
1094
+ wsProxies.delete(msg.wid)
1095
+ }
1096
+ }
1097
+
1098
+ async function handleBridgeJsonMessage(data, ws, env, ctx, wsProxies) {
1099
+ const msg = JSON.parse(data)
1100
+ switch (msg.t) {
1101
+ case 'hello':
1102
+ // v2 handshake — acknowledge with welcome echoing the negotiated
1103
+ // capability intersection. Capabilities advertised by the gateway
1104
+ // are kept in sync with src/bridge/client.ts (BRIDGE_CLIENT_CAPABILITIES).
1105
+ ws.send(JSON.stringify({
1106
+ t: 'welcome',
1107
+ protocolVersion: 2,
1108
+ capabilities: ['streams', 'ws-relay', 'http-transfer']
1109
+ .filter((c) => Array.isArray(msg.capabilities) && msg.capabilities.includes(c))
1110
+ .sort()
1111
+ }))
1112
+ break
1113
+ case 'rpc.call':
1114
+ await handleBridgeRpcCall(msg, ws, env, ctx)
1115
+ break
1116
+ case 'ws.open':
1117
+ await handleBridgeWsOpen(msg, ws, env, wsProxies)
1118
+ break
1119
+ case 'ws.close':
1120
+ handleBridgeWsClose(msg, wsProxies)
1121
+ break
1122
+ }
1123
+ }
1124
+
1125
+ function handleBridgeWebSocket(request, env, ctx) {
1126
+ const { 0: client, 1: server } = new WebSocketPair()
1127
+ server.accept()
1128
+
1129
+ // Per-connection state: recreated for every bridge client so reloads and
1130
+ // concurrent clients never share WS proxy entries.
1131
+ const wsProxies = new Map()
1132
+
1133
+ server.addEventListener('message', async (event) => {
1134
+ try {
1135
+ if (typeof event.data === 'string') {
1136
+ await handleBridgeJsonMessage(event.data, server, env, ctx, wsProxies)
1137
+ }
1138
+ } catch (error) {
1139
+ console.error('[Gateway] Error:', error)
1140
+ }
1141
+ })
1142
+
1143
+ server.addEventListener('close', () => {
1144
+ for (const proxy of wsProxies.values()) {
1145
+ // Best-effort cleanup: the DO-side WS may already be closed or in an
1146
+ // invalid state; any throw here would abort sibling closes. Surface
1147
+ // the swallowed error when DEVFLARE_DEBUG_BRIDGE is enabled.
1148
+ try { proxy.doWs.close() } catch (error) {
1149
+ if (globalThis.DEVFLARE_DEBUG_BRIDGE) {
1150
+ console.warn('[devflare:bridge] proxy.doWs.close() failed', error)
1151
+ }
1152
+ }
1153
+ }
1154
+ wsProxies.clear()
1155
+ })
1156
+
1157
+ return new Response(null, { status: 101, webSocket: client })
1158
+ }
1159
+
1160
+ // ---------------------------------------------------------------------------
1161
+ // HTTP transfer for R2 bodies (shared with src/bridge/server.ts in shape)
1162
+ // ---------------------------------------------------------------------------
1163
+
1164
+ async function handleHttpTransfer(request, env, url) {
1165
+ const transferIdEncoded = url.pathname.split('/').pop()
1166
+ const transferId = decodeURIComponent(transferIdEncoded || '')
1167
+ const [binding, ...keyParts] = transferId.split(':')
1168
+ const key = keyParts.join(':')
1169
+ const bucket = env[binding]
1170
+
1171
+ if (!bucket) return new Response('Bucket not found: ' + binding, { status: 404 })
1172
+
1173
+ if (request.method === 'PUT' || request.method === 'POST') {
1174
+ const result = await bucket.put(key, request.body)
1175
+ return new Response(JSON.stringify(serializeR2Object(result)), {
1176
+ headers: { 'Content-Type': 'application/json' }
1177
+ })
1178
+ }
1179
+
1180
+ if (request.method === 'GET') {
1181
+ const object = await bucket.get(key)
1182
+ if (!object) return new Response('Not found', { status: 404 })
1183
+ return new Response(object.body, {
1184
+ headers: {
1185
+ 'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
1186
+ 'Content-Length': String(object.size)
1187
+ }
1188
+ })
1189
+ }
1190
+
1191
+ return new Response('Method not allowed', { status: 405 })
1192
+ }
1193
+ `;
1194
+
1195
+ // src/bridge/miniflare.ts
1196
+ function isIgnorableMiniflareDisposeError(error) {
1197
+ if (!(error instanceof Error)) {
1198
+ return false;
1199
+ }
1200
+ const details = error;
1201
+ return details.code === "EBADF" && details.syscall === "kill";
1202
+ }
1203
+
306
1204
  // src/dev-server/dev-server-state.ts
307
1205
  function createDevServerState(initial) {
308
1206
  return {
@@ -363,7 +1261,7 @@ async function disposeDevServerState(state) {
363
1261
  }
364
1262
 
365
1263
  // src/dev-server/miniflare-dev-config.ts
366
- import { resolve as resolve4 } from "pathe";
1264
+ import { resolve as resolve5 } from "pathe";
367
1265
 
368
1266
  // src/browser-shim/binding-worker.ts
369
1267
  var MAX_CHUNK_SIZE = 1048575;
@@ -928,7 +1826,7 @@ async function handleDoWebSocket(request, env, url, route) {
928
1826
  }
929
1827
 
930
1828
  // src/dev-server/miniflare-worker-config.ts
931
- import { resolve as resolve2 } from "pathe";
1829
+ import { resolve as resolve3 } from "pathe";
932
1830
  var DEFAULT_MODULE_RULES = [
933
1831
  { type: "ESModule", include: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.mjs"] },
934
1832
  { type: "CommonJS", include: ["**/*.js", "**/*.cjs"] },
@@ -1024,7 +1922,7 @@ function makeMiniflareWorker(context, options) {
1024
1922
  };
1025
1923
  if (options.scriptPath) {
1026
1924
  workerConfig.scriptPath = options.scriptPath;
1027
- workerConfig.modulesRoot = loadedConfig.baseDir ? resolve2(cwd, loadedConfig.baseDir) : cwd;
1925
+ workerConfig.modulesRoot = loadedConfig.baseDir ? resolve3(cwd, loadedConfig.baseDir) : cwd;
1028
1926
  workerConfig.modulesRules = [
1029
1927
  ...loadedConfig.rules?.map(toMiniflareModuleRule) ?? [],
1030
1928
  ...DEFAULT_MODULE_RULES
@@ -1043,7 +1941,7 @@ function makeMiniflareWorker(context, options) {
1043
1941
  }
1044
1942
 
1045
1943
  // src/dev-server/worker-surface-paths.ts
1046
- import { dirname, resolve as resolve3 } from "pathe";
1944
+ import { dirname as dirname2, resolve as resolve4 } from "pathe";
1047
1945
  var DEFAULT_TRANSPORT_ENTRY_FILES = [
1048
1946
  "src/transport.ts",
1049
1947
  "src/transport.js",
@@ -1056,18 +1954,18 @@ function addWorkerWatchRoots(roots, cwd, configuredPath, defaultEntries) {
1056
1954
  return;
1057
1955
  }
1058
1956
  if (typeof configuredPath === "string" && configuredPath) {
1059
- roots.add(dirname(resolve3(cwd, configuredPath)));
1957
+ roots.add(dirname2(resolve4(cwd, configuredPath)));
1060
1958
  return;
1061
1959
  }
1062
1960
  for (const defaultEntry of defaultEntries) {
1063
- roots.add(dirname(resolve3(cwd, defaultEntry)));
1961
+ roots.add(dirname2(resolve4(cwd, defaultEntry)));
1064
1962
  }
1065
1963
  }
1066
1964
  function collectWorkerWatchRoots(cwd, config, mainWorkerSurfacePaths) {
1067
1965
  const roots = new Set;
1068
1966
  for (const surfacePath of Object.values(mainWorkerSurfacePaths)) {
1069
1967
  if (surfacePath) {
1070
- roots.add(dirname(surfacePath));
1968
+ roots.add(dirname2(surfacePath));
1071
1969
  }
1072
1970
  }
1073
1971
  addWorkerWatchRoots(roots, cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES);
@@ -1104,7 +2002,7 @@ function buildMiniflareDevConfig(input) {
1104
2002
  logger
1105
2003
  } = input;
1106
2004
  const bindings = loadedConfig.bindings ?? {};
1107
- const persistPath = resolve4(cwd, ".devflare/data");
2005
+ const persistPath = resolve5(cwd, ".devflare/data");
1108
2006
  const appWorkerName = loadedConfig.name;
1109
2007
  const shouldRunMainWorker = !enableVite && (hasWorkerSurfacePaths(mainWorkerSurfacePaths) || Boolean(mainWorkerRoutes?.routes.length));
1110
2008
  const queueProducers = buildQueueProducers(bindings);
@@ -1328,7 +2226,7 @@ function createRuntimeStdioForwarder(logger) {
1328
2226
  }
1329
2227
 
1330
2228
  // src/dev-server/server-startup-helpers.ts
1331
- import { resolve as resolve5 } from "pathe";
2229
+ import { resolve as resolve6 } from "pathe";
1332
2230
 
1333
2231
  // src/browser-shim/server.ts
1334
2232
  import { existsSync } from "node:fs";
@@ -1336,7 +2234,7 @@ import {
1336
2234
  createServer
1337
2235
  } from "node:http";
1338
2236
  import { homedir } from "node:os";
1339
- import { join } from "node:path";
2237
+ import { join as join2 } from "node:path";
1340
2238
  import {
1341
2239
  Browser as BrowserType,
1342
2240
  detectBrowserPlatform,
@@ -1437,7 +2335,7 @@ function createBrowserShim(options = {}) {
1437
2335
  logger,
1438
2336
  verbose = false,
1439
2337
  keepAlive = 60000,
1440
- cacheDir = join(homedir(), ".devflare", "chrome"),
2338
+ cacheDir = join2(homedir(), ".devflare", "chrome"),
1441
2339
  allowNoSandbox = false
1442
2340
  } = options;
1443
2341
  const chromeLaunchArgs = resolveChromeFlags({ allowNoSandbox });
@@ -1635,7 +2533,7 @@ function createBrowserShim(options = {}) {
1635
2533
  res.end("Not found");
1636
2534
  }
1637
2535
  function readBody(req) {
1638
- return new Promise((resolve5, reject) => {
2536
+ return new Promise((resolve6, reject) => {
1639
2537
  const chunks = [];
1640
2538
  let totalBytes = 0;
1641
2539
  req.on("data", (chunk) => {
@@ -1647,7 +2545,7 @@ function createBrowserShim(options = {}) {
1647
2545
  }
1648
2546
  chunks.push(chunk);
1649
2547
  });
1650
- req.on("end", () => resolve5(Buffer.concat(chunks).toString()));
2548
+ req.on("end", () => resolve6(Buffer.concat(chunks).toString()));
1651
2549
  req.on("error", reject);
1652
2550
  });
1653
2551
  }
@@ -1796,10 +2694,10 @@ function createBrowserShim(options = {}) {
1796
2694
  });
1797
2695
  });
1798
2696
  }
1799
- await new Promise((resolve5, reject) => {
2697
+ await new Promise((resolve6, reject) => {
1800
2698
  server.on("error", reject);
1801
2699
  server.listen(port, host, () => {
1802
- resolve5();
2700
+ resolve6();
1803
2701
  });
1804
2702
  });
1805
2703
  logger?.success(`Browser shim server ready on http://${host}:${port}`);
@@ -1809,8 +2707,8 @@ function createBrowserShim(options = {}) {
1809
2707
  await closeSession(sessionId, 3, "ServerShutdown");
1810
2708
  }
1811
2709
  if (server) {
1812
- await new Promise((resolve5) => {
1813
- server.close(() => resolve5());
2710
+ await new Promise((resolve6) => {
2711
+ server.close(() => resolve6());
1814
2712
  });
1815
2713
  server = null;
1816
2714
  }
@@ -1868,7 +2766,7 @@ function formatErrorMessage(error) {
1868
2766
  }
1869
2767
  async function resolveWorkerConfigWatchPath(cwd, configPath) {
1870
2768
  if (configPath) {
1871
- const explicitPath = resolve5(cwd, configPath);
2769
+ const explicitPath = resolve6(cwd, configPath);
1872
2770
  const fs = await import("node:fs/promises");
1873
2771
  try {
1874
2772
  await fs.access(explicitPath);
@@ -1939,7 +2837,7 @@ async function maybeStartDOBundler(config, options) {
1939
2837
  if (typeof doPattern !== "string" || !doPattern) {
1940
2838
  return { bundler: null, result: null };
1941
2839
  }
1942
- const outDir = resolve5(options.cwd, ".devflare/do-bundles");
2840
+ const outDir = resolve6(options.cwd, ".devflare/do-bundles");
1943
2841
  const bundler = createDOBundler({
1944
2842
  cwd: options.cwd,
1945
2843
  pattern: doPattern,
@@ -2155,7 +3053,7 @@ function createDevServer(options) {
2155
3053
  state.bundledMainWorkerScriptPath = await bundleWorkerEntry({
2156
3054
  cwd,
2157
3055
  inputFile: state.mainWorkerScriptPath,
2158
- outFile: resolve6(cwd, ".devflare", "worker-entrypoints", "main.js"),
3056
+ outFile: resolve7(cwd, ".devflare", "worker-entrypoints", "main.js"),
2159
3057
  rolldownOptions: state.config.rolldown?.options,
2160
3058
  sourcemap: state.config.rolldown?.sourcemap,
2161
3059
  minify: state.config.rolldown?.minify,
@@ -2273,11 +3171,11 @@ function createDevServer(options) {
2273
3171
  cwd,
2274
3172
  configPath: state.resolvedWorkerConfigPath ?? undefined
2275
3173
  });
2276
- state.serviceBindingResolution = state.config.bindings?.services ? await resolveServiceBindings(state.config, state.resolvedWorkerConfigPath ? dirname2(state.resolvedWorkerConfigPath) : cwd) : null;
3174
+ state.serviceBindingResolution = state.config.bindings?.services ? await resolveServiceBindings(state.config, state.resolvedWorkerConfigPath ? dirname3(state.resolvedWorkerConfigPath) : cwd) : null;
2277
3175
  }
2278
3176
  async function waitForDotenvChange() {
2279
3177
  const configWatchPath = state.resolvedWorkerConfigPath ?? await resolveWorkerConfigWatchPath(cwd, configPath);
2280
- const startDir = configWatchPath ? dirname2(configWatchPath) : cwd;
3178
+ const startDir = configWatchPath ? dirname3(configWatchPath) : cwd;
2281
3179
  const watchPaths = getDevflareDotenvPaths(startDir);
2282
3180
  const { watch } = await import("chokidar");
2283
3181
  await new Promise((resolveWait, rejectWait) => {
@@ -2434,11 +3332,11 @@ async function createLogWriter(cwd, options) {
2434
3332
  const fs = await import("node:fs");
2435
3333
  let logPath;
2436
3334
  if (options.logTemp) {
2437
- logPath = resolve7(cwd, ".log");
3335
+ logPath = resolve8(cwd, ".log");
2438
3336
  } else {
2439
3337
  const now = new Date;
2440
3338
  const timestamp = now.toISOString().replace(/[:.]/g, "-").replace("T", "_").slice(0, 19);
2441
- logPath = resolve7(cwd, `.log-${timestamp}`);
3339
+ logPath = resolve8(cwd, `.log-${timestamp}`);
2442
3340
  }
2443
3341
  const fileStream = fs.createWriteStream(logPath, { flags: "w" });
2444
3342
  const ansiRegex = /\x1b\[[0-9;]*m/g;
@@ -2486,7 +3384,7 @@ async function runDevCommand(parsed, logger, options) {
2486
3384
  logTemp: logTempEnabled
2487
3385
  });
2488
3386
  if (logWriter) {
2489
- const logFile = relative(cwd, logWriter.path) || ".log";
3387
+ const logFile = relative2(cwd, logWriter.path) || ".log";
2490
3388
  logLine(logger, `${dim("logging", theme)} ${logFile}`);
2491
3389
  }
2492
3390
  const devLogger = createConsola({