@cloudflare/vite-plugin 0.0.0-abffd425c → 0.0.0-ac0f1ad4c

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,7 @@ 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
493
  import replace from "@rollup/plugin-replace";
494
494
 
495
495
  // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
@@ -1558,7 +1558,7 @@ var MagicString = class _MagicString {
1558
1558
 
1559
1559
  // src/index.ts
1560
1560
  import { Miniflare } from "miniflare";
1561
- import colors2 from "picocolors";
1561
+ import colors3 from "picocolors";
1562
1562
  import * as vite7 from "vite";
1563
1563
 
1564
1564
  // src/constants.ts
@@ -1589,7 +1589,7 @@ function matchAdditionalModule(source) {
1589
1589
  return null;
1590
1590
  }
1591
1591
  function createModuleReference(type, id) {
1592
- return `__CLOUDFLARE_MODULE__${type}__${id}__`;
1592
+ return `__CLOUDFLARE_MODULE__${type}__${id}__CLOUDFLARE_MODULE__`;
1593
1593
  }
1594
1594
 
1595
1595
  // src/asset-config.ts
@@ -5784,7 +5784,8 @@ var z = /* @__PURE__ */ Object.freeze({
5784
5784
  // ../workers-shared/utils/types.ts
5785
5785
  var InternalConfigSchema = z.object({
5786
5786
  account_id: z.number().optional(),
5787
- script_id: z.number().optional()
5787
+ script_id: z.number().optional(),
5788
+ debug: z.boolean().optional()
5788
5789
  });
5789
5790
  var RouterConfigSchema = z.object({
5790
5791
  invoke_user_worker_ahead_of_assets: z.boolean().optional(),
@@ -5832,14 +5833,14 @@ var AssetConfigSchema = z.object({
5832
5833
  });
5833
5834
 
5834
5835
  // src/asset-config.ts
5835
- function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFile) {
5836
+ function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFilePath) {
5836
5837
  if (!resolvedPluginConfig.experimental?.headersAndRedirectsDevModeSupport) {
5837
5838
  return false;
5838
5839
  }
5839
5840
  return [
5840
5841
  getRedirectsConfigPath(resolvedViteConfig),
5841
5842
  getHeadersConfigPath(resolvedViteConfig)
5842
- ].includes(path.resolve(changedFile));
5843
+ ].includes(changedFilePath);
5843
5844
  }
5844
5845
  function getAssetsConfig(resolvedPluginConfig, entryWorkerConfig, resolvedConfig) {
5845
5846
  const assetsConfig = resolvedPluginConfig.type === "assets-only" ? resolvedPluginConfig.config.assets : entryWorkerConfig?.assets;
@@ -12880,6 +12881,15 @@ function isNodeCompat(workerConfig) {
12880
12881
  }
12881
12882
  return false;
12882
12883
  }
12884
+ function isNodeAls(workerConfig) {
12885
+ return workerConfig !== void 0 && getNodeCompat(
12886
+ workerConfig.compatibility_date,
12887
+ workerConfig.compatibility_flags ?? []
12888
+ ).mode === "als";
12889
+ }
12890
+ function isNodeAlsModule(path10) {
12891
+ return /^(node:)?async_hooks$/.test(path10);
12892
+ }
12883
12893
  function injectGlobalCode(id, code) {
12884
12894
  const injectedCode = Object.entries(env.inject).map(([globalName, globalInject]) => {
12885
12895
  if (typeof globalInject === "string") {
@@ -12910,7 +12920,7 @@ globalThis.${globalName} = var_${globalName}.${exportName};
12910
12920
  }
12911
12921
  function resolveNodeJSImport(source) {
12912
12922
  const alias = env.alias[source];
12913
- if (alias) {
12923
+ if (alias && !nodeCompatExternals.has(alias)) {
12914
12924
  return {
12915
12925
  unresolved: alias,
12916
12926
  resolved: resolvePathSync(alias, { url: import.meta.url })
@@ -12983,7 +12993,7 @@ var NodeJsCompatWarnings = class {
12983
12993
  // src/shared.ts
12984
12994
  var UNKNOWN_HOST = "http://localhost";
12985
12995
  var INIT_PATH = "/__vite_plugin_cloudflare_init__";
12986
- var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__`;
12996
+ var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__CLOUDFLARE_MODULE__`;
12987
12997
  var additionalModuleRE = new RegExp(ADDITIONAL_MODULE_PATTERN);
12988
12998
  var additionalModuleGlobalRE = new RegExp(
12989
12999
  ADDITIONAL_MODULE_PATTERN,
@@ -13019,19 +13029,6 @@ function toMiniflareRequest(request) {
13019
13029
  duplex: "half"
13020
13030
  });
13021
13031
  }
13022
- function nodeHeadersToWebHeaders(nodeHeaders) {
13023
- const headers = new Headers();
13024
- for (const [key, value] of Object.entries(nodeHeaders)) {
13025
- if (typeof value === "string") {
13026
- headers.append(key, value);
13027
- } else if (Array.isArray(value)) {
13028
- for (const item of value) {
13029
- headers.append(key, item);
13030
- }
13031
- }
13032
- }
13033
- return headers;
13034
- }
13035
13032
  var postfixRE = /[?#].*$/;
13036
13033
  function cleanUrl(url) {
13037
13034
  return url.replace(postfixRE, "");
@@ -13260,7 +13257,7 @@ import { unstable_readConfig } from "wrangler";
13260
13257
  function getDeployConfigPath(root) {
13261
13258
  return path5.resolve(root, ".wrangler", "deploy", "config.json");
13262
13259
  }
13263
- function getWorkerConfigs(root) {
13260
+ function getWorkerConfigs(root, mixedModeEnabled) {
13264
13261
  const deployConfigPath = getDeployConfigPath(root);
13265
13262
  const deployConfig = JSON.parse(
13266
13263
  fs2.readFileSync(deployConfigPath, "utf-8")
@@ -13273,7 +13270,10 @@ function getWorkerConfigs(root) {
13273
13270
  path5.dirname(deployConfigPath),
13274
13271
  configPath
13275
13272
  );
13276
- return unstable_readConfig({ config: resolvedConfigPath });
13273
+ return unstable_readConfig(
13274
+ { config: resolvedConfigPath },
13275
+ { experimental: { mixedModeEnabled } }
13276
+ );
13277
13277
  });
13278
13278
  }
13279
13279
  function getRelativePathToWorkerConfig(deployConfigDirectory, root, outputDirectory) {
@@ -13345,12 +13345,18 @@ import {
13345
13345
  LogLevel,
13346
13346
  Response as MiniflareResponse
13347
13347
  } from "miniflare";
13348
+ import colors2 from "picocolors";
13348
13349
  import { globSync } from "tinyglobby";
13349
13350
  import "vite";
13350
- import { unstable_getMiniflareWorkerOptions } from "wrangler";
13351
- function getPersistence(root, persistState) {
13351
+ import {
13352
+ experimental_pickRemoteBindings,
13353
+ experimental_startMixedModeSession,
13354
+ unstable_convertConfigBindingsToStartWorkerBindings,
13355
+ unstable_getMiniflareWorkerOptions
13356
+ } from "wrangler";
13357
+ function getPersistenceRoot(root, persistState) {
13352
13358
  if (persistState === false) {
13353
- return {};
13359
+ return;
13354
13360
  }
13355
13361
  const defaultPersistPath = ".wrangler/state";
13356
13362
  const persistPath = path6.resolve(
@@ -13358,14 +13364,7 @@ function getPersistence(root, persistState) {
13358
13364
  typeof persistState === "object" ? persistState.path : defaultPersistPath,
13359
13365
  "v3"
13360
13366
  );
13361
- return {
13362
- cachePersist: path6.join(persistPath, "cache"),
13363
- d1Persist: path6.join(persistPath, "d1"),
13364
- durableObjectsPersist: path6.join(persistPath, "do"),
13365
- kvPersist: path6.join(persistPath, "kv"),
13366
- r2Persist: path6.join(persistPath, "r2"),
13367
- workflowsPersist: path6.join(persistPath, "workflows")
13368
- };
13367
+ return persistPath;
13369
13368
  }
13370
13369
  function missingWorkerErrorMessage(workerName) {
13371
13370
  return `${workerName} does not match a worker name.`;
@@ -13449,7 +13448,30 @@ function getEntryWorkerConfig(resolvedPluginConfig) {
13449
13448
  }
13450
13449
  return resolvedPluginConfig.workers[resolvedPluginConfig.entryWorkerEnvironmentName];
13451
13450
  }
13452
- function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13451
+ function filterTails(tails, userWorkers, log) {
13452
+ return tails?.filter((tailService) => {
13453
+ let name;
13454
+ if (typeof tailService === "string") {
13455
+ name = tailService;
13456
+ } else if (typeof tailService === "object" && "name" in tailService && typeof tailService.name === "string") {
13457
+ name = tailService.name;
13458
+ } else {
13459
+ return true;
13460
+ }
13461
+ const found = userWorkers.some((w) => w.name === name);
13462
+ if (!found) {
13463
+ log(
13464
+ colors2.dim(
13465
+ colors2.yellow(
13466
+ `Tail consumer "${name}" was not found in your config. Make sure you add it if you'd like to simulate receiving tail events locally.`
13467
+ )
13468
+ )
13469
+ );
13470
+ }
13471
+ return found;
13472
+ });
13473
+ }
13474
+ async function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13453
13475
  const resolvedViteConfig = viteDevServer.config;
13454
13476
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
13455
13477
  const assetsConfig = getAssetsConfig(
@@ -13525,53 +13547,60 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13525
13547
  }
13526
13548
  }
13527
13549
  ];
13528
- const workersFromConfig = resolvedPluginConfig.type === "workers" ? Object.entries(resolvedPluginConfig.workers).map(
13529
- ([environmentName, workerConfig]) => {
13530
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13531
- {
13532
- ...workerConfig,
13533
- assets: void 0
13534
- },
13535
- resolvedPluginConfig.cloudflareEnv
13536
- );
13537
- const { externalWorkers: externalWorkers2 } = miniflareWorkerOptions;
13538
- const { ratelimits, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13539
- return {
13540
- externalWorkers: externalWorkers2,
13541
- worker: {
13542
- ...workerOptions,
13543
- name: workerOptions.name ?? workerConfig.name,
13544
- unsafeInspectorProxy: inspectorPort !== false,
13545
- modulesRoot: miniflareModulesRoot,
13546
- unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13547
- serviceBindings: {
13548
- ...workerOptions.serviceBindings,
13549
- ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13550
- [workerConfig.assets.binding]: ASSET_WORKER_NAME
13551
- } : {},
13552
- __VITE_INVOKE_MODULE__: async (request) => {
13553
- const payload = await request.json();
13554
- const invokePayloadData = payload.data;
13555
- assert6(
13556
- invokePayloadData.name === "fetchModule",
13557
- `Invalid invoke event: ${invokePayloadData.name}`
13558
- );
13559
- const [moduleId] = invokePayloadData.data;
13560
- if (additionalModuleRE.test(moduleId)) {
13561
- const result2 = {
13562
- externalize: moduleId,
13563
- type: "module"
13564
- };
13565
- 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
+ modulesRoot: miniflareModulesRoot,
13574
+ unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13575
+ serviceBindings: {
13576
+ ...workerOptions.serviceBindings,
13577
+ ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13578
+ [workerConfig.assets.binding]: ASSET_WORKER_NAME
13579
+ } : {},
13580
+ __VITE_INVOKE_MODULE__: async (request) => {
13581
+ const payload = await request.json();
13582
+ const invokePayloadData = payload.data;
13583
+ assert6(
13584
+ invokePayloadData.name === "fetchModule",
13585
+ `Invalid invoke event: ${invokePayloadData.name}`
13586
+ );
13587
+ const [moduleId] = invokePayloadData.data;
13588
+ if (additionalModuleRE.test(moduleId)) {
13589
+ const result2 = {
13590
+ externalize: moduleId,
13591
+ type: "module"
13592
+ };
13593
+ return MiniflareResponse.json({ result: result2 });
13594
+ }
13595
+ const devEnvironment = viteDevServer.environments[environmentName];
13596
+ const result = await devEnvironment.hot.handleInvoke(payload);
13597
+ return MiniflareResponse.json(result);
13566
13598
  }
13567
- const devEnvironment = viteDevServer.environments[environmentName];
13568
- const result = await devEnvironment.hot.handleInvoke(payload);
13569
- return MiniflareResponse.json(result);
13570
13599
  }
13571
13600
  }
13572
- }
13573
- };
13574
- }
13601
+ };
13602
+ }
13603
+ )
13575
13604
  ) : [];
13576
13605
  const userWorkers = workersFromConfig.map((options) => options.worker);
13577
13606
  const externalWorkers = workersFromConfig.flatMap(
@@ -13583,6 +13612,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13583
13612
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13584
13613
  return {
13585
13614
  log: logger,
13615
+ logRequests: false,
13586
13616
  inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13587
13617
  unsafeInspectorProxy: inspectorPort !== false,
13588
13618
  handleRuntimeStdio(stdout, stderr) {
@@ -13592,7 +13622,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13592
13622
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13593
13623
  );
13594
13624
  },
13595
- ...getPersistence(
13625
+ defaultPersistRoot: getPersistenceRoot(
13596
13626
  resolvedViteConfig.root,
13597
13627
  resolvedPluginConfig.persistState
13598
13628
  ),
@@ -13640,6 +13670,11 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13640
13670
  }
13641
13671
  return {
13642
13672
  ...workerOptions,
13673
+ tails: filterTails(
13674
+ workerOptions.tails,
13675
+ userWorkers,
13676
+ viteDevServer.config.logger.warn
13677
+ ),
13643
13678
  modules: [
13644
13679
  {
13645
13680
  type: "ESModule",
@@ -13721,22 +13756,37 @@ function getPreviewModules(main, modulesRules) {
13721
13756
  ]
13722
13757
  };
13723
13758
  }
13724
- function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort) {
13759
+ async function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, mixedModeEnabled, inspectorPort) {
13725
13760
  const resolvedViteConfig = vitePreviewServer.config;
13726
- const workers = workerConfigs.flatMap((config) => {
13727
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
13728
- const { externalWorkers } = miniflareWorkerOptions;
13729
- const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13730
- return [
13731
- {
13732
- ...workerOptions,
13733
- name: workerOptions.name ?? config.name,
13734
- unsafeInspectorProxy: inspectorPort !== false,
13735
- ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13736
- },
13737
- ...externalWorkers
13738
- ];
13739
- });
13761
+ const workers = (await Promise.all(
13762
+ workerConfigs.map(async (workerConfig) => {
13763
+ const mixedModeSession = mixedModeEnabled ? await maybeStartOrUpdateMixedModeSession(workerConfig) : void 0;
13764
+ const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13765
+ workerConfig,
13766
+ void 0,
13767
+ {
13768
+ mixedModeConnectionString: mixedModeSession?.mixedModeConnectionString,
13769
+ mixedModeEnabled
13770
+ }
13771
+ );
13772
+ const { externalWorkers } = miniflareWorkerOptions;
13773
+ const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13774
+ return [
13775
+ {
13776
+ ...workerOptions,
13777
+ tails: filterTails(
13778
+ workerOptions.tails,
13779
+ workerConfigs,
13780
+ vitePreviewServer.config.logger.warn
13781
+ ),
13782
+ name: workerOptions.name ?? workerConfig.name,
13783
+ unsafeInspectorProxy: inspectorPort !== false,
13784
+ ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13785
+ },
13786
+ ...externalWorkers
13787
+ ];
13788
+ })
13789
+ )).flat();
13740
13790
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13741
13791
  return {
13742
13792
  log: logger,
@@ -13749,11 +13799,13 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13749
13799
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13750
13800
  );
13751
13801
  },
13752
- ...getPersistence(resolvedViteConfig.root, persistState),
13802
+ defaultPersistRoot: getPersistenceRoot(
13803
+ resolvedViteConfig.root,
13804
+ persistState
13805
+ ),
13753
13806
  workers
13754
13807
  };
13755
13808
  }
13756
- var removedMessages = [/^Ready on http/, /^Updated and ready on http/];
13757
13809
  var ViteMiniflareLogger = class extends Log {
13758
13810
  logger;
13759
13811
  constructor(config) {
@@ -13761,11 +13813,6 @@ var ViteMiniflareLogger = class extends Log {
13761
13813
  this.logger = config.logger;
13762
13814
  }
13763
13815
  logWithLevel(level, message) {
13764
- for (const removedMessage of removedMessages) {
13765
- if (removedMessage.test(message)) {
13766
- return;
13767
- }
13768
- }
13769
13816
  switch (level) {
13770
13817
  case LogLevel.ERROR:
13771
13818
  return this.logger.error(message);
@@ -13775,6 +13822,8 @@ var ViteMiniflareLogger = class extends Log {
13775
13822
  return this.logger.info(message);
13776
13823
  }
13777
13824
  }
13825
+ logReady() {
13826
+ }
13778
13827
  };
13779
13828
  function miniflareLogLevelFromViteLogLevel(level = "info") {
13780
13829
  switch (level) {
@@ -13788,6 +13837,24 @@ function miniflareLogLevelFromViteLogLevel(level = "info") {
13788
13837
  return LogLevel.NONE;
13789
13838
  }
13790
13839
  }
13840
+ var mixedModeSessionsMap = /* @__PURE__ */ new Map();
13841
+ async function maybeStartOrUpdateMixedModeSession(workerConfig) {
13842
+ const workerRemoteBindings = experimental_pickRemoteBindings(
13843
+ unstable_convertConfigBindingsToStartWorkerBindings(workerConfig) ?? {}
13844
+ );
13845
+ assert6(workerConfig.name, "Found workerConfig without a name");
13846
+ let mixedModeSession = mixedModeSessionsMap.get(workerConfig.name);
13847
+ if (mixedModeSession === void 0) {
13848
+ if (Object.keys(workerRemoteBindings).length > 0) {
13849
+ mixedModeSession = await experimental_startMixedModeSession(workerRemoteBindings);
13850
+ mixedModeSessionsMap.set(workerConfig.name, mixedModeSession);
13851
+ }
13852
+ } else {
13853
+ await mixedModeSession.updateBindings(workerRemoteBindings);
13854
+ }
13855
+ await mixedModeSession?.ready;
13856
+ return mixedModeSession;
13857
+ }
13791
13858
 
13792
13859
  // src/plugin-config.ts
13793
13860
  import assert8 from "node:assert";
@@ -13842,12 +13909,15 @@ var nullableNonApplicable = [
13842
13909
  "site",
13843
13910
  "tsconfig"
13844
13911
  ];
13845
- function readWorkerConfig(configPath, env2) {
13912
+ function readWorkerConfig(configPath, env2, mixedModeEnabled) {
13846
13913
  const nonApplicable = {
13847
13914
  replacedByVite: /* @__PURE__ */ new Set(),
13848
13915
  notRelevant: /* @__PURE__ */ new Set()
13849
13916
  };
13850
- const config = unstable_readConfig2({ config: configPath, env: env2 }, {});
13917
+ const config = unstable_readConfig2(
13918
+ { config: configPath, env: env2 },
13919
+ { experimental: { mixedModeEnabled } }
13920
+ );
13851
13921
  const raw = structuredClone(config);
13852
13922
  nullableNonApplicable.forEach((prop) => {
13853
13923
  if (config[prop] !== void 0) {
@@ -13942,11 +14012,15 @@ function isNotRelevant(configName) {
13942
14012
  function missingFieldErrorMessage(field, configPath, env2) {
13943
14013
  return `No ${field} field provided in '${configPath}'${env2 ? ` for '${env2}' environment` : ""}`;
13944
14014
  }
13945
- function getWorkerConfig(configPath, env2, opts) {
14015
+ function getWorkerConfig(configPath, env2, mixedModeEnabled, opts) {
13946
14016
  if (opts?.visitedConfigPaths?.has(configPath)) {
13947
14017
  throw new Error(`Duplicate Wrangler config path found: ${configPath}`);
13948
14018
  }
13949
- const { raw, config, nonApplicable } = readWorkerConfig(configPath, env2);
14019
+ const { raw, config, nonApplicable } = readWorkerConfig(
14020
+ configPath,
14021
+ env2,
14022
+ mixedModeEnabled
14023
+ );
13950
14024
  opts?.visitedConfigPaths?.add(configPath);
13951
14025
  if (!config.name) {
13952
14026
  throw new Error(missingFieldErrorMessage(`'name'`, configPath, env2));
@@ -14071,6 +14145,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14071
14145
  const entryWorkerResolvedConfig = getWorkerConfig(
14072
14146
  entryWorkerConfigPath,
14073
14147
  cloudflareEnv,
14148
+ pluginConfig.experimental?.mixedMode ?? false,
14074
14149
  {
14075
14150
  visitedConfigPaths: configPaths,
14076
14151
  isEntryWorker: true
@@ -14104,6 +14179,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14104
14179
  const workerResolvedConfig = getWorkerConfig(
14105
14180
  workerConfigPath,
14106
14181
  cloudflareEnv,
14182
+ pluginConfig.experimental?.mixedMode ?? false,
14107
14183
  {
14108
14184
  visitedConfigPaths: configPaths
14109
14185
  }
@@ -14138,6 +14214,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14138
14214
  }
14139
14215
 
14140
14216
  // src/websockets.ts
14217
+ import { createHeaders } from "@mjackson/node-fetch-server";
14141
14218
  import { coupleWebSocket } from "miniflare";
14142
14219
  import { WebSocketServer } from "ws";
14143
14220
  function handleWebSocket(httpServer, getFetcher) {
@@ -14149,7 +14226,7 @@ function handleWebSocket(httpServer, getFetcher) {
14149
14226
  if (request.headers["sec-websocket-protocol"]?.startsWith("vite")) {
14150
14227
  return;
14151
14228
  }
14152
- const headers = nodeHeadersToWebHeaders(request.headers);
14229
+ const headers = createHeaders(request);
14153
14230
  const fetcher = await getFetcher();
14154
14231
  const response = await fetcher(url, {
14155
14232
  headers,
@@ -14181,12 +14258,15 @@ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolve
14181
14258
  for (const envName of workersEnvironmentNames) {
14182
14259
  const workerEnvConfig = resolvedViteConfig.environments[envName];
14183
14260
  assert9(workerEnvConfig, `Missing environment config for "${envName}"`);
14184
- const { optimizeDeps, resolve: resolve8 } = workerEnvConfig;
14261
+ const { optimizeDeps, resolve: resolve7 } = workerEnvConfig;
14185
14262
  const disallowedConfig = {};
14186
14263
  const disallowedOptimizeDepsExcludeEntries = (optimizeDeps.exclude ?? []).filter((entry) => {
14187
14264
  if (cloudflareBuiltInModules.includes(entry)) {
14188
14265
  return false;
14189
14266
  }
14267
+ if (isNodeAlsModule(entry) && isNodeAls(resolvedPluginConfig.workers[envName])) {
14268
+ return false;
14269
+ }
14190
14270
  if (NODEJS_MODULES_RE.test(entry) && isNodeCompat(resolvedPluginConfig.workers[envName])) {
14191
14271
  return false;
14192
14272
  }
@@ -14195,8 +14275,8 @@ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolve
14195
14275
  if (disallowedOptimizeDepsExcludeEntries.length > 0) {
14196
14276
  disallowedConfig.optimizeDepsExclude = disallowedOptimizeDepsExcludeEntries;
14197
14277
  }
14198
- if (resolve8.external === true || resolve8.external.length > 0) {
14199
- disallowedConfig.resolveExternal = resolve8.external;
14278
+ if (resolve7.external === true || resolve7.external.length > 0) {
14279
+ disallowedConfig.resolveExternal = resolve7.external;
14200
14280
  }
14201
14281
  if (Object.keys(disallowedConfig).length > 0) {
14202
14282
  disallowedEnvsConfigs.set(envName, disallowedConfig);
@@ -14402,95 +14482,97 @@ function cloudflare2(pluginConfig = {}) {
14402
14482
  }
14403
14483
  },
14404
14484
  hotUpdate(options) {
14405
- if (
14406
- // Vite normalizes `options.file` so we use `path.resolve` for Windows compatibility
14407
- resolvedPluginConfig.configPaths.has(path9.resolve(options.file)) || hasAssetsConfigChanged(
14408
- resolvedPluginConfig,
14409
- resolvedViteConfig,
14410
- options.file
14411
- )
14412
- ) {
14485
+ const changedFilePath = path9.resolve(options.file);
14486
+ if (resolvedPluginConfig.configPaths.has(changedFilePath) || hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) || hasAssetsConfigChanged(
14487
+ resolvedPluginConfig,
14488
+ resolvedViteConfig,
14489
+ changedFilePath
14490
+ )) {
14413
14491
  options.server.restart();
14414
14492
  return [];
14415
14493
  }
14416
14494
  },
14417
14495
  async configureServer(viteDevServer) {
14418
- assert10(
14419
- viteDevServer.httpServer,
14420
- "Unexpected error: No Vite HTTP server"
14496
+ const inputInspectorPort = await getInputInspectorPortOption(
14497
+ pluginConfig,
14498
+ viteDevServer
14499
+ );
14500
+ const miniflareDevOptions = await getDevMiniflareOptions(
14501
+ resolvedPluginConfig,
14502
+ viteDevServer,
14503
+ inputInspectorPort
14421
14504
  );
14422
14505
  if (!miniflare) {
14423
- const inputInspectorPort = await getInputInspectorPortOption(
14424
- pluginConfig,
14425
- viteDevServer
14426
- );
14427
- miniflare = new Miniflare(
14428
- getDevMiniflareOptions(
14429
- resolvedPluginConfig,
14430
- viteDevServer,
14431
- inputInspectorPort
14432
- )
14433
- );
14506
+ miniflare = new Miniflare(miniflareDevOptions);
14434
14507
  } else {
14435
- const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14436
- await miniflare.setOptions(
14437
- getDevMiniflareOptions(
14438
- resolvedPluginConfig,
14439
- viteDevServer,
14440
- resolvedInspectorPort ?? false
14441
- )
14442
- );
14508
+ await miniflare.setOptions(miniflareDevOptions);
14443
14509
  }
14444
14510
  await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
14445
- const middleware = createMiddleware(
14446
- async ({ request }) => {
14511
+ if (viteDevServer.httpServer) {
14512
+ handleWebSocket(viteDevServer.httpServer, async () => {
14447
14513
  assert10(miniflare, `Miniflare not defined`);
14448
14514
  const routerWorker = await getRouterWorker(miniflare);
14449
- return routerWorker.fetch(toMiniflareRequest(request), {
14450
- redirect: "manual"
14451
- });
14452
- },
14453
- { alwaysCallNext: false }
14454
- );
14455
- handleWebSocket(viteDevServer.httpServer, async () => {
14456
- assert10(miniflare, `Miniflare not defined`);
14457
- const routerWorker = await getRouterWorker(miniflare);
14458
- return routerWorker.fetch;
14459
- });
14515
+ return routerWorker.fetch;
14516
+ });
14517
+ }
14460
14518
  return () => {
14461
- viteDevServer.middlewares.use((req, res, next) => {
14462
- middleware(req, res, next);
14519
+ viteDevServer.middlewares.use(async (req, res, next) => {
14520
+ try {
14521
+ assert10(miniflare, `Miniflare not defined`);
14522
+ const routerWorker = await getRouterWorker(miniflare);
14523
+ const request = createRequest(req, res);
14524
+ const response = await routerWorker.fetch(
14525
+ toMiniflareRequest(request),
14526
+ {
14527
+ redirect: "manual"
14528
+ }
14529
+ );
14530
+ if (req.httpVersionMajor === 2) {
14531
+ response.headers.delete("transfer-encoding");
14532
+ }
14533
+ await sendResponse(res, response);
14534
+ } catch (error) {
14535
+ next(error);
14536
+ }
14463
14537
  });
14464
14538
  };
14465
14539
  },
14466
14540
  async configurePreviewServer(vitePreviewServer) {
14467
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14541
+ const workerConfigs = getWorkerConfigs(
14542
+ vitePreviewServer.config.root,
14543
+ pluginConfig.experimental?.mixedMode ?? false
14544
+ );
14468
14545
  const inputInspectorPort = await getInputInspectorPortOption(
14469
14546
  pluginConfig,
14470
14547
  vitePreviewServer
14471
14548
  );
14472
14549
  const miniflare2 = new Miniflare(
14473
- getPreviewMiniflareOptions(
14550
+ await getPreviewMiniflareOptions(
14474
14551
  vitePreviewServer,
14475
14552
  workerConfigs,
14476
14553
  pluginConfig.persistState ?? true,
14554
+ !!pluginConfig.experimental?.mixedMode,
14477
14555
  inputInspectorPort
14478
14556
  )
14479
14557
  );
14480
- const middleware = createMiddleware(
14481
- ({ request }) => {
14482
- return miniflare2.dispatchFetch(toMiniflareRequest(request), {
14483
- redirect: "manual"
14484
- });
14485
- },
14486
- { alwaysCallNext: false }
14487
- );
14488
14558
  handleWebSocket(
14489
14559
  vitePreviewServer.httpServer,
14490
14560
  () => miniflare2.dispatchFetch
14491
14561
  );
14492
- vitePreviewServer.middlewares.use((req, res, next) => {
14493
- middleware(req, res, next);
14562
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14563
+ try {
14564
+ const request = createRequest(req, res);
14565
+ const response = await miniflare2.dispatchFetch(
14566
+ toMiniflareRequest(request),
14567
+ { redirect: "manual" }
14568
+ );
14569
+ if (req.httpVersionMajor === 2) {
14570
+ response.headers.delete("transfer-encoding");
14571
+ }
14572
+ await sendResponse(res, response);
14573
+ } catch (error) {
14574
+ next(error);
14575
+ }
14494
14576
  });
14495
14577
  }
14496
14578
  },
@@ -14683,6 +14765,25 @@ function cloudflare2(pluginConfig = {}) {
14683
14765
  );
14684
14766
  }
14685
14767
  },
14768
+ // Plugin that handles Node.js Async Local Storage (ALS) compatibility support for Vite Environments that are hosted in Cloudflare Workers.
14769
+ {
14770
+ name: "vite-plugin-cloudflare:nodejs-als",
14771
+ apply(_config, env2) {
14772
+ return !env2.isPreview;
14773
+ },
14774
+ configEnvironment(name, config) {
14775
+ if (isNodeAls(getWorkerConfig2(name))) {
14776
+ return {
14777
+ resolve: {
14778
+ builtins: ["async_hooks", "node:async_hooks"]
14779
+ },
14780
+ optimizeDeps: {
14781
+ exclude: ["async_hooks", "node:async_hooks"]
14782
+ }
14783
+ };
14784
+ }
14785
+ }
14786
+ },
14686
14787
  // Plugin that provides an __debug path for debugging the Cloudflare Workers.
14687
14788
  {
14688
14789
  name: "vite-plugin-cloudflare:debug",
@@ -14707,7 +14808,10 @@ function cloudflare2(pluginConfig = {}) {
14707
14808
  });
14708
14809
  },
14709
14810
  async configurePreviewServer(vitePreviewServer) {
14710
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14811
+ const workerConfigs = getWorkerConfigs(
14812
+ vitePreviewServer.config.root,
14813
+ pluginConfig.experimental?.mixedMode ?? false
14814
+ );
14711
14815
  if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
14712
14816
  addDebugToVitePrintUrls(vitePreviewServer);
14713
14817
  }
@@ -14748,6 +14852,9 @@ function cloudflare2(pluginConfig = {}) {
14748
14852
  build.onResolve(
14749
14853
  { filter: NODEJS_MODULES_RE },
14750
14854
  ({ path: path10, importer }) => {
14855
+ if (isNodeAls(workerConfig) && isNodeAlsModule(path10)) {
14856
+ return;
14857
+ }
14751
14858
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14752
14859
  nodeJsCompatWarnings?.registerImport(path10, importer);
14753
14860
  return { path: path10, external: true };
@@ -14777,6 +14884,9 @@ function cloudflare2(pluginConfig = {}) {
14777
14884
  async resolveId(source, importer) {
14778
14885
  const workerConfig = getWorkerConfig2(this.environment.name);
14779
14886
  if (workerConfig && !isNodeCompat(workerConfig)) {
14887
+ if (isNodeAls(workerConfig) && isNodeAlsModule(source)) {
14888
+ return;
14889
+ }
14780
14890
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14781
14891
  if (nodejsBuiltins.has(source)) {
14782
14892
  nodeJsCompatWarnings?.registerImport(source, importer);
@@ -14795,10 +14905,16 @@ function cloudflare2(pluginConfig = {}) {
14795
14905
  }
14796
14906
  }
14797
14907
  async function getInputInspectorPortOption(pluginConfig, viteServer) {
14908
+ if (pluginConfig.inspectorPort === void 0 || pluginConfig.inspectorPort === 0) {
14909
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14910
+ if (resolvedInspectorPort !== null) {
14911
+ return resolvedInspectorPort;
14912
+ }
14913
+ }
14798
14914
  const inputInspectorPort = pluginConfig.inspectorPort ?? await getFirstAvailablePort(DEFAULT_INSPECTOR_PORT);
14799
14915
  if (pluginConfig.inspectorPort === void 0 && inputInspectorPort !== DEFAULT_INSPECTOR_PORT) {
14800
14916
  viteServer.config.logger.warn(
14801
- colors2.dim(
14917
+ colors3.dim(
14802
14918
  `Default inspector port ${DEFAULT_INSPECTOR_PORT} not available, using ${inputInspectorPort} instead
14803
14919
  `
14804
14920
  )
@@ -14824,6 +14940,19 @@ function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14824
14940
  }
14825
14941
  return null;
14826
14942
  }
14943
+ function hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) {
14944
+ return [...resolvedPluginConfig.configPaths].some((configPath) => {
14945
+ const dotDevDotVars = path9.join(path9.dirname(configPath), ".dev.vars");
14946
+ if (dotDevDotVars === changedFilePath) {
14947
+ return true;
14948
+ }
14949
+ if (resolvedPluginConfig.cloudflareEnv) {
14950
+ const dotDevDotVarsForEnv = `${dotDevDotVars}.${resolvedPluginConfig.cloudflareEnv}`;
14951
+ return dotDevDotVarsForEnv === changedFilePath;
14952
+ }
14953
+ return false;
14954
+ });
14955
+ }
14827
14956
  export {
14828
14957
  cloudflare2 as cloudflare
14829
14958
  };