devflare 1.0.0-next.39 → 1.0.0-next.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/dist/_chunks/account-BtWcv3X9.js +462 -0
  2. package/dist/_chunks/account-resources-CsmVowJp.js +159 -0
  3. package/dist/_chunks/ai-CBEuLdoP.js +322 -0
  4. package/dist/_chunks/api-TzdliH-6.js +568 -0
  5. package/dist/_chunks/build-3T6O4uIg.js +24 -0
  6. package/dist/_chunks/build-artifacts-8TqBSQkG.js +483 -0
  7. package/dist/_chunks/cli-BTF1X4SG.js +1128 -0
  8. package/dist/_chunks/cloudflare-BaloqI3H.js +157 -0
  9. package/dist/_chunks/colors-DiK6wPJ5.js +13 -0
  10. package/dist/_chunks/command-utils-BsfkmTqh.js +45 -0
  11. package/dist/_chunks/compiler-uoyAQ8zW.js +424 -0
  12. package/dist/_chunks/config-D5u-bEkn.js +78 -0
  13. package/dist/_chunks/config-path-DCPto4XB.js +42 -0
  14. package/dist/_chunks/context-CX50Y2Kb.js +2250 -0
  15. package/dist/_chunks/decorators-QmV57ixr.js +19 -0
  16. package/dist/_chunks/dependencies-C2oxFjU_.js +57 -0
  17. package/dist/_chunks/deploy-DMTr6JeR.js +915 -0
  18. package/dist/_chunks/dev-CvRHmRFZ.js +3456 -0
  19. package/dist/_chunks/doctor-DIG8DoFU.js +219 -0
  20. package/dist/_chunks/durable-object-DMtH0XYX.js +234 -0
  21. package/dist/_chunks/env-S0_nMVz1.js +125 -0
  22. package/dist/_chunks/family-DXC5SdFK.js +143 -0
  23. package/dist/_chunks/generated-artifacts-dMJY4KAt.js +32 -0
  24. package/dist/_chunks/glob-CmQOvunB.js +56 -0
  25. package/dist/_chunks/init-3moXTgpb.js +165 -0
  26. package/dist/_chunks/loader-DLXO60RO.js +1153 -0
  27. package/dist/_chunks/local-dev-vars-CTSa-wvF.js +81 -0
  28. package/dist/_chunks/local-hyperdrive-CJ90j46O.js +119 -0
  29. package/dist/_chunks/local-media-bindings-DsAW4AMF.js +335 -0
  30. package/dist/_chunks/local-secrets-DMmEOygL.js +123 -0
  31. package/dist/_chunks/local-workflow-entrypoints-Wip3o1u8.js +90 -0
  32. package/dist/_chunks/login-BmnDzDlH.js +51 -0
  33. package/dist/_chunks/package-metadata-DAuCkyvK.js +39 -0
  34. package/dist/_chunks/preferences-BKp_7XJx.js +241 -0
  35. package/dist/_chunks/preview-BhqDmq8I.js +456 -0
  36. package/dist/_chunks/preview-registry-ClAbLTHH.js +1186 -0
  37. package/dist/_chunks/preview-resources-DdXj8LMM.js +358 -0
  38. package/dist/_chunks/previews-Dlr13x5M.js +1134 -0
  39. package/dist/_chunks/productions-D3AnOHac.js +411 -0
  40. package/dist/_chunks/ref-CYJNAAe_.js +178 -0
  41. package/dist/_chunks/remote-CZnP-HLJ.js +79 -0
  42. package/dist/_chunks/remote-config-D39BY9ji.js +132 -0
  43. package/dist/_chunks/resolve-package-Y84HB3Nt.js +133 -0
  44. package/dist/_chunks/rolldown-runtime-CvQ6eiug.js +14 -0
  45. package/dist/_chunks/routes-C3FqES2W.js +796 -0
  46. package/dist/_chunks/runtime-FvXvfuZ2.js +550 -0
  47. package/dist/_chunks/schema-normalization-DWVleVxo.js +477 -0
  48. package/dist/_chunks/secrets-70eN0Q6C.js +95 -0
  49. package/dist/_chunks/token-kguIDmej.js +333 -0
  50. package/dist/_chunks/tokens-iVcgNXi-.js +221 -0
  51. package/dist/_chunks/types-OrLbzv4I.js +476 -0
  52. package/dist/_chunks/ui-BUoZApvE.js +103 -0
  53. package/dist/_chunks/usage-BBTGzjon.js +272 -0
  54. package/dist/_chunks/vite-CsI0E-uV.js +1235 -0
  55. package/dist/_chunks/vite-utils-OVLMV605.js +183 -0
  56. package/dist/_chunks/worker-CS1jgNFE.js +410 -0
  57. package/dist/_chunks/worker-bundler-dTTnYU3n.js +458 -0
  58. package/dist/_chunks/worker-entrypoint-CQW77lG8.js +247 -0
  59. package/dist/_chunks/workerName-CFJsLZA-.js +23 -0
  60. package/dist/bridge/index.d.ts +6 -6
  61. package/dist/bridge/miniflare.d.ts +2 -2
  62. package/dist/bridge/proxy.d.ts +1 -1
  63. package/dist/bridge/v2/body-streams.d.ts +1 -1
  64. package/dist/bridge/v2/codec.d.ts +4 -4
  65. package/dist/bridge/v2/index.d.ts +10 -10
  66. package/dist/bridge/v2/serialization.d.ts +1 -1
  67. package/dist/bridge/v2/value-codec.d.ts +1 -1
  68. package/dist/bridge/v2/value-serialization.d.ts.map +1 -1
  69. package/dist/bridge/v2/ws-relay.d.ts +3 -3
  70. package/dist/browser-shim/index.d.ts +2 -2
  71. package/dist/browser.d.ts +70 -70
  72. package/dist/browser.js +74 -2462
  73. package/dist/bundler/do-bundler.d.ts +1 -1
  74. package/dist/bundler/index.d.ts +3 -3
  75. package/dist/bundler/rolldown-shared.d.ts +1 -1
  76. package/dist/bundler/worker-bundler.d.ts +1 -1
  77. package/dist/cli/build-manifest.d.ts +1 -1
  78. package/dist/cli/command-utils.d.ts +1 -1
  79. package/dist/cli/commands/account.d.ts +1 -1
  80. package/dist/cli/commands/ai.d.ts +1 -1
  81. package/dist/cli/commands/build-artifacts.d.ts +5 -5
  82. package/dist/cli/commands/build.d.ts +1 -1
  83. package/dist/cli/commands/config.d.ts +1 -1
  84. package/dist/cli/commands/deploy/prepare.d.ts +2 -2
  85. package/dist/cli/commands/deploy/runtime.d.ts +1 -1
  86. package/dist/cli/commands/deploy/verification.d.ts +1 -1
  87. package/dist/cli/commands/deploy.d.ts +1 -1
  88. package/dist/cli/commands/dev.d.ts +1 -1
  89. package/dist/cli/commands/doctor.d.ts +1 -1
  90. package/dist/cli/commands/init.d.ts +1 -1
  91. package/dist/cli/commands/login.d.ts +1 -1
  92. package/dist/cli/commands/previews-support/cleanup.d.ts +1 -1
  93. package/dist/cli/commands/previews-support/family.d.ts +3 -3
  94. package/dist/cli/commands/previews-support/render.d.ts +3 -3
  95. package/dist/cli/commands/previews-support/theme.d.ts +2 -2
  96. package/dist/cli/commands/previews-support/types.d.ts +2 -2
  97. package/dist/cli/commands/previews.d.ts +1 -1
  98. package/dist/cli/commands/productions.d.ts +1 -1
  99. package/dist/cli/commands/remote.d.ts +1 -1
  100. package/dist/cli/commands/secrets.d.ts +1 -1
  101. package/dist/cli/commands/token.d.ts +1 -1
  102. package/dist/cli/commands/type-generation/discovery.d.ts +2 -2
  103. package/dist/cli/commands/type-generation/generator.d.ts +3 -3
  104. package/dist/cli/commands/type-generation/models.d.ts +1 -1
  105. package/dist/cli/commands/types.d.ts +1 -1
  106. package/dist/cli/commands/worker.d.ts +1 -1
  107. package/dist/cli/deploy-strategy.d.ts +1 -1
  108. package/dist/cli/deploy-target.d.ts +1 -1
  109. package/dist/cli/help-pages/pages/account.d.ts +1 -1
  110. package/dist/cli/help-pages/pages/core.d.ts +1 -1
  111. package/dist/cli/help-pages/pages/index.d.ts +1 -1
  112. package/dist/cli/help-pages/pages/misc.d.ts +1 -1
  113. package/dist/cli/help-pages/pages/previews.d.ts +1 -1
  114. package/dist/cli/help-pages/pages/productions.d.ts +1 -1
  115. package/dist/cli/help-pages/render.d.ts +2 -2
  116. package/dist/cli/help-pages/shared.d.ts +1 -1
  117. package/dist/cli/help.d.ts +2 -2
  118. package/dist/cli/index.js +2 -1383
  119. package/dist/cli/preview-bindings.d.ts +3 -3
  120. package/dist/cli/preview.d.ts +1 -1
  121. package/dist/cli/wrangler-auth.d.ts +1 -1
  122. package/dist/cloudflare/account-core.d.ts +2 -2
  123. package/dist/cloudflare/account-resources.d.ts +2 -2
  124. package/dist/cloudflare/account-status.d.ts +1 -1
  125. package/dist/cloudflare/account-workers.d.ts +2 -2
  126. package/dist/cloudflare/account.d.ts +7 -7
  127. package/dist/cloudflare/auth.d.ts +1 -1
  128. package/dist/cloudflare/index.d.ts +13 -13
  129. package/dist/cloudflare/index.js +4 -59
  130. package/dist/cloudflare/kv-namespace.d.ts +1 -1
  131. package/dist/cloudflare/preview-registry-cache.d.ts +1 -1
  132. package/dist/cloudflare/preview-registry-inference.d.ts +2 -2
  133. package/dist/cloudflare/preview-registry-records.d.ts +3 -3
  134. package/dist/cloudflare/preview-registry-shape.d.ts +2 -2
  135. package/dist/cloudflare/preview-registry-store.d.ts +3 -3
  136. package/dist/cloudflare/preview-registry-transport.d.ts +2 -2
  137. package/dist/cloudflare/preview-registry-types.d.ts +2 -2
  138. package/dist/cloudflare/preview-registry.d.ts +5 -5
  139. package/dist/cloudflare/tokens.d.ts +2 -2
  140. package/dist/cloudflare/usage.d.ts +2 -2
  141. package/dist/config/binding-resolution-helpers.d.ts +1 -1
  142. package/dist/config/compiler/bindings.d.ts +2 -2
  143. package/dist/config/compiler/core-helpers.d.ts +2 -2
  144. package/dist/config/compiler/do-workers.d.ts +2 -2
  145. package/dist/config/compiler/paths.d.ts +1 -1
  146. package/dist/config/compiler.d.ts +6 -6
  147. package/dist/config/define.d.ts +2 -2
  148. package/dist/config/deploy-resources.d.ts +5 -5
  149. package/dist/config/env-vars.d.ts +1 -1
  150. package/dist/config/framework-providers.d.ts +1 -1
  151. package/dist/config/index.d.ts +12 -12
  152. package/dist/config/loader.d.ts +2 -2
  153. package/dist/config/local-dev-vars.d.ts +1 -1
  154. package/dist/config/preview-resources.d.ts +4 -4
  155. package/dist/config/preview.d.ts +1 -1
  156. package/dist/config/ref.d.ts +2 -2
  157. package/dist/config/resolve-phased.d.ts +4 -4
  158. package/dist/config/resolve.d.ts +1 -1
  159. package/dist/config/resource-resolution.d.ts +6 -6
  160. package/dist/config/schema-env.d.ts +20 -20
  161. package/dist/config/schema-normalization.d.ts +1 -1
  162. package/dist/config/schema-types-bindings.d.ts +4 -4
  163. package/dist/config/schema-types-build.d.ts +1 -1
  164. package/dist/config/schema-types.d.ts +7 -7
  165. package/dist/config/schema.d.ts +46 -46
  166. package/dist/config/service-bindings-validation.d.ts +1 -1
  167. package/dist/config-entry.d.ts +6 -6
  168. package/dist/config-entry.js +3 -8
  169. package/dist/decorators/index.d.ts +2 -2
  170. package/dist/decorators/index.js +2 -9
  171. package/dist/dev-server/d1-migrations.d.ts +1 -1
  172. package/dist/dev-server/dev-server-state.d.ts +6 -6
  173. package/dist/dev-server/gateway-script.d.ts +1 -1
  174. package/dist/dev-server/index.d.ts +1 -1
  175. package/dist/dev-server/miniflare-bindings.d.ts +1 -1
  176. package/dist/dev-server/miniflare-dev-config.d.ts +5 -5
  177. package/dist/dev-server/miniflare-worker-config.d.ts +3 -3
  178. package/dist/dev-server/server-startup-helpers.d.ts +6 -6
  179. package/dist/dev-server/worker-surface-paths.d.ts +2 -2
  180. package/dist/index.d.ts +8 -8
  181. package/dist/index.js +9 -22
  182. package/dist/runtime/context-events.d.ts +1 -1
  183. package/dist/runtime/context.d.ts +3 -3
  184. package/dist/runtime/exports.d.ts +2 -2
  185. package/dist/runtime/index.d.ts +10 -10
  186. package/dist/runtime/index.js +5 -57
  187. package/dist/runtime/middleware.d.ts +1 -1
  188. package/dist/runtime/router/index.d.ts +3 -3
  189. package/dist/runtime/validation.d.ts +1 -1
  190. package/dist/secrets/local-secrets.d.ts +1 -1
  191. package/dist/shims/local-media-bindings.d.ts +1 -1
  192. package/dist/sveltekit/index.d.ts +1 -1
  193. package/dist/sveltekit/index.js +327 -9
  194. package/dist/sveltekit/local-bindings.d.ts +1 -1
  195. package/dist/sveltekit/platform.d.ts +1 -1
  196. package/dist/test/binding-hints.d.ts +2 -2
  197. package/dist/test/cf.d.ts +19 -19
  198. package/dist/test/index.d.ts +18 -18
  199. package/dist/test/index.js +4495 -46
  200. package/dist/test/offline-bindings.d.ts +3 -3
  201. package/dist/test/resolve-service-bindings.d.ts +1 -1
  202. package/dist/test/simple-context-bindings.d.ts +1 -1
  203. package/dist/test/simple-context-durable-objects.d.ts +1 -1
  204. package/dist/test/simple-context-env.d.ts +2 -2
  205. package/dist/test/simple-context-handlers.d.ts +2 -2
  206. package/dist/test/simple-context-lifecycle.d.ts +2 -2
  207. package/dist/test/simple-context-mfconfig.d.ts +1 -1
  208. package/dist/test/simple-context-multi-worker.d.ts +2 -2
  209. package/dist/test/simple-context-runtime.d.ts +1 -1
  210. package/dist/test/simple-context-startup.d.ts +1 -1
  211. package/dist/test/simple-context.d.ts +1 -1
  212. package/dist/test/utilities/env.d.ts +3 -3
  213. package/dist/test/utilities.d.ts +10 -10
  214. package/dist/test/worker.d.ts +1 -1
  215. package/dist/transform/index.d.ts +2 -2
  216. package/dist/utils/send-email.js +163 -19
  217. package/dist/vite/config-file.d.ts +2 -2
  218. package/dist/vite/index.d.ts +3 -3
  219. package/dist/vite/index.js +2 -31
  220. package/dist/vite/plugin-config-hook.d.ts +1 -1
  221. package/dist/vite/plugin-context.d.ts +3 -3
  222. package/dist/vite/plugin-durable-objects.d.ts +2 -2
  223. package/dist/vite/plugin-programmatic.d.ts +1 -1
  224. package/dist/vite/plugin-service-bindings.d.ts +2 -2
  225. package/dist/vite/plugin.d.ts +3 -3
  226. package/dist/worker-entry/composed-worker.d.ts +1 -1
  227. package/dist/worker-entry/routes.d.ts +2 -2
  228. package/dist/worker-entry/surface-paths.d.ts +1 -1
  229. package/dist/workflows/local-workflow-entrypoints.d.ts +1 -1
  230. package/package.json +5 -3
  231. package/dist/account-4tgh03a8.js +0 -484
  232. package/dist/ai-r3zqmxan.js +0 -261
  233. package/dist/api-6z01z734.js +0 -33
  234. package/dist/build-kw625v84.js +0 -51
  235. package/dist/config-ghk2bxj3.js +0 -102
  236. package/dist/deploy-9kee65n9.js +0 -1062
  237. package/dist/dev-x8zr249a.js +0 -3569
  238. package/dist/doctor-0ng5qrr1.js +0 -258
  239. package/dist/durable-object-0ybmg08a.js +0 -13
  240. package/dist/index-04wh9bxx.js +0 -514
  241. package/dist/index-0cc05hzv.js +0 -74
  242. package/dist/index-2yv7w548.js +0 -185
  243. package/dist/index-37x76zdn.js +0 -4
  244. package/dist/index-3cpzsr47.js +0 -125
  245. package/dist/index-3t6rypgc.js +0 -13
  246. package/dist/index-4mmpccrb.js +0 -309
  247. package/dist/index-5dkjffqz.js +0 -25
  248. package/dist/index-5hy7jmv3.js +0 -890
  249. package/dist/index-627srx16.js +0 -45
  250. package/dist/index-7m557715.js +0 -283
  251. package/dist/index-a8pnvg3r.js +0 -52
  252. package/dist/index-aabgympv.js +0 -39
  253. package/dist/index-atwc3csp.js +0 -256
  254. package/dist/index-cv4cvrxe.js +0 -2046
  255. package/dist/index-h7r11y4a.js +0 -539
  256. package/dist/index-hvtd936d.js +0 -1229
  257. package/dist/index-kcp7y951.js +0 -136
  258. package/dist/index-maw0jjnn.js +0 -147
  259. package/dist/index-mek9msfv.js +0 -705
  260. package/dist/index-n4xkaymm.js +0 -236
  261. package/dist/index-nkk59p3y.js +0 -579
  262. package/dist/index-phcrvs6d.js +0 -342
  263. package/dist/index-se4kw8tm.js +0 -460
  264. package/dist/index-x8s9rwfh.js +0 -2020
  265. package/dist/index-y7w3x9p1.js +0 -18
  266. package/dist/index-z9gy8w6b.js +0 -57
  267. package/dist/index-zdd0d9qa.js +0 -199
  268. package/dist/init-tb8jqgvr.js +0 -180
  269. package/dist/login-4h1sfsed.js +0 -75
  270. package/dist/previews-qr7c5j8h.js +0 -1336
  271. package/dist/productions-xpmd6bw8.js +0 -505
  272. package/dist/remote-kqcvhnfx.js +0 -192
  273. package/dist/secrets-6wbdsdek.js +0 -89
  274. package/dist/token-yp1qa70y.js +0 -419
  275. package/dist/types-15yv4cj3.js +0 -701
  276. package/dist/worker-1yg72jxg.js +0 -510
  277. package/dist/worker-entrypoint-y8s9kdcx.js +0 -15
