@cloudflare/vite-plugin 1.14.1 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import * as vite from "vite";
2
+ import { Miniflare, Request, Response } from "miniflare";
2
3
  import "wrangler";
3
4
 
4
5
  //#region src/plugin-config.d.ts
@@ -40,4 +41,4 @@ interface PluginConfig extends EntryWorkerConfig {
40
41
  declare function cloudflare(pluginConfig?: PluginConfig): vite.Plugin[];
41
42
  //#endregion
42
43
  export { type PluginConfig, cloudflare };
43
- //# sourceMappingURL=index.d.ts.map
44
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin-config.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAsBU,KAFE,YAAA,GAEc,OAAA,GAAA;EAIhB,IAAA,EAAA,MAAA;AAA0C,CAAA;AAII,UAR9C,gBAAA,CAYY;EAKL,eAAa,CAAA,EAAA;IACV,IAAA,CAAA,EAAA,MAAA;EACJ,CAAA;;UAfN,iBAAA,SAA0B,gBAaE,CAAA;EAAiB,UAAA,CAAA,EAAA,MAAA;;UAT7C,qBAAA,SAA8B;;ACQxC;UDJU,YAAA;;;;UAKO,YAAA,SAAqB;qBAClB;iBACJ;;;iBAGA;;;;;;AAxBhB;AAAsD;AAE5B;AAI0B;AAII;AASvC,iBCDD,UAAA,CDCc,YAAA,CAAA,ECDW,YDCX,CAAA,ECD+B,IAAA,CAAK,MDCpC,EAAA"}
@@ -1,7 +1,8 @@
1
1
  import { builtinModules } from "node:module";
2
2
  import * as vite from "vite";
3
3
  import assert from "node:assert";
4
- import { CoreHeaders, Log, LogLevel, Miniflare, Request as Request$1, Response as Response$1, coupleWebSocket, getDefaultDevRegistryPath, getNodeCompat, kCurrentWorker, kUnsafeEphemeralUniqueKey } from "miniflare";
4
+ import { CoreHeaders, Log, LogLevel, Miniflare, Request as Request$1, Response as Response$1, coupleWebSocket, getDefaultDevRegistryPath, getNodeCompat, kUnsafeEphemeralUniqueKey } from "miniflare";
5
+ import { maybeStartOrUpdateRemoteProxySession, unstable_convertConfigBindingsToStartWorkerBindings, unstable_getDurableObjectClassNameToUseSQLiteMap, unstable_getMiniflareWorkerOptions, unstable_getVarsForDev, unstable_readConfig } from "wrangler";
5
6
  import * as path$2 from "node:path";
6
7
  import path, { relative } from "node:path";
7
8
  import * as util$1 from "node:util";
@@ -9,7 +10,6 @@ import { format, inspect } from "node:util";
9
10
  import { createHeaders, createRequest, sendResponse } from "@remix-run/node-fetch-server";
10
11
  import * as fs$1 from "node:fs";
11
12
  import fs, { readFileSync, realpathSync, statSync } from "node:fs";
12
- import { maybeStartOrUpdateRemoteProxySession, unstable_convertConfigBindingsToStartWorkerBindings, unstable_getMiniflareWorkerOptions, unstable_getVarsForDev, unstable_readConfig } from "wrangler";
13
13
  import { getCloudflarePreset } from "@cloudflare/unenv-preset";
14
14
  import { URL as URL$1, fileURLToPath, pathToFileURL } from "node:url";
15
15
  import process$1 from "node:process";
@@ -111,6 +111,83 @@ function toMiniflareRequest(request$1) {
111
111
  });
112
112
  }
113
113
 
