@cloudflare/vite-plugin 0.0.0-9b469e213 → 0.0.0-9b66c33e4

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/index.js CHANGED
@@ -489,7 +489,8 @@ import assert10 from "node:assert";
489
489
  import * as fs5 from "node:fs";
490
490
  import * as fsp2 from "node:fs/promises";
491
491
  import * as path9 from "node:path";
492
- import { createMiddleware } from "@hattip/adapter-node";
492
+ import { createRequest, sendResponse } from "@mjackson/node-fetch-server";
493
+ import replace from "@rollup/plugin-replace";
493
494
 
494
495
  // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
495
496
  var comma = ",".charCodeAt(0);
@@ -1557,7 +1558,7 @@ var MagicString = class _MagicString {
1557
1558
 
1558
1559
  // src/index.ts
1559
1560
  import { Miniflare } from "miniflare";
1560
- import colors2 from "picocolors";
1561
+ import colors3 from "picocolors";
1561
1562
  import * as vite7 from "vite";
1562
1563
 
1563
1564
  // src/constants.ts
@@ -1570,6 +1571,7 @@ var ADDITIONAL_MODULE_TYPES = [
1570
1571
  "Text"
1571
1572
  ];
1572
1573
  var DEFAULT_INSPECTOR_PORT = 9229;
1574
+ var kRequestType = Symbol("kRequestType");
1573
1575
 
1574
1576
  // src/additional-modules.ts
1575
1577
  var moduleRules = [
@@ -1588,7 +1590,7 @@ function matchAdditionalModule(source) {
1588
1590
  return null;
1589
1591
  }
1590
1592
  function createModuleReference(type, id) {
1591
- return `__CLOUDFLARE_MODULE__${type}__${id}__`;
1593
+ return `__CLOUDFLARE_MODULE__${type}__${id}__CLOUDFLARE_MODULE__`;
1592
1594
  }
1593
1595
 
1594
1596
  // src/asset-config.ts
@@ -5783,7 +5785,8 @@ var z = /* @__PURE__ */ Object.freeze({
5783
5785
  // ../workers-shared/utils/types.ts
5784
5786
  var InternalConfigSchema = z.object({
5785
5787
  account_id: z.number().optional(),
5786
- script_id: z.number().optional()
5788
+ script_id: z.number().optional(),
5789
+ debug: z.boolean().optional()
5787
5790
  });
5788
5791
  var RouterConfigSchema = z.object({
5789
5792
  invoke_user_worker_ahead_of_assets: z.boolean().optional(),
@@ -5831,14 +5834,14 @@ var AssetConfigSchema = z.object({
5831
5834
  });
5832
5835
 
5833
5836
  // src/asset-config.ts
5834
- function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFile) {
5837
+ function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFilePath) {
5835
5838
  if (!resolvedPluginConfig.experimental?.headersAndRedirectsDevModeSupport) {
5836
5839
  return false;
5837
5840
  }
5838
5841
  return [
5839
5842
  getRedirectsConfigPath(resolvedViteConfig),
5840
5843
  getHeadersConfigPath(resolvedViteConfig)
5841
- ].includes(path.resolve(changedFile));
5844
+ ].includes(changedFilePath);
5842
5845
  }
5843
5846
  function getAssetsConfig(resolvedPluginConfig, entryWorkerConfig, resolvedConfig) {
5844
5847
  const assetsConfig = resolvedPluginConfig.type === "assets-only" ? resolvedPluginConfig.config.assets : entryWorkerConfig?.assets;
@@ -12646,8 +12649,8 @@ function packageResolve(specifier, base, conditions) {
12646
12649
  let packageJsonPath = fileURLToPath$1(packageJsonUrl);
12647
12650
  let lastPath;
12648
12651
  do {
12649
- const stat = tryStatSync(packageJsonPath.slice(0, -13));
12650
- if (!stat || !stat.isDirectory()) {
12652
+ const stat2 = tryStatSync(packageJsonPath.slice(0, -13));
12653
+ if (!stat2 || !stat2.isDirectory()) {
12651
12654
  lastPath = packageJsonPath;
12652
12655
  packageJsonUrl = new URL$1(
12653
12656
  (isScoped ? "../../../../node_modules/" : "../../../node_modules/") + packageName + "/package.json",
@@ -12777,8 +12780,8 @@ function _resolve(id, options = {}) {
12777
12780
  }
12778
12781
  if (isAbsolute(id)) {
12779
12782
  try {
12780
- const stat = statSync(id);
12781
- if (stat.isFile()) {
12783
+ const stat2 = statSync(id);
12784
+ if (stat2.isFile()) {
12782
12785
  return pathToFileURL(id);
12783
12786
  }
12784
12787
  } catch (error) {
@@ -12879,6 +12882,15 @@ function isNodeCompat(workerConfig) {
12879
12882
  }
12880
12883
  return false;
12881
12884
  }
12885
+ function isNodeAls(workerConfig) {
12886
+ return workerConfig !== void 0 && getNodeCompat(
12887
+ workerConfig.compatibility_date,
12888
+ workerConfig.compatibility_flags ?? []
12889
+ ).mode === "als";
12890
+ }
12891
+ function isNodeAlsModule(path10) {
12892
+ return /^(node:)?async_hooks$/.test(path10);
12893
+ }
12882
12894
  function injectGlobalCode(id, code) {
12883
12895
  const injectedCode = Object.entries(env.inject).map(([globalName, globalInject]) => {
12884
12896
  if (typeof globalInject === "string") {
@@ -12909,7 +12921,7 @@ globalThis.${globalName} = var_${globalName}.${exportName};
12909
12921
  }
12910
12922
  function resolveNodeJSImport(source) {
12911
12923
  const alias = env.alias[source];
12912
- if (alias) {
12924
+ if (alias && !nodeCompatExternals.has(alias)) {
12913
12925
  return {
12914
12926
  unresolved: alias,
12915
12927
  resolved: resolvePathSync(alias, { url: import.meta.url })
@@ -12982,7 +12994,7 @@ var NodeJsCompatWarnings = class {
12982
12994
  // src/shared.ts
12983
12995
  var UNKNOWN_HOST = "http://localhost";
12984
12996
  var INIT_PATH = "/__vite_plugin_cloudflare_init__";
12985
- var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__`;
12997
+ var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__CLOUDFLARE_MODULE__`;
12986
12998
  var additionalModuleRE = new RegExp(ADDITIONAL_MODULE_PATTERN);
12987
12999
  var additionalModuleGlobalRE = new RegExp(
12988
13000
  ADDITIONAL_MODULE_PATTERN,
@@ -12999,9 +13011,6 @@ function getOutputDirectory(userConfig, environmentName) {
12999
13011
  const rootOutputDirectory = userConfig.build?.outDir ?? "dist";
13000
13012
  return userConfig.environments?.[environmentName]?.build?.outDir ?? path4.join(rootOutputDirectory, environmentName);
13001
13013
  }
13002
- function getRouterWorker(miniflare2) {
13003
- return miniflare2.getWorker(ROUTER_WORKER_NAME);
13004
- }
13005
13014
  function toMiniflareRequest(request) {
13006
13015
  const host = request.headers.get("Host");
13007
13016
  if (host) {
@@ -13018,19 +13027,6 @@ function toMiniflareRequest(request) {
13018
13027
  duplex: "half"
13019
13028
  });
13020
13029
  }
13021
- function nodeHeadersToWebHeaders(nodeHeaders) {
13022
- const headers = new Headers();
13023
- for (const [key, value] of Object.entries(nodeHeaders)) {
13024
- if (typeof value === "string") {
13025
- headers.append(key, value);
13026
- } else if (Array.isArray(value)) {
13027
- for (const item of value) {
13028
- headers.append(key, item);
13029
- }
13030
- }
13031
- }
13032
- return headers;
13033
- }
13034
13030
  var postfixRE = /[?#].*$/;
13035
13031
  function cleanUrl(url) {
13036
13032
  return url.replace(postfixRE, "");
@@ -13259,7 +13255,7 @@ import { unstable_readConfig } from "wrangler";
13259
13255
  function getDeployConfigPath(root) {
13260
13256
  return path5.resolve(root, ".wrangler", "deploy", "config.json");
13261
13257
  }
13262
- function getWorkerConfigs(root) {
13258
+ function getWorkerConfigs(root, mixedModeEnabled) {
13263
13259
  const deployConfigPath = getDeployConfigPath(root);
13264
13260
  const deployConfig = JSON.parse(
13265
13261
  fs2.readFileSync(deployConfigPath, "utf-8")
@@ -13272,7 +13268,10 @@ function getWorkerConfigs(root) {
13272
13268
  path5.dirname(deployConfigPath),
13273
13269
  configPath
13274
13270
  );
13275
- return unstable_readConfig({ config: resolvedConfigPath });
13271
+ return unstable_readConfig(
13272
+ { config: resolvedConfigPath },
13273
+ { experimental: { mixedModeEnabled } }
13274
+ );
13276
13275
  });
13277
13276
  }
13278
13277
  function getRelativePathToWorkerConfig(deployConfigDirectory, root, outputDirectory) {
@@ -13339,17 +13338,24 @@ import * as fsp from "node:fs/promises";
13339
13338
  import * as path6 from "node:path";
13340
13339
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13341
13340
  import {
13341
+ getDefaultDevRegistryPath,
13342
13342
  kCurrentWorker,
13343
13343
  Log,
13344
13344
  LogLevel,
13345
13345
  Response as MiniflareResponse
13346
13346
  } from "miniflare";
13347
+ import colors2 from "picocolors";
13347
13348
  import { globSync } from "tinyglobby";
13348
13349
  import "vite";
13349
- import { unstable_getMiniflareWorkerOptions } from "wrangler";
13350
- function getPersistence(root, persistState) {
13350
+ import {
13351
+ experimental_pickRemoteBindings,
13352
+ experimental_startMixedModeSession,
13353
+ unstable_convertConfigBindingsToStartWorkerBindings,
13354
+ unstable_getMiniflareWorkerOptions
13355
+ } from "wrangler";
13356
+ function getPersistenceRoot(root, persistState) {
13351
13357
  if (persistState === false) {
13352
- return {};
13358
+ return;
13353
13359
  }
13354
13360
  const defaultPersistPath = ".wrangler/state";
13355
13361
  const persistPath = path6.resolve(
@@ -13357,14 +13363,7 @@ function getPersistence(root, persistState) {
13357
13363
  typeof persistState === "object" ? persistState.path : defaultPersistPath,
13358
13364
  "v3"
13359
13365
  );
13360
- return {
13361
- cachePersist: path6.join(persistPath, "cache"),
13362
- d1Persist: path6.join(persistPath, "d1"),
13363
- durableObjectsPersist: path6.join(persistPath, "do"),
13364
- kvPersist: path6.join(persistPath, "kv"),
13365
- r2Persist: path6.join(persistPath, "r2"),
13366
- workflowsPersist: path6.join(persistPath, "workflows")
13367
- };
13366
+ return persistPath;
13368
13367
  }
13369
13368
  function missingWorkerErrorMessage(workerName) {
13370
13369
  return `${workerName} does not match a worker name.`;
@@ -13448,7 +13447,29 @@ function getEntryWorkerConfig(resolvedPluginConfig) {
13448
13447
  }
13449
13448
  return resolvedPluginConfig.workers[resolvedPluginConfig.entryWorkerEnvironmentName];
13450
13449
  }
13451
- function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13450
+ function logUnknownTails(tails, userWorkers, log) {
13451
+ for (const tailService of tails ?? []) {
13452
+ let name;
13453
+ if (typeof tailService === "string") {
13454
+ name = tailService;
13455
+ } else if (typeof tailService === "object" && "name" in tailService && typeof tailService.name === "string") {
13456
+ name = tailService.name;
13457
+ } else {
13458
+ continue;
13459
+ }
13460
+ const found = userWorkers.some((w) => w.name === name);
13461
+ if (!found) {
13462
+ log(
13463
+ colors2.dim(
13464
+ colors2.yellow(
13465
+ `Tail consumer "${name}" was not found in your config. Make sure you add it to the config or run it in another dev session if you'd like to simulate receiving tail events locally.`
13466
+ )
13467
+ )
13468
+ );
13469
+ }
13470
+ }
13471
+ }
13472
+ async function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13452
13473
  const resolvedViteConfig = viteDevServer.config;
13453
13474
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
13454
13475
  const assetsConfig = getAssetsConfig(
@@ -13499,12 +13520,14 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13499
13520
  serviceBindings: {
13500
13521
  __VITE_ASSET_EXISTS__: async (request) => {
13501
13522
  const { pathname } = new URL(request.url);
13502
- const filePath = path6.join(resolvedViteConfig.root, pathname);
13503
- let exists;
13504
- try {
13505
- exists = fs3.statSync(filePath).isFile();
13506
- } catch (error) {
13507
- exists = false;
13523
+ let exists = false;
13524
+ if (pathname.endsWith(".html")) {
13525
+ try {
13526
+ const filePath = path6.join(resolvedViteConfig.root, pathname);
13527
+ const stats = await fsp.stat(filePath);
13528
+ exists = stats.isFile();
13529
+ } catch (error) {
13530
+ }
13508
13531
  }
13509
13532
  return MiniflareResponse.json(exists);
13510
13533
  },
@@ -13518,59 +13541,75 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13518
13541
  headers: { "Content-Type": "text/html" }
13519
13542
  });
13520
13543
  } catch (error) {
13521
- throw new Error(`Unexpected error. Failed to load ${pathname}`);
13544
+ throw new Error(`Unexpected error. Failed to load "${pathname}".`);
13522
13545
  }
13523
13546
  }
13524
13547
  }
13525
13548
  }
13526
13549
  ];
13527
- const workersFromConfig = resolvedPluginConfig.type === "workers" ? Object.entries(resolvedPluginConfig.workers).map(
13528
- ([environmentName, workerConfig]) => {
13529
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13530
- {
13531
- ...workerConfig,
13532
- assets: void 0
13533
- },
13534
- resolvedPluginConfig.cloudflareEnv
13535
- );
13536
- const { externalWorkers: externalWorkers2 } = miniflareWorkerOptions;
13537
- const { ratelimits, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13538
- return {
13539
- externalWorkers: externalWorkers2,
13540
- worker: {
13541
- ...workerOptions,
13542
- name: workerOptions.name ?? workerConfig.name,
13543
- unsafeInspectorProxy: inspectorPort !== false,
13544
- modulesRoot: miniflareModulesRoot,
13545
- unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13546
- serviceBindings: {
13547
- ...workerOptions.serviceBindings,
13548
- ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13549
- [workerConfig.assets.binding]: ASSET_WORKER_NAME
13550
- } : {},
13551
- __VITE_INVOKE_MODULE__: async (request) => {
13552
- const payload = await request.json();
13553
- const invokePayloadData = payload.data;
13554
- assert6(
13555
- invokePayloadData.name === "fetchModule",
13556
- `Invalid invoke event: ${invokePayloadData.name}`
13557
- );
13558
- const [moduleId] = invokePayloadData.data;
13559
- if (additionalModuleRE.test(moduleId)) {
13560
- const result2 = {
13561
- externalize: moduleId,
13562
- type: "module"
13563
- };
13564
- return MiniflareResponse.json({ result: result2 });
13550
+ const workersFromConfig = resolvedPluginConfig.type === "workers" ? await Promise.all(
13551
+ Object.entries(resolvedPluginConfig.workers).map(
13552
+ async ([environmentName, workerConfig]) => {
13553
+ const mixedModeSession = resolvedPluginConfig.experimental.mixedMode ? await maybeStartOrUpdateMixedModeSession(workerConfig) : void 0;
13554
+ const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13555
+ {
13556
+ ...workerConfig,
13557
+ assets: void 0
13558
+ },
13559
+ resolvedPluginConfig.cloudflareEnv,
13560
+ {
13561
+ mixedModeConnectionString: mixedModeSession?.mixedModeConnectionString,
13562
+ mixedModeEnabled: resolvedPluginConfig.experimental.mixedMode
13563
+ }
13564
+ );
13565
+ const { externalWorkers: externalWorkers2 } = miniflareWorkerOptions;
13566
+ const { ratelimits, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13567
+ return {
13568
+ externalWorkers: externalWorkers2,
13569
+ worker: {
13570
+ ...workerOptions,
13571
+ name: workerOptions.name ?? workerConfig.name,
13572
+ unsafeInspectorProxy: inspectorPort !== false,
13573
+ unsafeDirectSockets: environmentName === resolvedPluginConfig.entryWorkerEnvironmentName ? (
13574
+ // Expose the default entrypoint of the entry worker on the dev registry
13575
+ [{ entrypoint: void 0, proxy: true }]
13576
+ ) : [],
13577
+ modulesRoot: miniflareModulesRoot,
13578
+ unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13579
+ serviceBindings: {
13580
+ ...workerOptions.serviceBindings,
13581
+ ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13582
+ [workerConfig.assets.binding]: {
13583
+ node: (req, res) => {
13584
+ req[kRequestType] = "asset";
13585
+ viteDevServer.middlewares(req, res);
13586
+ }
13587
+ }
13588
+ } : {},
13589
+ __VITE_INVOKE_MODULE__: async (request) => {
13590
+ const payload = await request.json();
13591
+ const invokePayloadData = payload.data;
13592
+ assert6(
13593
+ invokePayloadData.name === "fetchModule",
13594
+ `Invalid invoke event: ${invokePayloadData.name}`
13595
+ );
13596
+ const [moduleId] = invokePayloadData.data;
13597
+ if (additionalModuleRE.test(moduleId)) {
13598
+ const result2 = {
13599
+ externalize: moduleId,
13600
+ type: "module"
13601
+ };
13602
+ return MiniflareResponse.json({ result: result2 });
13603
+ }
13604
+ const devEnvironment = viteDevServer.environments[environmentName];
13605
+ const result = await devEnvironment.hot.handleInvoke(payload);
13606
+ return MiniflareResponse.json(result);
13565
13607
  }
13566
- const devEnvironment = viteDevServer.environments[environmentName];
13567
- const result = await devEnvironment.hot.handleInvoke(payload);
13568
- return MiniflareResponse.json(result);
13569
13608
  }
13570
13609
  }
13571
- }
13572
- };
13573
- }
13610
+ };
13611
+ }
13612
+ )
13574
13613
  ) : [];
13575
13614
  const userWorkers = workersFromConfig.map((options) => options.worker);
13576
13615
  const externalWorkers = workersFromConfig.flatMap(
@@ -13582,8 +13621,10 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13582
13621
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13583
13622
  return {
13584
13623
  log: logger,
13624
+ logRequests: false,
13585
13625
  inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13586
13626
  unsafeInspectorProxy: inspectorPort !== false,
13627
+ unsafeDevRegistryPath: getDefaultDevRegistryPath(),
13587
13628
  handleRuntimeStdio(stdout, stderr) {
13588
13629
  const decoder = new TextDecoder();
13589
13630
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13591,7 +13632,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13591
13632
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13592
13633
  );
13593
13634
  },
13594
- ...getPersistence(
13635
+ defaultPersistRoot: getPersistenceRoot(
13595
13636
  resolvedViteConfig.root,
13596
13637
  resolvedPluginConfig.persistState
13597
13638
  ),
@@ -13637,6 +13678,11 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13637
13678
  `export const ${className} = createWorkflowEntrypointWrapper('${className}');`
13638
13679
  );
13639
13680
  }
13681
+ logUnknownTails(
13682
+ workerOptions.tails,
13683
+ userWorkers,
13684
+ viteDevServer.config.logger.warn
13685
+ );
13640
13686
  return {
13641
13687
  ...workerOptions,
13642
13688
  modules: [
@@ -13720,27 +13766,48 @@ function getPreviewModules(main, modulesRules) {
13720
13766
  ]
13721
13767
  };
13722
13768
  }
13723
- function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort) {
13769
+ async function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, mixedModeEnabled, inspectorPort) {
13724
13770
  const resolvedViteConfig = vitePreviewServer.config;
13725
- const workers = workerConfigs.flatMap((config) => {
13726
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
13727
- const { externalWorkers } = miniflareWorkerOptions;
13728
- const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13729
- return [
13730
- {
13731
- ...workerOptions,
13732
- name: workerOptions.name ?? config.name,
13733
- unsafeInspectorProxy: inspectorPort !== false,
13734
- ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13735
- },
13736
- ...externalWorkers
13737
- ];
13738
- });
13771
+ const workers = (await Promise.all(
13772
+ workerConfigs.map(async (workerConfig, i) => {
13773
+ const mixedModeSession = mixedModeEnabled ? await maybeStartOrUpdateMixedModeSession(workerConfig) : void 0;
13774
+ const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13775
+ workerConfig,
13776
+ void 0,
13777
+ {
13778
+ mixedModeConnectionString: mixedModeSession?.mixedModeConnectionString,
13779
+ mixedModeEnabled
13780
+ }
13781
+ );
13782
+ const { externalWorkers } = miniflareWorkerOptions;
13783
+ const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13784
+ logUnknownTails(
13785
+ workerOptions.tails,
13786
+ workerConfigs,
13787
+ vitePreviewServer.config.logger.warn
13788
+ );
13789
+ return [
13790
+ {
13791
+ ...workerOptions,
13792
+ name: workerOptions.name ?? workerConfig.name,
13793
+ unsafeInspectorProxy: inspectorPort !== false,
13794
+ unsafeDirectSockets: (
13795
+ // This exposes the default entrypoint of the entry worker on the dev registry
13796
+ // Assuming that the first worker config to be the entry worker.
13797
+ i === 0 ? [{ entrypoint: void 0, proxy: true }] : []
13798
+ ),
13799
+ ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13800
+ },
13801
+ ...externalWorkers
13802
+ ];
13803
+ })
13804
+ )).flat();
13739
13805
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13740
13806
  return {
13741
13807
  log: logger,
13742
13808
  inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13743
13809
  unsafeInspectorProxy: inspectorPort !== false,
13810
+ unsafeDevRegistryPath: getDefaultDevRegistryPath(),
13744
13811
  handleRuntimeStdio(stdout, stderr) {
13745
13812
  const decoder = new TextDecoder();
13746
13813
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13748,11 +13815,13 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13748
13815
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13749
13816
  );
13750
13817
  },
13751
- ...getPersistence(resolvedViteConfig.root, persistState),
13818
+ defaultPersistRoot: getPersistenceRoot(
13819
+ resolvedViteConfig.root,
13820
+ persistState
13821
+ ),
13752
13822
  workers
13753
13823
  };
13754
13824
  }
13755
- var removedMessages = [/^Ready on http/, /^Updated and ready on http/];
13756
13825
  var ViteMiniflareLogger = class extends Log {
13757
13826
  logger;
13758
13827
  constructor(config) {
@@ -13760,11 +13829,6 @@ var ViteMiniflareLogger = class extends Log {
13760
13829
  this.logger = config.logger;
13761
13830
  }
13762
13831
  logWithLevel(level, message) {
13763
- for (const removedMessage of removedMessages) {
13764
- if (removedMessage.test(message)) {
13765
- return;
13766
- }
13767
- }
13768
13832
  switch (level) {
13769
13833
  case LogLevel.ERROR:
13770
13834
  return this.logger.error(message);
@@ -13774,6 +13838,8 @@ var ViteMiniflareLogger = class extends Log {
13774
13838
  return this.logger.info(message);
13775
13839
  }
13776
13840
  }
13841
+ logReady() {
13842
+ }
13777
13843
  };
13778
13844
  function miniflareLogLevelFromViteLogLevel(level = "info") {
13779
13845
  switch (level) {
@@ -13787,6 +13853,24 @@ function miniflareLogLevelFromViteLogLevel(level = "info") {
13787
13853
  return LogLevel.NONE;
13788
13854
  }
13789
13855
  }
13856
+ var mixedModeSessionsMap = /* @__PURE__ */ new Map();
13857
+ async function maybeStartOrUpdateMixedModeSession(workerConfig) {
13858
+ const workerRemoteBindings = experimental_pickRemoteBindings(
13859
+ unstable_convertConfigBindingsToStartWorkerBindings(workerConfig) ?? {}
13860
+ );
13861
+ assert6(workerConfig.name, "Found workerConfig without a name");
13862
+ let mixedModeSession = mixedModeSessionsMap.get(workerConfig.name);
13863
+ if (mixedModeSession === void 0) {
13864
+ if (Object.keys(workerRemoteBindings).length > 0) {
13865
+ mixedModeSession = await experimental_startMixedModeSession(workerRemoteBindings);
13866
+ mixedModeSessionsMap.set(workerConfig.name, mixedModeSession);
13867
+ }
13868
+ } else {
13869
+ await mixedModeSession.updateBindings(workerRemoteBindings);
13870
+ }
13871
+ await mixedModeSession?.ready;
13872
+ return mixedModeSession;
13873
+ }
13790
13874
 
13791
13875
  // src/plugin-config.ts
13792
13876
  import assert8 from "node:assert";
@@ -13841,12 +13925,15 @@ var nullableNonApplicable = [
13841
13925
  "site",
13842
13926
  "tsconfig"
13843
13927
  ];
13844
- function readWorkerConfig(configPath, env2) {
13928
+ function readWorkerConfig(configPath, env2, mixedModeEnabled) {
13845
13929
  const nonApplicable = {
13846
13930
  replacedByVite: /* @__PURE__ */ new Set(),
13847
13931
  notRelevant: /* @__PURE__ */ new Set()
13848
13932
  };
13849
- const config = unstable_readConfig2({ config: configPath, env: env2 }, {});
13933
+ const config = unstable_readConfig2(
13934
+ { config: configPath, env: env2 },
13935
+ { experimental: { mixedModeEnabled } }
13936
+ );
13850
13937
  const raw = structuredClone(config);
13851
13938
  nullableNonApplicable.forEach((prop) => {
13852
13939
  if (config[prop] !== void 0) {
@@ -13941,11 +14028,15 @@ function isNotRelevant(configName) {
13941
14028
  function missingFieldErrorMessage(field, configPath, env2) {
13942
14029
  return `No ${field} field provided in '${configPath}'${env2 ? ` for '${env2}' environment` : ""}`;
13943
14030
  }
13944
- function getWorkerConfig(configPath, env2, opts) {
14031
+ function getWorkerConfig(configPath, env2, mixedModeEnabled, opts) {
13945
14032
  if (opts?.visitedConfigPaths?.has(configPath)) {
13946
14033
  throw new Error(`Duplicate Wrangler config path found: ${configPath}`);
13947
14034
  }
13948
- const { raw, config, nonApplicable } = readWorkerConfig(configPath, env2);
14035
+ const { raw, config, nonApplicable } = readWorkerConfig(
14036
+ configPath,
14037
+ env2,
14038
+ mixedModeEnabled
14039
+ );
13949
14040
  opts?.visitedConfigPaths?.add(configPath);
13950
14041
  if (!config.name) {
13951
14042
  throw new Error(missingFieldErrorMessage(`'name'`, configPath, env2));
@@ -14070,6 +14161,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14070
14161
  const entryWorkerResolvedConfig = getWorkerConfig(
14071
14162
  entryWorkerConfigPath,
14072
14163
  cloudflareEnv,
14164
+ pluginConfig.experimental?.mixedMode ?? false,
14073
14165
  {
14074
14166
  visitedConfigPaths: configPaths,
14075
14167
  isEntryWorker: true
@@ -14103,6 +14195,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14103
14195
  const workerResolvedConfig = getWorkerConfig(
14104
14196
  workerConfigPath,
14105
14197
  cloudflareEnv,
14198
+ pluginConfig.experimental?.mixedMode ?? false,
14106
14199
  {
14107
14200
  visitedConfigPaths: configPaths
14108
14201
  }
@@ -14137,6 +14230,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14137
14230
  }
14138
14231
 
14139
14232
  // src/websockets.ts
14233
+ import { createHeaders } from "@mjackson/node-fetch-server";
14140
14234
  import { coupleWebSocket } from "miniflare";
14141
14235
  import { WebSocketServer } from "ws";
14142
14236
  function handleWebSocket(httpServer, getFetcher) {
@@ -14148,7 +14242,7 @@ function handleWebSocket(httpServer, getFetcher) {
14148
14242
  if (request.headers["sec-websocket-protocol"]?.startsWith("vite")) {
14149
14243
  return;
14150
14244
  }
14151
- const headers = nodeHeadersToWebHeaders(request.headers);
14245
+ const headers = createHeaders(request);
14152
14246
  const fetcher = await getFetcher();
14153
14247
  const response = await fetcher(url, {
14154
14248
  headers,
@@ -14180,12 +14274,15 @@ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolve
14180
14274
  for (const envName of workersEnvironmentNames) {
14181
14275
  const workerEnvConfig = resolvedViteConfig.environments[envName];
14182
14276
  assert9(workerEnvConfig, `Missing environment config for "${envName}"`);
14183
- const { optimizeDeps, resolve: resolve8 } = workerEnvConfig;
14277
+ const { optimizeDeps, resolve: resolve7 } = workerEnvConfig;
14184
14278
  const disallowedConfig = {};
14185
14279
  const disallowedOptimizeDepsExcludeEntries = (optimizeDeps.exclude ?? []).filter((entry) => {
14186
14280
  if (cloudflareBuiltInModules.includes(entry)) {
14187
14281
  return false;
14188
14282
  }
14283
+ if (isNodeAlsModule(entry) && isNodeAls(resolvedPluginConfig.workers[envName])) {
14284
+ return false;
14285
+ }
14189
14286
  if (NODEJS_MODULES_RE.test(entry) && isNodeCompat(resolvedPluginConfig.workers[envName])) {
14190
14287
  return false;
14191
14288
  }
@@ -14194,8 +14291,8 @@ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolve
14194
14291
  if (disallowedOptimizeDepsExcludeEntries.length > 0) {
14195
14292
  disallowedConfig.optimizeDepsExclude = disallowedOptimizeDepsExcludeEntries;
14196
14293
  }
14197
- if (resolve8.external === true || resolve8.external.length > 0) {
14198
- disallowedConfig.resolveExternal = resolve8.external;
14294
+ if (resolve7.external === true || resolve7.external.length > 0) {
14295
+ disallowedConfig.resolveExternal = resolve7.external;
14199
14296
  }
14200
14297
  if (Object.keys(disallowedConfig).length > 0) {
14201
14298
  disallowedEnvsConfigs.set(envName, disallowedConfig);
@@ -14401,95 +14498,104 @@ function cloudflare2(pluginConfig = {}) {
14401
14498
  }
14402
14499
  },
14403
14500
  hotUpdate(options) {
14404
- if (
14405
- // Vite normalizes `options.file` so we use `path.resolve` for Windows compatibility
14406
- resolvedPluginConfig.configPaths.has(path9.resolve(options.file)) || hasAssetsConfigChanged(
14407
- resolvedPluginConfig,
14408
- resolvedViteConfig,
14409
- options.file
14410
- )
14411
- ) {
14501
+ const changedFilePath = path9.resolve(options.file);
14502
+ if (resolvedPluginConfig.configPaths.has(changedFilePath) || hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) || hasAssetsConfigChanged(
14503
+ resolvedPluginConfig,
14504
+ resolvedViteConfig,
14505
+ changedFilePath
14506
+ )) {
14412
14507
  options.server.restart();
14413
14508
  return [];
14414
14509
  }
14415
14510
  },
14416
14511
  async configureServer(viteDevServer) {
14417
- assert10(
14418
- viteDevServer.httpServer,
14419
- "Unexpected error: No Vite HTTP server"
14512
+ const inputInspectorPort = await getInputInspectorPortOption(
14513
+ pluginConfig,
14514
+ viteDevServer
14515
+ );
14516
+ const miniflareDevOptions = await getDevMiniflareOptions(
14517
+ resolvedPluginConfig,
14518
+ viteDevServer,
14519
+ inputInspectorPort
14420
14520
  );
14421
14521
  if (!miniflare) {
14422
- const inputInspectorPort = await getInputInspectorPortOption(
14423
- pluginConfig,
14424
- viteDevServer
14425
- );
14426
- miniflare = new Miniflare(
14427
- getDevMiniflareOptions(
14428
- resolvedPluginConfig,
14429
- viteDevServer,
14430
- inputInspectorPort
14431
- )
14432
- );
14522
+ miniflare = new Miniflare(miniflareDevOptions);
14433
14523
  } else {
14434
- const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14435
- await miniflare.setOptions(
14436
- getDevMiniflareOptions(
14437
- resolvedPluginConfig,
14438
- viteDevServer,
14439
- resolvedInspectorPort ?? false
14440
- )
14441
- );
14524
+ await miniflare.setOptions(miniflareDevOptions);
14442
14525
  }
14443
14526
  await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
14444
- const middleware = createMiddleware(
14445
- async ({ request }) => {
14527
+ if (viteDevServer.httpServer) {
14528
+ handleWebSocket(viteDevServer.httpServer, async () => {
14446
14529
  assert10(miniflare, `Miniflare not defined`);
14447
- const routerWorker = await getRouterWorker(miniflare);
14448
- return routerWorker.fetch(toMiniflareRequest(request), {
14449
- redirect: "manual"
14450
- });
14451
- },
14452
- { alwaysCallNext: false }
14453
- );
14454
- handleWebSocket(viteDevServer.httpServer, async () => {
14455
- assert10(miniflare, `Miniflare not defined`);
14456
- const routerWorker = await getRouterWorker(miniflare);
14457
- return routerWorker.fetch;
14458
- });
14530
+ const routerWorker = await miniflare.getWorker(ROUTER_WORKER_NAME);
14531
+ return routerWorker.fetch;
14532
+ });
14533
+ }
14459
14534
  return () => {
14460
- viteDevServer.middlewares.use((req, res, next) => {
14461
- middleware(req, res, next);
14535
+ viteDevServer.middlewares.use(async (req, res, next) => {
14536
+ try {
14537
+ assert10(miniflare, `Miniflare not defined`);
14538
+ const request = createRequest(req, res);
14539
+ let response;
14540
+ if (req[kRequestType] === "asset") {
14541
+ const assetWorker = await miniflare.getWorker(ASSET_WORKER_NAME);
14542
+ response = await assetWorker.fetch(
14543
+ toMiniflareRequest(request),
14544
+ { redirect: "manual" }
14545
+ );
14546
+ } else {
14547
+ const routerWorker = await miniflare.getWorker(ROUTER_WORKER_NAME);
14548
+ response = await routerWorker.fetch(
14549
+ toMiniflareRequest(request),
14550
+ { redirect: "manual" }
14551
+ );
14552
+ }
14553
+ if (req.httpVersionMajor === 2) {
14554
+ response.headers.delete("transfer-encoding");
14555
+ }
14556
+ await sendResponse(res, response);
14557
+ } catch (error) {
14558
+ next(error);
14559
+ }
14462
14560
  });
14463
14561
  };
14464
14562
  },
14465
14563
  async configurePreviewServer(vitePreviewServer) {
14466
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14564
+ const workerConfigs = getWorkerConfigs(
14565
+ vitePreviewServer.config.root,
14566
+ pluginConfig.experimental?.mixedMode ?? false
14567
+ );
14467
14568
  const inputInspectorPort = await getInputInspectorPortOption(
14468
14569
  pluginConfig,
14469
14570
  vitePreviewServer
14470
14571
  );
14471
14572
  const miniflare2 = new Miniflare(
14472
- getPreviewMiniflareOptions(
14573
+ await getPreviewMiniflareOptions(
14473
14574
  vitePreviewServer,
14474
14575
  workerConfigs,
14475
14576
  pluginConfig.persistState ?? true,
14577
+ !!pluginConfig.experimental?.mixedMode,
14476
14578
  inputInspectorPort
14477
14579
  )
14478
14580
  );
14479
- const middleware = createMiddleware(
14480
- ({ request }) => {
14481
- return miniflare2.dispatchFetch(toMiniflareRequest(request), {
14482
- redirect: "manual"
14483
- });
14484
- },
14485
- { alwaysCallNext: false }
14486
- );
14487
14581
  handleWebSocket(
14488
14582
  vitePreviewServer.httpServer,
14489
14583
  () => miniflare2.dispatchFetch
14490
14584
  );
14491
- vitePreviewServer.middlewares.use((req, res, next) => {
14492
- middleware(req, res, next);
14585
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14586
+ try {
14587
+ const request = createRequest(req, res);
14588
+ const response = await miniflare2.dispatchFetch(
14589
+ toMiniflareRequest(request),
14590
+ { redirect: "manual" }
14591
+ );
14592
+ if (req.httpVersionMajor === 2) {
14593
+ response.headers.delete("transfer-encoding");
14594
+ }
14595
+ await sendResponse(res, response);
14596
+ } catch (error) {
14597
+ next(error);
14598
+ }
14493
14599
  });
14494
14600
  }
14495
14601
  },
@@ -14598,6 +14704,18 @@ function cloudflare2(pluginConfig = {}) {
14598
14704
  configEnvironment(name) {
14599
14705
  if (isNodeCompat(getWorkerConfig2(name))) {
14600
14706
  return {
14707
+ build: {
14708
+ rollupOptions: {
14709
+ plugins: [
14710
+ replace({
14711
+ "process.env.NODE_ENV": JSON.stringify(
14712
+ process.env.NODE_ENV ?? "production"
14713
+ ),
14714
+ preventAssignment: true
14715
+ })
14716
+ ]
14717
+ }
14718
+ },
14601
14719
  resolve: {
14602
14720
  builtins: [...nodeCompatExternals]
14603
14721
  },
@@ -14639,7 +14757,9 @@ function cloudflare2(pluginConfig = {}) {
14639
14757
  },
14640
14758
  async transform(code, id) {
14641
14759
  const workerConfig = getWorkerConfig2(this.environment.name);
14642
- assert10(workerConfig, "Expected a worker config");
14760
+ if (!workerConfig) {
14761
+ return;
14762
+ }
14643
14763
  const resolvedId = await this.resolve(workerConfig.main);
14644
14764
  if (id === resolvedId?.id) {
14645
14765
  return injectGlobalCode(id, code);
@@ -14668,6 +14788,25 @@ function cloudflare2(pluginConfig = {}) {
14668
14788
  );
14669
14789
  }
14670
14790
  },
14791
+ // Plugin that handles Node.js Async Local Storage (ALS) compatibility support for Vite Environments that are hosted in Cloudflare Workers.
14792
+ {
14793
+ name: "vite-plugin-cloudflare:nodejs-als",
14794
+ apply(_config, env2) {
14795
+ return !env2.isPreview;
14796
+ },
14797
+ configEnvironment(name, config) {
14798
+ if (isNodeAls(getWorkerConfig2(name))) {
14799
+ return {
14800
+ resolve: {
14801
+ builtins: ["async_hooks", "node:async_hooks"]
14802
+ },
14803
+ optimizeDeps: {
14804
+ exclude: ["async_hooks", "node:async_hooks"]
14805
+ }
14806
+ };
14807
+ }
14808
+ }
14809
+ },
14671
14810
  // Plugin that provides an __debug path for debugging the Cloudflare Workers.
14672
14811
  {
14673
14812
  name: "vite-plugin-cloudflare:debug",
@@ -14692,7 +14831,10 @@ function cloudflare2(pluginConfig = {}) {
14692
14831
  });
14693
14832
  },
14694
14833
  async configurePreviewServer(vitePreviewServer) {
14695
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14834
+ const workerConfigs = getWorkerConfigs(
14835
+ vitePreviewServer.config.root,
14836
+ pluginConfig.experimental?.mixedMode ?? false
14837
+ );
14696
14838
  if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
14697
14839
  addDebugToVitePrintUrls(vitePreviewServer);
14698
14840
  }
@@ -14733,6 +14875,9 @@ function cloudflare2(pluginConfig = {}) {
14733
14875
  build.onResolve(
14734
14876
  { filter: NODEJS_MODULES_RE },
14735
14877
  ({ path: path10, importer }) => {
14878
+ if (isNodeAls(workerConfig) && isNodeAlsModule(path10)) {
14879
+ return;
14880
+ }
14736
14881
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14737
14882
  nodeJsCompatWarnings?.registerImport(path10, importer);
14738
14883
  return { path: path10, external: true };
@@ -14762,6 +14907,9 @@ function cloudflare2(pluginConfig = {}) {
14762
14907
  async resolveId(source, importer) {
14763
14908
  const workerConfig = getWorkerConfig2(this.environment.name);
14764
14909
  if (workerConfig && !isNodeCompat(workerConfig)) {
14910
+ if (isNodeAls(workerConfig) && isNodeAlsModule(source)) {
14911
+ return;
14912
+ }
14765
14913
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14766
14914
  if (nodejsBuiltins.has(source)) {
14767
14915
  nodeJsCompatWarnings?.registerImport(source, importer);
@@ -14780,10 +14928,16 @@ function cloudflare2(pluginConfig = {}) {
14780
14928
  }
14781
14929
  }
14782
14930
  async function getInputInspectorPortOption(pluginConfig, viteServer) {
14931
+ if (pluginConfig.inspectorPort === void 0 || pluginConfig.inspectorPort === 0) {
14932
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14933
+ if (resolvedInspectorPort !== null) {
14934
+ return resolvedInspectorPort;
14935
+ }
14936
+ }
14783
14937
  const inputInspectorPort = pluginConfig.inspectorPort ?? await getFirstAvailablePort(DEFAULT_INSPECTOR_PORT);
14784
14938
  if (pluginConfig.inspectorPort === void 0 && inputInspectorPort !== DEFAULT_INSPECTOR_PORT) {
14785
14939
  viteServer.config.logger.warn(
14786
- colors2.dim(
14940
+ colors3.dim(
14787
14941
  `Default inspector port ${DEFAULT_INSPECTOR_PORT} not available, using ${inputInspectorPort} instead
14788
14942
  `
14789
14943
  )
@@ -14809,6 +14963,19 @@ function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14809
14963
  }
14810
14964
  return null;
14811
14965
  }
14966
+ function hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) {
14967
+ return [...resolvedPluginConfig.configPaths].some((configPath) => {
14968
+ const dotDevDotVars = path9.join(path9.dirname(configPath), ".dev.vars");
14969
+ if (dotDevDotVars === changedFilePath) {
14970
+ return true;
14971
+ }
14972
+ if (resolvedPluginConfig.cloudflareEnv) {
14973
+ const dotDevDotVarsForEnv = `${dotDevDotVars}.${resolvedPluginConfig.cloudflareEnv}`;
14974
+ return dotDevDotVarsForEnv === changedFilePath;
14975
+ }
14976
+ return false;
14977
+ });
14978
+ }
14812
14979
  export {
14813
14980
  cloudflare2 as cloudflare
14814
14981
  };