miniflare 0.0.0-e4fe35cc5 → 0.0.0-e5ebdb143

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/dist/src/index.js CHANGED
@@ -95,11 +95,11 @@ var require_Mime = __commonJS({
95
95
  }
96
96
  }
97
97
  };
98
- Mime.prototype.getType = function(path27) {
99
- path27 = String(path27);
100
- let last = path27.replace(/^.*[/\\]/, "").toLowerCase();
98
+ Mime.prototype.getType = function(path28) {
99
+ path28 = String(path28);
100
+ let last = path28.replace(/^.*[/\\]/, "").toLowerCase();
101
101
  let ext = last.replace(/^.*\./, "").toLowerCase();
102
- let hasPath = last.length < path27.length;
102
+ let hasPath = last.length < path28.length;
103
103
  let hasDot = ext.length < last.length - 1;
104
104
  return (hasDot || !hasPath) && this._types[ext] || null;
105
105
  };
@@ -2456,7 +2456,6 @@ __export(src_exports, {
2456
2456
  DispatchFetchDispatcher: () => DispatchFetchDispatcher,
2457
2457
  DurableObjectsOptionsSchema: () => DurableObjectsOptionsSchema,
2458
2458
  DurableObjectsSharedOptionsSchema: () => DurableObjectsSharedOptionsSchema,
2459
- ENTRY_SOCKET_HTTP_OPTIONS: () => ENTRY_SOCKET_HTTP_OPTIONS,
2460
2459
  ErrorEvent: () => ErrorEvent,
2461
2460
  File: () => import_undici4.File,
2462
2461
  FormData: () => import_undici4.FormData,
@@ -2535,10 +2534,15 @@ __export(src_exports, {
2535
2534
  TlsOptions_Version: () => import_workerd_capnp.TlsOptions_Version,
2536
2535
  TypedEventTarget: () => TypedEventTarget,
2537
2536
  WORKER_BINDING_SERVICE_LOOPBACK: () => WORKER_BINDING_SERVICE_LOOPBACK,
2537
+ WORKFLOWS_PLUGIN: () => WORKFLOWS_PLUGIN,
2538
+ WORKFLOWS_PLUGIN_NAME: () => WORKFLOWS_PLUGIN_NAME,
2539
+ WORKFLOWS_STORAGE_SERVICE_NAME: () => WORKFLOWS_STORAGE_SERVICE_NAME,
2538
2540
  WaitGroup: () => WaitGroup,
2539
2541
  WebSocket: () => WebSocket,
2540
2542
  WebSocketPair: () => WebSocketPair,
2541
2543
  Worker_Binding_CryptoKey_Usage: () => import_workerd_capnp.Worker_Binding_CryptoKey_Usage,
2544
+ WorkflowsOptionsSchema: () => WorkflowsOptionsSchema,
2545
+ WorkflowsSharedOptionsSchema: () => WorkflowsSharedOptionsSchema,
2542
2546
  __MiniflareFunctionWrapper: () => __MiniflareFunctionWrapper,
2543
2547
  _enableControlEndpoints: () => _enableControlEndpoints,
2544
2548
  _forceColour: () => _forceColour,
@@ -2547,7 +2551,7 @@ __export(src_exports, {
2547
2551
  _transformsForContentEncodingAndContentType: () => _transformsForContentEncodingAndContentType,
2548
2552
  base64Decode: () => base64Decode,
2549
2553
  base64Encode: () => base64Encode,
2550
- buildAssetsManifest: () => buildAssetsManifest,
2554
+ buildAssetManifest: () => buildAssetManifest,
2551
2555
  compileModuleRules: () => compileModuleRules,
2552
2556
  coupleWebSocket: () => coupleWebSocket,
2553
2557
  createFetchMock: () => createFetchMock,
@@ -2567,6 +2571,7 @@ __export(src_exports, {
2567
2571
  getFreshSourceMapSupport: () => getFreshSourceMapSupport,
2568
2572
  getGlobalServices: () => getGlobalServices,
2569
2573
  getMiniflareObjectBindings: () => getMiniflareObjectBindings,
2574
+ getNodeCompat: () => getNodeCompat,
2570
2575
  getPersistPath: () => getPersistPath,
2571
2576
  getRootPath: () => getRootPath,
2572
2577
  globsToRegExps: () => globsToRegExps,
@@ -2611,11 +2616,11 @@ __export(src_exports, {
2611
2616
  module.exports = __toCommonJS(src_exports);
2612
2617
  var import_assert12 = __toESM(require("assert"));
2613
2618
  var import_crypto3 = __toESM(require("crypto"));
2614
- var import_fs21 = __toESM(require("fs"));
2619
+ var import_fs22 = __toESM(require("fs"));
2615
2620
  var import_http6 = __toESM(require("http"));
2616
2621
  var import_net = __toESM(require("net"));
2617
2622
  var import_os2 = __toESM(require("os"));
2618
- var import_path25 = __toESM(require("path"));
2623
+ var import_path26 = __toESM(require("path"));
2619
2624
  var import_web5 = require("stream/web");
2620
2625
  var import_util5 = __toESM(require("util"));
2621
2626
  var import_zlib = __toESM(require("zlib"));
@@ -2702,7 +2707,7 @@ function zod_worker_default() {
2702
2707
 
2703
2708
  // src/index.ts
2704
2709
  var import_ws3 = require("ws");
2705
- var import_zod21 = require("zod");
2710
+ var import_zod22 = require("zod");
2706
2711
 
2707
2712
  // src/cf.ts
2708
2713
  var import_assert = __toESM(require("assert"));
@@ -3310,12 +3315,12 @@ function createHTTPRevivers(impl) {
3310
3315
  },
3311
3316
  Request(value) {
3312
3317
  (0, import_node_assert.default)(Array.isArray(value));
3313
- const [method, url17, headers, cf, body] = value;
3318
+ const [method, url18, headers, cf, body] = value;
3314
3319
  (0, import_node_assert.default)(typeof method === "string");
3315
- (0, import_node_assert.default)(typeof url17 === "string");
3320
+ (0, import_node_assert.default)(typeof url18 === "string");
3316
3321
  (0, import_node_assert.default)(headers instanceof impl.Headers);
3317
3322
  (0, import_node_assert.default)(body === null || impl.isReadableStream(body));
3318
- return new impl.Request(url17, {
3323
+ return new impl.Request(url18, {
3319
3324
  method,
3320
3325
  headers,
3321
3326
  cf,
@@ -3444,23 +3449,23 @@ function parseWithReadableStreams(impl, stringified, revivers2) {
3444
3449
  }
3445
3450
 
3446
3451
  // src/workers/core/routing.ts
3447
- function matchRoutes(routes, url17) {
3452
+ function matchRoutes(routes, url18) {
3448
3453
  for (const route of routes) {
3449
- if (route.protocol && route.protocol !== url17.protocol)
3454
+ if (route.protocol && route.protocol !== url18.protocol)
3450
3455
  continue;
3451
3456
  if (route.allowHostnamePrefix) {
3452
- if (!url17.hostname.endsWith(route.hostname))
3457
+ if (!url18.hostname.endsWith(route.hostname))
3453
3458
  continue;
3454
3459
  } else {
3455
- if (url17.hostname !== route.hostname)
3460
+ if (url18.hostname !== route.hostname)
3456
3461
  continue;
3457
3462
  }
3458
- const path27 = url17.pathname + url17.search;
3463
+ const path28 = url18.pathname + url18.search;
3459
3464
  if (route.allowPathSuffix) {
3460
- if (!path27.startsWith(route.path))
3465
+ if (!path28.startsWith(route.path))
3461
3466
  continue;
3462
3467
  } else {
3463
- if (path27 !== route.path)
3468
+ if (path28 !== route.path)
3464
3469
  continue;
3465
3470
  }
3466
3471
  return route.target;
@@ -3705,8 +3710,8 @@ function decodeSitesKey(key) {
3705
3710
  return key.startsWith(SITES_NO_CACHE_PREFIX) ? decodeURIComponent(key.substring(SITES_NO_CACHE_PREFIX.length)) : key;
3706
3711
  }
3707
3712
  function isSitesRequest(request) {
3708
- const url17 = new URL(request.url);
3709
- return url17.pathname.startsWith(`/${SITES_NO_CACHE_PREFIX}`);
3713
+ const url18 = new URL(request.url);
3714
+ return url18.pathname.startsWith(`/${SITES_NO_CACHE_PREFIX}`);
3710
3715
  }
3711
3716
  function serialiseRegExp(regExp) {
3712
3717
  const str = regExp.toString();
@@ -3782,11 +3787,18 @@ var QueueConsumerOptionsSchema = /* @__PURE__ */ import_zod2.z.object({
3782
3787
  // https://developers.cloudflare.com/queues/platform/configuration/#consumer
3783
3788
  // https://developers.cloudflare.com/queues/platform/limits/
3784
3789
  maxBatchSize: import_zod2.z.number().min(0).max(100).optional(),
3785
- maxBatchTimeout: import_zod2.z.number().min(0).max(30).optional(),
3790
+ maxBatchTimeout: import_zod2.z.number().min(0).max(60).optional(),
3786
3791
  // seconds
3787
3792
  maxRetires: import_zod2.z.number().min(0).max(100).optional(),
3793
+ // deprecated
3794
+ maxRetries: import_zod2.z.number().min(0).max(100).optional(),
3788
3795
  deadLetterQueue: import_zod2.z.ostring(),
3789
3796
  retryDelay: QueueMessageDelaySchema
3797
+ }).transform((queue) => {
3798
+ if (queue.maxRetires !== void 0) {
3799
+ queue.maxRetries = queue.maxRetires;
3800
+ }
3801
+ return queue;
3790
3802
  });
3791
3803
  var QueueConsumerSchema = /* @__PURE__ */ import_zod2.z.intersection(
3792
3804
  QueueConsumerOptionsSchema,
@@ -3853,8 +3865,8 @@ var Response = class extends import_undici3.Response {
3853
3865
  Object.setPrototypeOf(response, Response.prototype);
3854
3866
  return response;
3855
3867
  }
3856
- static redirect(url17, status) {
3857
- const response = import_undici3.Response.redirect(url17, status);
3868
+ static redirect(url18, status) {
3869
+ const response = import_undici3.Response.redirect(url18, status);
3858
3870
  Object.setPrototypeOf(response, Response.prototype);
3859
3871
  return response;
3860
3872
  }
@@ -4362,14 +4374,14 @@ async function fetch3(input, init2) {
4362
4374
  const requestInit = init2;
4363
4375
  const request = new Request(input, requestInit);
4364
4376
  if (request.method === "GET" && request.headers.get("upgrade") === "websocket") {
4365
- const url17 = new URL(request.url);
4366
- if (url17.protocol !== "http:" && url17.protocol !== "https:") {
4377
+ const url18 = new URL(request.url);
4378
+ if (url18.protocol !== "http:" && url18.protocol !== "https:") {
4367
4379
  throw new TypeError(
4368
- `Fetch API cannot load: ${url17.toString()}.
4380
+ `Fetch API cannot load: ${url18.toString()}.
4369
4381
  Make sure you're using http(s):// URLs for WebSocket requests via fetch.`
4370
4382
  );
4371
4383
  }
4372
- url17.protocol = url17.protocol.replace("http", "ws");
4384
+ url18.protocol = url18.protocol.replace("http", "ws");
4373
4385
  const headers = {};
4374
4386
  let protocols;
4375
4387
  for (const [key, value] of request.headers.entries()) {
@@ -4381,10 +4393,10 @@ Make sure you're using http(s):// URLs for WebSocket requests via fetch.`
4381
4393
  }
4382
4394
  let rejectUnauthorized;
4383
4395
  if (requestInit.dispatcher instanceof DispatchFetchDispatcher) {
4384
- requestInit.dispatcher.addHeaders(headers, url17.pathname + url17.search);
4396
+ requestInit.dispatcher.addHeaders(headers, url18.pathname + url18.search);
4385
4397
  rejectUnauthorized = { rejectUnauthorized: false };
4386
4398
  }
4387
- const ws = new import_ws2.default(url17, protocols, {
4399
+ const ws = new import_ws2.default(url18, protocols, {
4388
4400
  followRedirects: request.redirect === "follow",
4389
4401
  headers,
4390
4402
  ...rejectUnauthorized
@@ -4443,8 +4455,8 @@ var DispatchFetchDispatcher = class extends undici.Dispatcher {
4443
4455
  this.cfBlobJson = JSON.stringify(cfBlob);
4444
4456
  }
4445
4457
  cfBlobJson;
4446
- addHeaders(headers, path27) {
4447
- const originalURL = this.userRuntimeOrigin + path27;
4458
+ addHeaders(headers, path28) {
4459
+ const originalURL = this.userRuntimeOrigin + path28;
4448
4460
  addHeader(headers, CoreHeaders.ORIGINAL_URL, originalURL);
4449
4461
  addHeader(headers, CoreHeaders.DISABLE_PRETTY_ERROR, "true");
4450
4462
  if (this.cfBlobJson !== void 0) {
@@ -4457,16 +4469,16 @@ var DispatchFetchDispatcher = class extends undici.Dispatcher {
4457
4469
  origin = this.actualRuntimeOrigin;
4458
4470
  if (origin === this.actualRuntimeOrigin) {
4459
4471
  options.origin = origin;
4460
- let path27 = options.path;
4472
+ let path28 = options.path;
4461
4473
  if (options.query !== void 0) {
4462
- const url17 = new URL(path27, "http://placeholder/");
4474
+ const url18 = new URL(path28, "http://placeholder/");
4463
4475
  for (const [key, value] of Object.entries(options.query)) {
4464
- url17.searchParams.append(key, value);
4476
+ url18.searchParams.append(key, value);
4465
4477
  }
4466
- path27 = url17.pathname + url17.search;
4478
+ path28 = url18.pathname + url18.search;
4467
4479
  }
4468
4480
  options.headers ??= {};
4469
- this.addHeaders(options.headers, path27);
4481
+ this.addHeaders(options.headers, path28);
4470
4482
  return this.runtimeDispatcher.dispatch(options, handler);
4471
4483
  } else {
4472
4484
  return this.globalDispatcher.dispatch(options, handler);
@@ -4527,11 +4539,6 @@ ez/dHA==
4527
4539
  `;
4528
4540
 
4529
4541
  // src/http/server.ts
4530
- var ENTRY_SOCKET_HTTP_OPTIONS = {
4531
- // Even though we inject a `cf` object in the entry worker, allow it to
4532
- // be customised via `dispatchFetch`
4533
- cfBlobHeader: CoreHeaders.CF_BLOB
4534
- };
4535
4542
  async function getEntrySocketHttpOptions(coreOpts) {
4536
4543
  let privateKey = void 0;
4537
4544
  let certificateChain = void 0;
@@ -4548,7 +4555,6 @@ async function getEntrySocketHttpOptions(coreOpts) {
4548
4555
  if (privateKey && certificateChain) {
4549
4556
  return {
4550
4557
  https: {
4551
- options: ENTRY_SOCKET_HTTP_OPTIONS,
4552
4558
  tlsOptions: {
4553
4559
  keypair: {
4554
4560
  privateKey,
@@ -4558,7 +4564,7 @@ async function getEntrySocketHttpOptions(coreOpts) {
4558
4564
  }
4559
4565
  };
4560
4566
  } else {
4561
- return { http: ENTRY_SOCKET_HTTP_OPTIONS };
4567
+ return { http: {} };
4562
4568
  }
4563
4569
  }
4564
4570
  function valueOrFile(value, filePath) {
@@ -4587,7 +4593,7 @@ var import_undici4 = require("undici");
4587
4593
  // src/plugins/assets/index.ts
4588
4594
  var import_node_crypto = __toESM(require("node:crypto"));
4589
4595
  var import_promises7 = __toESM(require("node:fs/promises"));
4590
- var import_node_path = __toESM(require("node:path"));
4596
+ var import_node_path2 = __toESM(require("node:path"));
4591
4597
 
4592
4598
  // ../workers-shared/utils/constants.ts
4593
4599
  var HEADER_SIZE = 20;
@@ -4603,7 +4609,8 @@ var MAX_ASSET_SIZE = 25 * 1024 * 1024;
4603
4609
  // ../workers-shared/utils/types.ts
4604
4610
  var import_zod4 = require("zod");
4605
4611
  var RoutingConfigSchema = import_zod4.z.object({
4606
- has_user_worker: import_zod4.z.boolean().optional()
4612
+ has_user_worker: import_zod4.z.boolean().optional(),
4613
+ invoke_user_worker_ahead_of_assets: import_zod4.z.boolean().optional()
4607
4614
  });
4608
4615
  var AssetConfigSchema = import_zod4.z.object({
4609
4616
  html_handling: import_zod4.z.enum([
@@ -4612,14 +4619,18 @@ var AssetConfigSchema = import_zod4.z.object({
4612
4619
  "drop-trailing-slash",
4613
4620
  "none"
4614
4621
  ]).optional(),
4615
- not_found_handling: import_zod4.z.enum(["single-page-application", "404-page", "none"]).optional()
4622
+ not_found_handling: import_zod4.z.enum(["single-page-application", "404-page", "none"]).optional(),
4623
+ serve_directly: import_zod4.z.boolean().optional()
4616
4624
  });
4617
4625
 
4618
4626
  // ../workers-shared/utils/helpers.ts
4627
+ var import_node_path = require("node:path");
4619
4628
  var import_mime = __toESM(require_mime());
4620
- var encodeFilePath = (filePath, sep) => {
4621
- const encodedPath = filePath.split(sep).map((segment) => encodeURIComponent(segment)).join("/");
4622
- return "/" + encodedPath;
4629
+ var normalizeFilePath = (relativeFilepath) => {
4630
+ if ((0, import_node_path.isAbsolute)(relativeFilepath)) {
4631
+ throw new Error(`Expected relative path`);
4632
+ }
4633
+ return "/" + relativeFilepath.split(import_node_path.sep).join("/");
4623
4634
  };
4624
4635
  var getContentType = (absFilePath) => {
4625
4636
  let contentType = (0, import_mime.getType)(absFilePath) || "application/octet-stream";
@@ -4629,7 +4640,7 @@ var getContentType = (absFilePath) => {
4629
4640
  return contentType;
4630
4641
  };
4631
4642
 
4632
- // ../../node_modules/.pnpm/pretty-bytes@6.0.0/node_modules/pretty-bytes/index.js
4643
+ // ../../node_modules/.pnpm/pretty-bytes@6.1.1/node_modules/pretty-bytes/index.js
4633
4644
  var BYTE_UNITS = [
4634
4645
  "B",
4635
4646
  "kB",
@@ -4643,7 +4654,7 @@ var BYTE_UNITS = [
4643
4654
  ];
4644
4655
  var BIBYTE_UNITS = [
4645
4656
  "B",
4646
- "kiB",
4657
+ "KiB",
4647
4658
  "MiB",
4648
4659
  "GiB",
4649
4660
  "TiB",
@@ -4690,11 +4701,13 @@ function prettyBytes(number, options) {
4690
4701
  options = {
4691
4702
  bits: false,
4692
4703
  binary: false,
4704
+ space: true,
4693
4705
  ...options
4694
4706
  };
4695
4707
  const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
4708
+ const separator = options.space ? " " : "";
4696
4709
  if (options.signed && number === 0) {
4697
- return ` 0 ${UNITS[0]}`;
4710
+ return ` 0${separator}${UNITS[0]}`;
4698
4711
  }
4699
4712
  const isNegative = number < 0;
4700
4713
  const prefix = isNegative ? "-" : options.signed ? "+" : "";
@@ -4710,7 +4723,7 @@ function prettyBytes(number, options) {
4710
4723
  }
4711
4724
  if (number < 1) {
4712
4725
  const numberString2 = toLocaleString(number, options.locale, localeOptions);
4713
- return prefix + numberString2 + " " + UNITS[0];
4726
+ return prefix + numberString2 + separator + UNITS[0];
4714
4727
  }
4715
4728
  const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
4716
4729
  number /= (options.binary ? 1024 : 1e3) ** exponent;
@@ -4719,7 +4732,7 @@ function prettyBytes(number, options) {
4719
4732
  }
4720
4733
  const numberString = toLocaleString(Number(number), options.locale, localeOptions);
4721
4734
  const unit = UNITS[exponent];
4722
- return prefix + numberString + " " + unit;
4735
+ return prefix + numberString + separator + unit;
4723
4736
  }
4724
4737
 
4725
4738
  // embed-worker:/home/runner/work/workers-sdk/workers-sdk/packages/miniflare/src/workers/assets/assets.worker.ts
@@ -4945,6 +4958,12 @@ var Runtime = class {
4945
4958
  }
4946
4959
  };
4947
4960
 
4961
+ // src/plugins/assets/constants.ts
4962
+ var ASSETS_PLUGIN_NAME = "assets";
4963
+ var ASSETS_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:assets-service`;
4964
+ var ROUTER_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:router`;
4965
+ var ASSETS_KV_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:kv`;
4966
+
4948
4967
  // src/plugins/cache/index.ts
4949
4968
  var import_promises4 = __toESM(require("fs/promises"));
4950
4969
 
@@ -5069,12 +5088,12 @@ var kUnsafeEphemeralUniqueKey = Symbol.for(
5069
5088
  var import_url11 = require("url");
5070
5089
  var RouterError = class extends MiniflareError {
5071
5090
  };
5072
- function routeSpecificity(url17) {
5073
- const hostParts = url17.host.split(".");
5091
+ function routeSpecificity(url18) {
5092
+ const hostParts = url18.host.split(".");
5074
5093
  let hostScore = hostParts.length;
5075
5094
  if (hostParts[0] === "*")
5076
5095
  hostScore -= 2;
5077
- const pathParts = url17.pathname.split("/");
5096
+ const pathParts = url18.pathname.split("/");
5078
5097
  let pathScore = pathParts.length;
5079
5098
  if (pathParts[pathParts.length - 1] === "*")
5080
5099
  pathScore -= 2;
@@ -5088,30 +5107,30 @@ function parseRoutes(allRoutes) {
5088
5107
  let urlInput = route;
5089
5108
  if (!hasProtocol)
5090
5109
  urlInput = `https://${urlInput}`;
5091
- const url17 = new import_url11.URL(urlInput);
5092
- const specificity = routeSpecificity(url17);
5093
- const protocol = hasProtocol ? url17.protocol : void 0;
5094
- const internationalisedAllowHostnamePrefix = url17.hostname.startsWith("xn--*");
5095
- const allowHostnamePrefix = url17.hostname.startsWith("*") || internationalisedAllowHostnamePrefix;
5096
- const anyHostname = url17.hostname === "*";
5110
+ const url18 = new import_url11.URL(urlInput);
5111
+ const specificity = routeSpecificity(url18);
5112
+ const protocol = hasProtocol ? url18.protocol : void 0;
5113
+ const internationalisedAllowHostnamePrefix = url18.hostname.startsWith("xn--*");
5114
+ const allowHostnamePrefix = url18.hostname.startsWith("*") || internationalisedAllowHostnamePrefix;
5115
+ const anyHostname = url18.hostname === "*";
5097
5116
  if (allowHostnamePrefix && !anyHostname) {
5098
- let hostname = url17.hostname;
5117
+ let hostname = url18.hostname;
5099
5118
  if (internationalisedAllowHostnamePrefix) {
5100
5119
  hostname = (0, import_url11.domainToUnicode)(hostname);
5101
5120
  }
5102
- url17.hostname = hostname.substring(1);
5121
+ url18.hostname = hostname.substring(1);
5103
5122
  }
5104
- const allowPathSuffix = url17.pathname.endsWith("*");
5123
+ const allowPathSuffix = url18.pathname.endsWith("*");
5105
5124
  if (allowPathSuffix) {
5106
- url17.pathname = url17.pathname.substring(0, url17.pathname.length - 1);
5125
+ url18.pathname = url18.pathname.substring(0, url18.pathname.length - 1);
5107
5126
  }
5108
- if (url17.search) {
5127
+ if (url18.search) {
5109
5128
  throw new RouterError(
5110
5129
  "ERR_QUERY_STRING",
5111
5130
  `Route "${route}" for "${target}" contains a query string. This is not allowed.`
5112
5131
  );
5113
5132
  }
5114
- if (url17.toString().includes("*") && !anyHostname) {
5133
+ if (url18.toString().includes("*") && !anyHostname) {
5115
5134
  throw new RouterError(
5116
5135
  "ERR_INFIX_WILDCARD",
5117
5136
  `Route "${route}" for "${target}" contains an infix wildcard. This is not allowed.`
@@ -5123,8 +5142,8 @@ function parseRoutes(allRoutes) {
5123
5142
  specificity,
5124
5143
  protocol,
5125
5144
  allowHostnamePrefix,
5126
- hostname: anyHostname ? "" : url17.hostname,
5127
- path: url17.pathname,
5145
+ hostname: anyHostname ? "" : url18.hostname,
5146
+ path: url18.pathname,
5128
5147
  allowPathSuffix
5129
5148
  });
5130
5149
  }
@@ -5165,11 +5184,11 @@ function namespaceEntries(namespaces) {
5165
5184
  return [];
5166
5185
  }
5167
5186
  }
5168
- function maybeParseURL(url17) {
5169
- if (typeof url17 !== "string" || import_path14.default.isAbsolute(url17))
5187
+ function maybeParseURL(url18) {
5188
+ if (typeof url18 !== "string" || import_path14.default.isAbsolute(url18))
5170
5189
  return;
5171
5190
  try {
5172
- return new URL(url17);
5191
+ return new URL(url18);
5173
5192
  } catch {
5174
5193
  }
5175
5194
  }
@@ -5178,16 +5197,16 @@ function getPersistPath(pluginName, tmpPath, persist) {
5178
5197
  if (persist === void 0 || persist === false) {
5179
5198
  return memoryishPath;
5180
5199
  }
5181
- const url17 = maybeParseURL(persist);
5182
- if (url17 !== void 0) {
5183
- if (url17.protocol === "memory:") {
5200
+ const url18 = maybeParseURL(persist);
5201
+ if (url18 !== void 0) {
5202
+ if (url18.protocol === "memory:") {
5184
5203
  return memoryishPath;
5185
- } else if (url17.protocol === "file:") {
5186
- return (0, import_url12.fileURLToPath)(url17);
5204
+ } else if (url18.protocol === "file:") {
5205
+ return (0, import_url12.fileURLToPath)(url18);
5187
5206
  }
5188
5207
  throw new MiniflareCoreError(
5189
5208
  "ERR_PERSIST_UNSUPPORTED",
5190
- `Unsupported "${url17.protocol}" persistence protocol for storage: ${url17.href}`
5209
+ `Unsupported "${url18.protocol}" persistence protocol for storage: ${url18.href}`
5191
5210
  );
5192
5211
  }
5193
5212
  return persist === true ? import_path14.default.join(DEFAULT_PERSIST_ROOT, pluginName) : persist;
@@ -5482,6 +5501,51 @@ var import_util = require("util");
5482
5501
  var import_acorn = require("acorn");
5483
5502
  var import_acorn_walk = require("acorn-walk");
5484
5503
  var import_zod9 = require("zod");
5504
+
5505
+ // src/plugins/core/node-compat.ts
5506
+ function getNodeCompat(compatibilityDate = "2000-01-01", compatibilityFlags, opts) {
5507
+ const { nodeCompat = false } = opts ?? {};
5508
+ const {
5509
+ hasNodejsAlsFlag,
5510
+ hasNodejsCompatFlag,
5511
+ hasNodejsCompatV2Flag,
5512
+ hasNoNodejsCompatV2Flag,
5513
+ hasExperimentalNodejsCompatV2Flag
5514
+ } = parseNodeCompatibilityFlags(compatibilityFlags);
5515
+ const nodeCompatSwitchOverDate = "2024-09-23";
5516
+ const legacy = nodeCompat === true;
5517
+ let mode = null;
5518
+ if (hasNodejsCompatV2Flag || hasNodejsCompatFlag && compatibilityDate >= nodeCompatSwitchOverDate && !hasNoNodejsCompatV2Flag) {
5519
+ mode = "v2";
5520
+ } else if (hasNodejsCompatFlag) {
5521
+ mode = "v1";
5522
+ } else if (hasNodejsAlsFlag) {
5523
+ mode = "als";
5524
+ } else if (legacy) {
5525
+ mode = "legacy";
5526
+ }
5527
+ return {
5528
+ mode,
5529
+ hasNodejsAlsFlag,
5530
+ hasNodejsCompatFlag,
5531
+ hasNodejsCompatV2Flag,
5532
+ hasNoNodejsCompatV2Flag,
5533
+ hasExperimentalNodejsCompatV2Flag
5534
+ };
5535
+ }
5536
+ function parseNodeCompatibilityFlags(compatibilityFlags) {
5537
+ return {
5538
+ hasNodejsAlsFlag: compatibilityFlags.includes("nodejs_als"),
5539
+ hasNodejsCompatFlag: compatibilityFlags.includes("nodejs_compat"),
5540
+ hasNodejsCompatV2Flag: compatibilityFlags.includes("nodejs_compat_v2"),
5541
+ hasNoNodejsCompatV2Flag: compatibilityFlags.includes("no_nodejs_compat_v2"),
5542
+ hasExperimentalNodejsCompatV2Flag: compatibilityFlags.includes(
5543
+ "experimental:nodejs_compat_v2"
5544
+ )
5545
+ };
5546
+ }
5547
+
5548
+ // src/plugins/core/modules.ts
5485
5549
  var SUGGEST_BUNDLE = "If you're trying to import an npm package, you'll need to bundle your Worker first.";
5486
5550
  var SUGGEST_NODE = "If you're trying to import a Node.js built-in module, or an npm package that uses Node.js built-ins, you'll either need to:\n- Bundle your Worker, configuring your bundler to polyfill Node.js built-ins\n- Configure your bundler to load Workers-compatible builds by changing the main fields/conditions\n- Enable the `nodejs_compat` compatibility flag and use the `NodeJsCompatModule` module type\n- Find an alternative package that doesn't require Node.js built-ins";
5487
5551
  var builtinModulesWithPrefix = import_module.builtinModules.concat(
@@ -5589,15 +5653,18 @@ function getResolveErrorPrefix(referencingPath) {
5589
5653
  return `Unable to resolve "${relative}" dependency`;
5590
5654
  }
5591
5655
  var ModuleLocator = class {
5592
- constructor(modulesRoot, additionalModuleNames, rules = [], compatibilityFlags) {
5656
+ constructor(modulesRoot, additionalModuleNames, rules = [], compatibilityDate, compatibilityFlags) {
5593
5657
  this.modulesRoot = modulesRoot;
5594
5658
  this.additionalModuleNames = additionalModuleNames;
5595
5659
  rules = rules.concat(DEFAULT_MODULE_RULES);
5596
5660
  this.#compiledRules = compileModuleRules(rules);
5597
- this.#nodejsCompat = compatibilityFlags?.includes("nodejs_compat") ?? false;
5661
+ this.#nodejsCompatMode = getNodeCompat(
5662
+ compatibilityDate,
5663
+ compatibilityFlags ?? []
5664
+ ).mode;
5598
5665
  }
5599
5666
  #compiledRules;
5600
- #nodejsCompat;
5667
+ #nodejsCompatMode;
5601
5668
  #visitedPaths = /* @__PURE__ */ new Set();
5602
5669
  modules = [];
5603
5670
  visitEntrypoint(code, modulePath) {
@@ -5681,7 +5748,14 @@ ${dim(modulesConfig)}`;
5681
5748
  }
5682
5749
  const spec = specExpression.value;
5683
5750
  const isNodeJsCompatModule = referencingType === "NodeJsCompatModule";
5684
- if (this.#nodejsCompat && spec.startsWith("node:") || spec.startsWith("cloudflare:") || spec.startsWith("workerd:") || isNodeJsCompatModule && builtinModulesWithPrefix.includes(spec) || this.additionalModuleNames.includes(spec)) {
5751
+ if (
5752
+ // `cloudflare:` and `workerd:` imports don't need to be included explicitly
5753
+ spec.startsWith("cloudflare:") || spec.startsWith("workerd:") || // Node.js compat v1 requires imports to be prefixed with `node:`
5754
+ this.#nodejsCompatMode === "v1" && spec.startsWith("node:") || // Node.js compat modules and v2 can also handle non-prefixed imports
5755
+ (this.#nodejsCompatMode === "v2" || isNodeJsCompatModule) && builtinModulesWithPrefix.includes(spec) || // Async Local Storage mode (node_als) only deals with `node:async_hooks` imports
5756
+ this.#nodejsCompatMode === "als" && spec === "node:async_hooks" || // Any "additional" external modules can be ignored
5757
+ this.additionalModuleNames.includes(spec)
5758
+ ) {
5685
5759
  return;
5686
5760
  }
5687
5761
  if (maybeGetStringScriptPathIndex(referencingName) !== void 0) {
@@ -5752,60 +5826,60 @@ function createJavaScriptModule(code, name, modulePath, type) {
5752
5826
  }
5753
5827
  var encoder = new import_util.TextEncoder();
5754
5828
  var decoder = new import_util.TextDecoder();
5755
- function contentsToString(contents17) {
5756
- return typeof contents17 === "string" ? contents17 : decoder.decode(contents17);
5829
+ function contentsToString(contents18) {
5830
+ return typeof contents18 === "string" ? contents18 : decoder.decode(contents18);
5757
5831
  }
5758
- function contentsToArray(contents17) {
5759
- return typeof contents17 === "string" ? encoder.encode(contents17) : contents17;
5832
+ function contentsToArray(contents18) {
5833
+ return typeof contents18 === "string" ? encoder.encode(contents18) : contents18;
5760
5834
  }
5761
5835
  function convertModuleDefinition(modulesRoot, def) {
5762
5836
  const name = moduleName(modulesRoot, def.path);
5763
- const contents17 = def.contents ?? (0, import_fs12.readFileSync)(def.path);
5837
+ const contents18 = def.contents ?? (0, import_fs12.readFileSync)(def.path);
5764
5838
  switch (def.type) {
5765
5839
  case "ESModule":
5766
5840
  case "CommonJS":
5767
5841
  case "NodeJsCompatModule":
5768
5842
  return createJavaScriptModule(
5769
- contentsToString(contents17),
5843
+ contentsToString(contents18),
5770
5844
  name,
5771
5845
  import_path15.default.resolve(modulesRoot, def.path),
5772
5846
  def.type
5773
5847
  );
5774
5848
  case "Text":
5775
- return { name, text: contentsToString(contents17) };
5849
+ return { name, text: contentsToString(contents18) };
5776
5850
  case "Data":
5777
- return { name, data: contentsToArray(contents17) };
5851
+ return { name, data: contentsToArray(contents18) };
5778
5852
  case "CompiledWasm":
5779
- return { name, wasm: contentsToArray(contents17) };
5853
+ return { name, wasm: contentsToArray(contents18) };
5780
5854
  case "PythonModule":
5781
- return { name, pythonModule: contentsToString(contents17) };
5855
+ return { name, pythonModule: contentsToString(contents18) };
5782
5856
  case "PythonRequirement":
5783
- return { name, pythonRequirement: contentsToString(contents17) };
5857
+ return { name, pythonRequirement: contentsToString(contents18) };
5784
5858
  default:
5785
5859
  const exhaustive = def.type;
5786
5860
  import_assert5.default.fail(`Unreachable: ${exhaustive} modules are unsupported`);
5787
5861
  }
5788
5862
  }
5789
5863
  function convertWorkerModule(mod) {
5790
- const path27 = mod.name;
5791
- (0, import_assert5.default)(path27 !== void 0);
5864
+ const path28 = mod.name;
5865
+ (0, import_assert5.default)(path28 !== void 0);
5792
5866
  const m = mod;
5793
5867
  if ("esModule" in m)
5794
- return { path: path27, type: "ESModule" };
5868
+ return { path: path28, type: "ESModule" };
5795
5869
  else if ("commonJsModule" in m)
5796
- return { path: path27, type: "CommonJS" };
5870
+ return { path: path28, type: "CommonJS" };
5797
5871
  else if ("nodeJsCompatModule" in m)
5798
- return { path: path27, type: "NodeJsCompatModule" };
5872
+ return { path: path28, type: "NodeJsCompatModule" };
5799
5873
  else if ("text" in m)
5800
- return { path: path27, type: "Text" };
5874
+ return { path: path28, type: "Text" };
5801
5875
  else if ("data" in m)
5802
- return { path: path27, type: "Data" };
5876
+ return { path: path28, type: "Data" };
5803
5877
  else if ("wasm" in m)
5804
- return { path: path27, type: "CompiledWasm" };
5878
+ return { path: path28, type: "CompiledWasm" };
5805
5879
  else if ("pythonModule" in m)
5806
- return { path: path27, type: "PythonModule" };
5880
+ return { path: path28, type: "PythonModule" };
5807
5881
  else if ("pythonRequirement" in m)
5808
- return { path: path27, type: "PythonRequirement" };
5882
+ return { path: path28, type: "PythonRequirement" };
5809
5883
  (0, import_assert5.default)(
5810
5884
  !("json" in m || "fallbackService" in m),
5811
5885
  "Unreachable: json or fallbackService modules aren't generated"
@@ -6008,8 +6082,8 @@ function getSourceMapper() {
6008
6082
  // src/plugins/core/errors/index.ts
6009
6083
  function maybeGetDiskFile(filePath) {
6010
6084
  try {
6011
- const contents17 = import_fs13.default.readFileSync(filePath, "utf8");
6012
- return { path: filePath, contents: contents17 };
6085
+ const contents18 = import_fs13.default.readFileSync(filePath, "utf8");
6086
+ return { path: filePath, contents: contents18 };
6013
6087
  } catch (e) {
6014
6088
  if (e.code !== "ENOENT")
6015
6089
  throw e;
@@ -6024,8 +6098,8 @@ function maybeGetFile(workerSrcOpts, fileSpecifier) {
6024
6098
  const modulesRoot = srcOpts.modulesRoot ?? "";
6025
6099
  for (const module2 of srcOpts.modules) {
6026
6100
  if (module2.contents !== void 0 && import_path16.default.resolve(modulesRoot, module2.path) === filePath) {
6027
- const contents17 = contentsToString(module2.contents);
6028
- return { path: filePath, contents: contents17 };
6101
+ const contents18 = contentsToString(module2.contents);
6102
+ return { path: filePath, contents: contents18 };
6029
6103
  }
6030
6104
  }
6031
6105
  } else if ("script" in srcOpts && "scriptPath" in srcOpts && srcOpts.script !== void 0 && srcOpts.scriptPath !== void 0) {
@@ -6209,7 +6283,7 @@ var SynchronousFetcher = class {
6209
6283
  transferList: [this.#channel.port2]
6210
6284
  });
6211
6285
  }
6212
- fetch(url17, init2) {
6286
+ fetch(url18, init2) {
6213
6287
  this.#ensureWorker();
6214
6288
  Atomics.store(
6215
6289
  this.#notifyHandle,
@@ -6222,7 +6296,7 @@ var SynchronousFetcher = class {
6222
6296
  this.#channel.port1.postMessage({
6223
6297
  id,
6224
6298
  method: init2.method,
6225
- url: url17.toString(),
6299
+ url: url18.toString(),
6226
6300
  headers: init2.headers,
6227
6301
  body: init2.body
6228
6302
  });
@@ -6342,8 +6416,8 @@ var ProxyClient = class {
6342
6416
  }
6343
6417
  };
6344
6418
  var ProxyClientBridge = class {
6345
- constructor(url17, dispatchFetch) {
6346
- this.url = url17;
6419
+ constructor(url18, dispatchFetch) {
6420
+ this.url = url18;
6347
6421
  this.dispatchFetch = dispatchFetch;
6348
6422
  this.#finalizationRegistry = new FinalizationRegistry(this.#finalizeProxy);
6349
6423
  }
@@ -6866,7 +6940,11 @@ var CoreOptionsSchemaInput = import_zod12.z.intersection(
6866
6940
  unsafeEphemeralDurableObjects: import_zod12.z.boolean().optional(),
6867
6941
  unsafeDirectSockets: UnsafeDirectSocketSchema.array().optional(),
6868
6942
  unsafeEvalBinding: import_zod12.z.string().optional(),
6869
- unsafeUseModuleFallbackService: import_zod12.z.boolean().optional()
6943
+ unsafeUseModuleFallbackService: import_zod12.z.boolean().optional(),
6944
+ /** Used to set the vitest pool worker SELF binding to point to the router worker if there are assets.
6945
+ (If there are assets but we're not using vitest, the miniflare entry worker can point directly to RW.)
6946
+ */
6947
+ hasAssetsAndIsVitest: import_zod12.z.boolean().optional()
6870
6948
  })
6871
6949
  );
6872
6950
  var CoreOptionsSchema = CoreOptionsSchemaInput.transform((value) => {
@@ -6931,7 +7009,7 @@ var SCRIPT_CUSTOM_SERVICE = `addEventListener("fetch", (event) => {
6931
7009
  request.headers.set("${CoreHeaders.ORIGINAL_URL}", request.url);
6932
7010
  event.respondWith(${CoreBindings.SERVICE_LOOPBACK}.fetch(request));
6933
7011
  })`;
6934
- function getCustomServiceDesignator(refererName, workerIndex, kind, name, service) {
7012
+ function getCustomServiceDesignator(refererName, workerIndex, kind, name, service, hasAssetsAndIsVitest = false) {
6935
7013
  let serviceName;
6936
7014
  let entrypoint;
6937
7015
  if (typeof service === "function") {
@@ -6948,7 +7026,7 @@ function getCustomServiceDesignator(refererName, workerIndex, kind, name, servic
6948
7026
  serviceName = getBuiltinServiceName(workerIndex, kind, name);
6949
7027
  }
6950
7028
  } else if (service === kCurrentWorker) {
6951
- serviceName = getUserServiceName(refererName);
7029
+ serviceName = hasAssetsAndIsVitest ? ROUTER_SERVICE_NAME : getUserServiceName(refererName);
6952
7030
  } else {
6953
7031
  serviceName = getUserServiceName(service);
6954
7032
  }
@@ -7004,11 +7082,20 @@ function validateCompatibilityDate(log, compatibilityDate) {
7004
7082
  }
7005
7083
  return compatibilityDate;
7006
7084
  }
7007
- function buildJsonBindings(bindings) {
7008
- return Object.entries(bindings).map(([name, value]) => ({
7009
- name,
7010
- json: JSON.stringify(value)
7011
- }));
7085
+ function buildBindings(bindings) {
7086
+ return Object.entries(bindings).map(([name, value]) => {
7087
+ if (typeof value === "string") {
7088
+ return {
7089
+ name,
7090
+ text: value
7091
+ };
7092
+ } else {
7093
+ return {
7094
+ name,
7095
+ json: JSON.stringify(value)
7096
+ };
7097
+ }
7098
+ });
7012
7099
  }
7013
7100
  var WRAPPED_MODULE_PREFIX = "miniflare-internal:wrapped:";
7014
7101
  function workerNameToWrappedModule(workerName) {
@@ -7025,7 +7112,7 @@ var CORE_PLUGIN = {
7025
7112
  getBindings(options, workerIndex) {
7026
7113
  const bindings = [];
7027
7114
  if (options.bindings !== void 0) {
7028
- bindings.push(...buildJsonBindings(options.bindings));
7115
+ bindings.push(...buildBindings(options.bindings));
7029
7116
  }
7030
7117
  if (options.wasmBindings !== void 0) {
7031
7118
  bindings.push(
@@ -7037,7 +7124,7 @@ var CORE_PLUGIN = {
7037
7124
  if (options.textBlobBindings !== void 0) {
7038
7125
  bindings.push(
7039
7126
  ...Object.entries(options.textBlobBindings).map(
7040
- ([name, path27]) => import_promises6.default.readFile(path27, "utf8").then((text) => ({ name, text }))
7127
+ ([name, path28]) => import_promises6.default.readFile(path28, "utf8").then((text) => ({ name, text }))
7041
7128
  )
7042
7129
  );
7043
7130
  }
@@ -7059,7 +7146,8 @@ var CORE_PLUGIN = {
7059
7146
  workerIndex,
7060
7147
  "#" /* UNKNOWN */,
7061
7148
  name,
7062
- service
7149
+ service,
7150
+ options.hasAssetsAndIsVitest
7063
7151
  )
7064
7152
  };
7065
7153
  })
@@ -7073,7 +7161,7 @@ var CORE_PLUGIN = {
7073
7161
  const entrypoint = isObject ? designator.entrypoint : void 0;
7074
7162
  const bindings2 = isObject ? designator.bindings : void 0;
7075
7163
  const moduleName2 = workerNameToWrappedModule(scriptName);
7076
- const innerBindings = bindings2 === void 0 ? [] : buildJsonBindings(bindings2);
7164
+ const innerBindings = bindings2 === void 0 ? [] : buildBindings(bindings2);
7077
7165
  return {
7078
7166
  name,
7079
7167
  wrapped: { moduleName: moduleName2, entrypoint, innerBindings }
@@ -7109,7 +7197,7 @@ var CORE_PLUGIN = {
7109
7197
  if (options.textBlobBindings !== void 0) {
7110
7198
  bindingEntries2.push(
7111
7199
  ...Object.entries(options.textBlobBindings).map(
7112
- ([name, path27]) => import_promises6.default.readFile(path27, "utf8").then((text) => [name, text])
7200
+ ([name, path28]) => import_promises6.default.readFile(path28, "utf8").then((text) => [name, text])
7113
7201
  )
7114
7202
  );
7115
7203
  }
@@ -7281,7 +7369,8 @@ Ensure ${stringName} doesn't include unbundled \`import\`s.`
7281
7369
  workerIndex,
7282
7370
  "$" /* KNOWN */,
7283
7371
  CUSTOM_SERVICE_KNOWN_OUTBOUND,
7284
- options.outboundService
7372
+ options.outboundService,
7373
+ options.hasAssetsAndIsVitest
7285
7374
  ),
7286
7375
  cacheApiOutbound: { name: getCacheServiceName(workerIndex) },
7287
7376
  moduleFallback: options.unsafeUseModuleFallbackService && sharedOptions.unsafeModuleFallbackService !== void 0 ? `localhost:${loopbackPort}` : void 0
@@ -7444,6 +7533,7 @@ function getWorkerScript(options, workerIndex, additionalModuleNames) {
7444
7533
  modulesRoot,
7445
7534
  additionalModuleNames,
7446
7535
  options.modulesRules,
7536
+ options.compatibilityDate,
7447
7537
  options.compatibilityFlags
7448
7538
  );
7449
7539
  locator.visitEntrypoint(code, scriptPath);
@@ -7454,21 +7544,17 @@ function getWorkerScript(options, workerIndex, additionalModuleNames) {
7454
7544
  }
7455
7545
  }
7456
7546
 
7457
- // src/plugins/assets/constants.ts
7458
- var ASSETS_PLUGIN_NAME = "assets";
7459
- var ASSETS_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:assets-service`;
7460
- var ROUTER_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:router`;
7461
- var ASSETS_KV_SERVICE_NAME = `${ASSETS_PLUGIN_NAME}:kv`;
7462
-
7463
7547
  // src/plugins/assets/schema.ts
7464
7548
  var import_zod13 = require("zod");
7465
7549
  var AssetsOptionsSchema = import_zod13.z.object({
7466
7550
  assets: import_zod13.z.object({
7551
+ // User worker name or vitest runner - this is only ever set inside miniflare
7552
+ // The assets plugin needs access to the worker name to create the router worker - user worker binding
7467
7553
  workerName: import_zod13.z.string().optional(),
7468
- path: PathSchema,
7469
- bindingName: import_zod13.z.string().optional(),
7470
- routingConfig: RoutingConfigSchema,
7471
- assetConfig: AssetConfigSchema
7554
+ directory: PathSchema,
7555
+ binding: import_zod13.z.string().optional(),
7556
+ routingConfig: RoutingConfigSchema.optional(),
7557
+ assetConfig: AssetConfigSchema.optional()
7472
7558
  }).optional()
7473
7559
  });
7474
7560
 
@@ -7476,35 +7562,37 @@ var AssetsOptionsSchema = import_zod13.z.object({
7476
7562
  var ASSETS_PLUGIN = {
7477
7563
  options: AssetsOptionsSchema,
7478
7564
  async getBindings(options) {
7479
- if (!options.assets?.bindingName) {
7565
+ if (!options.assets?.binding) {
7480
7566
  return [];
7481
7567
  }
7482
7568
  return [
7483
7569
  {
7484
7570
  // binding between User Worker and Asset Worker
7485
- name: options.assets.bindingName,
7571
+ name: options.assets.binding,
7486
7572
  service: { name: ASSETS_SERVICE_NAME }
7487
7573
  }
7488
7574
  ];
7489
7575
  },
7490
7576
  async getNodeBindings(options) {
7491
- if (!options.assets?.bindingName) {
7577
+ if (!options.assets?.binding) {
7492
7578
  return {};
7493
7579
  }
7494
7580
  return {
7495
- [options.assets.bindingName]: new ProxyNodeBinding()
7581
+ [options.assets.binding]: new ProxyNodeBinding()
7496
7582
  };
7497
7583
  },
7498
7584
  async getServices({ options }) {
7499
7585
  if (!options.assets) {
7500
7586
  return [];
7501
7587
  }
7502
- const assetsReverseMap = await createReverseMap(options.assets?.path);
7503
7588
  const storageServiceName = `${ASSETS_PLUGIN_NAME}:storage`;
7504
7589
  const storageService = {
7505
7590
  name: storageServiceName,
7506
- disk: { path: options.assets.path, writable: true }
7591
+ disk: { path: options.assets.directory, writable: true }
7507
7592
  };
7593
+ const { encodedAssetManifest, assetsReverseMap } = await buildAssetManifest(
7594
+ options.assets.directory
7595
+ );
7508
7596
  const namespaceService = {
7509
7597
  name: ASSETS_KV_SERVICE_NAME,
7510
7598
  worker: {
@@ -7523,12 +7611,11 @@ var ASSETS_PLUGIN = {
7523
7611
  },
7524
7612
  {
7525
7613
  name: "ASSETS_REVERSE_MAP",
7526
- json: assetsReverseMap
7614
+ json: JSON.stringify(assetsReverseMap)
7527
7615
  }
7528
7616
  ]
7529
7617
  }
7530
7618
  };
7531
- const assetsManifest = await buildAssetsManifest(options.assets.path);
7532
7619
  const assetService = {
7533
7620
  name: ASSETS_SERVICE_NAME,
7534
7621
  worker: {
@@ -7546,11 +7633,11 @@ var ASSETS_PLUGIN = {
7546
7633
  },
7547
7634
  {
7548
7635
  name: "ASSETS_MANIFEST",
7549
- data: assetsManifest
7636
+ data: encodedAssetManifest
7550
7637
  },
7551
7638
  {
7552
7639
  name: "CONFIG",
7553
- json: JSON.stringify(options.assets.assetConfig)
7640
+ json: JSON.stringify(options.assets.assetConfig ?? {})
7554
7641
  }
7555
7642
  ]
7556
7643
  }
@@ -7584,20 +7671,21 @@ var ASSETS_PLUGIN = {
7584
7671
  return [storageService, namespaceService, assetService, routerService];
7585
7672
  }
7586
7673
  };
7587
- var buildAssetsManifest = async (dir) => {
7588
- const manifest = await walk(dir);
7674
+ var buildAssetManifest = async (dir) => {
7675
+ const { manifest, assetsReverseMap } = await walk(dir);
7589
7676
  const sortedAssetManifest = sortManifest(manifest);
7590
7677
  const encodedAssetManifest = encodeManifest(sortedAssetManifest);
7591
- return encodedAssetManifest;
7678
+ return { encodedAssetManifest, assetsReverseMap };
7592
7679
  };
7593
7680
  var walk = async (dir) => {
7594
7681
  const files = await import_promises7.default.readdir(dir, { recursive: true });
7595
7682
  const manifest = [];
7683
+ const assetsReverseMap = {};
7596
7684
  let counter = 0;
7597
7685
  await Promise.all(
7598
7686
  files.map(async (file) => {
7599
- const filepath = import_node_path.default.join(dir, file);
7600
- const relativeFilepath = import_node_path.default.relative(dir, filepath);
7687
+ const filepath = import_node_path2.default.join(dir, file);
7688
+ const relativeFilepath = import_node_path2.default.relative(dir, filepath);
7601
7689
  const filestat = await import_promises7.default.stat(filepath);
7602
7690
  if (filestat.isSymbolicLink() || filestat.isDirectory()) {
7603
7691
  return;
@@ -7619,9 +7707,19 @@ Cloudflare Workers supports assets with sizes of up to ${prettyBytes(
7619
7707
  Ensure all assets in your assets directory "${dir}" conform with the Workers maximum size requirement.`
7620
7708
  );
7621
7709
  }
7622
- manifest.push(
7623
- await hashPath(encodeFilePath(relativeFilepath, import_node_path.default.sep))
7624
- );
7710
+ const [pathHash, contentHash] = await Promise.all([
7711
+ hashPath(normalizeFilePath(relativeFilepath)),
7712
+ // used absolute filepath here so that changes to the enclosing asset folder will be registered
7713
+ hashPath(filepath + filestat.mtimeMs.toString())
7714
+ ]);
7715
+ manifest.push({
7716
+ pathHash,
7717
+ contentHash
7718
+ });
7719
+ assetsReverseMap[bytesToHex(contentHash)] = {
7720
+ filePath: relativeFilepath,
7721
+ contentType: getContentType(filepath)
7722
+ };
7625
7723
  counter++;
7626
7724
  }
7627
7725
  })
@@ -7633,23 +7731,23 @@ Cloudflare Workers supports up to ${MAX_ASSET_COUNT.toLocaleString()} assets in
7633
7731
  Ensure your assets directory contains a maximum of ${MAX_ASSET_COUNT.toLocaleString()} files, and that you have specified your assets directory correctly.`
7634
7732
  );
7635
7733
  }
7636
- return manifest;
7734
+ return { manifest, assetsReverseMap };
7637
7735
  };
7638
7736
  var sortManifest = (manifest) => {
7639
7737
  return manifest.sort(comparisonFn);
7640
7738
  };
7641
7739
  var comparisonFn = (a, b) => {
7642
- if (a.length < b.length) {
7740
+ if (a.pathHash.length < b.pathHash.length) {
7643
7741
  return -1;
7644
7742
  }
7645
- if (a.length > b.length) {
7743
+ if (a.pathHash.length > b.pathHash.length) {
7646
7744
  return 1;
7647
7745
  }
7648
- for (const [i, v] of a.entries()) {
7649
- if (v < b[i]) {
7746
+ for (const [i, v] of a.pathHash.entries()) {
7747
+ if (v < b.pathHash[i]) {
7650
7748
  return -1;
7651
7749
  }
7652
- if (v > b[i]) {
7750
+ if (v > b.pathHash[i]) {
7653
7751
  return 1;
7654
7752
  }
7655
7753
  }
@@ -7661,40 +7759,20 @@ var encodeManifest = (manifest) => {
7661
7759
  );
7662
7760
  for (const [i, entry] of manifest.entries()) {
7663
7761
  const entryOffset = HEADER_SIZE + i * ENTRY_SIZE;
7664
- assetManifestBytes.set(entry, entryOffset + PATH_HASH_OFFSET);
7665
- assetManifestBytes.set(entry, entryOffset + CONTENT_HASH_OFFSET);
7762
+ assetManifestBytes.set(entry.pathHash, entryOffset + PATH_HASH_OFFSET);
7763
+ assetManifestBytes.set(
7764
+ entry.contentHash,
7765
+ entryOffset + CONTENT_HASH_OFFSET
7766
+ );
7666
7767
  }
7667
7768
  return assetManifestBytes;
7668
7769
  };
7669
- var createReverseMap = async (dir) => {
7670
- const files = await import_promises7.default.readdir(dir, { recursive: true });
7671
- const assetsReverseMap = {};
7672
- await Promise.all(
7673
- files.map(async (file) => {
7674
- const filepath = import_node_path.default.join(dir, file);
7675
- const relativeFilepath = import_node_path.default.relative(dir, filepath);
7676
- const filestat = await import_promises7.default.stat(filepath);
7677
- if (filestat.isSymbolicLink() || filestat.isDirectory()) {
7678
- return;
7679
- } else {
7680
- const pathHash = bytesToHex(
7681
- await hashPath(encodeFilePath(relativeFilepath, import_node_path.default.sep))
7682
- );
7683
- assetsReverseMap[pathHash] = {
7684
- filePath: relativeFilepath,
7685
- contentType: getContentType(filepath)
7686
- };
7687
- }
7688
- })
7689
- );
7690
- return JSON.stringify(assetsReverseMap);
7691
- };
7692
7770
  var bytesToHex = (buffer) => {
7693
7771
  return [...new Uint8Array(buffer)].map((b) => b.toString(16).padStart(2, "0")).join("");
7694
7772
  };
7695
- var hashPath = async (path27) => {
7773
+ var hashPath = async (path28) => {
7696
7774
  const encoder3 = new TextEncoder();
7697
- const data = encoder3.encode(path27);
7775
+ const data = encoder3.encode(path28);
7698
7776
  const hashBuffer = await import_node_crypto.default.subtle.digest("SHA-256", data.buffer);
7699
7777
  return new Uint8Array(hashBuffer, 0, PATH_HASH_SIZE);
7700
7778
  };
@@ -7835,55 +7913,55 @@ var D1_PLUGIN = {
7835
7913
  var import_node_assert3 = __toESM(require("node:assert"));
7836
7914
  var import_zod15 = require("zod");
7837
7915
  var HYPERDRIVE_PLUGIN_NAME = "hyperdrive";
7838
- function hasPostgresProtocol(url17) {
7839
- return url17.protocol === "postgresql:" || url17.protocol === "postgres:";
7916
+ function hasPostgresProtocol(url18) {
7917
+ return url18.protocol === "postgresql:" || url18.protocol === "postgres:";
7840
7918
  }
7841
- function getPort(url17) {
7842
- if (url17.port !== "")
7843
- return url17.port;
7844
- if (hasPostgresProtocol(url17))
7919
+ function getPort(url18) {
7920
+ if (url18.port !== "")
7921
+ return url18.port;
7922
+ if (hasPostgresProtocol(url18))
7845
7923
  return "5432";
7846
- import_node_assert3.default.fail(`Expected known protocol, got ${url17.protocol}`);
7924
+ import_node_assert3.default.fail(`Expected known protocol, got ${url18.protocol}`);
7847
7925
  }
7848
- var HyperdriveSchema = import_zod15.z.union([import_zod15.z.string().url(), import_zod15.z.instanceof(URL)]).transform((url17, ctx) => {
7849
- if (typeof url17 === "string")
7850
- url17 = new URL(url17);
7851
- if (url17.protocol === "") {
7926
+ var HyperdriveSchema = import_zod15.z.union([import_zod15.z.string().url(), import_zod15.z.instanceof(URL)]).transform((url18, ctx) => {
7927
+ if (typeof url18 === "string")
7928
+ url18 = new URL(url18);
7929
+ if (url18.protocol === "") {
7852
7930
  ctx.addIssue({
7853
7931
  code: import_zod15.z.ZodIssueCode.custom,
7854
7932
  message: "You must specify the database protocol - e.g. 'postgresql'."
7855
7933
  });
7856
- } else if (!hasPostgresProtocol(url17)) {
7934
+ } else if (!hasPostgresProtocol(url18)) {
7857
7935
  ctx.addIssue({
7858
7936
  code: import_zod15.z.ZodIssueCode.custom,
7859
7937
  message: "Only PostgreSQL or PostgreSQL compatible databases are currently supported."
7860
7938
  });
7861
7939
  }
7862
- if (url17.host === "") {
7940
+ if (url18.host === "") {
7863
7941
  ctx.addIssue({
7864
7942
  code: import_zod15.z.ZodIssueCode.custom,
7865
7943
  message: "You must provide a hostname or IP address in your connection string - e.g. 'user:password@database-hostname.example.com:5432/databasename"
7866
7944
  });
7867
7945
  }
7868
- if (url17.pathname === "") {
7946
+ if (url18.pathname === "") {
7869
7947
  ctx.addIssue({
7870
7948
  code: import_zod15.z.ZodIssueCode.custom,
7871
7949
  message: "You must provide a database name as the path component - e.g. /postgres"
7872
7950
  });
7873
7951
  }
7874
- if (url17.username === "") {
7952
+ if (url18.username === "") {
7875
7953
  ctx.addIssue({
7876
7954
  code: import_zod15.z.ZodIssueCode.custom,
7877
7955
  message: "You must provide a username - e.g. 'user:password@database.example.com:port/databasename'"
7878
7956
  });
7879
7957
  }
7880
- if (url17.password === "") {
7958
+ if (url18.password === "") {
7881
7959
  ctx.addIssue({
7882
7960
  code: import_zod15.z.ZodIssueCode.custom,
7883
7961
  message: "You must provide a password - e.g. 'user:password@database.example.com:port/databasename' "
7884
7962
  });
7885
7963
  }
7886
- return url17;
7964
+ return url18;
7887
7965
  });
7888
7966
  var HyperdriveInputOptionsSchema = import_zod15.z.object({
7889
7967
  hyperdrives: import_zod15.z.record(import_zod15.z.string(), HyperdriveSchema).optional()
@@ -7892,9 +7970,9 @@ var HYPERDRIVE_PLUGIN = {
7892
7970
  options: HyperdriveInputOptionsSchema,
7893
7971
  getBindings(options) {
7894
7972
  return Object.entries(options.hyperdrives ?? {}).map(
7895
- ([name, url17]) => {
7896
- const database = url17.pathname.replace("/", "");
7897
- const scheme = url17.protocol.replace(":", "");
7973
+ ([name, url18]) => {
7974
+ const database = url18.pathname.replace("/", "");
7975
+ const scheme = url18.protocol.replace(":", "");
7898
7976
  return {
7899
7977
  name,
7900
7978
  hyperdrive: {
@@ -7902,8 +7980,8 @@ var HYPERDRIVE_PLUGIN = {
7902
7980
  name: `${HYPERDRIVE_PLUGIN_NAME}:${name}`
7903
7981
  },
7904
7982
  database: decodeURIComponent(database),
7905
- user: decodeURIComponent(url17.username),
7906
- password: decodeURIComponent(url17.password),
7983
+ user: decodeURIComponent(url18.username),
7984
+ password: decodeURIComponent(url18.password),
7907
7985
  scheme
7908
7986
  }
7909
7987
  };
@@ -7912,11 +7990,11 @@ var HYPERDRIVE_PLUGIN = {
7912
7990
  },
7913
7991
  getNodeBindings(options) {
7914
7992
  return Object.fromEntries(
7915
- Object.entries(options.hyperdrives ?? {}).map(([name, url17]) => {
7993
+ Object.entries(options.hyperdrives ?? {}).map(([name, url18]) => {
7916
7994
  const connectionOverrides = {
7917
- connectionString: `${url17}`,
7918
- port: Number.parseInt(url17.port),
7919
- host: url17.hostname
7995
+ connectionString: `${url18}`,
7996
+ port: Number.parseInt(url18.port),
7997
+ host: url18.hostname
7920
7998
  };
7921
7999
  const proxyNodeBinding = new ProxyNodeBinding({
7922
8000
  get(target, prop) {
@@ -7929,10 +8007,10 @@ var HYPERDRIVE_PLUGIN = {
7929
8007
  },
7930
8008
  async getServices({ options }) {
7931
8009
  return Object.entries(options.hyperdrives ?? {}).map(
7932
- ([name, url17]) => ({
8010
+ ([name, url18]) => ({
7933
8011
  name: `${HYPERDRIVE_PLUGIN_NAME}:${name}`,
7934
8012
  external: {
7935
- address: `${url17.hostname}:${getPort(url17)}`,
8013
+ address: `${url18.hostname}:${getPort(url18)}`,
7936
8014
  tcp: {}
7937
8015
  }
7938
8016
  })
@@ -8266,7 +8344,11 @@ var QUEUES_PLUGIN = {
8266
8344
  { name: "broker.worker.js", esModule: broker_worker_default() }
8267
8345
  ],
8268
8346
  durableObjectNamespaces: [
8269
- { className: QUEUE_BROKER_OBJECT_CLASS_NAME, uniqueKey }
8347
+ {
8348
+ className: QUEUE_BROKER_OBJECT_CLASS_NAME,
8349
+ uniqueKey,
8350
+ preventEviction: true
8351
+ }
8270
8352
  ],
8271
8353
  // Miniflare's Queue broker is in-memory only at the moment
8272
8354
  durableObjectStorage: { inMemory: kVoid },
@@ -8470,7 +8552,7 @@ var RatelimitOptionsSchema = import_zod19.z.object({
8470
8552
  var RATELIMIT_PLUGIN_NAME = "ratelimit";
8471
8553
  var SERVICE_RATELIMIT_PREFIX = `${RATELIMIT_PLUGIN_NAME}`;
8472
8554
  var SERVICE_RATELIMIT_MODULE = `cloudflare-internal:${SERVICE_RATELIMIT_PREFIX}:module`;
8473
- function buildJsonBindings2(bindings) {
8555
+ function buildJsonBindings(bindings) {
8474
8556
  return Object.entries(bindings).map(([name, value]) => ({
8475
8557
  name,
8476
8558
  json: JSON.stringify(value)
@@ -8487,7 +8569,7 @@ var RATELIMIT_PLUGIN = {
8487
8569
  name,
8488
8570
  wrapped: {
8489
8571
  moduleName: SERVICE_RATELIMIT_MODULE,
8490
- innerBindings: buildJsonBindings2({
8572
+ innerBindings: buildJsonBindings({
8491
8573
  namespaceId: name,
8492
8574
  limit: config.simple.limit,
8493
8575
  period: config.simple.period
@@ -8529,6 +8611,125 @@ var RATELIMIT_PLUGIN = {
8529
8611
  }
8530
8612
  };
8531
8613
 
8614
+ // src/plugins/workflows/index.ts
8615
+ var import_promises12 = __toESM(require("fs/promises"));
8616
+
8617
+ // embed-worker:/home/runner/work/workers-sdk/workers-sdk/packages/miniflare/src/workers/workflows/binding.worker.ts
8618
+ var import_fs21 = __toESM(require("fs"));
8619
+ var import_path25 = __toESM(require("path"));
8620
+ var import_url21 = __toESM(require("url"));
8621
+ var contents17;
8622
+ function binding_worker_default() {
8623
+ if (contents17 !== void 0)
8624
+ return contents17;
8625
+ const filePath = import_path25.default.join(__dirname, "workers", "workflows/binding.worker.js");
8626
+ contents17 = import_fs21.default.readFileSync(filePath, "utf8") + "//# sourceURL=" + import_url21.default.pathToFileURL(filePath);
8627
+ return contents17;
8628
+ }
8629
+
8630
+ // src/plugins/workflows/index.ts
8631
+ var import_zod20 = require("zod");
8632
+ var WorkflowsOptionsSchema = import_zod20.z.object({
8633
+ workflows: import_zod20.z.record(
8634
+ import_zod20.z.object({
8635
+ name: import_zod20.z.string(),
8636
+ className: import_zod20.z.string(),
8637
+ scriptName: import_zod20.z.string().optional()
8638
+ })
8639
+ ).optional()
8640
+ });
8641
+ var WorkflowsSharedOptionsSchema = import_zod20.z.object({
8642
+ workflowsPersist: PersistenceSchema
8643
+ });
8644
+ var WORKFLOWS_PLUGIN_NAME = "workflows";
8645
+ var WORKFLOWS_STORAGE_SERVICE_NAME = `${WORKFLOWS_PLUGIN_NAME}:storage`;
8646
+ var WORKFLOWS_PLUGIN = {
8647
+ options: WorkflowsOptionsSchema,
8648
+ sharedOptions: WorkflowsSharedOptionsSchema,
8649
+ async getBindings(options) {
8650
+ return Object.entries(options.workflows ?? {}).map(
8651
+ ([bindingName, workflow]) => ({
8652
+ name: bindingName,
8653
+ service: {
8654
+ name: `${WORKFLOWS_PLUGIN_NAME}:${workflow.name}`,
8655
+ entrypoint: "WorkflowBinding"
8656
+ }
8657
+ })
8658
+ );
8659
+ },
8660
+ async getNodeBindings(options) {
8661
+ return Object.fromEntries(
8662
+ Object.keys(options.workflows ?? {}).map((bindingName) => [
8663
+ bindingName,
8664
+ new ProxyNodeBinding()
8665
+ ])
8666
+ );
8667
+ },
8668
+ async getServices({ options, sharedOptions, tmpPath }) {
8669
+ const persistPath = getPersistPath(
8670
+ WORKFLOWS_PLUGIN_NAME,
8671
+ tmpPath,
8672
+ sharedOptions.workflowsPersist
8673
+ );
8674
+ await import_promises12.default.mkdir(persistPath, { recursive: true });
8675
+ const storageServices = Object.entries(
8676
+ options.workflows ?? {}
8677
+ ).map(([_, workflow]) => ({
8678
+ name: `${WORKFLOWS_STORAGE_SERVICE_NAME}-${workflow.name}`,
8679
+ disk: { path: persistPath, writable: true }
8680
+ }));
8681
+ const services = Object.entries(options.workflows ?? {}).map(
8682
+ ([_bindingName, workflow]) => {
8683
+ const uniqueKey = `miniflare-workflows-${workflow.name}`;
8684
+ const workflowsBinding = {
8685
+ name: `${WORKFLOWS_PLUGIN_NAME}:${workflow.name}`,
8686
+ worker: {
8687
+ compatibilityDate: "2024-10-22",
8688
+ modules: [
8689
+ {
8690
+ name: "workflows.mjs",
8691
+ esModule: binding_worker_default()
8692
+ }
8693
+ ],
8694
+ durableObjectNamespaces: [
8695
+ {
8696
+ className: "Engine",
8697
+ enableSql: true,
8698
+ uniqueKey,
8699
+ preventEviction: true
8700
+ }
8701
+ ],
8702
+ durableObjectStorage: {
8703
+ localDisk: `${WORKFLOWS_STORAGE_SERVICE_NAME}-${workflow.name}`
8704
+ },
8705
+ bindings: [
8706
+ {
8707
+ name: "ENGINE",
8708
+ durableObjectNamespace: { className: "Engine" }
8709
+ },
8710
+ {
8711
+ name: "USER_WORKFLOW",
8712
+ service: {
8713
+ name: getUserServiceName(workflow.scriptName),
8714
+ entrypoint: workflow.className
8715
+ }
8716
+ }
8717
+ ]
8718
+ }
8719
+ };
8720
+ return workflowsBinding;
8721
+ }
8722
+ );
8723
+ if (services.length === 0) {
8724
+ return [];
8725
+ }
8726
+ return [...storageServices, ...services];
8727
+ },
8728
+ getPersistPath({ workflowsPersist }, tmpPath) {
8729
+ return getPersistPath(WORKFLOWS_PLUGIN_NAME, tmpPath, workflowsPersist);
8730
+ }
8731
+ };
8732
+
8532
8733
  // src/plugins/index.ts
8533
8734
  var PLUGINS = {
8534
8735
  [CORE_PLUGIN_NAME2]: CORE_PLUGIN,
@@ -8540,7 +8741,8 @@ var PLUGINS = {
8540
8741
  [R2_PLUGIN_NAME]: R2_PLUGIN,
8541
8742
  [HYPERDRIVE_PLUGIN_NAME]: HYPERDRIVE_PLUGIN,
8542
8743
  [RATELIMIT_PLUGIN_NAME]: RATELIMIT_PLUGIN,
8543
- [ASSETS_PLUGIN_NAME]: ASSETS_PLUGIN
8744
+ [ASSETS_PLUGIN_NAME]: ASSETS_PLUGIN,
8745
+ [WORKFLOWS_PLUGIN_NAME]: WORKFLOWS_PLUGIN
8544
8746
  };
8545
8747
  var PLUGIN_ENTRIES = Object.entries(PLUGINS);
8546
8748
 
@@ -8646,8 +8848,8 @@ function hasMultipleDistinctMessages(issues, atDepth) {
8646
8848
  }
8647
8849
  return false;
8648
8850
  }
8649
- function annotate(groupCounts, annotated, input, issue, path27, groupId) {
8650
- if (path27.length === 0) {
8851
+ function annotate(groupCounts, annotated, input, issue, path28, groupId) {
8852
+ if (path28.length === 0) {
8651
8853
  if (issue.code === "invalid_union") {
8652
8854
  const unionIssues = issue.unionErrors.flatMap(({ issues }) => issues);
8653
8855
  let newGroupId;
@@ -8694,7 +8896,7 @@ function annotate(groupCounts, annotated, input, issue, path27, groupId) {
8694
8896
  [kGroupId]: groupId
8695
8897
  };
8696
8898
  }
8697
- const [head, ...tail] = path27;
8899
+ const [head, ...tail] = path28;
8698
8900
  (0, import_assert11.default)(isRecord(input), "Expected object/array input for nested issue");
8699
8901
  if (annotated === void 0) {
8700
8902
  if (Array.isArray(input)) {
@@ -8904,7 +9106,7 @@ function validateOptions(opts) {
8904
9106
  );
8905
9107
  const sharedRootPath = multipleWorkers ? getRootPath(sharedOpts) : "";
8906
9108
  const workerRootPaths = workerOpts.map(
8907
- (opts2) => import_path25.default.resolve(sharedRootPath, getRootPath(opts2))
9109
+ (opts2) => import_path26.default.resolve(sharedRootPath, getRootPath(opts2))
8908
9110
  );
8909
9111
  try {
8910
9112
  for (const [key, plugin] of PLUGIN_ENTRIES) {
@@ -8920,7 +9122,7 @@ function validateOptions(opts) {
8920
9122
  }
8921
9123
  }
8922
9124
  } catch (e) {
8923
- if (e instanceof import_zod21.z.ZodError) {
9125
+ if (e instanceof import_zod22.z.ZodError) {
8924
9126
  let formatted;
8925
9127
  try {
8926
9128
  formatted = formatZodError(e, opts);
@@ -9084,8 +9286,15 @@ function getQueueProducers(allWorkerOpts) {
9084
9286
  ])
9085
9287
  );
9086
9288
  }
9087
- for (const [bindingName, opts] of Object.entries(workerProducers)) {
9088
- queueProducers.set(bindingName, { workerName, ...opts });
9289
+ const producersIterable = Object.entries(
9290
+ workerProducers
9291
+ );
9292
+ for (const [bindingName, opts] of producersIterable) {
9293
+ if (typeof opts === "string") {
9294
+ queueProducers.set(bindingName, { workerName, queueName: opts });
9295
+ } else {
9296
+ queueProducers.set(bindingName, { workerName, ...opts });
9297
+ }
9089
9298
  }
9090
9299
  }
9091
9300
  }
@@ -9325,7 +9534,7 @@ var Miniflare2 = class {
9325
9534
  }
9326
9535
  }
9327
9536
  });
9328
- this.#tmpPath = import_path25.default.join(
9537
+ this.#tmpPath = import_path26.default.join(
9329
9538
  import_os2.default.tmpdir(),
9330
9539
  `miniflare-${import_crypto3.default.randomBytes(16).toString("hex")}`
9331
9540
  );
@@ -9333,7 +9542,7 @@ var Miniflare2 = class {
9333
9542
  this.#removeExitHook = (0, import_exit_hook.default)(() => {
9334
9543
  void this.#runtime?.dispose();
9335
9544
  try {
9336
- import_fs21.default.rmSync(this.#tmpPath, { force: true, recursive: true });
9545
+ import_fs22.default.rmSync(this.#tmpPath, { force: true, recursive: true });
9337
9546
  } catch (e) {
9338
9547
  this.#log.debug(`Unable to remove temporary directory: ${String(e)}`);
9339
9548
  }
@@ -9370,7 +9579,7 @@ var Miniflare2 = class {
9370
9579
  if (!(response instanceof Response)) {
9371
9580
  response = new Response(response.body, response);
9372
9581
  }
9373
- return import_zod21.z.instanceof(Response).parse(response);
9582
+ return import_zod22.z.instanceof(Response).parse(response);
9374
9583
  } catch (e) {
9375
9584
  return new Response(e?.stack ?? e, { status: 500 });
9376
9585
  }
@@ -9395,11 +9604,11 @@ var Miniflare2 = class {
9395
9604
  (0, import_assert12.default)(!Array.isArray(cfBlob));
9396
9605
  const cf = cfBlob ? JSON.parse(cfBlob) : void 0;
9397
9606
  const originalUrl = headers.get(CoreHeaders.ORIGINAL_URL);
9398
- const url17 = new URL(originalUrl ?? req.url ?? "", "http://localhost");
9607
+ const url18 = new URL(originalUrl ?? req.url ?? "", "http://localhost");
9399
9608
  headers.delete(CoreHeaders.ORIGINAL_URL);
9400
9609
  const noBody = req.method === "GET" || req.method === "HEAD";
9401
9610
  const body = noBody ? void 0 : safeReadableStreamFrom(req);
9402
- const request = new Request(url17, {
9611
+ const request = new Request(url18, {
9403
9612
  method: req.method,
9404
9613
  headers,
9405
9614
  body,
@@ -9420,13 +9629,13 @@ var Miniflare2 = class {
9420
9629
  request,
9421
9630
  this
9422
9631
  );
9423
- } else if (url17.pathname === "/core/error") {
9632
+ } else if (url18.pathname === "/core/error") {
9424
9633
  response = await handlePrettyErrorRequest(
9425
9634
  this.#log,
9426
9635
  this.#workerSrcOpts,
9427
9636
  request
9428
9637
  );
9429
- } else if (url17.pathname === "/core/log") {
9638
+ } else if (url18.pathname === "/core/log") {
9430
9639
  const level = parseInt(request.headers.get(SharedHeaders.LOG_LEVEL));
9431
9640
  (0, import_assert12.default)(
9432
9641
  0 /* NONE */ <= level && level <= 5 /* VERBOSE */,
@@ -9561,18 +9770,26 @@ var Miniflare2 = class {
9561
9770
  sockets.push({
9562
9771
  name: SOCKET_ENTRY_LOCAL,
9563
9772
  service: { name: SERVICE_ENTRY },
9564
- http: ENTRY_SOCKET_HTTP_OPTIONS,
9773
+ http: {},
9565
9774
  address: "127.0.0.1:0"
9566
9775
  });
9567
9776
  }
9568
9777
  const proxyBindings = [];
9569
9778
  const allWorkerBindings = /* @__PURE__ */ new Map();
9570
9779
  const wrappedBindingsToPopulate = [];
9780
+ if (this.#workerOpts[0].assets.assets) {
9781
+ this.#workerOpts[0].assets.assets.workerName = this.#workerOpts[0].core.name;
9782
+ }
9571
9783
  for (let i = 0; i < allWorkerOpts.length; i++) {
9572
9784
  const previousWorkerOpts = allPreviousWorkerOpts?.[i];
9573
9785
  const workerOpts = allWorkerOpts[i];
9574
9786
  const workerName = workerOpts.core.name ?? "";
9575
9787
  const isModulesWorker = Boolean(workerOpts.core.modules);
9788
+ if (workerOpts.workflows.workflows) {
9789
+ for (const workflow of Object.values(workerOpts.workflows.workflows)) {
9790
+ workflow.scriptName ??= workerOpts.core.name;
9791
+ }
9792
+ }
9576
9793
  const workerBindings = [];
9577
9794
  allWorkerBindings.set(workerName, workerBindings);
9578
9795
  const additionalModules = [];
@@ -9687,8 +9904,11 @@ var Miniflare2 = class {
9687
9904
  const globalServices = getGlobalServices({
9688
9905
  sharedOptions: sharedOpts.core,
9689
9906
  allWorkerRoutes,
9690
- // if Workers + Assets project, point to router Worker service rather than user Worker
9691
- fallbackWorkerName: this.#workerOpts[0].assets.assets ? ROUTER_SERVICE_NAME : getUserServiceName(this.#workerOpts[0].core.name),
9907
+ // if Workers + Assets project but NOT Vitest, point to router Worker instead
9908
+ // if Vitest with assets, the self binding on the test runner will point to RW
9909
+ fallbackWorkerName: this.#workerOpts[0].assets.assets && !this.#workerOpts[0].core.name?.startsWith(
9910
+ "vitest-pool-workers-runner-"
9911
+ ) ? ROUTER_SERVICE_NAME : getUserServiceName(this.#workerOpts[0].core.name),
9692
9912
  loopbackPort,
9693
9913
  log: this.#log,
9694
9914
  proxyBindings
@@ -9902,11 +10122,11 @@ var Miniflare2 = class {
9902
10122
  (0, import_assert12.default)(this.#runtimeEntryURL !== void 0);
9903
10123
  (0, import_assert12.default)(this.#runtimeDispatcher !== void 0);
9904
10124
  const forward = new Request(input, init2);
9905
- const url17 = new URL(forward.url);
10125
+ const url18 = new URL(forward.url);
9906
10126
  const actualRuntimeOrigin = this.#runtimeEntryURL.origin;
9907
- const userRuntimeOrigin = url17.origin;
9908
- url17.protocol = this.#runtimeEntryURL.protocol;
9909
- url17.host = this.#runtimeEntryURL.host;
10127
+ const userRuntimeOrigin = url18.origin;
10128
+ url18.protocol = this.#runtimeEntryURL.protocol;
10129
+ url18.host = this.#runtimeEntryURL.host;
9910
10130
  if (forward.body !== null && forward.headers.get("Content-Length") === "0") {
9911
10131
  forward.headers.delete("Content-Length");
9912
10132
  }
@@ -9920,7 +10140,7 @@ var Miniflare2 = class {
9920
10140
  );
9921
10141
  const forwardInit = forward;
9922
10142
  forwardInit.dispatcher = dispatcher;
9923
- const response = await fetch3(url17, forwardInit);
10143
+ const response = await fetch3(url18, forwardInit);
9924
10144
  const stack = response.headers.get(CoreHeaders.ERROR_STACK);
9925
10145
  if (response.status === 500 && stack !== null) {
9926
10146
  const caught = JsonErrorSchema.parse(await response.json());
@@ -10070,7 +10290,7 @@ var Miniflare2 = class {
10070
10290
  await this.#proxyClient?.dispose();
10071
10291
  await this.#runtime?.dispose();
10072
10292
  await this.#stopLoopbackServer();
10073
- await import_fs21.default.promises.rm(this.#tmpPath, { force: true, recursive: true });
10293
+ await import_fs22.default.promises.rm(this.#tmpPath, { force: true, recursive: true });
10074
10294
  maybeInstanceRegistry?.delete(this);
10075
10295
  }
10076
10296
  }
@@ -10104,7 +10324,6 @@ var Miniflare2 = class {
10104
10324
  DispatchFetchDispatcher,
10105
10325
  DurableObjectsOptionsSchema,
10106
10326
  DurableObjectsSharedOptionsSchema,
10107
- ENTRY_SOCKET_HTTP_OPTIONS,
10108
10327
  ErrorEvent,
10109
10328
  File,
10110
10329
  FormData,
@@ -10183,10 +10402,15 @@ var Miniflare2 = class {
10183
10402
  TlsOptions_Version,
10184
10403
  TypedEventTarget,
10185
10404
  WORKER_BINDING_SERVICE_LOOPBACK,
10405
+ WORKFLOWS_PLUGIN,
10406
+ WORKFLOWS_PLUGIN_NAME,
10407
+ WORKFLOWS_STORAGE_SERVICE_NAME,
10186
10408
  WaitGroup,
10187
10409
  WebSocket,
10188
10410
  WebSocketPair,
10189
10411
  Worker_Binding_CryptoKey_Usage,
10412
+ WorkflowsOptionsSchema,
10413
+ WorkflowsSharedOptionsSchema,
10190
10414
  __MiniflareFunctionWrapper,
10191
10415
  _enableControlEndpoints,
10192
10416
  _forceColour,
@@ -10195,7 +10419,7 @@ var Miniflare2 = class {
10195
10419
  _transformsForContentEncodingAndContentType,
10196
10420
  base64Decode,
10197
10421
  base64Encode,
10198
- buildAssetsManifest,
10422
+ buildAssetManifest,
10199
10423
  compileModuleRules,
10200
10424
  coupleWebSocket,
10201
10425
  createFetchMock,
@@ -10215,6 +10439,7 @@ var Miniflare2 = class {
10215
10439
  getFreshSourceMapSupport,
10216
10440
  getGlobalServices,
10217
10441
  getMiniflareObjectBindings,
10442
+ getNodeCompat,
10218
10443
  getPersistPath,
10219
10444
  getRootPath,
10220
10445
  globsToRegExps,