114
+ //#endregion
115
+ //#region src/export-types.ts
116
+ function getWorkerNameToWorkerEntrypointExportsMap(workers) {
117
+ const workerNameToWorkerEntrypointExportsMap = new Map(workers.map((worker) => [worker.config.name, /* @__PURE__ */ new Set()]));
118
+ for (const worker of workers) for (const value of worker.config.services ?? []) if (value.entrypoint !== void 0 && value.entrypoint !== "default") workerNameToWorkerEntrypointExportsMap.get(value.service)?.add(value.entrypoint);
119
+ return workerNameToWorkerEntrypointExportsMap;
120
+ }
121
+ function getWorkerNameToDurableObjectExportsMap(workers) {
122
+ const workerNameToDurableObjectExportsMap = new Map(workers.map((worker) => [worker.config.name, new Set(unstable_getDurableObjectClassNameToUseSQLiteMap(worker.config.migrations).keys())]));
123
+ for (const worker of workers) for (const value of worker.config.durable_objects.bindings) if (value.script_name) workerNameToDurableObjectExportsMap.get(value.script_name)?.add(value.class_name);
124
+ else workerNameToDurableObjectExportsMap.get(worker.config.name)?.add(value.class_name);
125
+ return workerNameToDurableObjectExportsMap;
126
+ }
127
+ function getWorkerNameToWorkflowEntrypointExportsMap(workers) {
128
+ const workerNameToWorkflowEntrypointExportsMap = new Map(workers.map((worker) => [worker.config.name, /* @__PURE__ */ new Set()]));
129
+ for (const worker of workers) for (const value of worker.config.workflows) if (value.script_name) workerNameToWorkflowEntrypointExportsMap.get(value.script_name)?.add(value.class_name);
130
+ else workerNameToWorkflowEntrypointExportsMap.get(worker.config.name)?.add(value.class_name);
131
+ return workerNameToWorkflowEntrypointExportsMap;
132
+ }
133
+ /**
134
+ * Derives initial export types for all Workers from the Worker config files and returns them in a Map
135
+ */
136
+ function getInitialWorkerNameToExportTypesMap(resolvedPluginConfig) {
137
+ const workers = [...resolvedPluginConfig.environmentNameToWorkerMap.values()];
138
+ const workerNameToWorkerEntrypointExportsMap = getWorkerNameToWorkerEntrypointExportsMap(workers);
139
+ const workerNameToDurableObjectExportsMap = getWorkerNameToDurableObjectExportsMap(workers);
140
+ const workerNameToWorkflowEntrypointExportsMap = getWorkerNameToWorkflowEntrypointExportsMap(workers);
141
+ return new Map(workers.map((worker) => {
142
+ const workerEntrypointExports = workerNameToWorkerEntrypointExportsMap.get(worker.config.name);
143
+ assert(workerEntrypointExports, `WorkerEntrypoint exports not found for Worker "${worker.config.name}"`);
144
+ const durableObjectExports = workerNameToDurableObjectExportsMap.get(worker.config.name);
145
+ assert(durableObjectExports, `DurableObject exports not found for Worker "${worker.config.name}"`);
146
+ const workflowEntrypointExports = workerNameToWorkflowEntrypointExportsMap.get(worker.config.name);
147
+ assert(workflowEntrypointExports, `WorkflowEntrypoint exports not found for Worker "${worker.config.name}"`);
148
+ const exportTypes = {};
149
+ for (const exportName of workerEntrypointExports) exportTypes[exportName] = "WorkerEntrypoint";
150
+ for (const exportName of durableObjectExports) exportTypes[exportName] = "DurableObject";
151
+ for (const exportName of workflowEntrypointExports) exportTypes[exportName] = "WorkflowEntrypoint";
152
+ return [worker.config.name, exportTypes];
153
+ }));
154
+ }
155
+ /**
156
+ * Fetches the export types for all Workers and returns them in a Map
157
+ */
158
+ async function getCurrentWorkerNameToExportTypesMap(resolvedPluginConfig, viteDevServer, miniflare) {
159
+ const results = await Promise.all([...resolvedPluginConfig.environmentNameToWorkerMap].map(async ([environmentName, worker]) => {
160
+ debuglog(`Fetching export types for worker "${worker.config.name}"`);
161
+ const exportTypes = await viteDevServer.environments[environmentName].fetchWorkerExportTypes(miniflare, worker.config);
162
+ return [worker.config.name, exportTypes];
163
+ }));
164
+ return new Map(results);
165
+ }
166
+ /**
167
+ * Compares the export types for all Workers and returns `true` if any have changed
168
+ */
169
+ function compareWorkerNameToExportTypesMaps(oldWorkerNameToExportTypesMap, newWorkerNameToExportTypesMap) {
170
+ for (const workerName of newWorkerNameToExportTypesMap.keys()) {
171
+ const oldExportTypes = oldWorkerNameToExportTypesMap.get(workerName);
172
+ assert(oldExportTypes, "Expected old export types to be defined");
173
+ const newExportTypes = newWorkerNameToExportTypesMap.get(workerName);
174
+ assert(newExportTypes, "Expected new export types to be defined");
175
+ if (compareExportTypes(oldExportTypes, newExportTypes)) return true;
176
+ }
177
+ return false;
178
+ }
179
+ /**
180
+ * Compares two `ExportTypes` objects and returns true if they do not match.
181
+ * Checks for added/removed exports and changed export types.
182
+ */
183
+ function compareExportTypes(oldExportTypes, newExportTypes) {
184
+ const oldKeys = Object.keys(oldExportTypes);
185
+ const newKeys = Object.keys(newExportTypes);
186
+ if (oldKeys.length !== newKeys.length) return true;
187
+ for (const key of newKeys) if (!(key in oldExportTypes) || oldExportTypes[key] !== newExportTypes[key]) return true;
188
+ return false;
189
+ }
190
+
114
191
  //#endregion
115
192
  //#region src/context.ts
116
193
  /**
@@ -151,6 +228,16 @@ var PluginContext = class {
151
228
  const miniflareInspectorUrl = await this.#sharedContext.miniflare.getInspectorURL();
152
229
  return Number.parseInt(miniflareInspectorUrl.port);
153
230
  }
231
+ setWorkerNameToExportTypesMap(workerNameToExportTypesMap) {
232
+ this.#sharedContext.workerNameToExportTypesMap = workerNameToExportTypesMap;
233
+ }
234
+ get workerNameToExportTypesMap() {
235
+ if (!this.#sharedContext.workerNameToExportTypesMap) {
236
+ if (this.resolvedPluginConfig.type !== "workers") return /* @__PURE__ */ new Map();
237
+ return getInitialWorkerNameToExportTypesMap(this.resolvedPluginConfig);
238
+ }
239
+ return this.#sharedContext.workerNameToExportTypesMap;
240
+ }
154
241
  setHasShownWorkerConfigWarnings(hasShownWorkerConfigWarnings) {
155
242
  this.#sharedContext.hasShownWorkerConfigWarnings = hasShownWorkerConfigWarnings;
156
243
  }
@@ -178,14 +265,14 @@ var PluginContext = class {
178
265
  return this.#resolvedViteConfig;
179
266
  }
180
267
  getWorkerConfig(environmentName) {
181
- return this.resolvedPluginConfig.type === "workers" ? this.resolvedPluginConfig.workers[environmentName] : void 0;
268
+ return this.resolvedPluginConfig.type === "workers" ? this.resolvedPluginConfig.environmentNameToWorkerMap.get(environmentName)?.config : void 0;
182
269
  }
183
270
  get entryWorkerConfig() {
184
271
  if (this.resolvedPluginConfig.type !== "workers") return;
185
- return this.resolvedPluginConfig.workers[this.resolvedPluginConfig.entryWorkerEnvironmentName];
272
+ return this.resolvedPluginConfig.environmentNameToWorkerMap.get(this.resolvedPluginConfig.entryWorkerEnvironmentName)?.config;
186
273
  }