@@ -1,2046 +0,0 @@
1
- import {
2
- discoverEntrypointsSync,
3
- resolvePackageSpecifier
4
- } from "./index-3cpzsr47.js";
5
- import {
6
- DEFAULT_DO_PATTERN,
7
- findFiles,
8
- findFilesSync
9
- } from "./index-5dkjffqz.js";
10
- import {
11
- compileBuildConfig,
12
- compileConfig,
13
- compileToProgrammaticConfig,
14
- isolateViteBuildOutputPaths,
15
- rebaseWranglerConfigPaths,
16
- writeWranglerConfig
17
- } from "./index-mek9msfv.js";
18
- import {
19
- configSchema,
20
- getLocalD1DatabaseIdentifier,
21
- getLocalKVNamespaceIdentifier,
22
- loadConfig,
23
- normalizeArtifactsBinding,
24
- normalizeDOBinding,
25
- normalizeDispatchNamespaceBinding,
26
- normalizeHyperdriveBinding,
27
- normalizeImagesBinding,
28
- normalizeMediaBinding,
29
- normalizeMtlsCertificateBinding,
30
- normalizePipelineBinding,
31
- normalizeSecretsStoreBinding,
32
- normalizeWorkflowBinding,
33
- resolveConfigEnvVars,
34
- resolveConfigForEnvironment,
35
- resolveConfigPath,
36
- resolveResources
37
- } from "./index-x8s9rwfh.js";
38
- import {
39
- SUPPORTED_WORKER_EXTENSIONS,
40
- transformWorkerEntrypoint
41
- } from "./index-7m557715.js";
42
- import {
43
- findDurableObjectClasses
44
- } from "./index-4mmpccrb.js";
45
- import {
46
- __require
47
- } from "./index-37x76zdn.js";
48
- // src/vite/plugin.ts
49
- import { dirname as dirname3, resolve as resolve6 } from "pathe";
50
-
51
- // src/vite/plugin-config-hook.ts
52
- async function tryLoadDevflareConfig(cwd, configPath, command) {
53
- try {
54
- return await loadConfig({ cwd, configFile: configPath });
55
- } catch (error) {
56
- if (command === "build") {
57
- console.warn("[devflare] Could not load config:", error);
58
- }
59
- return null;
60
- }
61
- }
62
- function buildWorkerNameDefine(lfConfig, existing) {
63
- const workerNameValue = lfConfig.name ?? "unknown";
64
- return {
65
- ...existing,
66
- __DEVFLARE_WORKER_NAME__: JSON.stringify(workerNameValue)
67
- };
68
- }
69
- function buildWebSocketProxyConfig(lfConfig, bridgePort, wsProxyPatterns) {
70
- const patterns = [...wsProxyPatterns];
71
- if (lfConfig.wsRoutes && lfConfig.wsRoutes.length > 0) {
72
- for (const route of lfConfig.wsRoutes) {
73
- if (!patterns.includes(route.pattern)) {
74
- patterns.push(route.pattern);
75
- }
76
- }
77
- }
78
- if (patterns.length === 0)
79
- return null;
80
- const proxyConfig = {};
81
- for (const pattern of patterns) {
82
- proxyConfig[pattern] = {
83
- target: `http://127.0.0.1:${bridgePort}`,
84
- changeOrigin: true,
85
- ws: true,
86
- configure: (proxy) => {
87
- proxy.on("error", (err) => {
88
- console.error(`[devflare] Proxy error: ${err.message}`);
89
- });
90
- }
91
- };
92
- }
93
- if (Object.keys(proxyConfig).length === 0)
94
- return null;
95
- console.log(`[devflare] WebSocket proxy configured for: ${patterns.join(", ")}`);
96
- return proxyConfig;
97
- }
98
- async function buildPluginConfigHookResult(cwd, options, command, existingDefine) {
99
- const lfConfig = await tryLoadDevflareConfig(cwd, options.configPath, command);
100
- const returnConfig = {};
101
- if (lfConfig) {
102
- returnConfig.define = buildWorkerNameDefine(lfConfig, existingDefine);
103
- }
104
- if (command === "serve" && process.env.DEVFLARE_DEV && lfConfig) {
105
- const port = options.bridgePort ?? 8787;
106
- const proxyConfig = buildWebSocketProxyConfig(lfConfig, port, options.wsProxyPatterns);
107
- if (proxyConfig) {
108
- returnConfig.server = { proxy: proxyConfig };
109
- }
110
- }
111
- return Object.keys(returnConfig).length > 0 ? returnConfig : undefined;
112
- }
113
-
114
- // src/vite/plugin-context.ts
115
- import { isAbsolute, relative as relative3, resolve as resolve5 } from "pathe";
116
-
117
- // src/test/resolve-service-bindings.ts
118
- import { existsSync, readFileSync } from "fs";
119
- import { dirname, join, resolve } from "path";
120
-
121
- // src/dev-server/miniflare-bindings.ts
122
- function buildQueueProducers(bindings) {
123
- if (!bindings.queues?.producers) {
124
- return;
125
- }
126
- const producers = {};
127
- for (const [bindingName, queueName] of Object.entries(bindings.queues.producers)) {
128
- producers[bindingName] = { queueName };
129
- }
130
- return producers;
131
- }
132
- function buildQueueConsumers(bindings) {
133
- if (!bindings.queues?.consumers || bindings.queues.consumers.length === 0) {
134
- return;
135
- }
136
- const consumers = {};
137
- for (const consumer of bindings.queues.consumers) {
138
- consumers[consumer.queue] = {
139
- ...consumer.maxBatchSize !== undefined && { maxBatchSize: consumer.maxBatchSize },
140
- ...consumer.maxBatchTimeout !== undefined && { maxBatchTimeout: consumer.maxBatchTimeout },
141
- ...consumer.maxRetries !== undefined && { maxRetries: consumer.maxRetries },
142
- ...consumer.deadLetterQueue && { deadLetterQueue: consumer.deadLetterQueue },
143
- ...consumer.maxConcurrency !== undefined && { maxConcurrency: consumer.maxConcurrency },
144
- ...consumer.retryDelay !== undefined && { retryDelay: consumer.retryDelay }
145
- };
146
- }
147
- return consumers;
148
- }
149
- function buildRateLimitsConfig(bindings) {
150
- if (!bindings.rateLimits) {
151
- return;
152
- }
153
- return Object.fromEntries(Object.entries(bindings.rateLimits).map(([name, binding]) => [
154
- name,
155
- {
156
- simple: {
157
- limit: binding.simple.limit,
158
- period: binding.simple.period
159
- }
160
- }
161
- ]));
162
- }
163
- function buildVersionMetadataConfig(bindings) {
164
- return bindings.versionMetadata?.binding;
165
- }
166
- function buildWorkerLoadersConfig(bindings) {
167
- if (!bindings.workerLoaders) {
168
- return;
169
- }
170
- return Object.fromEntries(Object.keys(bindings.workerLoaders).map((bindingName) => [bindingName, {}]));
171
- }
172
- function buildMtlsCertificatesConfig(bindings) {
173
- if (!bindings.mtlsCertificates) {
174
- return;
175
- }
176
- return Object.fromEntries(Object.entries(bindings.mtlsCertificates).map(([bindingName, binding]) => {
177
- const normalized = normalizeMtlsCertificateBinding(binding);
178
- return [
179
- bindingName,
180
- {
181
- certificate_id: normalized.certificateId
182
- }
183
- ];
184
- }));
185
- }
186
- function buildDispatchNamespacesConfig(bindings) {
187
- if (!bindings.dispatchNamespaces) {
188
- return;
189
- }
190
- return Object.fromEntries(Object.entries(bindings.dispatchNamespaces).map(([bindingName, binding]) => {
191
- const normalized = normalizeDispatchNamespaceBinding(binding);
192
- return [
193
- bindingName,
194
- {
195
- namespace: normalized.namespace
196
- }
197
- ];
198
- }));
199
- }
200
- function buildWorkflowsConfig(bindings) {
201
- if (!bindings.workflows) {
202
- return;
203
- }
204
- return Object.fromEntries(Object.entries(bindings.workflows).map(([bindingName, binding]) => {
205
- const normalized = normalizeWorkflowBinding(binding);
206
- return [
207
- bindingName,
208
- {
209
- name: normalized.name,
210
- className: normalized.className,
211
- ...normalized.scriptName && { scriptName: normalized.scriptName },
212
- ...normalized.limits && { stepLimit: normalized.limits.steps }
213
- }
214
- ];
215
- }));
216
- }
217
- function buildPipelinesConfig(bindings) {
218
- if (!bindings.pipelines) {
219
- return;
220
- }
221
- return Object.fromEntries(Object.entries(bindings.pipelines).map(([bindingName, binding]) => {
222
- const normalized = normalizePipelineBinding(binding);
223
- return [
224
- bindingName,
225
- typeof binding === "string" ? normalized.pipeline : { pipeline: normalized.pipeline }
226
- ];
227
- }));
228
- }
229
- function getHyperdriveLocalConnectionString(bindingName, binding) {
230
- const cloudflareEnvName = `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_${bindingName}`;
231
- const wranglerEnvName = `WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${bindingName}`;
232
- const envValue = process.env[cloudflareEnvName] ?? process.env[wranglerEnvName];
233
- if (envValue?.trim()) {
234
- return envValue;
235
- }
236
- const normalized = normalizeHyperdriveBinding(binding);
237
- return normalized.localConnectionString;
238
- }
239
- function buildHyperdrivesConfig(bindings) {
240
- if (!bindings.hyperdrive) {
241
- return;
242
- }
243
- const hyperdrives = Object.fromEntries(Object.entries(bindings.hyperdrive).map(([bindingName, binding]) => {
244
- const localConnectionString = getHyperdriveLocalConnectionString(bindingName, binding);
245
- return localConnectionString ? [bindingName, localConnectionString] : null;
246
- }).filter((entry) => entry !== null));
247
- return Object.keys(hyperdrives).length > 0 ? hyperdrives : undefined;
248
- }
249
- function buildImagesConfig(bindings) {
250
- if (!bindings.images) {
251
- return;
252
- }
253
- const [entry] = Object.entries(bindings.images);
254
- if (!entry) {
255
- return;
256
- }
257
- const [bindingName, binding] = entry;
258
- const normalized = normalizeImagesBinding(bindingName, binding);
259
- return {
260
- binding: normalized.binding
261
- };
262
- }
263
- function buildMediaConfig(bindings) {
264
- if (!bindings.media) {
265
- return;
266
- }
267
- const [entry] = Object.entries(bindings.media);
268
- if (!entry) {
269
- return;
270
- }
271
- const [bindingName, binding] = entry;
272
- const normalized = normalizeMediaBinding(bindingName, binding);
273
- return {
274
- binding: normalized.binding
275
- };
276
- }
277
- function buildArtifactsConfig(bindings) {
278
- if (!bindings.artifacts) {
279
- return;
280
- }
281
- return Object.fromEntries(Object.entries(bindings.artifacts).map(([bindingName, binding]) => {
282
- const normalized = normalizeArtifactsBinding(binding);
283
- return [
284
- bindingName,
285
- {
286
- namespace: normalized.namespace
287
- }
288
- ];
289
- }));
290
- }
291
- function buildAiSearchNamespacesConfig(bindings) {
292
- if (!bindings.aiSearchNamespaces) {
293
- return;
294
- }
295
- return Object.fromEntries(Object.entries(bindings.aiSearchNamespaces).map(([bindingName, binding]) => [
296
- bindingName,
297
- {
298
- namespace: binding.namespace
299
- }
300
- ]));
301
- }
302
- function buildAiSearchInstancesConfig(bindings) {
303
- if (!bindings.aiSearch) {
304
- return;
305
- }
306
- return Object.fromEntries(Object.entries(bindings.aiSearch).map(([bindingName, binding]) => [
307
- bindingName,
308
- {
309
- instance_name: binding.instanceName
310
- }
311
- ]));
312
- }
313
- function buildSecretsStoreConfig(bindings, defaultSecretsStoreId, excludedBindingNames = new Set) {
314
- if (!bindings.secretsStore) {
315
- return;
316
- }
317
- const entries = Object.entries(bindings.secretsStore).flatMap(([bindingName, binding]) => {
318
- if (excludedBindingNames.has(bindingName)) {
319
- return [];
320
- }
321
- const normalized = normalizeSecretsStoreBinding(binding, defaultSecretsStoreId, bindingName);
322
- return [
323
- [
324
- bindingName,
325
- {
326
- store_id: normalized.storeId,
327
- secret_name: normalized.secretName
328
- }
329
- ]
330
- ];
331
- });
332
- return entries.length > 0 ? Object.fromEntries(entries) : undefined;
333
- }
334
- function buildSendEmailConfig(bindings) {
335
- if (!bindings.sendEmail) {
336
- return;
337
- }
338
- return {
339
- send_email: Object.entries(bindings.sendEmail).map(([name, binding]) => ({
340
- name,
341
- ...binding.destinationAddress && {
342
- destination_address: binding.destinationAddress
343
- },
344
- ...binding.allowedDestinationAddresses && {
345
- allowed_destination_addresses: binding.allowedDestinationAddresses
346
- },
347
- ...binding.allowedSenderAddresses && {
348
- allowed_sender_addresses: binding.allowedSenderAddresses
349
- }
350
- }))
351
- };
352
- }
353
-
354
- // src/test/resolve-service-bindings.ts
355
- function getBunRuntime() {
356
- const g = globalThis;
357
- if (typeof g.Bun === "object" && g.Bun !== null) {
358
- return g.Bun;
359
- }
360
- return;
361
- }
362
- function discoverDOFilesSync(dir, pattern = DEFAULT_DO_PATTERN) {
363
- const classToPath = new Map;
364
- try {
365
- const files = findFilesSync(pattern, { cwd: dir });
366
- for (const filePath of files) {
367
- try {
368
- const code = readFileSync(filePath, "utf-8");
369
- const classNames = findDurableObjectClasses(code);
370
- for (const className of classNames) {
371
- if (!classToPath.has(className)) {
372
- classToPath.set(className, filePath);
373
- }
374
- }
375
- } catch {}
376
- }
377
- } catch {}
378
- return classToPath;
379
- }
380
- var bundleCache = new Map;
381
- function findDefaultServiceWorkerEntrypoint(refConfigDir) {
382
- for (const candidate of ["worker.ts", "worker.js", "src/worker.ts", "src/worker.js"]) {
383
- const absolutePath = resolve(refConfigDir, candidate);
384
- if (existsSync(absolutePath)) {
385
- return absolutePath;
386
- }
387
- }
388
- return null;
389
- }
390
- function buildRawServiceBindings(services) {
391
- if (!services || Object.keys(services).length === 0) {
392
- return;
393
- }
394
- return Object.fromEntries(Object.entries(services).map(([bindingName, binding]) => [
395
- bindingName,
396
- {
397
- name: binding.service,
398
- ...binding.entrypoint && { entrypoint: binding.entrypoint }
399
- }
400
- ]));
401
- }
402
- function buildReferencedWorkerRuntimeConfig(config) {
403
- const bindings = config.bindings ?? {};
404
- const queueProducers = buildQueueProducers(bindings);
405
- const queueConsumers = buildQueueConsumers(bindings);
406
- const rateLimits = buildRateLimitsConfig(bindings);
407
- const versionMetadata = buildVersionMetadataConfig(bindings);
408
- const workerLoaders = buildWorkerLoadersConfig(bindings);
409
- const mtlsCertificates = buildMtlsCertificatesConfig(bindings);
410
- const dispatchNamespaces = buildDispatchNamespacesConfig(bindings);
411
- const workflows = buildWorkflowsConfig(bindings);
412
- const pipelines = buildPipelinesConfig(bindings);
413
- const hyperdrives = buildHyperdrivesConfig(bindings);
414
- const media = buildMediaConfig(bindings);
415
- const artifacts = buildArtifactsConfig(bindings);
416
- const aiSearchNamespaces = buildAiSearchNamespacesConfig(bindings);
417
- const aiSearchInstances = buildAiSearchInstancesConfig(bindings);
418
- const secretsStoreSecrets = buildSecretsStoreConfig(bindings, config.secretsStoreId);
419
- const email = buildSendEmailConfig(bindings);
420
- const serviceBindings = buildRawServiceBindings(bindings.services);
421
- return {
422
- ...config.compatibilityFlags && { compatibilityFlags: config.compatibilityFlags },
423
- ...config.vars && { bindings: config.vars },
424
- ...bindings.kv && {
425
- kvNamespaces: Object.fromEntries(Object.entries(bindings.kv).map(([bindingName, bindingConfig]) => [
426
- bindingName,
427
- getLocalKVNamespaceIdentifier(bindingConfig)
428
- ]))
429
- },
430
- ...bindings.r2 && { r2Buckets: bindings.r2 },
431
- ...bindings.d1 && {
432
- d1Databases: Object.fromEntries(Object.entries(bindings.d1).map(([bindingName, bindingConfig]) => [
433
- bindingName,
434
- getLocalD1DatabaseIdentifier(bindingConfig)
435
- ]))
436
- },
437
- ...queueProducers && { queueProducers },
438
- ...queueConsumers && { queueConsumers },
439
- ...rateLimits && { ratelimits: rateLimits },
440
- ...versionMetadata && { versionMetadata },
441
- ...workerLoaders && { workerLoaders },
442
- ...mtlsCertificates && { mtlsCertificates },
443
- ...dispatchNamespaces && { dispatchNamespaces },
444
- ...workflows && { workflows },
445
- ...pipelines && { pipelines },
446
- ...hyperdrives && { hyperdrives },
447
- ...media && { media },
448
- ...artifacts && { artifacts },
449
- ...aiSearchNamespaces && { aiSearchNamespaces },
450
- ...aiSearchInstances && { aiSearchInstances },
451
- ...secretsStoreSecrets && { secretsStoreSecrets },
452
- ...email && { email },
453
- ...serviceBindings && { serviceBindings }
454
- };
455
- }
456
- function normalizeReferencedConfig(config) {
457
- return configSchema.parse(config);
458
- }
459
- function resolveReferencedConfigDir(ref, parentConfigDir) {
460
- const configPath = ref.configPath;
461
- if (!configPath || configPath === "<resolved>") {
462
- return null;
463
- }
464
- return dirname(resolvePackageSpecifier(configPath, parentConfigDir));
465
- }
466
- async function resolveReferencedLocalDurableObjects(config, configDir, workerName, serviceBindings = {}) {
467
- const doPattern = config.files?.durableObjects;
468
- const dosConfig = config.bindings?.durableObjects;
469
- if (typeof doPattern !== "string" || !dosConfig || Object.keys(dosConfig).length === 0) {
470
- return { workers: [], bindings: {} };
471
- }
472
- const discoveredDOs = discoverDOFilesSync(configDir, doPattern);
473
- const doClasses = [];
474
- for (const [bindingName, rawDoConfig] of Object.entries(dosConfig)) {
475
- const doConfig = normalizeDOBinding(rawDoConfig);
476
- if (doConfig.kind !== "local") {
477
- continue;
478
- }
479
- const scriptPath = discoveredDOs.get(doConfig.className);
480
- if (!scriptPath) {
481
- console.warn(`[devflare] DO "${bindingName}" (class: ${doConfig.className}) not found in files.durableObjects for "${workerName}"`);
482
- continue;
483
- }
484
- doClasses.push({ bindingName, className: doConfig.className, scriptPath });
485
- }
486
- if (doClasses.length === 0) {
487
- return { workers: [], bindings: {} };
488
- }
489
- const doWorkerName = `${workerName}-durable-objects`;
490
- const script = await bundleDOClasses(doClasses, doWorkerName);
491
- if (!script) {
492
- return { workers: [], bindings: {} };
493
- }
494
- const durableObjects = Object.fromEntries(doClasses.map((do_) => [do_.bindingName, do_.className]));
495
- const runtimeConfig = buildReferencedWorkerRuntimeConfig(config);
496
- const doRuntimeConfig = { ...runtimeConfig };
497
- delete doRuntimeConfig.queueConsumers;
498
- const mergedServiceBindings = {
499
- ...runtimeConfig.serviceBindings ?? {},
500
- ...serviceBindings
501
- };
502
- return {
503
- workers: [
504
- {
505
- name: doWorkerName,
506
- script,
507
- modules: true,
508
- compatibilityDate: config.compatibilityDate,
509
- ...doRuntimeConfig,
510
- ...Object.keys(mergedServiceBindings).length > 0 && {
511
- serviceBindings: mergedServiceBindings
512
- },
513
- durableObjects
514
- }
515
- ],
516
- bindings: Object.fromEntries(doClasses.map((do_) => [
517
- do_.bindingName,
518
- {
519
- className: do_.className,
520
- scriptName: doWorkerName
521
- }
522
- ]))
523
- };
524
- }
525
- async function resolveServiceBindings(config, configDir, seenWorkers = new Set) {
526
- const services = config.bindings?.services;
527
- if (!services) {
528
- return { workers: [], primaryServiceBindings: {} };
529
- }
530
- const workersByName = new Map;
531
- const primaryServiceBindings = {};
532
- for (const [bindingName, binding] of Object.entries(services)) {
533
- const workerBinding = binding;
534
- const ref = workerBinding.__ref;
535
- if (ref) {
536
- if ("__import" in ref && typeof ref.__import === "function") {
537
- await ref.resolve();
538
- }
539
- const workerName = ref.name;
540
- const entrypoint = workerBinding.entrypoint;
541
- if (!workersByName.has(workerName) && !seenWorkers.has(workerName)) {
542
- const refConfig = normalizeReferencedConfig(ref.config);
543
- const worker = await resolveRefWorker(ref, entrypoint, configDir, refConfig);
544
- if (worker) {
545
- const refConfigDir = resolveReferencedConfigDir(ref, configDir);
546
- if (ref.config && refConfigDir) {
547
- const nested = await resolveServiceBindings(refConfig, refConfigDir, new Set([...seenWorkers, workerName]));
548
- worker.serviceBindings = {
549
- ...worker.serviceBindings ?? {},
550
- ...nested.primaryServiceBindings
551
- };
552
- for (const nestedWorker of nested.workers) {
553
- if (!workersByName.has(nestedWorker.name)) {
554
- workersByName.set(nestedWorker.name, nestedWorker);
555
- }
556
- }
557
- const localDOs = await resolveReferencedLocalDurableObjects(refConfig, refConfigDir, workerName, nested.primaryServiceBindings);
558
- worker.durableObjects = {
559
- ...worker.durableObjects ?? {},
560
- ...localDOs.bindings
561
- };
562
- for (const doWorker of localDOs.workers) {
563
- if (!workersByName.has(doWorker.name)) {
564
- workersByName.set(doWorker.name, doWorker);
565
- }
566
- }
567
- }
568
- workersByName.set(workerName, worker);
569
- }
570
- }
571
- primaryServiceBindings[bindingName] = {
572
- name: workerName,
573
- ...entrypoint && { entrypoint }
574
- };
575
- } else {
576
- primaryServiceBindings[bindingName] = {
577
- name: workerBinding.service,
578
- ...workerBinding.entrypoint && { entrypoint: workerBinding.entrypoint }
579
- };
580
- }
581
- }
582
- return {
583
- workers: [...workersByName.values()],
584
- primaryServiceBindings
585
- };
586
- }
587
- async function resolveRefWorker(ref, _entrypoint, parentConfigDir, resolvedConfig) {
588
- const config = resolvedConfig ?? normalizeReferencedConfig(ref.config);
589
- if (!config)
590
- return null;
591
- const refConfigDir = resolveReferencedConfigDir(ref, parentConfigDir);
592
- if (!refConfigDir) {
593
- console.warn(`[devflare] Cannot resolve worker "${ref.name}" - configPath not available`);
594
- return null;
595
- }
596
- const entrypoints = [];
597
- const workerEntrypointPath = findDefaultServiceWorkerEntrypoint(refConfigDir);
598
- if (workerEntrypointPath) {
599
- entrypoints.push({
600
- path: workerEntrypointPath,
601
- className: "Worker",
602
- isWorkerTs: true
603
- });
604
- }
605
- if (config.files?.entrypoints !== false) {
606
- const discoveredEntrypoints = discoverEntrypointsSync(refConfigDir, typeof config.files?.entrypoints === "string" ? config.files.entrypoints : undefined);
607
- for (const ep of discoveredEntrypoints) {
608
- entrypoints.push({
609
- path: ep.filePath,
610
- className: ep.className,
611
- isWorkerTs: false
612
- });
613
- }
614
- }
615
- if (entrypoints.length === 0) {
616
- console.warn(`[devflare] Worker "${ref.name}" has no entry points`);
617
- return null;
618
- }
619
- const script = await bundleAllEntrypoints(entrypoints, ref.name);
620
- if (!script)
621
- return null;
622
- return {
623
- name: ref.name,
624
- script,
625
- modules: true,
626
- compatibilityDate: config.compatibilityDate ?? "2025-01-01",
627
- ...buildReferencedWorkerRuntimeConfig(config)
628
- };
629
- }
630
- async function bundleAllEntrypoints(entrypoints, workerName) {
631
- const cacheKey = entrypoints.map((ep) => `${ep.path}::${ep.className}`).join("|");
632
- const cached = bundleCache.get(cacheKey);
633
- if (cached) {
634
- return cached;
635
- }
636
- const bun = getBunRuntime();
637
- if (!bun) {
638
- console.warn(`[devflare] Cannot bundle service worker "${workerName}" — the Bun runtime is required to bundle worker scripts, ` + "but this process is not running under Bun. The service binding will be left unresolved. " + "Run your tests with `bun test` (or the devflare test runner) to enable multi-worker service bindings.");
639
- return null;
640
- }
641
- try {
642
- const { readFileSync: readFileSync2, writeFileSync, mkdirSync, unlinkSync } = await import("fs");
643
- const imports = [];
644
- const exports = [];
645
- let defaultExportClass = null;
646
- for (let i = 0;i < entrypoints.length; i++) {
647
- const ep = entrypoints[i];
648
- const sourceCode = readFileSync2(ep.path, "utf-8");
649
- if (ep.isWorkerTs) {
650
- const result = transformWorkerEntrypoint(sourceCode, ep.path, {
651
- className: ep.className,
652
- injectContext: false
653
- });
654
- if (result) {
655
- const tempDir2 = join(dirname(ep.path), ".devflare");
656
- mkdirSync(tempDir2, { recursive: true });
657
- const tempPath = join(tempDir2, `__${ep.className}_${i}.ts`);
658
- writeFileSync(tempPath, result.code);
659
- imports.push(`import { ${ep.className} } from '${tempPath.replace(/\\/g, "/")}'`);
660
- exports.push(ep.className);
661
- if (!defaultExportClass) {
662
- defaultExportClass = ep.className;
663
- }
664
- }
665
- } else {
666
- imports.push(`import { ${ep.className} } from '${ep.path.replace(/\\/g, "/")}'`);
667
- exports.push(ep.className);
668
- }
669
- }
670
- const defaultExport = defaultExportClass ? `
671
- export default ${defaultExportClass}` : "";
672
- const entryCode = `
673
- ${imports.join(`
674
- `)}
675
- export { ${exports.join(", ")} }${defaultExport}
676
- `;
677
- const tempDir = join(dirname(entrypoints[0].path), ".devflare");
678
- mkdirSync(tempDir, { recursive: true });
679
- const entryPath = join(tempDir, `__entry_${workerName}.ts`);
680
- writeFileSync(entryPath, entryCode);
681
- try {
682
- const result = await bun.build({
683
- entrypoints: [entryPath],
684
- target: "browser",
685
- format: "esm",
686
- minify: false,
687
- external: ["cloudflare:workers", "cloudflare:*"]
688
- });
689
- if (!result.success) {
690
- console.warn(`[devflare] Failed to bundle worker "${workerName}": ${result.logs.join(`
691
- `)}`);
692
- return null;
693
- }
694
- const bundledCode = await result.outputs[0].text();
695
- bundleCache.set(cacheKey, bundledCode);
696
- return bundledCode;
697
- } finally {
698
- try {
699
- unlinkSync(entryPath);
700
- } catch {}
701
- }
702
- } catch (error) {
703
- console.warn(`[devflare] Error bundling worker "${workerName}":`, error);
704
- return null;
705
- }
706
- }
707
- async function bundleDOClasses(doClasses, workerName) {
708
- const cacheKey = `do:${doClasses.map((d) => `${d.scriptPath}::${d.className}`).join("|")}`;
709
- const cached = bundleCache.get(cacheKey);
710
- if (cached)
711
- return cached;
712
- const bun = getBunRuntime();
713
- if (!bun) {
714
- console.warn(`[devflare] Cannot bundle Durable Object worker "${workerName}" — the Bun runtime is required to bundle DO classes, ` + "but this process is not running under Bun. The Durable Object binding will be left unresolved. Run your tests with `bun test` (or the devflare test runner) to enable cross-worker Durable Objects.");
715
- return null;
716
- }
717
- try {
718
- const { writeFileSync, mkdirSync, unlinkSync } = await import("fs");
719
- const imports = doClasses.map((d) => `import { ${d.className} } from '${d.scriptPath.replace(/\\/g, "/")}'`).join(`
720
- `);
721
- const exports = doClasses.map((d) => d.className).join(", ");
722
- const entryCode = `
723
- ${imports}
724
-
725
- // Re-export DO classes for Miniflare binding
726
- export { ${exports} }
727
-
728
- // Default export with fetch handler
729
- export default {
730
- async fetch(request, env) {
731
- return new Response('DO Worker: ${workerName}')
732
- }
733
- }
734
- `;
735
- const tempDir = join(dirname(doClasses[0].scriptPath), ".devflare");
736
- mkdirSync(tempDir, { recursive: true });
737
- const entryPath = join(tempDir, `__do_entry_${workerName}.ts`);
738
- writeFileSync(entryPath, entryCode);
739
- try {
740
- const result = await bun.build({
741
- entrypoints: [entryPath],
742
- target: "browser",
743
- format: "esm",
744
- minify: false,
745
- external: ["cloudflare:workers", "cloudflare:*"]
746
- });
747
- if (!result.success) {
748
- console.warn(`[devflare] Failed to bundle DO worker "${workerName}": ${result.logs.join(`
749
- `)}`);
750
- return null;
751
- }
752
- const bundledCode = await result.outputs[0].text();
753
- bundleCache.set(cacheKey, bundledCode);
754
- return bundledCode;
755
- } finally {
756
- try {
757
- unlinkSync(entryPath);
758
- } catch {}
759
- }
760
- } catch (error) {
761
- console.warn(`[devflare] Error bundling DO worker "${workerName}":`, error);
762
- return null;
763
- }
764
- }
765
-
766
- // src/worker-entry/composed-worker.ts
767
- import { dirname as dirname2, relative as relative2, resolve as resolve4 } from "pathe";
768
-
769
- // src/worker-entry/durable-object-discovery.ts
770
- async function discoverDurableObjectFiles(cwd, pattern) {
771
- const result = new Map;
772
- const matchedFiles = await findFiles(pattern, { cwd });
773
- const fs = await import("node:fs/promises");
774
- for (const filePath of matchedFiles) {
775
- try {
776
- const code = await fs.readFile(filePath, "utf-8");
777
- const classNames = findDurableObjectClasses(code);
778
- if (classNames.length > 0) {
779
- result.set(filePath, classNames);
780
- }
781
- } catch (error) {
782
- console.warn(`[devflare] Failed to read DO file: ${filePath}`, error);
783
- }
784
- }
785
- return result;
786
- }
787
- async function discoverDurableObjects(projectRoot, pattern, workerName) {
788
- const files = await discoverDurableObjectFiles(projectRoot, pattern);
789
- return { files, workerName };
790
- }
791
-
792
- // src/worker-entry/routes.ts
793
- import { relative, resolve as resolve2 } from "pathe";
794
- var DEFAULT_ROUTE_DIR = "src/routes";
795
- var DEFAULT_ROUTE_FILE_PATTERNS = SUPPORTED_WORKER_EXTENSIONS.map((ext) => `**/*${ext}`);
796
- function normalizeRoutePrefix(prefix) {
797
- if (!prefix || prefix === "/") {
798
- return "";
799
- }
800
- const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
801
- return normalized.replace(/\/+$/g, "");
802
- }
803
- function createStaticSegmentsFromPrefix(prefix) {
804
- if (!prefix) {
805
- return [];
806
- }
807
- return prefix.split("/").filter(Boolean).map((value) => ({
808
- type: "static",
809
- value
810
- }));
811
- }
812
- function shouldIgnoreRouteFile(relativePath) {
813
- return relativePath.split("/").some((segment) => segment.startsWith("_"));
814
- }
815
- function toRoutePath(segments) {
816
- if (segments.length === 0) {
817
- return "/";
818
- }
819
- return `/${segments.map((segment) => {
820
- if (segment.type === "static") {
821
- return segment.value;
822
- }
823
- if (segment.type === "param") {
824
- return `[${segment.name}]`;
825
- }
826
- if (segment.type === "rest") {
827
- return `[...${segment.name}]`;
828
- }
829
- return `[[...${segment.name}]]`;
830
- }).join("/")}`;
831
- }
832
- function getRouteSignature(segments) {
833
- if (segments.length === 0) {
834
- return "/";
835
- }
836
- return segments.map((segment) => {
837
- if (segment.type === "static") {
838
- return `static:${segment.value}`;
839
- }
840
- if (segment.type === "param") {
841
- return "param";
842
- }
843
- if (segment.type === "rest") {
844
- return "rest";
845
- }
846
- return "optional-rest";
847
- }).join("/");
848
- }
849
- function getSegmentPriority(segment) {
850
- if (segment.type === "static") {
851
- return 4;
852
- }
853
- if (segment.type === "param") {
854
- return 3;
855
- }
856
- if (segment.type === "rest") {
857
- return 1;
858
- }
859
- return 0;
860
- }
861
- function compareRoutes(a, b) {
862
- const maxLength = Math.max(a.segments.length, b.segments.length);
863
- for (let index = 0;index < maxLength; index += 1) {
864
- const left = a.segments[index];
865
- const right = b.segments[index];
866
- if (!left && !right) {
867
- break;
868
- }
869
- if (!left) {
870
- return 1;
871
- }
872
- if (!right) {
873
- return -1;
874
- }
875
- const priorityDifference = getSegmentPriority(right) - getSegmentPriority(left);
876
- if (priorityDifference !== 0) {
877
- return priorityDifference;
878
- }
879
- if (left.type === "static" && right.type === "static") {
880
- const lexicalDifference = left.value.localeCompare(right.value);
881
- if (lexicalDifference !== 0) {
882
- return lexicalDifference;
883
- }
884
- }
885
- }
886
- return a.filePath.localeCompare(b.filePath);
887
- }
888
- function parseRouteSegments(relativePath, prefixSegments) {
889
- const withoutExtension = relativePath.replace(/\.[^.]+$/u, "");
890
- const rawSegments = withoutExtension.split("/").filter(Boolean);
891
- const routeSegments = [...prefixSegments];
892
- for (let index = 0;index < rawSegments.length; index += 1) {
893
- const segment = rawSegments[index];
894
- const isLastSegment = index === rawSegments.length - 1;
895
- if (segment === "index" && isLastSegment) {
896
- continue;
897
- }
898
- const optionalRestMatch = segment.match(/^\[\[\.\.\.(.+)\]\]$/u);
899
- if (optionalRestMatch) {
900
- if (!isLastSegment) {
901
- throw new Error(`Optional rest segment must be the final segment: ${relativePath}`);
902
- }
903
- routeSegments.push({
904
- type: "optional-rest",
905
- name: optionalRestMatch[1]
906
- });
907
- continue;
908
- }
909
- const restMatch = segment.match(/^\[\.\.\.(.+)\]$/u);
910
- if (restMatch) {
911
- if (!isLastSegment) {
912
- throw new Error(`Rest segment must be the final segment: ${relativePath}`);
913
- }
914
- routeSegments.push({
915
- type: "rest",
916
- name: restMatch[1]
917
- });
918
- continue;
919
- }
920
- const dynamicMatch = segment.match(/^\[(.+)\]$/u);
921
- if (dynamicMatch) {
922
- routeSegments.push({
923
- type: "param",
924
- name: dynamicMatch[1]
925
- });
926
- continue;
927
- }
928
- routeSegments.push({
929
- type: "static",
930
- value: segment
931
- });
932
- }
933
- return routeSegments;
934
- }
935
- async function directoryExists(dirPath) {
936
- const fs = await import("node:fs/promises");
937
- try {
938
- const stat = await fs.stat(dirPath);
939
- return stat.isDirectory();
940
- } catch {
941
- return false;
942
- }
943
- }
944
- function getRouteDirectoryCandidate(cwd, config) {
945
- const routesConfig = config.files?.routes;
946
- if (routesConfig === false) {
947
- return null;
948
- }
949
- const dir = routesConfig?.dir ?? DEFAULT_ROUTE_DIR;
950
- return {
951
- dir,
952
- absoluteDir: resolve2(cwd, dir),
953
- prefix: normalizeRoutePrefix(routesConfig?.prefix)
954
- };
955
- }
956
- async function discoverRoutes(cwd, config) {
957
- const routeDirectory = getRouteDirectoryCandidate(cwd, config);
958
- if (!routeDirectory) {
959
- return null;
960
- }
961
- if (!await directoryExists(routeDirectory.absoluteDir)) {
962
- return null;
963
- }
964
- const prefixSegments = createStaticSegmentsFromPrefix(routeDirectory.prefix);
965
- const files = await findFiles(DEFAULT_ROUTE_FILE_PATTERNS, {
966
- cwd: routeDirectory.absoluteDir,
967
- absolute: true
968
- });
969
- const discoveredRoutes = [];
970
- const routeSignatures = new Map;
971
- for (const absolutePath of files) {
972
- const relativeToRouteDir = relative(routeDirectory.absoluteDir, absolutePath).replace(/\\/g, "/");
973
- if (shouldIgnoreRouteFile(relativeToRouteDir)) {
974
- continue;
975
- }
976
- const segments = parseRouteSegments(relativeToRouteDir, prefixSegments);
977
- const routePath = toRoutePath(segments);
978
- const filePath = relative(cwd, absolutePath).replace(/\\/g, "/");
979
- const signature = getRouteSignature(segments);
980
- const existingFilePath = routeSignatures.get(signature);
981
- if (existingFilePath) {
982
- throw new Error(`Conflicting file routes detected for "${routePath}". Both "${existingFilePath}" and "${filePath}" resolve to the same route.`);
983
- }
984
- routeSignatures.set(signature, filePath);
985
- discoveredRoutes.push({
986
- absolutePath,
987
- filePath,
988
- routePath,
989
- segments
990
- });
991
- }
992
- if (discoveredRoutes.length === 0) {
993
- return null;
994
- }
995
- discoveredRoutes.sort(compareRoutes);
996
- return {
997
- dir: routeDirectory.dir,
998
- absoluteDir: routeDirectory.absoluteDir,
999
- prefix: routeDirectory.prefix,
1000
- routes: discoveredRoutes
1001
- };
1002
- }
1003
-
1004
- // src/worker-entry/surface-paths.ts
1005
- import { resolve as resolve3 } from "pathe";
1006
- var defaultEntriesFor = (surface) => SUPPORTED_WORKER_EXTENSIONS.map((ext) => `src/${surface}${ext}`);
1007
- var DEFAULT_FETCH_ENTRY_FILES = defaultEntriesFor("fetch");
1008
- var DEFAULT_QUEUE_ENTRY_FILES = defaultEntriesFor("queue");
1009
- var DEFAULT_SCHEDULED_ENTRY_FILES = defaultEntriesFor("scheduled");
1010
- var DEFAULT_EMAIL_ENTRY_FILES = defaultEntriesFor("email");
1011
- var DEFAULT_TAIL_ENTRY_FILES = defaultEntriesFor("tail");
1012
- var BUILD_OUTPUT_PATH_PREFIXES = [
1013
- ".svelte-kit/",
1014
- ".adapter-cloudflare/",
1015
- ".next/",
1016
- ".nuxt/",
1017
- ".output/",
1018
- ".vercel/",
1019
- "dist/",
1020
- "build/",
1021
- ".vinxi/",
1022
- ".solid/"
1023
- ];
1024
- function looksLikeBuildArtifactPath(configuredPath) {
1025
- const normalised = configuredPath.replace(/\\/g, "/").replace(/^\.\//, "");
1026
- return BUILD_OUTPUT_PATH_PREFIXES.some((prefix) => normalised.startsWith(prefix));
1027
- }
1028
- async function resolveWorkerHandlerPath(cwd, configuredPath, defaultEntries, surfaceName = "worker") {
1029
- if (configuredPath === false) {
1030
- return null;
1031
- }
1032
- const fs = await import("node:fs/promises");
1033
- if (typeof configuredPath === "string" && configuredPath) {
1034
- const absolutePath = resolve3(cwd, configuredPath);
1035
- try {
1036
- await fs.access(absolutePath);
1037
- return absolutePath;
1038
- } catch {
1039
- if (looksLikeBuildArtifactPath(configuredPath)) {
1040
- throw new Error(`Configured ${surfaceName} handler "${configuredPath}" was not found.
1041
-
1042
- This path looks like a framework build output (e.g. SvelteKit / Vite / Next).
1043
- Devflare resolves handler paths BEFORE your framework runs its build, so the file
1044
- does not exist yet at this stage.
1045
-
1046
- ` + `Recommended fix — point devflare at the build artifact via wrangler passthrough
1047
- ` + `instead of files.${surfaceName}, so devflare skips composition and lets your
1048
- framework write the worker entry that wrangler/vite then picks up:
1049
-
1050
- files: { ${surfaceName}: false },
1051
- wrangler: {
1052
- passthrough: { main: '${configuredPath}' }
1053
- }
1054
-
1055
- Alternatively, run your framework build (e.g. \`vite build\`) before \`devflare build\`,
1056
- or move the handler to a source file that exists at config time.`);
1057
- }
1058
- throw new Error(`Configured ${surfaceName} handler "${configuredPath}" was not found`);
1059
- }
1060
- }
1061
- for (const defaultEntry of defaultEntries) {
1062
- const absolutePath = resolve3(cwd, defaultEntry);
1063
- try {
1064
- await fs.access(absolutePath);
1065
- return absolutePath;
1066
- } catch {}
1067
- }
1068
- return null;
1069
- }
1070
- async function resolveWorkerSurfacePaths(cwd, config) {
1071
- return {
1072
- fetch: await resolveWorkerHandlerPath(cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES, "fetch"),
1073
- queue: await resolveWorkerHandlerPath(cwd, config.files?.queue, DEFAULT_QUEUE_ENTRY_FILES, "queue"),
1074
- scheduled: await resolveWorkerHandlerPath(cwd, config.files?.scheduled, DEFAULT_SCHEDULED_ENTRY_FILES, "scheduled"),
1075
- email: await resolveWorkerHandlerPath(cwd, config.files?.email, DEFAULT_EMAIL_ENTRY_FILES, "email"),
1076
- tail: await resolveWorkerHandlerPath(cwd, config.files?.tail, DEFAULT_TAIL_ENTRY_FILES, "tail")
1077
- };
1078
- }
1079
- function hasWorkerSurfacePaths(surfacePaths) {
1080
- return Object.values(surfacePaths).some((surfacePath) => typeof surfacePath === "string" && surfacePath.length > 0);
1081
- }
1082
-
1083
- // src/worker-entry/composed-worker.ts
1084
- class CodeBuilder {
1085
- sections = [];
1086
- importStatement(specifiers, from) {
1087
- this.sections.push(`import { ${specifiers.join(", ")} } from '${from}'`);
1088
- return this;
1089
- }
1090
- importNamespace(identifier, from) {
1091
- this.sections.push(`import * as ${identifier} from '${from}'`);
1092
- return this;
1093
- }
1094
- reExport(names, from) {
1095
- this.sections.push(`export { ${names.join(", ")} } from '${from}'`);
1096
- return this;
1097
- }
1098
- constDeclaration(name, value) {
1099
- this.sections.push(`const ${name} = ${value}`);
1100
- return this;
1101
- }
1102
- classDeclaration(body) {
1103
- this.sections.push(body);
1104
- return this;
1105
- }
1106
- exportDefault(body) {
1107
- this.sections.push(`export default ${body}`);
1108
- return this;
1109
- }
1110
- raw(text) {
1111
- this.sections.push(text);
1112
- return this;
1113
- }
1114
- blank() {
1115
- this.sections.push("");
1116
- return this;
1117
- }
1118
- toString() {
1119
- return this.sections.join(`
1120
- `);
1121
- }
1122
- }
1123
- var DEV_ONLY_EMAIL_HOOKS_SOURCE = `
1124
- function __devflareCreateEmailHeaders(rawBody) {
1125
- const headers = new Headers()
1126
- const lines = rawBody.split(/\\r?\\n/)
1127
-
1128
- for (const line of lines) {
1129
- if (line.trim() === '') {
1130
- break
1131
- }
1132
-
1133
- const colonIndex = line.indexOf(':')
1134
- if (colonIndex <= 0) {
1135
- continue
1136
- }
1137
-
1138
- headers.append(line.slice(0, colonIndex).trim(), line.slice(colonIndex + 1).trim())
1139
- }
1140
-
1141
- return headers
1142
- }
1143
-
1144
- function __devflareCreateEmailRawStream(rawBody) {
1145
- return new ReadableStream({
1146
- start(controller) {
1147
- controller.enqueue(new TextEncoder().encode(rawBody))
1148
- controller.close()
1149
- }
1150
- })
1151
- }
1152
-
1153
- async function __devflareHandleInternalEmail(request, env, ctx) {
1154
- if (!__devflareEmailHandler) {
1155
- return new Response('Email handler not configured', { status: 501 })
1156
- }
1157
-
1158
- const from = request.headers.get('x-devflare-email-from') || 'unknown@example.com'
1159
- const to = request.headers.get('x-devflare-email-to') || 'worker@example.com'
1160
- const rawBody = await request.text()
1161
- const emailMessage = {
1162
- from,
1163
- to,
1164
- headers: __devflareCreateEmailHeaders(rawBody),
1165
- raw: __devflareCreateEmailRawStream(rawBody),
1166
- rawSize: rawBody.length,
1167
- setReject(reason) {
1168
- console.warn('[Devflare email rejected]', reason)
1169
- },
1170
- async forward(rcptTo) {
1171
- console.log('[Devflare email forwarded]', rcptTo)
1172
- return Promise.resolve()
1173
- },
1174
- async reply(message) {
1175
- console.log('[Devflare email reply sent]', message?.from)
1176
- return Promise.resolve()
1177
- }
1178
- }
1179
-
1180
- const __devflareEvent = createEmailEvent(emailMessage, env, ctx)
1181
-
1182
- await runWithEventContext(
1183
- __devflareEvent,
1184
- () => __devflareEmailHandler(__devflareEvent, env, ctx)
1185
- )
1186
-
1187
- return new Response(JSON.stringify({ ok: true, from, to }), {
1188
- headers: { 'Content-Type': 'application/json' }
1189
- })
1190
- }
1191
- `;
1192
- function emitDevOnlyEmailHooks(builder, options) {
1193
- if (!options.enabled) {
1194
- return;
1195
- }
1196
- builder.raw(DEV_ONLY_EMAIL_HOOKS_SOURCE);
1197
- }
1198
- var RESOLVE_HANDLER_DECLARATION = `const __devflareResolveHandler = (module, namedExport) => {
1199
- const defaultExport = module.default
1200
-
1201
- if (typeof defaultExport === 'function') {
1202
- return defaultExport
1203
- }
1204
-
1205
- if (defaultExport && typeof defaultExport[namedExport] === 'function') {
1206
- return defaultExport[namedExport].bind(defaultExport)
1207
- }
1208
-
1209
- if (typeof module[namedExport] === 'function') {
1210
- return module[namedExport]
1211
- }
1212
-
1213
- return null
1214
- }`;
1215
- function buildDefaultExportBody(options) {
1216
- const devOnlyEmailEntry = options.includeDevOnlyHooks ? `const url = new URL(request.url)
1217
-
1218
- if (
1219
- request.headers.get('x-devflare-event') === 'email'
1220
- && url.pathname === '/_devflare/internal/email'
1221
- ) {
1222
- return __devflareHandleInternalEmail(request, env, ctx)
1223
- }
1224
-
1225
- ` : "";
1226
- return `{
1227
- ...(${options.hasFetchDispatch ? "true" : "false"}
1228
- ? {
1229
- async fetch(request, env, ctx) {
1230
- ${devOnlyEmailEntry}const __devflareInitialRouteMatch = __devflareHasRoutes ? matchFetchRoute(__devflareRoutes, request) : null
1231
- const __devflareEvent = createFetchEvent(request, env, ctx, {
1232
- params: __devflareInitialRouteMatch?.params ?? {}
1233
- })
1234
- return runWithEventContext(
1235
- __devflareEvent,
1236
- () => invokeFetchModule(
1237
- __devflareFetchModule,
1238
- __devflareEvent,
1239
- __devflareHasRoutes
1240
- ? createRouteResolve(__devflareRoutes, __devflareEvent)
1241
- : undefined
1242
- )
1243
- )
1244
- }
1245
- }
1246
- : {}),
1247
- ...(__devflareQueueHandler
1248
- ? {
1249
- async queue(batch, env, ctx) {
1250
- assertExplicitQueueHandlerStyle(__devflareQueueHandler)
1251
- const __devflareEvent = createQueueEvent(batch, env, ctx)
1252
- return runWithEventContext(
1253
- __devflareEvent,
1254
- () => __devflareQueueHandler(__devflareEvent, env, ctx)
1255
- )
1256
- }
1257
- }
1258
- : {}),
1259
- ...(__devflareScheduledHandler
1260
- ? {
1261
- async scheduled(controller, env, ctx) {
1262
- assertExplicitScheduledHandlerStyle(__devflareScheduledHandler)
1263
- const __devflareEvent = createScheduledEvent(controller, env, ctx)
1264
- return runWithEventContext(
1265
- __devflareEvent,
1266
- () => __devflareScheduledHandler(__devflareEvent, env, ctx)
1267
- )
1268
- }
1269
- }
1270
- : {}),
1271
- ...(__devflareEmailHandler
1272
- ? {
1273
- async email(message, env, ctx) {
1274
- const __devflareEvent = createEmailEvent(message, env, ctx)
1275
- return runWithEventContext(
1276
- __devflareEvent,
1277
- () => __devflareEmailHandler(__devflareEvent, env, ctx)
1278
- )
1279
- }
1280
- }
1281
- : {}),
1282
- ...(__devflareTailHandler
1283
- ? {
1284
- async tail(events, env, ctx) {
1285
- const __devflareEvent = createTailEvent(events, env, ctx)
1286
- return runWithEventContext(
1287
- __devflareEvent,
1288
- () => __devflareTailHandler.length >= 2
1289
- ? __devflareTailHandler(events, env, ctx)
1290
- : __devflareTailHandler(__devflareEvent, env, ctx)
1291
- )
1292
- }
1293
- }
1294
- : {})
1295
- }`;
1296
- }
1297
- function getComposedWorkerEntrypointSource(surfaceImportPaths, configuredLocalSendEmailBindings = {}, durableObjectExports = [], routeImports = [], options = {}) {
1298
- const includeDevOnlyHooks = options.includeDevOnlyHooks ?? options.devInternalEmail === true;
1299
- const importsBuilder = new CodeBuilder;
1300
- importsBuilder.importStatement([
1301
- "assertExplicitQueueHandlerStyle",
1302
- "assertExplicitScheduledHandlerStyle",
1303
- "createEmailEvent",
1304
- "createFetchEvent",
1305
- "createQueueEvent",
1306
- "createRouteResolve",
1307
- "createScheduledEvent",
1308
- "createTailEvent",
1309
- "invokeFetchModule",
1310
- "matchFetchRoute",
1311
- "runWithEventContext",
1312
- "setLocalSendEmailBindings"
1313
- ], "devflare/runtime");
1314
- const fallbackModules = [
1315
- { identifier: "__devflareFetchModule", importPath: surfaceImportPaths.fetch },
1316
- { identifier: "__devflareQueueModule", importPath: surfaceImportPaths.queue },
1317
- { identifier: "__devflareScheduledModule", importPath: surfaceImportPaths.scheduled },
1318
- { identifier: "__devflareEmailModule", importPath: surfaceImportPaths.email },
1319
- { identifier: "__devflareTailModule", importPath: surfaceImportPaths.tail }
1320
- ];
1321
- const fallbacksBuilder = new CodeBuilder;
1322
- for (const { identifier, importPath } of fallbackModules) {
1323
- if (importPath) {
1324
- importsBuilder.importNamespace(identifier, importPath);
1325
- } else {
1326
- fallbacksBuilder.constDeclaration(identifier, "{}");
1327
- }
1328
- }
1329
- for (const routeImport of routeImports) {
1330
- importsBuilder.importNamespace(routeImport.identifier, routeImport.importPath);
1331
- }
1332
- const reExportsBuilder = new CodeBuilder;
1333
- for (const { classNames, importPath } of durableObjectExports) {
1334
- reExportsBuilder.reExport(classNames, importPath);
1335
- }
1336
- const routeManifestEntries = routeImports.map(({ identifier, filePath, routePath, segmentsJson }) => {
1337
- return ` { filePath: ${JSON.stringify(filePath)}, routePath: ${JSON.stringify(routePath)}, segments: ${segmentsJson}, module: ${identifier} }`;
1338
- });
1339
- const builder = new CodeBuilder;
1340
- builder.raw(importsBuilder.toString());
1341
- builder.raw(fallbacksBuilder.toString());
1342
- builder.raw(reExportsBuilder.toString());
1343
- builder.blank();
1344
- builder.raw(`setLocalSendEmailBindings(${JSON.stringify(configuredLocalSendEmailBindings)})`);
1345
- builder.blank();
1346
- builder.constDeclaration("__devflareHasFetchModule", surfaceImportPaths.fetch ? "true" : "false");
1347
- builder.raw(`const __devflareRoutes = [
1348
- ${routeManifestEntries.join(`,
1349
- `)}
1350
- ]`);
1351
- builder.constDeclaration("__devflareHasRoutes", "__devflareRoutes.length > 0");
1352
- builder.blank();
1353
- builder.raw(RESOLVE_HANDLER_DECLARATION);
1354
- builder.blank();
1355
- builder.constDeclaration("__devflareQueueHandler", "__devflareResolveHandler(__devflareQueueModule, 'queue')");
1356
- builder.constDeclaration("__devflareScheduledHandler", "__devflareResolveHandler(__devflareScheduledModule, 'scheduled')");
1357
- builder.constDeclaration("__devflareEmailHandler", "__devflareResolveHandler(__devflareEmailModule, 'email')");
1358
- builder.constDeclaration("__devflareTailHandler", "__devflareResolveHandler(__devflareTailModule, 'tail')");
1359
- emitDevOnlyEmailHooks(builder, { enabled: includeDevOnlyHooks });
1360
- builder.blank();
1361
- builder.exportDefault(buildDefaultExportBody({
1362
- hasFetchDispatch: Boolean(surfaceImportPaths.fetch) || routeImports.length > 0 || includeDevOnlyHooks,
1363
- includeDevOnlyHooks
1364
- }));
1365
- builder.raw("");
1366
- return builder.toString();
1367
- }
1368
- function toImportSpecifier(fromFilePath, toFilePath) {
1369
- const specifier = relative2(dirname2(fromFilePath), toFilePath).replace(/\\/g, "/");
1370
- return specifier.startsWith(".") ? specifier : `./${specifier}`;
1371
- }
1372
- function createGeneratedRouteModuleImports(entryPath, routeDiscovery) {
1373
- if (!routeDiscovery) {
1374
- return [];
1375
- }
1376
- return routeDiscovery.routes.map((route, index) => ({
1377
- identifier: `__devflareRouteModule${index}`,
1378
- importPath: toImportSpecifier(entryPath, route.absolutePath),
1379
- filePath: route.filePath,
1380
- routePath: route.routePath,
1381
- segmentsJson: JSON.stringify(route.segments)
1382
- }));
1383
- }
1384
- async function createGeneratedDurableObjectExports(entryPath, cwd, config) {
1385
- if (config.files?.durableObjects === false || !config.bindings?.durableObjects) {
1386
- return [];
1387
- }
1388
- const localClassNames = new Set(Object.values(config.bindings.durableObjects).map((binding) => normalizeDOBinding(binding)).filter((binding) => binding.kind === "local").map((binding) => binding.className));
1389
- if (localClassNames.size === 0) {
1390
- return [];
1391
- }
1392
- const pattern = typeof config.files?.durableObjects === "string" ? config.files.durableObjects : DEFAULT_DO_PATTERN;
1393
- const discoveredFiles = await discoverDurableObjectFiles(cwd, pattern);
1394
- const exports = [];
1395
- const discoveredClassNames = new Set;
1396
- for (const [filePath, allClassNames] of discoveredFiles) {
1397
- const classNames = allClassNames.filter((className) => localClassNames.has(className));
1398
- if (classNames.length === 0) {
1399
- continue;
1400
- }
1401
- for (const className of classNames) {
1402
- discoveredClassNames.add(className);
1403
- }
1404
- exports.push({
1405
- importPath: toImportSpecifier(entryPath, filePath),
1406
- filePath,
1407
- classNames
1408
- });
1409
- }
1410
- const missingClassNames = Array.from(localClassNames).filter((className) => !discoveredClassNames.has(className));
1411
- if (missingClassNames.length > 0) {
1412
- throw new Error(`Failed to discover local Durable Object class${missingClassNames.length === 1 ? "" : "es"} ${missingClassNames.join(", ")} for worker composition. ` + `Ensure files.durableObjects matches the source file pattern for your do.* files.`);
1413
- }
1414
- return exports;
1415
- }
1416
- function mayRequireCompositionBesidesFetch(config) {
1417
- const files = config.files ?? {};
1418
- if (typeof files.queue === "string" && files.queue)
1419
- return true;
1420
- if (typeof files.scheduled === "string" && files.scheduled)
1421
- return true;
1422
- if (typeof files.email === "string" && files.email)
1423
- return true;
1424
- if (typeof files.tail === "string" && files.tail)
1425
- return true;
1426
- if (files.durableObjects)
1427
- return true;
1428
- if (files.routes)
1429
- return true;
1430
- const bindings = config.bindings ?? {};
1431
- const doBindings = bindings.durableObjects;
1432
- if (doBindings && Object.keys(doBindings).length > 0)
1433
- return true;
1434
- const sendEmail = bindings.sendEmail;
1435
- if (sendEmail && Object.keys(sendEmail).length > 0)
1436
- return true;
1437
- return false;
1438
- }
1439
- function needsComposedWorkerEntrypoint(cwd, surfacePaths, config, routeDiscovery) {
1440
- const hasAdditionalWorkerSurfaces = Boolean(surfacePaths.queue || surfacePaths.scheduled || surfacePaths.email || surfacePaths.tail || routeDiscovery?.routes.length);
1441
- if (hasAdditionalWorkerSurfaces) {
1442
- return true;
1443
- }
1444
- if (!surfacePaths.fetch) {
1445
- return false;
1446
- }
1447
- const assetsDirectory = config.assets?.directory;
1448
- if (assetsDirectory) {
1449
- const generatedAssetsWorkerPath = resolve4(cwd, assetsDirectory, "_worker.js");
1450
- if (surfacePaths.fetch === generatedAssetsWorkerPath) {
1451
- return false;
1452
- }
1453
- }
1454
- return Boolean(surfacePaths.fetch);
1455
- }
1456
- async function prepareComposedWorkerEntrypoint(cwd, config, environment, options = {}) {
1457
- const resolvedConfig = resolveConfigForEnvironment(config, environment);
1458
- if (resolvedConfig.wrangler?.passthrough && Object.prototype.hasOwnProperty.call(resolvedConfig.wrangler.passthrough, "main")) {
1459
- return null;
1460
- }
1461
- const configuredFetch = resolvedConfig.files?.fetch;
1462
- if (typeof configuredFetch === "string" && looksLikeBuildArtifactPath(configuredFetch)) {
1463
- const fs2 = await import("node:fs/promises");
1464
- const fetchAbsolute = resolve4(cwd, configuredFetch);
1465
- let fetchExists = true;
1466
- try {
1467
- await fs2.access(fetchAbsolute);
1468
- } catch {
1469
- fetchExists = false;
1470
- }
1471
- if (!fetchExists && !mayRequireCompositionBesidesFetch(resolvedConfig)) {
1472
- return null;
1473
- }
1474
- }
1475
- const surfacePaths = await resolveWorkerSurfacePaths(cwd, resolvedConfig);
1476
- const routeDiscovery = await discoverRoutes(cwd, resolvedConfig);
1477
- if (!needsComposedWorkerEntrypoint(cwd, surfacePaths, resolvedConfig, routeDiscovery)) {
1478
- return null;
1479
- }
1480
- const fs = await import("node:fs/promises");
1481
- const entryDir = resolve4(cwd, ".devflare", "worker-entrypoints");
1482
- const entryPath = resolve4(entryDir, "main.ts");
1483
- await fs.mkdir(entryDir, { recursive: true });
1484
- const surfaceImportPaths = {
1485
- fetch: surfacePaths.fetch ? toImportSpecifier(entryPath, surfacePaths.fetch) : null,
1486
- queue: surfacePaths.queue ? toImportSpecifier(entryPath, surfacePaths.queue) : null,
1487
- scheduled: surfacePaths.scheduled ? toImportSpecifier(entryPath, surfacePaths.scheduled) : null,
1488
- email: surfacePaths.email ? toImportSpecifier(entryPath, surfacePaths.email) : null,
1489
- tail: surfacePaths.tail ? toImportSpecifier(entryPath, surfacePaths.tail) : null
1490
- };
1491
- const durableObjectExports = await createGeneratedDurableObjectExports(entryPath, cwd, resolvedConfig);
1492
- const routeImports = createGeneratedRouteModuleImports(entryPath, routeDiscovery);
1493
- await fs.writeFile(entryPath, getComposedWorkerEntrypointSource(surfaceImportPaths, resolvedConfig.bindings?.sendEmail ?? {}, durableObjectExports, routeImports, options));
1494
- return entryPath;
1495
- }
1496
-
1497
- // src/vite/plugin-durable-objects.ts
1498
- var VIRTUAL_DO_ENTRY = "virtual:devflare-do-entry";
1499
- var RESOLVED_VIRTUAL_DO_ENTRY = "\x00" + VIRTUAL_DO_ENTRY;
1500
- function generateVirtualDOEntry(discovery) {
1501
- const lines = [
1502
- "// Auto-generated by devflare — DO entry module",
1503
- "// Re-exports all Durable Object classes discovered from files.durableObjects pattern",
1504
- ""
1505
- ];
1506
- for (const [filePath, classNames] of discovery.files) {
1507
- const normalizedPath = filePath.replace(/\\/g, "/");
1508
- lines.push(`export { ${classNames.join(", ")} } from '${normalizedPath}'`);
1509
- }
1510
- lines.push("");
1511
- lines.push("// Default fetch handler for DO worker");
1512
- lines.push("export default {");
1513
- lines.push("\tasync fetch(request: Request): Promise<Response> {");
1514
- lines.push('\t\treturn new Response("Devflare DO Worker", { status: 200 })');
1515
- lines.push("\t}");
1516
- lines.push("}");
1517
- return lines.join(`
1518
- `);
1519
- }
1520
- function createAuxiliaryWorkerConfig(wranglerConfig, discovery) {
1521
- const doBindings = wranglerConfig.durable_objects?.bindings?.map((binding) => ({
1522
- name: binding.name,
1523
- class_name: binding.class_name
1524
- })) ?? [];
1525
- return {
1526
- config: {
1527
- name: discovery.workerName,
1528
- main: VIRTUAL_DO_ENTRY,
1529
- compatibility_date: wranglerConfig.compatibility_date,
1530
- compatibility_flags: wranglerConfig.compatibility_flags,
1531
- durable_objects: { bindings: doBindings },
1532
- migrations: wranglerConfig.migrations,
1533
- kv_namespaces: wranglerConfig.kv_namespaces,
1534
- d1_databases: wranglerConfig.d1_databases,
1535
- r2_buckets: wranglerConfig.r2_buckets,
1536
- browser: wranglerConfig.browser
1537
- }
1538
- };
1539
- }
1540
- function logDiscoveredDurableObjects(projectRoot, discovery) {
1541
- if (!discovery || discovery.files.size === 0) {
1542
- return;
1543
- }
1544
- console.log(`[devflare] Discovered ${discovery.files.size} DO file(s):`);
1545
- for (const [filePath, classes] of discovery.files) {
1546
- console.log(` • ${filePath.replace(projectRoot, ".")} → ${classes.join(", ")}`);
1547
- }
1548
- }
1549
-
1550
- // src/vite/plugin-service-bindings.ts
1551
- var VIRTUAL_SERVICE_WORKER_PREFIX = "virtual:devflare-service-worker/";
1552
- var RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX = "\x00" + VIRTUAL_SERVICE_WORKER_PREFIX;
1553
- function virtualServiceWorkerId(workerName) {
1554
- return `${VIRTUAL_SERVICE_WORKER_PREFIX}${encodeURIComponent(workerName)}`;
1555
- }
1556
- function resolvedVirtualServiceWorkerId(workerName) {
1557
- return `${RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX}${encodeURIComponent(workerName)}`;
1558
- }
1559
- function objectEntries(record) {
1560
- return record ? Object.entries(record) : [];
1561
- }
1562
- function toWranglerDurableObjectBinding(name, value) {
1563
- if (typeof value === "string") {
1564
- return { name, class_name: value };
1565
- }
1566
- return {
1567
- name,
1568
- class_name: value.className,
1569
- script_name: value.scriptName
1570
- };
1571
- }
1572
- function toWranglerWorkerConfig(worker) {
1573
- const queueProducers = worker.queueProducers ? objectEntries(worker.queueProducers).map(([binding, producer]) => ({
1574
- binding,
1575
- queue: producer.queueName
1576
- })) : undefined;
1577
- const queueConsumers = worker.queueConsumers ? objectEntries(worker.queueConsumers).map(([queue, consumer]) => ({
1578
- queue,
1579
- ...consumer.maxBatchSize !== undefined && {
1580
- max_batch_size: consumer.maxBatchSize
1581
- },
1582
- ...consumer.maxBatchTimeout !== undefined && {
1583
- max_batch_timeout: consumer.maxBatchTimeout
1584
- },
1585
- ...consumer.maxRetries !== undefined && { max_retries: consumer.maxRetries },
1586
- ...typeof consumer.deadLetterQueue === "string" && {
1587
- dead_letter_queue: consumer.deadLetterQueue
1588
- },
1589
- ...consumer.maxConcurrency !== undefined && {
1590
- max_concurrency: consumer.maxConcurrency
1591
- },
1592
- ...consumer.retryDelay !== undefined && { retry_delay: consumer.retryDelay }
1593
- })) : undefined;
1594
- const queues = queueProducers || queueConsumers ? {
1595
- ...queueProducers && { producers: queueProducers },
1596
- ...queueConsumers && { consumers: queueConsumers }
1597
- } : undefined;
1598
- const durableObjectBindings = worker.durableObjects ? objectEntries(worker.durableObjects).map(([name, value]) => toWranglerDurableObjectBinding(name, value)) : [];
1599
- const serviceBindings = worker.serviceBindings ? objectEntries(worker.serviceBindings).map(([binding, target]) => ({
1600
- binding,
1601
- service: target.name,
1602
- ...target.entrypoint && { entrypoint: target.entrypoint }
1603
- })) : [];
1604
- const config = {
1605
- name: worker.name,
1606
- main: virtualServiceWorkerId(worker.name),
1607
- compatibility_date: worker.compatibilityDate,
1608
- ...worker.compatibilityFlags && { compatibility_flags: worker.compatibilityFlags },
1609
- ...worker.bindings && { vars: worker.bindings },
1610
- ...worker.kvNamespaces && {
1611
- kv_namespaces: objectEntries(worker.kvNamespaces).map(([binding, id]) => ({
1612
- binding,
1613
- id
1614
- }))
1615
- },
1616
- ...worker.r2Buckets && {
1617
- r2_buckets: objectEntries(worker.r2Buckets).map(([binding, bucket_name]) => ({
1618
- binding,
1619
- bucket_name
1620
- }))
1621
- },
1622
- ...worker.d1Databases && {
1623
- d1_databases: objectEntries(worker.d1Databases).map(([binding, database_id]) => ({
1624
- binding,
1625
- database_id,
1626
- database_name: database_id
1627
- }))
1628
- },
1629
- ...durableObjectBindings.length > 0 && {
1630
- durable_objects: {
1631
- bindings: durableObjectBindings
1632
- }
1633
- },
1634
- ...serviceBindings.length > 0 && {
1635
- services: serviceBindings
1636
- },
1637
- ...queues && { queues }
1638
- };
1639
- return config;
1640
- }
1641
- function createAuxiliaryServiceWorkerConfigs(resolution) {
1642
- if (!resolution || resolution.workers.length === 0) {
1643
- return { auxiliaryWorkers: [], virtualModules: new Map };
1644
- }
1645
- const virtualModules = new Map;
1646
- const auxiliaryWorkers = resolution.workers.map((worker) => {
1647
- virtualModules.set(resolvedVirtualServiceWorkerId(worker.name), worker.script);
1648
- return {
1649
- config: toWranglerWorkerConfig(worker)
1650
- };
1651
- });
1652
- return { auxiliaryWorkers, virtualModules };
1653
- }
1654
-
1655
- // src/vite/plugin-context.ts
1656
- var CONFIG_DIR = ".devflare";
1657
- function removeDevflareHandledServeBindings(config) {
1658
- const next = { ...config };
1659
- delete next.workflows;
1660
- delete next.media;
1661
- return next;
1662
- }
1663
- async function buildPluginContextState(projectRoot, devflareConfig, environment, mode = "serve", configDir = projectRoot) {
1664
- const resourceResolvedConfig = mode === "build" ? await resolveResources(devflareConfig, { phase: "build", environment }) : await resolveResources(devflareConfig, { phase: "local", environment });
1665
- const effectiveConfig = await resolveConfigEnvVars(resourceResolvedConfig, {
1666
- cwd: configDir,
1667
- mode: mode === "build" ? "build" : "dev"
1668
- });
1669
- const compiledWranglerConfig = mode === "build" ? compileBuildConfig(effectiveConfig) : compileConfig(effectiveConfig);
1670
- const wranglerConfig = mode === "build" ? isolateViteBuildOutputPaths(projectRoot, compiledWranglerConfig) : removeDevflareHandledServeBindings(compiledWranglerConfig);
1671
- const cloudflareConfig = {
1672
- ...mode === "build" ? isolateViteBuildOutputPaths(projectRoot, compileToProgrammaticConfig(effectiveConfig, environment, {
1673
- preserveNamedBindings: true
1674
- })) : removeDevflareHandledServeBindings(compileToProgrammaticConfig(effectiveConfig, environment))
1675
- };
1676
- const composedMainEntry = mode === "build" ? null : await prepareComposedWorkerEntrypoint(projectRoot, effectiveConfig, environment);
1677
- if (composedMainEntry) {
1678
- const relativeMain = relative3(projectRoot, composedMainEntry);
1679
- wranglerConfig.main = relativeMain;
1680
- cloudflareConfig.main = relativeMain;
1681
- }
1682
- let durableObjects = null;
1683
- let auxiliaryWorkerConfig = null;
1684
- let serviceWorkerVirtualModules = new Map;
1685
- let serviceAuxiliaryWorkerConfigs = [];
1686
- const doPatternConfig = effectiveConfig.files?.durableObjects;
1687
- const doPattern = typeof doPatternConfig === "string" ? doPatternConfig : DEFAULT_DO_PATTERN;
1688
- if (doPatternConfig !== false) {
1689
- const doWorkerName = `${wranglerConfig.name}-do`;
1690
- const discovery = await discoverDurableObjects(projectRoot, doPattern, doWorkerName);
1691
- if (discovery.files.size > 0) {
1692
- durableObjects = discovery;
1693
- if (wranglerConfig.durable_objects?.bindings) {
1694
- for (const binding of wranglerConfig.durable_objects.bindings) {
1695
- binding.script_name = doWorkerName;
1696
- }
1697
- }
1698
- if (cloudflareConfig.durable_objects) {
1699
- const doConfig = cloudflareConfig.durable_objects;
1700
- for (const binding of doConfig.bindings) {
1701
- binding.script_name = doWorkerName;
1702
- }
1703
- }
1704
- auxiliaryWorkerConfig = createAuxiliaryWorkerConfig(wranglerConfig, discovery);
1705
- }
1706
- }
1707
- if (mode === "serve" && effectiveConfig.bindings?.services) {
1708
- const serviceBindingResolution = await resolveServiceBindings(effectiveConfig, configDir);
1709
- const serviceWorkers = createAuxiliaryServiceWorkerConfigs(serviceBindingResolution);
1710
- serviceAuxiliaryWorkerConfigs = serviceWorkers.auxiliaryWorkers;
1711
- serviceWorkerVirtualModules = serviceWorkers.virtualModules;
1712
- }
1713
- const auxiliaryWorkerConfigs = [
1714
- ...auxiliaryWorkerConfig ? [auxiliaryWorkerConfig] : [],
1715
- ...serviceAuxiliaryWorkerConfigs
1716
- ];
1717
- return {
1718
- wranglerConfig,
1719
- cloudflareConfig,
1720
- auxiliaryWorkerConfigs,
1721
- serviceWorkerVirtualModules,
1722
- durableObjects,
1723
- auxiliaryWorkerConfig
1724
- };
1725
- }
1726
- async function ensureGeneratedConfigDir(projectRoot) {
1727
- const configDir = resolve5(projectRoot, CONFIG_DIR);
1728
- const fs = await import("node:fs/promises");
1729
- await fs.mkdir(configDir, { recursive: true });
1730
- const gitignorePath = resolve5(configDir, ".gitignore");
1731
- try {
1732
- await fs.access(gitignorePath);
1733
- } catch {
1734
- await fs.writeFile(gitignorePath, `*
1735
- `, "utf-8");
1736
- }
1737
- return configDir;
1738
- }
1739
- async function writeGeneratedWranglerConfig(projectRoot, wranglerConfig) {
1740
- const configDir = await ensureGeneratedConfigDir(projectRoot);
1741
- const wranglerFileConfig = rebaseWranglerConfigPaths(projectRoot, configDir, wranglerConfig);
1742
- await writeWranglerConfig(configDir, wranglerFileConfig, "wrangler.jsonc");
1743
- }
1744
- async function resolvePluginConfigPath(projectRoot, configPath) {
1745
- if (configPath) {
1746
- return isAbsolute(configPath) ? configPath : resolve5(projectRoot, configPath);
1747
- }
1748
- return await resolveConfigPath(projectRoot) ?? null;
1749
- }
1750
-
1751
- // src/vite/plugin-transform.ts
1752
- var TRANSFORMABLE_EXTENSIONS = [".ts", ".tsx", ".js"];
1753
- function isTransformCandidate(id) {
1754
- if (id.includes("node_modules"))
1755
- return false;
1756
- return TRANSFORMABLE_EXTENSIONS.some((ext) => id.endsWith(ext));
1757
- }
1758
- async function runWorkerEntryTransform(code, id) {
1759
- if (!id.endsWith("worker.ts") && !id.endsWith("worker.js")) {
1760
- return null;
1761
- }
1762
- const { shouldTransformWorker, transformWorkerEntrypoint: transformWorkerEntrypoint2 } = await import("./worker-entrypoint-y8s9kdcx.js");
1763
- if (!shouldTransformWorker(code, id)) {
1764
- return null;
1765
- }
1766
- const result = transformWorkerEntrypoint2(code, id);
1767
- if (!result)
1768
- return null;
1769
- return {
1770
- code: result.code,
1771
- map: result.map
1772
- };
1773
- }
1774
- async function runDurableObjectTransform(code, id, options) {
1775
- if (!options.doTransforms)
1776
- return null;
1777
- if (!code.includes("DurableObject") && !code.includes("@durableObject")) {
1778
- return null;
1779
- }
1780
- const { transformDurableObject } = await import("./durable-object-0ybmg08a.js");
1781
- return transformDurableObject(code, id);
1782
- }
1783
- async function runDevflareTransform(code, id, options) {
1784
- if (!isTransformCandidate(id))
1785
- return null;
1786
- const workerResult = await runWorkerEntryTransform(code, id);
1787
- if (workerResult)
1788
- return workerResult;
1789
- return await runDurableObjectTransform(code, id, options);
1790
- }
1791
-
1792
- // src/vite/plugin.ts
1793
- var CONFIG_DIR2 = ".devflare";
1794
- function createPluginState() {
1795
- return {
1796
- context: {
1797
- wranglerConfig: null,
1798
- cloudflareConfig: null,
1799
- projectRoot: process.cwd(),
1800
- auxiliaryWorkerConfig: null,
1801
- auxiliaryWorkerConfigs: [],
1802
- serviceWorkerVirtualModules: new Map,
1803
- durableObjects: null
1804
- },
1805
- projectRoot: process.cwd(),
1806
- devflareConfig: null,
1807
- resolvedPluginConfigPath: null
1808
- };
1809
- }
1810
- async function loadAndApplyConfig(state, options, mode, onContextUpdated) {
1811
- state.devflareConfig = await loadConfig({
1812
- cwd: state.projectRoot,
1813
- configFile: options.configPath
1814
- });
1815
- const pluginState = await buildPluginContextState(state.projectRoot, state.devflareConfig, options.environment, mode, state.resolvedPluginConfigPath ? dirname3(state.resolvedPluginConfigPath) : state.projectRoot);
1816
- Object.assign(state.context, {
1817
- projectRoot: state.projectRoot,
1818
- ...pluginState
1819
- });
1820
- onContextUpdated(state.context);
1821
- logDiscoveredDurableObjects(state.projectRoot, pluginState.durableObjects);
1822
- await writeGeneratedWranglerConfig(state.projectRoot, pluginState.wranglerConfig);
1823
- }
1824
- var lastPluginContext = createPluginState().context;
1825
- function devflarePlugin(options = {}) {
1826
- const {
1827
- configPath,
1828
- environment,
1829
- doTransforms = true,
1830
- watchConfig = true,
1831
- bridgePort = process.env.DEVFLARE_BRIDGE_PORT ? Number.parseInt(process.env.DEVFLARE_BRIDGE_PORT, 10) : undefined,
1832
- wsProxyPatterns = []
1833
- } = options;
1834
- const state = createPluginState();
1835
- return {
1836
- name: "devflare",
1837
- enforce: "pre",
1838
- async config(config, { command }) {
1839
- const cwd = config.root ?? process.cwd();
1840
- return buildPluginConfigHookResult(cwd, { configPath, bridgePort, wsProxyPatterns }, command, config.define ?? {});
1841
- },
1842
- resolveId(id) {
1843
- if (id === VIRTUAL_DO_ENTRY) {
1844
- return RESOLVED_VIRTUAL_DO_ENTRY;
1845
- }
1846
- if (id.startsWith(VIRTUAL_SERVICE_WORKER_PREFIX)) {
1847
- return "\x00" + id;
1848
- }
1849
- return null;
1850
- },
1851
- async load(id) {
1852
- if (id === RESOLVED_VIRTUAL_DO_ENTRY) {
1853
- if (!state.context.durableObjects) {
1854
- return `// No Durable Objects configured
1855
- export default { fetch: () => new Response("No DOs") }`;
1856
- }
1857
- return generateVirtualDOEntry(state.context.durableObjects);
1858
- }
1859
- if (id.startsWith(RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX)) {
1860
- return state.context.serviceWorkerVirtualModules.get(id) ?? null;
1861
- }
1862
- return null;
1863
- },
1864
- async configResolved(config) {
1865
- state.projectRoot = config.root;
1866
- state.context.projectRoot = state.projectRoot;
1867
- state.resolvedPluginConfigPath = await resolvePluginConfigPath(state.projectRoot, configPath);
1868
- try {
1869
- await loadAndApplyConfig(state, { configPath, environment }, config.command === "build" ? "build" : "serve", (ctx) => {
1870
- lastPluginContext = ctx;
1871
- });
1872
- if (config.command === "serve") {
1873
- console.log("[devflare] Config generated to .devflare/wrangler.jsonc");
1874
- if (state.context.auxiliaryWorkerConfig) {
1875
- console.log("[devflare] ✓ Auxiliary DO worker configured");
1876
- }
1877
- }
1878
- if (config.command === "build") {
1879
- console.log(`[devflare] Generated ${CONFIG_DIR2}/wrangler.jsonc`);
1880
- }
1881
- } catch (error) {
1882
- if (error instanceof Error) {
1883
- console.error("[devflare] Config error:", error.message);
1884
- }
1885
- throw error;
1886
- }
1887
- },
1888
- configureServer(server) {
1889
- if (!watchConfig)
1890
- return;
1891
- const fullConfigPath = state.resolvedPluginConfigPath ?? resolve6(state.projectRoot, configPath || "devflare.config.ts");
1892
- server.watcher.add(fullConfigPath);
1893
- server.watcher.on("change", async (changedPath) => {
1894
- if (changedPath === fullConfigPath) {
1895
- console.log("[devflare] Config changed, reloading...");
1896
- try {
1897
- await loadAndApplyConfig(state, { configPath, environment }, "serve", (ctx) => {
1898
- lastPluginContext = ctx;
1899
- });
1900
- console.log("[devflare] Config reloaded");
1901
- server.ws.send({
1902
- type: "full-reload",
1903
- path: "*"
1904
- });
1905
- } catch (error) {
1906
- console.error("[devflare] Failed to reload config:", error);
1907
- }
1908
- }
1909
- });
1910
- },
1911
- async transform(code, id) {
1912
- return runDevflareTransform(code, id, { doTransforms });
1913
- }
1914
- };
1915
- }
1916
-
1917
- // src/vite/config-file.ts
1918
- var CONFIG_DIR3 = ".devflare";
1919
- var GENERATED_VITE_CONFIG_FILENAME = "vite.config.mjs";
1920
- function hasInlineViteConfig(viteConfig) {
1921
- return Boolean(viteConfig && Object.keys(viteConfig).length > 0);
1922
- }
1923
- function resolveEffectiveViteProject(detection, config, environment) {
1924
- const resolvedConfig = resolveConfigForEnvironment(config, environment);
1925
- const hasDevflareConfig = hasInlineViteConfig(resolvedConfig.vite);
1926
- return {
1927
- ...detection,
1928
- hasDevflareViteConfig: hasDevflareConfig,
1929
- shouldStartVite: detection.shouldStartVite || hasDevflareConfig,
1930
- wantsViteIntegration: detection.wantsViteIntegration || hasDevflareConfig
1931
- };
1932
- }
1933
- function isPromiseLike(value) {
1934
- return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
1935
- }
1936
- function normalizePluginOptions(pluginOption) {
1937
- if (typeof pluginOption === "undefined") {
1938
- return [];
1939
- }
1940
- return Array.isArray(pluginOption) ? pluginOption : [pluginOption];
1941
- }
1942
- function removePluginByName(pluginOption, pluginName) {
1943
- if (Array.isArray(pluginOption)) {
1944
- const filteredPlugins = pluginOption.map((nestedPlugin) => removePluginByName(nestedPlugin, pluginName)).filter((nestedPlugin) => typeof nestedPlugin !== "undefined");
1945
- return filteredPlugins.length > 0 ? filteredPlugins : undefined;
1946
- }
1947
- if (!pluginOption || typeof pluginOption === "boolean" || isPromiseLike(pluginOption)) {
1948
- return pluginOption;
1949
- }
1950
- return pluginOption.name === pluginName ? undefined : pluginOption;
1951
- }
1952
- function withInjectedDevflarePlugin(config, pluginOptions) {
1953
- const existingPlugins = normalizePluginOptions(config.plugins).map((pluginOption) => removePluginByName(pluginOption, "devflare")).filter((pluginOption) => typeof pluginOption !== "undefined");
1954
- return {
1955
- ...config,
1956
- plugins: [devflarePlugin(pluginOptions), ...existingPlugins]
1957
- };
1958
- }
1959
- async function resolveViteUserConfig(configEnv, options = {}) {
1960
- const { loadConfigFromFile, mergeConfig } = await import("vite");
1961
- const cwd = options.cwd ?? process.cwd();
1962
- const devflareConfig = await loadConfig({
1963
- cwd,
1964
- configFile: options.configPath
1965
- });
1966
- const resolvedDevflareConfig = resolveConfigForEnvironment(devflareConfig, options.environment);
1967
- const inlineViteConfig = resolvedDevflareConfig.vite ?? {};
1968
- const localConfig = options.localConfigPath ? (await loadConfigFromFile(configEnv, options.localConfigPath, cwd))?.config ?? {} : {};
1969
- const mergedConfig = mergeConfig(localConfig, inlineViteConfig);
1970
- const normalizedConfig = mergedConfig.root ? mergedConfig : {
1971
- ...mergedConfig,
1972
- root: cwd
1973
- };
1974
- return withInjectedDevflarePlugin(normalizedConfig, {
1975
- configPath: options.configPath,
1976
- environment: options.environment,
1977
- bridgePort: options.bridgePort
1978
- });
1979
- }
1980
- async function ensureGeneratedConfigDir2(cwd) {
1981
- const fs = await import("node:fs/promises");
1982
- const { resolve: resolve7 } = await import("pathe");
1983
- const configDir = resolve7(cwd, CONFIG_DIR3);
1984
- await fs.mkdir(configDir, { recursive: true });
1985
- const gitignorePath = resolve7(configDir, ".gitignore");
1986
- try {
1987
- await fs.access(gitignorePath);
1988
- } catch {
1989
- await fs.writeFile(gitignorePath, `*
1990
- `, "utf-8");
1991
- }
1992
- return configDir;
1993
- }
1994
- async function resolveDevflarePackageRoot(currentFilePath) {
1995
- const fs = await import("node:fs/promises");
1996
- const { dirname: dirname4, resolve: resolve7 } = await import("pathe");
1997
- let currentDir = dirname4(currentFilePath);
1998
- while (true) {
1999
- const packageJsonPath = resolve7(currentDir, "package.json");
2000
- try {
2001
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
2002
- if (packageJson.name === "devflare") {
2003
- return currentDir;
2004
- }
2005
- } catch {}
2006
- const parentDir = dirname4(currentDir);
2007
- if (parentDir === currentDir) {
2008
- break;
2009
- }
2010
- currentDir = parentDir;
2011
- }
2012
- throw new Error("Could not resolve the devflare package root for generated Vite config imports.");
2013
- }
2014
- async function resolveGeneratedViteImportPath(configDir) {
2015
- const { fileURLToPath } = await import("node:url");
2016
- const { extname, normalize, relative: relative4, resolve: resolve7 } = await import("pathe");
2017
- const currentFilePath = normalize(fileURLToPath(import.meta.url));
2018
- const currentExtension = extname(currentFilePath);
2019
- const packageRoot = await resolveDevflarePackageRoot(currentFilePath);
2020
- const viteEntryPath = currentFilePath.includes("/dist/") ? resolve7(packageRoot, "dist/vite/index.js") : resolve7(packageRoot, `src/vite/index${currentExtension}`);
2021
- const relativeImportPath = relative4(configDir, viteEntryPath);
2022
- return relativeImportPath.startsWith(".") ? relativeImportPath : `./${relativeImportPath}`;
2023
- }
2024
- async function writeGeneratedViteConfig(options) {
2025
- const fs = await import("node:fs/promises");
2026
- const { resolve: resolve7 } = await import("pathe");
2027
- const configDir = await ensureGeneratedConfigDir2(options.cwd);
2028
- const generatedConfigPath = resolve7(configDir, GENERATED_VITE_CONFIG_FILENAME);
2029
- const viteImportPath = await resolveGeneratedViteImportPath(configDir);
2030
- const content = `import { defineConfig } from 'vite'
2031
- import { resolveViteUserConfig } from ${JSON.stringify(viteImportPath)}
2032
-
2033
- export default defineConfig(async (env) => {
2034
- return await resolveViteUserConfig(env, {
2035
- cwd: ${JSON.stringify(options.cwd)},
2036
- configPath: ${JSON.stringify(options.configPath)},
2037
- environment: ${JSON.stringify(options.environment)},
2038
- localConfigPath: ${JSON.stringify(options.localConfigPath)},
2039
- bridgePort: ${JSON.stringify(options.bridgePort)}
2040
- })
2041
- })
2042
- `;
2043
- await fs.writeFile(generatedConfigPath, content, "utf-8");
2044
- return generatedConfigPath;
2045
- }
2046
- export { discoverDurableObjectFiles, buildQueueProducers, buildQueueConsumers, buildRateLimitsConfig, buildVersionMetadataConfig, buildWorkerLoadersConfig, buildMtlsCertificatesConfig, buildDispatchNamespacesConfig, buildWorkflowsConfig, buildPipelinesConfig, buildHyperdrivesConfig, buildImagesConfig, buildMediaConfig, buildArtifactsConfig, buildAiSearchNamespacesConfig, buildAiSearchInstancesConfig, buildSecretsStoreConfig, buildSendEmailConfig, resolveServiceBindings, getRouteDirectoryCandidate, discoverRoutes, DEFAULT_FETCH_ENTRY_FILES, DEFAULT_QUEUE_ENTRY_FILES, DEFAULT_SCHEDULED_ENTRY_FILES, DEFAULT_EMAIL_ENTRY_FILES, resolveWorkerSurfacePaths, hasWorkerSurfacePaths, prepareComposedWorkerEntrypoint, hasInlineViteConfig, resolveEffectiveViteProject, resolveViteUserConfig, writeGeneratedViteConfig, devflarePlugin2 as devflarePlugin, getPluginContext, getCloudflareConfig, getDevflareConfigs, devflarePlugin3 as devflarePlugin1 };