187
274
  getNodeJsCompat(environmentName) {
188
- return this.resolvedPluginConfig.type === "workers" ? this.resolvedPluginConfig.nodeJsCompatMap.get(environmentName) : void 0;
275
+ return this.resolvedPluginConfig.type === "workers" ? this.resolvedPluginConfig.environmentNameToWorkerMap.get(environmentName)?.nodeJsCompat : void 0;
189
276
  }
190
277
  };
191
278
  function assertIsNotPreview(ctx) {
@@ -297,7 +384,7 @@ function writeDeployConfig(resolvedPluginConfig, resolvedViteConfig) {
297
384
  } else {
298
385
  let entryWorkerConfigPath;
299
386
  const auxiliaryWorkers = [];
300
- for (const environmentName of Object.keys(resolvedPluginConfig.workers)) {
387
+ for (const environmentName of resolvedPluginConfig.environmentNameToWorkerMap.keys()) {
301
388
  const outputDirectory = resolvedViteConfig.environments[environmentName]?.build.outDir;
302
389
  assert(outputDirectory, `Unexpected error: ${environmentName} environment output directory is undefined`);
303
390
  const configPath = getRelativePathToWorkerConfig(deployConfigDirectory, resolvedViteConfig.root, outputDirectory);
@@ -6877,9 +6964,6 @@ const allowedWranglerConfigExtensions = [
6877
6964
 
6878
6965
  //#endregion
6879
6966
  //#region src/plugin-config.ts
6880
- function workerNameToEnvironmentName(workerName) {
6881
- return workerName.replaceAll("-", "_");
6882
- }
6883
6967
  function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
6884
6968
  const shared = {
6885
6969
  persistState: pluginConfig.persistState ?? true,
@@ -6914,7 +6998,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
6914
6998
  const entryWorkerEnvironmentName = pluginConfig.viteEnvironment?.name ?? workerNameToEnvironmentName(entryWorkerConfig.topLevelName);
6915
6999
  let staticRouting;
6916
7000
  if (Array.isArray(entryWorkerConfig.assets?.run_worker_first)) staticRouting = parseStaticRouting(entryWorkerConfig.assets.run_worker_first);
6917
- const workers = { [entryWorkerEnvironmentName]: entryWorkerConfig };
7001
+ const environmentNameToWorkerMap = new Map([[entryWorkerEnvironmentName, resolveWorker(entryWorkerConfig)]]);
6918
7002
  const auxiliaryWorkersResolvedConfigs = [];
6919
7003
  for (const auxiliaryWorker of pluginConfig.auxiliaryWorkers ?? []) {
6920
7004
  const workerResolvedConfig = getWorkerConfig(getValidatedWranglerConfigPath(root, auxiliaryWorker.configPath, true), cloudflareEnv, { visitedConfigPaths: configPaths });
@@ -6922,18 +7006,16 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
6922
7006
  assert(workerResolvedConfig.type === "worker", "Unexpected error: received AssetsOnlyResult with auxiliary workers.");
6923
7007
  const workerConfig = workerResolvedConfig.config;
6924
7008
  const workerEnvironmentName = auxiliaryWorker.viteEnvironment?.name ?? workerNameToEnvironmentName(workerConfig.topLevelName);
6925
- if (workers[workerEnvironmentName]) throw new Error(`Duplicate Vite environment name found: ${workerEnvironmentName}`);
6926
- workers[workerEnvironmentName] = workerConfig;
7009
+ if (environmentNameToWorkerMap.has(workerEnvironmentName)) throw new Error(`Duplicate Vite environment name found: ${workerEnvironmentName}`);
7010
+ environmentNameToWorkerMap.set(workerEnvironmentName, resolveWorker(workerConfig));
6927
7011
  }
6928
- const nodeJsCompatMap = new Map(Object.entries(workers).filter(([_, workerConfig]) => hasNodeJsCompat(workerConfig)).map(([environmentName, workerConfig]) => [environmentName, new NodeJsCompat(workerConfig)]));
6929
7012
  return {
6930
7013
  ...shared,
6931
7014
  type: "workers",
6932
7015
  cloudflareEnv,
6933
7016
  configPaths,
6934
- workers,
7017
+ environmentNameToWorkerMap,
6935
7018
  entryWorkerEnvironmentName,
6936
- nodeJsCompatMap,
6937
7019
  staticRouting,
6938
7020
  remoteBindings: pluginConfig.remoteBindings ?? true,
6939
7021
  rawConfigs: {
@@ -6942,6 +7024,15 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
6942
7024
  }
6943
7025
  };
6944
7026
  }
7027
+ function workerNameToEnvironmentName(workerName) {
7028
+ return workerName.replaceAll("-", "_");
7029
+ }
7030
+ function resolveWorker(workerConfig) {
7031
+ return {
7032
+ config: workerConfig,
7033
+ nodeJsCompat: hasNodeJsCompat(workerConfig) ? new NodeJsCompat(workerConfig) : void 0
7034
+ };
7035
+ }
6945
7036
 
6946
7037
  //#endregion
6947
7038
  //#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
@@ -13510,10 +13601,12 @@ function getHeadersConfigPath(config) {
13510
13601
  //#region src/shared.ts
13511
13602
  const UNKNOWN_HOST = "http://localhost";
13512
13603
  const INIT_PATH = "/__vite_plugin_cloudflare_init__";
13604
+ const GET_EXPORT_TYPES_PATH = "/__vite_plugin_cloudflare_get_export_types__";
13513
13605
  const WORKER_ENTRY_PATH_HEADER = "__VITE_WORKER_ENTRY_PATH__";
13514
13606
  const IS_ENTRY_WORKER_HEADER = "__VITE_IS_ENTRY_WORKER__";
13515
13607
  const virtualPrefix = "virtual:cloudflare/";
13516
13608
  const VIRTUAL_WORKER_ENTRY = `${virtualPrefix}worker-entry`;
13609
+ const VIRTUAL_EXPORT_TYPES = `${virtualPrefix}export-types`;
13517
13610
 
13518
13611
  //#endregion
13519
13612
  //#region src/plugins/virtual-modules.ts
@@ -13528,7 +13621,7 @@ const virtualModulesPlugin = createPlugin("virtual-modules", (ctx) => {
13528
13621
  return ctx.getWorkerConfig(environment.name) !== void 0;
13529
13622
  },
13530
13623
  resolveId(source) {
13531
- if (source === VIRTUAL_WORKER_ENTRY) return `\0${VIRTUAL_WORKER_ENTRY}`;
13624
+ if (source === VIRTUAL_WORKER_ENTRY || source === VIRTUAL_EXPORT_TYPES) return `\0${source}`;
13532
13625
  if (source === VIRTUAL_USER_ENTRY) {
13533
13626
  const workerConfig = ctx.getWorkerConfig(this.environment.name);
13534
13627
  assert(workerConfig, "Expected `workerConfig` to be defined");
@@ -13540,14 +13633,56 @@ const virtualModulesPlugin = createPlugin("virtual-modules", (ctx) => {
13540
13633
  const nodeJsCompat = ctx.getNodeJsCompat(this.environment.name);
13541
13634
  return `
13542
13635
  ${nodeJsCompat ? nodeJsCompat.injectGlobalCode() : ""}
13636
+ import { getExportTypes } from "${VIRTUAL_EXPORT_TYPES}";
13543
13637
  import * as mod from "${VIRTUAL_USER_ENTRY}";
13544
13638
  export * from "${VIRTUAL_USER_ENTRY}";
13545
13639
  export default mod.default ?? {};
13546
13640
  if (import.meta.hot) {
13547
- import.meta.hot.accept();
13641
+ import.meta.hot.accept((module) => {
13642
+ const exportTypes = getExportTypes(module);
13643
+ import.meta.hot.send("vite-plugin-cloudflare:worker-export-types", exportTypes);
13644
+ });
13548
13645
  }
13549
13646
  `;
13550
13647
  }
13648
+ if (id === `\0${VIRTUAL_EXPORT_TYPES}`) return `
13649
+ import {
13650
+ WorkerEntrypoint,
13651
+ DurableObject,
13652
+ WorkflowEntrypoint,
13653
+ } from "cloudflare:workers";
13654
+
13655
+ const baseClasses = new Map([
13656
+ ["WorkerEntrypoint", WorkerEntrypoint],
13657
+ ["DurableObject", DurableObject],
13658
+ ["WorkflowEntrypoint", WorkflowEntrypoint],
13659
+ ]);
13660
+
13661
+ export function getExportTypes(module) {
13662
+ const exportTypes = {};
13663
+
13664
+ for (const [key, value] of Object.entries(module)) {
13665
+ if (key === "default") {
13666
+ continue;
13667
+ }
13668
+
13669
+ let exportType
13670
+
13671
+ if (typeof value === "function") {
13672
+ for (const [type, baseClass] of baseClasses) {
13673
+ if (baseClass.prototype.isPrototypeOf(value.prototype)) {
13674
+ exportType = type;
13675
+ break;
13676
+ }
13677
+ }
13678
+ }
13679
+
13680
+ exportTypes[key] = exportType;
13681
+ }
13682
+
13683
+ return exportTypes;
13684
+ }
13685
+ `;
13551
13686
  }
13552
13687
  };
13553
13688
  });
@@ -13583,7 +13718,7 @@ function createBuildApp(resolvedPluginConfig) {
13583
13718
  else if (getHasPublicAssets(builder.config)) await fallbackBuild(builder, clientEnvironment);
13584
13719
  return;
13585
13720
  }
13586
- const workerEnvironments = Object.keys(resolvedPluginConfig.workers).map((environmentName) => {
13721
+ const workerEnvironments = [...resolvedPluginConfig.environmentNameToWorkerMap.keys()].map((environmentName) => {
13587
13722
  const environment = builder.environments[environmentName];
13588
13723
  assert(environment, `"${environmentName}" environment not found`);
13589
13724
  return environment;
@@ -13711,6 +13846,10 @@ var CloudflareDevEnvironment = class extends vite.DevEnvironment {
13711
13846
  webSocket.accept();
13712
13847
  this.#webSocketContainer.webSocket = webSocket;
13713
13848
  }
13849
+ async fetchWorkerExportTypes(miniflare, workerConfig) {
13850
+ await this.depsOptimizer?.init();
13851
+ return await (await miniflare.dispatchFetch(new URL(GET_EXPORT_TYPES_PATH, UNKNOWN_HOST), { headers: { [CoreHeaders.ROUTE_OVERRIDE]: workerConfig.name } })).json();
13852
+ }
13714
13853
  async fetchModule(id, importer, options) {
13715
13854
  if (additionalModuleRE.test(id)) return {
13716
13855
  externalize: id,
@@ -13809,10 +13948,10 @@ function getProcessEnvReplacements(hasNodeJsCompat$1, mode) {
13809
13948
  };
13810
13949
  }
13811
13950
  function initRunners(resolvedPluginConfig, viteDevServer, miniflare) {
13812
- return Promise.all(Object.entries(resolvedPluginConfig.workers).map(async ([environmentName, workerConfig]) => {
13813
- debuglog("Initializing worker:", workerConfig.name);
13951
+ return Promise.all([...resolvedPluginConfig.environmentNameToWorkerMap].map(([environmentName, worker]) => {
13952
+ debuglog("Initializing worker:", worker.config.name);
13814
13953
  const isEntryWorker = environmentName === resolvedPluginConfig.entryWorkerEnvironmentName;
13815
- return viteDevServer.environments[environmentName].initRunner(miniflare, workerConfig, isEntryWorker);
13954
+ return viteDevServer.environments[environmentName].initRunner(miniflare, worker.config, isEntryWorker);
13816
13955
  }));
13817
13956
  }
13818
13957
 
@@ -13850,9 +13989,8 @@ function hasLocalDevVarsFileChanged({ configPaths, cloudflareEnv }, changedFileP
13850
13989
  * Throws an error if Worker environments include configuration options that are incompatible with the plugin.
13851
13990
  */
13852
13991
  function validateWorkerEnvironmentOptions(resolvedPluginConfig, resolvedViteConfig) {
13853
- const workerEnvironmentNames = Object.keys(resolvedPluginConfig.workers);
13854
13992
  const disallowedEnvironmentOptionsMap = /* @__PURE__ */ new Map();
13855
- for (const environmentName of workerEnvironmentNames) {
13993
+ for (const environmentName of resolvedPluginConfig.environmentNameToWorkerMap.keys()) {
13856
13994
  const environmentOptions = resolvedViteConfig.environments[environmentName];
13857
13995
  assert(environmentOptions, `Missing environment config for "${environmentName}"`);
13858
13996
  const { resolve: resolve$1 } = environmentOptions;
@@ -13893,9 +14031,9 @@ const configPlugin = createPlugin("config", (ctx) => {
13893
14031
  ".dev.vars.*"
13894
14032
  ] } },
13895
14033
  environments: ctx.resolvedPluginConfig.type === "workers" ? {
13896
- ...Object.fromEntries(Object.entries(ctx.resolvedPluginConfig.workers).map(([environmentName, workerConfig]) => {
14034
+ ...Object.fromEntries([...ctx.resolvedPluginConfig.environmentNameToWorkerMap].map(([environmentName, worker]) => {
13897
14035
  return [environmentName, createCloudflareEnvironmentOptions({
13898
- workerConfig,
14036
+ workerConfig: worker.config,
13899
14037
  userConfig,
13900
14038
  mode: env.mode,
13901
14039
  environmentName,
@@ -14012,7 +14150,7 @@ const debugPlugin = createPlugin("debug", (ctx) => {
14012
14150
  assertIsNotPreview(ctx);
14013
14151
  if (!!process.env.VSCODE_INSPECTOR_OPTIONS) return;
14014
14152
  if (ctx.resolvedPluginConfig.type === "workers" && ctx.resolvedPluginConfig.inspectorPort !== false) addDebugToVitePrintUrls(viteDevServer);
14015
- const workerNames = ctx.resolvedPluginConfig.type === "workers" ? Object.values(ctx.resolvedPluginConfig.workers).map((worker) => worker.name) : [];
14153
+ const workerNames = ctx.resolvedPluginConfig.type === "workers" ? [...ctx.resolvedPluginConfig.environmentNameToWorkerMap.values()].map((worker) => worker.config.name) : [];
14016
14154
  viteDevServer.middlewares.use(DEBUG_PATH, async (_, res, next) => {
14017
14155
  const resolvedInspectorPort = await ctx.getResolvedInspectorPort();
14018
14156
  if (resolvedInspectorPort) {
@@ -15232,48 +15370,6 @@ function getPersistenceRoot(root, persistState) {
15232
15370
  if (persistState === false) return;
15233
15371
  return path$2.resolve(root, typeof persistState === "object" ? persistState.path : ".wrangler/state", "v3");
15234
15372
  }
15235
- function missingWorkerErrorMessage(workerName) {
15236
- return `${workerName} does not match a worker name.`;
15237
- }
15238
- function getWorkerToWorkerEntrypointNamesMap(workers) {
15239
- const workerToWorkerEntrypointNamesMap = new Map(workers.map((workerOptions) => [workerOptions.name, /* @__PURE__ */ new Set()]));
15240
- for (const worker of workers) for (const value of Object.values(worker.serviceBindings ?? {})) if (typeof value === "object" && "name" in value && value.entrypoint !== void 0 && value.entrypoint !== "default") {
15241
- const targetWorkerName = value.name === kCurrentWorker ? worker.name : value.name;
15242
- const entrypointNames = workerToWorkerEntrypointNamesMap.get(targetWorkerName);
15243
- if (entrypointNames) entrypointNames.add(value.entrypoint);
15244
- }
15245
- return workerToWorkerEntrypointNamesMap;
15246
- }
15247
- function getWorkerToDurableObjectClassNamesMap(workers) {
15248
- const workerToDurableObjectClassNamesMap = new Map(workers.map((workerOptions) => [workerOptions.name, /* @__PURE__ */ new Set()]));
15249
- for (const worker of workers) for (const value of Object.values(worker.durableObjects ?? {})) if (typeof value === "string") {
15250
- const classNames = workerToDurableObjectClassNamesMap.get(worker.name);
15251
- assert(classNames, missingWorkerErrorMessage(worker.name));
15252
- classNames.add(value);
15253
- } else if (typeof value === "object") if (value.scriptName) {
15254
- const classNames = workerToDurableObjectClassNamesMap.get(value.scriptName);
15255
- assert(classNames, missingWorkerErrorMessage(value.scriptName));
15256
- classNames.add(value.className);
15257
- } else {
15258
- const classNames = workerToDurableObjectClassNamesMap.get(worker.name);
15259
- assert(classNames, missingWorkerErrorMessage(worker.name));
15260
- classNames.add(value.className);
15261
- }
15262
- return workerToDurableObjectClassNamesMap;
15263
- }
15264
- function getWorkerToWorkflowEntrypointClassNamesMap(workers) {
15265
- const workerToWorkflowEntrypointClassNamesMap = new Map(workers.map((workerOptions) => [workerOptions.name, /* @__PURE__ */ new Set()]));
15266
- for (const worker of workers) for (const value of Object.values(worker.workflows ?? {})) if (value.scriptName) {
15267
- const classNames = workerToWorkflowEntrypointClassNamesMap.get(value.scriptName);
15268
- assert(classNames, missingWorkerErrorMessage(value.scriptName));
15269
- classNames.add(value.className);
15270
- } else {
15271
- const classNames = workerToWorkflowEntrypointClassNamesMap.get(worker.name);
15272
- assert(classNames, missingWorkerErrorMessage(worker.name));
15273
- classNames.add(value.className);
15274
- }
15275
- return workerToWorkflowEntrypointClassNamesMap;
15276
- }
15277
15373
  const miniflareModulesRoot = process.platform === "win32" ? "Z:\\" : "/";
15278
15374
  const ROUTER_WORKER_PATH = "./workers/router-worker.js";
15279
15375
  const ASSET_WORKER_PATH = "./workers/asset-worker.js";
@@ -15371,28 +15467,28 @@ async function getDevMiniflareOptions(ctx, viteDevServer) {
15371
15467
  }
15372
15468
  ];
15373
15469
  const containerTagToOptionsMap = /* @__PURE__ */ new Map();
15374
- const workersFromConfig = resolvedPluginConfig.type === "workers" ? await Promise.all(Object.entries(resolvedPluginConfig.workers).map(async ([environmentName, workerConfig]) => {
15375
- const bindings = unstable_convertConfigBindingsToStartWorkerBindings(workerConfig);
15376
- const preExistingRemoteProxySession = workerConfig.configPath ? remoteProxySessionsDataMap.get(workerConfig.configPath) : void 0;
15470
+ const workersFromConfig = resolvedPluginConfig.type === "workers" ? await Promise.all([...resolvedPluginConfig.environmentNameToWorkerMap].map(async ([environmentName, worker]) => {
15471
+ const bindings = unstable_convertConfigBindingsToStartWorkerBindings(worker.config);
15472
+ const preExistingRemoteProxySession = worker.config.configPath ? remoteProxySessionsDataMap.get(worker.config.configPath) : void 0;
15377
15473
  const remoteProxySessionData = !resolvedPluginConfig.remoteBindings ? null : await maybeStartOrUpdateRemoteProxySession({
15378
- name: workerConfig.name,
15474
+ name: worker.config.name,
15379
15475
  bindings: bindings ?? {}
15380
15476
  }, preExistingRemoteProxySession ?? null);
15381
- if (workerConfig.configPath && remoteProxySessionData) remoteProxySessionsDataMap.set(workerConfig.configPath, remoteProxySessionData);
15477
+ if (worker.config.configPath && remoteProxySessionData) remoteProxySessionsDataMap.set(worker.config.configPath, remoteProxySessionData);
15382
15478
  let containerBuildId;
15383
- if (workerConfig.containers?.length && workerConfig.dev.enable_containers) {
15479
+ if (worker.config.containers?.length && worker.config.dev.enable_containers) {
15384
15480
  const dockerPath = getDockerPath();
15385
- workerConfig.dev.container_engine = resolveDockerHost(dockerPath);
15481
+ worker.config.dev.container_engine = resolveDockerHost(dockerPath);
15386
15482
  containerBuildId = generateContainerBuildId();
15387
15483
  const options = getContainerOptions({
15388
- containersConfig: workerConfig.containers,
15484
+ containersConfig: worker.config.containers,
15389
15485
  containerBuildId,
15390
- configPath: workerConfig.configPath
15486
+ configPath: worker.config.configPath
15391
15487
  });
15392
15488
  for (const option of options ?? []) containerTagToOptionsMap.set(option.image_tag, option);
15393
15489
  }
15394
15490
  const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions({
15395
- ...workerConfig,
15491
+ ...worker.config,
15396
15492
  assets: void 0
15397
15493
  }, resolvedPluginConfig.cloudflareEnv, {
15398
15494
  remoteProxyConnectionString: remoteProxySessionData?.session?.remoteProxyConnectionString,
@@ -15404,7 +15500,7 @@ async function getDevMiniflareOptions(ctx, viteDevServer) {
15404
15500
  externalWorkers: externalWorkers$1,
15405
15501
  worker: {
15406
15502
  ...workerOptions,
15407
- name: workerOptions.name ?? workerConfig.name,
15503
+ name: workerOptions.name ?? worker.config.name,
15408
15504
  unsafeInspectorProxy: inputInspectorPort !== false,
15409
15505
  unsafeDirectSockets: environmentName === resolvedPluginConfig.entryWorkerEnvironmentName ? [{
15410
15506
  serviceName: VITE_PROXY_WORKER_NAME,
@@ -15415,7 +15511,7 @@ async function getDevMiniflareOptions(ctx, viteDevServer) {
15415
15511
  unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
15416
15512
  serviceBindings: {
15417
15513
  ...workerOptions.serviceBindings,
15418
- ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? { [workerConfig.assets.binding]: { node: (req, res) => {
15514
+ ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && worker.config.assets?.binding ? { [worker.config.assets.binding]: { node: (req, res) => {
15419
15515
  req[kRequestType] = "asset";
15420
15516
  viteDevServer.middlewares(req, res);
15421
15517
  } } } : {},
@@ -15430,9 +15526,6 @@ async function getDevMiniflareOptions(ctx, viteDevServer) {
15430
15526
  })) : [];
15431
15527
  const userWorkers = workersFromConfig.map((options) => options.worker);
15432
15528
  const externalWorkers = workersFromConfig.flatMap((options) => options.externalWorkers);
15433
- const workerToWorkerEntrypointNamesMap = getWorkerToWorkerEntrypointNamesMap(userWorkers);
15434
- const workerToDurableObjectClassNamesMap = getWorkerToDurableObjectClassNamesMap(userWorkers);
15435
- const workerToWorkflowEntrypointClassNamesMap = getWorkerToWorkflowEntrypointClassNamesMap(userWorkers);
15436
15529
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
15437
15530
  return {
15438
15531
  miniflareOptions: {
@@ -15448,19 +15541,13 @@ async function getDevMiniflareOptions(ctx, viteDevServer) {
15448
15541
  ...externalWorkers,
15449
15542
  ...userWorkers.map((workerOptions) => {
15450
15543
  const wrappers = [
15451
- `import { createWorkerEntrypointWrapper, createDurableObjectWrapper, createWorkflowEntrypointWrapper } from '${RUNNER_PATH}';`,
15452
- `export { __VITE_RUNNER_OBJECT__ } from '${RUNNER_PATH}';`,
15453
- `export default createWorkerEntrypointWrapper('default');`
15544
+ `import { createWorkerEntrypointWrapper, createDurableObjectWrapper, createWorkflowEntrypointWrapper } from "${RUNNER_PATH}";`,
15545
+ `export { __VITE_RUNNER_OBJECT__ } from "${RUNNER_PATH}";`,
15546
+ `export default createWorkerEntrypointWrapper("default");`
15454
15547
  ];
15455
- const workerEntrypointNames = workerToWorkerEntrypointNamesMap.get(workerOptions.name);
15456
- assert(workerEntrypointNames, `WorkerEntrypoint names not found for worker ${workerOptions.name}`);
15457
- for (const entrypointName of [...workerEntrypointNames].sort()) wrappers.push(`export const ${entrypointName} = createWorkerEntrypointWrapper('${entrypointName}');`);
15458
- const durableObjectClassNames = workerToDurableObjectClassNamesMap.get(workerOptions.name);
15459
- assert(durableObjectClassNames, `DurableObject class names not found for worker ${workerOptions.name}`);
15460
- for (const className of [...durableObjectClassNames].sort()) wrappers.push(`export const ${className} = createDurableObjectWrapper('${className}');`);
15461
- const workflowEntrypointClassNames = workerToWorkflowEntrypointClassNamesMap.get(workerOptions.name);
15462
- assert(workflowEntrypointClassNames, `WorkflowEntrypoint class names not found for worker: ${workerOptions.name}`);
15463
- for (const className of [...workflowEntrypointClassNames].sort()) wrappers.push(`export const ${className} = createWorkflowEntrypointWrapper('${className}');`);
15548
+ const exportTypes = ctx.workerNameToExportTypesMap.get(workerOptions.name);
15549
+ assert(exportTypes, `Expected exportTypes to be defined`);
15550
+ for (const [name, type] of Object.entries(exportTypes)) wrappers.push(`export const ${name} = create${type}Wrapper("${name}");`);
15464
15551
  logUnknownTails(workerOptions.tails, userWorkers, viteDevServer.config.logger.warn);
15465
15552
  return {
15466
15553
  ...workerOptions,
@@ -15656,6 +15743,10 @@ function handleWebSocket(httpServer, miniflare, entryWorkerName) {
15656
15743
 
15657
15744
  //#endregion
15658
15745
  //#region src/plugins/dev.ts
15746
+ let exitCallback$2 = () => {};
15747
+ process.on("exit", () => {
15748
+ exitCallback$2();
15749
+ });
15659
15750
  /**
15660
15751
  * Plugin to provide core development functionality
15661
15752
  */
@@ -15673,14 +15764,37 @@ const devPlugin = createPlugin("dev", (ctx) => {
15673
15764
  },
15674
15765
  async configureServer(viteDevServer) {
15675
15766
  assertIsNotPreview(ctx);
15676
- const { miniflareOptions, containerTagToOptionsMap } = await getDevMiniflareOptions(ctx, viteDevServer);
15677
- await ctx.startOrUpdateMiniflare(miniflareOptions);
15767
+ const initialOptions = await getDevMiniflareOptions(ctx, viteDevServer);
15768
+ let containerTagToOptionsMap = initialOptions.containerTagToOptionsMap;
15769
+ await ctx.startOrUpdateMiniflare(initialOptions.miniflareOptions);
15678
15770
  let preMiddleware;
15679
15771
  if (ctx.resolvedPluginConfig.type === "workers") {
15680
- const entryWorkerConfig = ctx.entryWorkerConfig;
15681
- assert(entryWorkerConfig, `No entry Worker config`);
15682
15772
  debuglog("Initializing the Vite module runners");
15683
15773
  await initRunners(ctx.resolvedPluginConfig, viteDevServer, ctx.miniflare);
15774
+ const currentWorkerNameToExportTypesMap = await getCurrentWorkerNameToExportTypesMap(ctx.resolvedPluginConfig, viteDevServer, ctx.miniflare);
15775
+ if (compareWorkerNameToExportTypesMaps(ctx.workerNameToExportTypesMap, currentWorkerNameToExportTypesMap)) {
15776
+ ctx.setWorkerNameToExportTypesMap(currentWorkerNameToExportTypesMap);
15777
+ const updatedOptions = await getDevMiniflareOptions(ctx, viteDevServer);
15778
+ containerTagToOptionsMap = updatedOptions.containerTagToOptionsMap;
15779
+ await ctx.startOrUpdateMiniflare(updatedOptions.miniflareOptions);
15780
+ await initRunners(ctx.resolvedPluginConfig, viteDevServer, ctx.miniflare);
15781
+ }
15782
+ for (const environmentName of ctx.resolvedPluginConfig.environmentNameToWorkerMap.keys()) {
15783
+ const environment = viteDevServer.environments[environmentName];
15784
+ assert(environment, `Expected environment "${environmentName}" to be defined`);
15785
+ environment.hot.on("vite-plugin-cloudflare:worker-export-types", async (newExportTypes) => {
15786
+ const workerConfig = ctx.getWorkerConfig(environmentName);
15787
+ assert(workerConfig, `Expected workerConfig for environment "${environmentName}" to be defined`);
15788
+ const oldExportTypes = ctx.workerNameToExportTypesMap.get(workerConfig.name);
15789
+ assert(oldExportTypes, `Expected export types for Worker "${workerConfig.name}" to be defined`);
15790
+ if (compareExportTypes(oldExportTypes, newExportTypes)) {
15791
+ viteDevServer.config.logger.info(colors.dim(colors.yellow("Worker exports have changed. Restarting dev server.")));
15792
+ await viteDevServer.restart();
15793
+ }
15794
+ });
15795
+ }
15796
+ const entryWorkerConfig = ctx.entryWorkerConfig;
15797
+ assert(entryWorkerConfig, `No entry Worker config`);
15684
15798
  const entryWorkerName = entryWorkerConfig.name;
15685
15799
  if (viteDevServer.httpServer) handleWebSocket(viteDevServer.httpServer, ctx.miniflare, entryWorkerName);
15686
15800
  const staticRouting = entryWorkerConfig.assets?.run_worker_first === true ? { user_worker: ["/*"] } : ctx.resolvedPluginConfig.staticRouting;
@@ -15696,7 +15810,7 @@ const devPlugin = createPlugin("dev", (ctx) => {
15696
15810
  const request$1 = new Request(new URL(req.url, UNKNOWN_HOST));
15697
15811
  if (req[kRequestType] === "asset") next();
15698
15812
  else if (excludeRulesMatcher({ request: request$1 })) {
15699
- req[kRequestType];
15813
+ req[kRequestType] = "asset";
15700
15814
  next();
15701
15815
  } else if (includeRulesMatcher({ request: request$1 })) userWorkerHandler(req, res, next);
15702
15816
  else next();
@@ -15712,9 +15826,9 @@ const devPlugin = createPlugin("dev", (ctx) => {
15712
15826
  });
15713
15827
  containerImageTags = new Set(containerTagToOptionsMap.keys());
15714
15828
  viteDevServer.config.logger.info(colors.dim(colors.yellow("\n⚡️ Containers successfully built. To rebuild your containers during development, restart the Vite dev server (r + enter).")));
15715
- process.on("exit", async () => {
15716
- if (containerTagToOptionsMap.size) cleanupContainers(getDockerPath(), containerImageTags);
15717
- });
15829
+ exitCallback$2 = () => {
15830
+ if (containerImageTags.size) cleanupContainers(getDockerPath(), containerImageTags);
15831
+ };
15718
15832
  }
15719
15833
  }
15720
15834
  return () => {
@@ -15802,11 +15916,18 @@ const nodeJsCompatPlugin = createPlugin("nodejs-compat", (ctx) => {
15802
15916
  }
15803
15917
  };
15804
15918
  });
15919
+ let exitCallback$1 = () => {};
15920
+ process.on("exit", () => {
15921
+ exitCallback$1();
15922
+ });
15805
15923
  /**
15806
15924
  * Plugin to warn if Node.js APIs are used without enabling the `nodejs_compat` compatibility flag
15807
15925
  */
15808
15926
  const nodeJsCompatWarningsPlugin = createPlugin("nodejs-compat-warnings", (ctx) => {
15809
15927
  const nodeJsCompatWarningsMap = /* @__PURE__ */ new Map();
15928
+ exitCallback$1 = () => {
15929
+ for (const nodeJsCompatWarnings of nodeJsCompatWarningsMap.values()) nodeJsCompatWarnings.renderWarnings();
15930
+ };
15810
15931
  return {
15811
15932
  enforce: "pre",
15812
15933
  configEnvironment(environmentName) {
@@ -15862,7 +15983,7 @@ const outputConfigPlugin = createPlugin("output-config", (ctx) => {
15862
15983
  assertIsNotPreview(ctx);
15863
15984
  let outputConfig;
15864
15985
  if (ctx.resolvedPluginConfig.type === "workers") {
15865
- const inputConfig = ctx.resolvedPluginConfig.workers[this.environment.name];
15986
+ const inputConfig = ctx.getWorkerConfig(this.environment.name);
15866
15987
  if (!inputConfig) return;
15867
15988
  const entryChunk = Object.values(bundle).find((chunk) => chunk.type === "chunk" && chunk.isEntry && chunk.name === MAIN_ENTRY_NAME);
15868
15989
  assert(entryChunk, `Expected entry chunk with name "${MAIN_ENTRY_NAME}"`);
@@ -15925,6 +16046,10 @@ function getAssetsDirectory(workerOutputDirectory, resolvedViteConfig) {
15925
16046
 
15926
16047
  //#endregion
15927
16048
  //#region src/plugins/preview.ts
16049
+ let exitCallback = () => {};
16050
+ process.on("exit", () => {
16051
+ exitCallback();
16052
+ });
15928
16053
  /**
15929
16054
  * Plugin to provide core preview functionality
15930
16055
  */
@@ -15944,9 +16069,9 @@ const previewPlugin = createPlugin("preview", (ctx) => {
15944
16069
  });
15945
16070
  const containerImageTags = new Set(containerTagToOptionsMap.keys());
15946
16071
  vitePreviewServer.config.logger.info(colors.dim(colors.yellow("\n⚡️ Containers successfully built.\n")));
15947
- process.on("exit", () => {
16072
+ exitCallback = () => {
15948
16073
  if (containerImageTags.size) cleanupContainers(dockerPath, containerImageTags);
15949
- });
16074
+ };
15950
16075
  }
15951
16076
  handleWebSocket(vitePreviewServer.httpServer, ctx.miniflare);
15952
16077
  vitePreviewServer.middlewares.use(createRequestHandler((request$1) => {
@@ -16053,4 +16178,4 @@ function cloudflare(pluginConfig = {}) {
16053
16178
 
16054
16179
  //#endregion
16055
16180
  export { cloudflare };
16056
- //# sourceMappingURL=index.js.map
16181
+ //# sourceMappingURL=index.mjs.map