everything-dev 1.53.2 → 2.0.0-rc.1

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 (713) hide show
  1. package/README.md +2 -11
  2. package/dist/_virtual/_rolldown/runtime.cjs +17 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +36 -0
  4. package/dist/api/auth-middleware.cjs +161 -0
  5. package/dist/api/auth-middleware.cjs.map +1 -0
  6. package/dist/api/auth-middleware.d.cts +69 -0
  7. package/dist/api/auth-middleware.d.mts +69 -0
  8. package/dist/api/auth-middleware.mjs +160 -0
  9. package/dist/api/auth-middleware.mjs.map +1 -0
  10. package/dist/api-contract.cjs +250 -62
  11. package/dist/api-contract.cjs.map +1 -1
  12. package/dist/api-contract.mjs +246 -65
  13. package/dist/api-contract.mjs.map +1 -1
  14. package/dist/app.cjs +99 -26
  15. package/dist/app.cjs.map +1 -1
  16. package/dist/app.d.cts +3 -0
  17. package/dist/app.d.mts +3 -0
  18. package/dist/app.mjs +100 -27
  19. package/dist/app.mjs.map +1 -1
  20. package/dist/auth-login.cjs +163 -0
  21. package/dist/auth-login.cjs.map +1 -0
  22. package/dist/auth-login.mjs +162 -0
  23. package/dist/auth-login.mjs.map +1 -0
  24. package/dist/auth-session.cjs +64 -0
  25. package/dist/auth-session.cjs.map +1 -0
  26. package/dist/auth-session.mjs +58 -0
  27. package/dist/auth-session.mjs.map +1 -0
  28. package/dist/auth-types-gen.cjs +0 -1
  29. package/dist/auth-types-gen.cjs.map +1 -1
  30. package/dist/build.cjs +37 -173
  31. package/dist/build.cjs.map +1 -1
  32. package/dist/build.mjs +37 -171
  33. package/dist/build.mjs.map +1 -1
  34. package/dist/bundle-cache.cjs +74 -0
  35. package/dist/bundle-cache.cjs.map +1 -0
  36. package/dist/bundle-cache.d.cts +27 -0
  37. package/dist/bundle-cache.d.mts +27 -0
  38. package/dist/bundle-cache.mjs +68 -0
  39. package/dist/bundle-cache.mjs.map +1 -0
  40. package/dist/bundle-fs-resolve.cjs +209 -0
  41. package/dist/bundle-fs-resolve.cjs.map +1 -0
  42. package/dist/bundle-fs-resolve.d.cts +76 -0
  43. package/dist/bundle-fs-resolve.d.mts +76 -0
  44. package/dist/bundle-fs-resolve.mjs +202 -0
  45. package/dist/bundle-fs-resolve.mjs.map +1 -0
  46. package/dist/cdn-deploy.cjs +126 -0
  47. package/dist/cdn-deploy.cjs.map +1 -0
  48. package/dist/cdn-deploy.mjs +124 -0
  49. package/dist/cdn-deploy.mjs.map +1 -0
  50. package/dist/cli/db-doctor.cjs +19 -19
  51. package/dist/cli/db-doctor.cjs.map +1 -1
  52. package/dist/cli/db-doctor.mjs +18 -18
  53. package/dist/cli/db-doctor.mjs.map +1 -1
  54. package/dist/cli/db-repair.cjs +9 -32
  55. package/dist/cli/db-repair.cjs.map +1 -1
  56. package/dist/cli/db-repair.mjs +9 -32
  57. package/dist/cli/db-repair.mjs.map +1 -1
  58. package/dist/cli/framework-version.cjs +7 -3
  59. package/dist/cli/framework-version.cjs.map +1 -1
  60. package/dist/cli/framework-version.mjs +7 -3
  61. package/dist/cli/framework-version.mjs.map +1 -1
  62. package/dist/cli/infra.cjs +159 -251
  63. package/dist/cli/infra.cjs.map +1 -1
  64. package/dist/cli/infra.mjs +154 -242
  65. package/dist/cli/infra.mjs.map +1 -1
  66. package/dist/cli/init.cjs +627 -199
  67. package/dist/cli/init.cjs.map +1 -1
  68. package/dist/cli/init.d.cts +61 -8
  69. package/dist/cli/init.d.mts +61 -8
  70. package/dist/cli/init.mjs +616 -197
  71. package/dist/cli/init.mjs.map +1 -1
  72. package/dist/cli/parse.cjs +8 -7
  73. package/dist/cli/parse.cjs.map +1 -1
  74. package/dist/cli/parse.mjs +9 -7
  75. package/dist/cli/parse.mjs.map +1 -1
  76. package/dist/cli/prompts.cjs +14 -1
  77. package/dist/cli/prompts.cjs.map +1 -1
  78. package/dist/cli/prompts.mjs +14 -1
  79. package/dist/cli/prompts.mjs.map +1 -1
  80. package/dist/cli/prune.cjs +220 -0
  81. package/dist/cli/prune.cjs.map +1 -0
  82. package/dist/cli/prune.mjs +220 -0
  83. package/dist/cli/prune.mjs.map +1 -0
  84. package/dist/cli/snapshot.cjs +2 -1
  85. package/dist/cli/snapshot.cjs.map +1 -1
  86. package/dist/cli/snapshot.mjs +2 -1
  87. package/dist/cli/snapshot.mjs.map +1 -1
  88. package/dist/cli/status.cjs +5 -4
  89. package/dist/cli/status.cjs.map +1 -1
  90. package/dist/cli/status.mjs +6 -5
  91. package/dist/cli/status.mjs.map +1 -1
  92. package/dist/cli/sync.cjs +156 -58
  93. package/dist/cli/sync.cjs.map +1 -1
  94. package/dist/cli/sync.mjs +158 -63
  95. package/dist/cli/sync.mjs.map +1 -1
  96. package/dist/cli/timing.cjs +0 -1
  97. package/dist/cli/timing.cjs.map +1 -1
  98. package/dist/cli/upgrade.cjs +95 -69
  99. package/dist/cli/upgrade.cjs.map +1 -1
  100. package/dist/cli/upgrade.mjs +97 -72
  101. package/dist/cli/upgrade.mjs.map +1 -1
  102. package/dist/cli/utils/helpers.cjs.map +1 -1
  103. package/dist/cli.cjs +320 -72
  104. package/dist/cli.cjs.map +1 -1
  105. package/dist/cli.mjs +316 -68
  106. package/dist/cli.mjs.map +1 -1
  107. package/dist/code-artifacts.cjs +76 -8
  108. package/dist/code-artifacts.cjs.map +1 -1
  109. package/dist/code-artifacts.mjs +76 -10
  110. package/dist/code-artifacts.mjs.map +1 -1
  111. package/dist/commands/build.cjs +65 -0
  112. package/dist/commands/build.cjs.map +1 -0
  113. package/dist/commands/build.mjs +65 -0
  114. package/dist/commands/build.mjs.map +1 -0
  115. package/dist/commands/config.cjs +77 -0
  116. package/dist/commands/config.cjs.map +1 -0
  117. package/dist/commands/config.d.cts +8 -0
  118. package/dist/commands/config.d.mts +8 -0
  119. package/dist/commands/config.mjs +74 -0
  120. package/dist/commands/config.mjs.map +1 -0
  121. package/dist/commands/db.cjs +107 -0
  122. package/dist/commands/db.cjs.map +1 -0
  123. package/dist/commands/db.mjs +107 -0
  124. package/dist/commands/db.mjs.map +1 -0
  125. package/dist/commands/deploy.cjs +336 -0
  126. package/dist/commands/deploy.cjs.map +1 -0
  127. package/dist/commands/deploy.mjs +334 -0
  128. package/dist/commands/deploy.mjs.map +1 -0
  129. package/dist/commands/dev.cjs +75 -0
  130. package/dist/commands/dev.cjs.map +1 -0
  131. package/dist/commands/dev.mjs +73 -0
  132. package/dist/commands/dev.mjs.map +1 -0
  133. package/dist/commands/init.cjs +234 -0
  134. package/dist/commands/init.cjs.map +1 -0
  135. package/dist/commands/init.mjs +231 -0
  136. package/dist/commands/init.mjs.map +1 -0
  137. package/dist/commands/keys.cjs +255 -0
  138. package/dist/commands/keys.cjs.map +1 -0
  139. package/dist/commands/keys.mjs +253 -0
  140. package/dist/commands/keys.mjs.map +1 -0
  141. package/dist/commands/ops.cjs +199 -0
  142. package/dist/commands/ops.cjs.map +1 -0
  143. package/dist/commands/ops.mjs +197 -0
  144. package/dist/commands/ops.mjs.map +1 -0
  145. package/dist/commands/plugins.cjs +211 -0
  146. package/dist/commands/plugins.cjs.map +1 -0
  147. package/dist/commands/plugins.mjs +211 -0
  148. package/dist/commands/plugins.mjs.map +1 -0
  149. package/dist/commands/shared.cjs +8 -0
  150. package/dist/commands/shared.cjs.map +1 -0
  151. package/dist/commands/shared.d.cts +6 -0
  152. package/dist/commands/shared.d.mts +6 -0
  153. package/dist/commands/shared.mjs +8 -0
  154. package/dist/commands/shared.mjs.map +1 -0
  155. package/dist/commands/upgrade.cjs +325 -0
  156. package/dist/commands/upgrade.cjs.map +1 -0
  157. package/dist/commands/upgrade.mjs +323 -0
  158. package/dist/commands/upgrade.mjs.map +1 -0
  159. package/dist/components/dev-render.cjs +340 -0
  160. package/dist/components/dev-render.cjs.map +1 -0
  161. package/dist/components/dev-render.mjs +332 -0
  162. package/dist/components/dev-render.mjs.map +1 -0
  163. package/dist/config.cjs +460 -221
  164. package/dist/config.cjs.map +1 -1
  165. package/dist/config.d.cts +491 -48
  166. package/dist/config.d.mts +491 -48
  167. package/dist/config.mjs +439 -212
  168. package/dist/config.mjs.map +1 -1
  169. package/dist/contract.cjs +327 -50
  170. package/dist/contract.cjs.map +1 -1
  171. package/dist/contract.d.cts +1951 -1062
  172. package/dist/contract.d.mts +1951 -1062
  173. package/dist/contract.meta.cjs +107 -12
  174. package/dist/contract.meta.cjs.map +1 -1
  175. package/dist/contract.meta.d.cts +166 -8
  176. package/dist/contract.meta.d.mts +166 -8
  177. package/dist/contract.meta.mjs +107 -11
  178. package/dist/contract.meta.mjs.map +1 -1
  179. package/dist/contract.mjs +580 -327
  180. package/dist/contract.mjs.map +1 -1
  181. package/dist/dag.cjs +5 -3
  182. package/dist/dag.cjs.map +1 -1
  183. package/dist/dag.mjs +6 -3
  184. package/dist/dag.mjs.map +1 -1
  185. package/dist/db/binding.cjs +80 -0
  186. package/dist/db/binding.cjs.map +1 -0
  187. package/dist/db/binding.d.cts +39 -0
  188. package/dist/db/binding.d.mts +39 -0
  189. package/dist/db/binding.mjs +78 -0
  190. package/dist/db/binding.mjs.map +1 -0
  191. package/dist/db/bindings.cjs +78 -0
  192. package/dist/db/bindings.cjs.map +1 -0
  193. package/dist/db/bindings.d.cts +34 -0
  194. package/dist/db/bindings.d.mts +34 -0
  195. package/dist/db/bindings.mjs +76 -0
  196. package/dist/db/bindings.mjs.map +1 -0
  197. package/dist/db/core.cjs +204 -0
  198. package/dist/db/core.cjs.map +1 -0
  199. package/dist/db/core.d.cts +69 -0
  200. package/dist/db/core.d.mts +69 -0
  201. package/dist/db/core.mjs +192 -0
  202. package/dist/db/core.mjs.map +1 -0
  203. package/dist/db/driver.cjs +167 -0
  204. package/dist/db/driver.cjs.map +1 -0
  205. package/dist/db/driver.d.cts +50 -0
  206. package/dist/db/driver.d.mts +50 -0
  207. package/dist/db/driver.mjs +165 -0
  208. package/dist/db/driver.mjs.map +1 -0
  209. package/dist/db/drizzle-kit.cjs +177 -0
  210. package/dist/db/drizzle-kit.cjs.map +1 -0
  211. package/dist/db/drizzle-kit.d.cts +25 -0
  212. package/dist/db/drizzle-kit.d.mts +25 -0
  213. package/dist/db/drizzle-kit.mjs +175 -0
  214. package/dist/db/drizzle-kit.mjs.map +1 -0
  215. package/dist/db/errors.cjs +27 -0
  216. package/dist/db/errors.cjs.map +1 -0
  217. package/dist/db/errors.d.cts +16 -0
  218. package/dist/db/errors.d.mts +16 -0
  219. package/dist/db/errors.mjs +26 -0
  220. package/dist/db/errors.mjs.map +1 -0
  221. package/dist/db/identity.cjs +55 -0
  222. package/dist/db/identity.cjs.map +1 -0
  223. package/dist/db/identity.d.cts +40 -0
  224. package/dist/db/identity.d.mts +40 -0
  225. package/dist/db/identity.mjs +53 -0
  226. package/dist/db/identity.mjs.map +1 -0
  227. package/dist/db/index.cjs +43 -0
  228. package/dist/db/index.d.cts +9 -0
  229. package/dist/db/index.d.mts +9 -0
  230. package/dist/db/index.mjs +10 -0
  231. package/dist/db/run-migrations.cjs +343 -0
  232. package/dist/db/run-migrations.cjs.map +1 -0
  233. package/dist/db/run-migrations.d.cts +87 -0
  234. package/dist/db/run-migrations.d.mts +87 -0
  235. package/dist/db/run-migrations.mjs +341 -0
  236. package/dist/db/run-migrations.mjs.map +1 -0
  237. package/dist/delegate-signer.cjs +85 -0
  238. package/dist/delegate-signer.cjs.map +1 -0
  239. package/dist/delegate-signer.mjs +84 -0
  240. package/dist/delegate-signer.mjs.map +1 -0
  241. package/dist/deploy-diff.cjs +119 -0
  242. package/dist/deploy-diff.cjs.map +1 -0
  243. package/dist/deploy-diff.mjs +109 -0
  244. package/dist/deploy-diff.mjs.map +1 -0
  245. package/dist/descriptor/constructors.cjs +49 -0
  246. package/dist/descriptor/constructors.cjs.map +1 -0
  247. package/dist/descriptor/constructors.d.cts +27 -0
  248. package/dist/descriptor/constructors.d.mts +27 -0
  249. package/dist/descriptor/constructors.mjs +45 -0
  250. package/dist/descriptor/constructors.mjs.map +1 -0
  251. package/dist/descriptor/index.cjs +24 -0
  252. package/dist/descriptor/index.d.cts +5 -0
  253. package/dist/descriptor/index.d.mts +5 -0
  254. package/dist/descriptor/index.mjs +6 -0
  255. package/dist/descriptor/resolve.cjs +258 -0
  256. package/dist/descriptor/resolve.cjs.map +1 -0
  257. package/dist/descriptor/resolve.d.cts +50 -0
  258. package/dist/descriptor/resolve.d.mts +50 -0
  259. package/dist/descriptor/resolve.mjs +252 -0
  260. package/dist/descriptor/resolve.mjs.map +1 -0
  261. package/dist/descriptor/schema.cjs +109 -0
  262. package/dist/descriptor/schema.cjs.map +1 -0
  263. package/dist/descriptor/schema.d.cts +217 -0
  264. package/dist/descriptor/schema.d.mts +217 -0
  265. package/dist/descriptor/schema.mjs +102 -0
  266. package/dist/descriptor/schema.mjs.map +1 -0
  267. package/dist/descriptor/serialize.cjs +45 -0
  268. package/dist/descriptor/serialize.cjs.map +1 -0
  269. package/dist/descriptor/serialize.d.cts +7 -0
  270. package/dist/descriptor/serialize.d.mts +7 -0
  271. package/dist/descriptor/serialize.mjs +45 -0
  272. package/dist/descriptor/serialize.mjs.map +1 -0
  273. package/dist/dev-log-pipeline.cjs +273 -0
  274. package/dist/dev-log-pipeline.cjs.map +1 -0
  275. package/dist/dev-log-pipeline.mjs +267 -0
  276. package/dist/dev-log-pipeline.mjs.map +1 -0
  277. package/dist/dev-logs.cjs +39 -8
  278. package/dist/dev-logs.cjs.map +1 -1
  279. package/dist/dev-logs.mjs +37 -9
  280. package/dist/dev-logs.mjs.map +1 -1
  281. package/dist/dev-program.cjs +405 -0
  282. package/dist/dev-program.cjs.map +1 -0
  283. package/dist/dev-program.d.cts +10 -0
  284. package/dist/dev-program.d.mts +10 -0
  285. package/dist/dev-program.mjs +395 -0
  286. package/dist/dev-program.mjs.map +1 -0
  287. package/dist/dev-session-data.d.cts +27 -0
  288. package/dist/dev-session-data.d.mts +27 -0
  289. package/dist/dev-session.cjs +178 -105
  290. package/dist/dev-session.cjs.map +1 -1
  291. package/dist/dev-session.mjs +180 -105
  292. package/dist/dev-session.mjs.map +1 -1
  293. package/dist/env/process-env.cjs +16 -0
  294. package/dist/env/process-env.cjs.map +1 -0
  295. package/dist/env/process-env.mjs +13 -0
  296. package/dist/env/process-env.mjs.map +1 -0
  297. package/dist/env/project-env.cjs +144 -0
  298. package/dist/env/project-env.cjs.map +1 -0
  299. package/dist/env/project-env.d.cts +1 -0
  300. package/dist/env/project-env.d.mts +1 -0
  301. package/dist/env/project-env.mjs +132 -0
  302. package/dist/env/project-env.mjs.map +1 -0
  303. package/dist/fastkv.cjs +59 -12
  304. package/dist/fastkv.cjs.map +1 -1
  305. package/dist/fastkv.d.cts +42 -6
  306. package/dist/fastkv.d.mts +42 -6
  307. package/dist/fastkv.mjs +58 -13
  308. package/dist/fastkv.mjs.map +1 -1
  309. package/dist/fingerprint.cjs +57 -0
  310. package/dist/fingerprint.cjs.map +1 -0
  311. package/dist/fingerprint.d.cts +14 -0
  312. package/dist/fingerprint.d.mts +14 -0
  313. package/dist/fingerprint.mjs +55 -0
  314. package/dist/fingerprint.mjs.map +1 -0
  315. package/dist/http-client.cjs +17 -17
  316. package/dist/http-client.cjs.map +1 -1
  317. package/dist/http-client.mjs +17 -17
  318. package/dist/http-client.mjs.map +1 -1
  319. package/dist/image-deploy.cjs +186 -0
  320. package/dist/image-deploy.cjs.map +1 -0
  321. package/dist/image-deploy.mjs +182 -0
  322. package/dist/image-deploy.mjs.map +1 -0
  323. package/dist/index.cjs +66 -18
  324. package/dist/index.d.cts +8 -7
  325. package/dist/index.d.mts +8 -7
  326. package/dist/index.mjs +6 -5
  327. package/dist/infra/docker.cjs +77 -0
  328. package/dist/infra/docker.cjs.map +1 -0
  329. package/dist/infra/docker.d.cts +10 -0
  330. package/dist/infra/docker.d.mts +10 -0
  331. package/dist/infra/docker.mjs +69 -0
  332. package/dist/infra/docker.mjs.map +1 -0
  333. package/dist/infra/materializer.cjs +74 -0
  334. package/dist/infra/materializer.cjs.map +1 -0
  335. package/dist/infra/materializer.mjs +70 -0
  336. package/dist/infra/materializer.mjs.map +1 -0
  337. package/dist/infra/planner.cjs +135 -103
  338. package/dist/infra/planner.cjs.map +1 -1
  339. package/dist/infra/planner.mjs +137 -104
  340. package/dist/infra/planner.mjs.map +1 -1
  341. package/dist/infra/port-ownership.cjs +57 -0
  342. package/dist/infra/port-ownership.cjs.map +1 -0
  343. package/dist/infra/port-ownership.mjs +57 -0
  344. package/dist/infra/port-ownership.mjs.map +1 -0
  345. package/dist/infra/preflight.cjs +45 -33
  346. package/dist/infra/preflight.cjs.map +1 -1
  347. package/dist/infra/preflight.d.cts +1 -0
  348. package/dist/infra/preflight.d.mts +1 -0
  349. package/dist/infra/preflight.mjs +46 -34
  350. package/dist/infra/preflight.mjs.map +1 -1
  351. package/dist/infra/types.cjs.map +1 -1
  352. package/dist/infra/types.d.cts +2 -0
  353. package/dist/infra/types.d.mts +2 -0
  354. package/dist/infra/types.mjs.map +1 -1
  355. package/dist/integrity.cjs +50 -61
  356. package/dist/integrity.cjs.map +1 -1
  357. package/dist/integrity.d.cts +16 -10
  358. package/dist/integrity.d.mts +16 -10
  359. package/dist/integrity.mjs +50 -59
  360. package/dist/integrity.mjs.map +1 -1
  361. package/dist/internal/manifest-normalizer.cjs +8 -2
  362. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  363. package/dist/internal/manifest-normalizer.mjs +9 -3
  364. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  365. package/dist/merge.cjs +19 -1
  366. package/dist/merge.cjs.map +1 -1
  367. package/dist/merge.d.cts +1 -1
  368. package/dist/merge.d.mts +1 -1
  369. package/dist/merge.mjs +19 -2
  370. package/dist/merge.mjs.map +1 -1
  371. package/dist/mf.cjs +190 -3
  372. package/dist/mf.cjs.map +1 -1
  373. package/dist/mf.d.cts +24 -2
  374. package/dist/mf.d.mts +24 -2
  375. package/dist/mf.mjs +189 -4
  376. package/dist/mf.mjs.map +1 -1
  377. package/dist/near-cli.cjs +59 -91
  378. package/dist/near-cli.cjs.map +1 -1
  379. package/dist/near-cli.mjs +58 -90
  380. package/dist/near-cli.mjs.map +1 -1
  381. package/dist/near-signer.cjs +73 -0
  382. package/dist/near-signer.cjs.map +1 -0
  383. package/dist/near-signer.mjs +70 -0
  384. package/dist/near-signer.mjs.map +1 -0
  385. package/dist/network.cjs +0 -1
  386. package/dist/network.cjs.map +1 -1
  387. package/dist/orchestrator.cjs +256 -87
  388. package/dist/orchestrator.cjs.map +1 -1
  389. package/dist/orchestrator.mjs +248 -87
  390. package/dist/orchestrator.mjs.map +1 -1
  391. package/dist/platform-deploy.cjs +81 -0
  392. package/dist/platform-deploy.cjs.map +1 -0
  393. package/dist/platform-deploy.mjs +80 -0
  394. package/dist/platform-deploy.mjs.map +1 -0
  395. package/dist/plugin.cjs +54 -1389
  396. package/dist/plugin.cjs.map +1 -1
  397. package/dist/plugin.d.cts +6 -896
  398. package/dist/plugin.d.mts +6 -896
  399. package/dist/plugin.mjs +53 -1387
  400. package/dist/plugin.mjs.map +1 -1
  401. package/dist/process-kill.cjs +44 -0
  402. package/dist/process-kill.cjs.map +1 -0
  403. package/dist/process-kill.mjs +43 -0
  404. package/dist/process-kill.mjs.map +1 -0
  405. package/dist/process-registry.cjs +64 -9
  406. package/dist/process-registry.cjs.map +1 -1
  407. package/dist/process-registry.mjs +61 -10
  408. package/dist/process-registry.mjs.map +1 -1
  409. package/dist/progress.cjs +45 -0
  410. package/dist/progress.cjs.map +1 -0
  411. package/dist/progress.d.cts +13 -0
  412. package/dist/progress.d.mts +13 -0
  413. package/dist/progress.mjs +42 -0
  414. package/dist/progress.mjs.map +1 -0
  415. package/dist/publish.cjs +513 -79
  416. package/dist/publish.cjs.map +1 -1
  417. package/dist/publish.mjs +515 -82
  418. package/dist/publish.mjs.map +1 -1
  419. package/dist/registry-use.cjs +41 -0
  420. package/dist/registry-use.cjs.map +1 -0
  421. package/dist/registry-use.mjs +40 -0
  422. package/dist/registry-use.mjs.map +1 -0
  423. package/dist/resolution/session.cjs +335 -0
  424. package/dist/resolution/session.cjs.map +1 -0
  425. package/dist/resolution/session.d.cts +105 -0
  426. package/dist/resolution/session.d.mts +105 -0
  427. package/dist/resolution/session.mjs +331 -0
  428. package/dist/resolution/session.mjs.map +1 -0
  429. package/dist/rollback.cjs +131 -0
  430. package/dist/rollback.cjs.map +1 -0
  431. package/dist/rollback.mjs +128 -0
  432. package/dist/rollback.mjs.map +1 -0
  433. package/dist/sdk.cjs +7 -7
  434. package/dist/sdk.d.cts +3 -3
  435. package/dist/sdk.d.mts +3 -3
  436. package/dist/sdk.mjs +2 -2
  437. package/dist/service-descriptor.cjs +67 -34
  438. package/dist/service-descriptor.cjs.map +1 -1
  439. package/dist/service-descriptor.d.cts +4 -1
  440. package/dist/service-descriptor.d.mts +3 -0
  441. package/dist/service-descriptor.mjs +63 -35
  442. package/dist/service-descriptor.mjs.map +1 -1
  443. package/dist/shared-deps.cjs +17 -16
  444. package/dist/shared-deps.cjs.map +1 -1
  445. package/dist/shared-deps.mjs +17 -16
  446. package/dist/shared-deps.mjs.map +1 -1
  447. package/dist/start-config-source.cjs +24 -0
  448. package/dist/start-config-source.cjs.map +1 -0
  449. package/dist/start-config-source.d.cts +29 -0
  450. package/dist/start-config-source.d.mts +29 -0
  451. package/dist/start-config-source.mjs +22 -0
  452. package/dist/start-config-source.mjs.map +1 -0
  453. package/dist/storage-upload.cjs +145 -0
  454. package/dist/storage-upload.cjs.map +1 -0
  455. package/dist/storage-upload.mjs +143 -0
  456. package/dist/storage-upload.mjs.map +1 -0
  457. package/dist/types.cjs +126 -20
  458. package/dist/types.cjs.map +1 -1
  459. package/dist/types.d.cts +867 -585
  460. package/dist/types.d.mts +867 -585
  461. package/dist/types.mjs +307 -208
  462. package/dist/types.mjs.map +1 -1
  463. package/dist/ui/api.cjs +105 -0
  464. package/dist/ui/api.cjs.map +1 -0
  465. package/dist/ui/api.d.cts +31 -0
  466. package/dist/ui/api.d.mts +31 -0
  467. package/dist/ui/api.mjs +99 -0
  468. package/dist/ui/api.mjs.map +1 -0
  469. package/dist/ui/auth-guards.cjs +50 -0
  470. package/dist/ui/auth-guards.cjs.map +1 -0
  471. package/dist/ui/auth-guards.d.cts +39 -0
  472. package/dist/ui/auth-guards.d.mts +39 -0
  473. package/dist/ui/auth-guards.mjs +48 -0
  474. package/dist/ui/auth-guards.mjs.map +1 -0
  475. package/dist/ui/auth.cjs +197 -0
  476. package/dist/ui/auth.cjs.map +1 -0
  477. package/dist/ui/auth.d.cts +56 -0
  478. package/dist/ui/auth.d.mts +56 -0
  479. package/dist/ui/auth.mjs +179 -0
  480. package/dist/ui/auth.mjs.map +1 -0
  481. package/dist/ui/entry.cjs +16 -0
  482. package/dist/ui/entry.cjs.map +1 -0
  483. package/dist/ui/entry.d.cts +12 -0
  484. package/dist/ui/entry.d.mts +12 -0
  485. package/dist/ui/entry.mjs +15 -0
  486. package/dist/ui/entry.mjs.map +1 -0
  487. package/dist/ui/head.cjs +14 -7
  488. package/dist/ui/head.cjs.map +1 -1
  489. package/dist/ui/head.mjs +15 -7
  490. package/dist/ui/head.mjs.map +1 -1
  491. package/dist/ui/hydrate.cjs +265 -0
  492. package/dist/ui/hydrate.cjs.map +1 -0
  493. package/dist/ui/hydrate.d.cts +48 -0
  494. package/dist/ui/hydrate.d.mts +48 -0
  495. package/dist/ui/hydrate.mjs +263 -0
  496. package/dist/ui/hydrate.mjs.map +1 -0
  497. package/dist/ui/i18n.cjs +153 -0
  498. package/dist/ui/i18n.cjs.map +1 -0
  499. package/dist/ui/i18n.d.cts +29 -0
  500. package/dist/ui/i18n.d.mts +29 -0
  501. package/dist/ui/i18n.mjs +140 -0
  502. package/dist/ui/i18n.mjs.map +1 -0
  503. package/dist/ui/index.cjs +19 -1
  504. package/dist/ui/index.d.cts +6 -3
  505. package/dist/ui/index.d.mts +6 -3
  506. package/dist/ui/index.mjs +5 -2
  507. package/dist/ui/locale.cjs +53 -0
  508. package/dist/ui/locale.cjs.map +1 -0
  509. package/dist/ui/locale.d.cts +18 -0
  510. package/dist/ui/locale.d.mts +18 -0
  511. package/dist/ui/locale.mjs +49 -0
  512. package/dist/ui/locale.mjs.map +1 -0
  513. package/dist/ui/manifest/index.cjs +25 -0
  514. package/dist/ui/manifest/index.cjs.map +1 -0
  515. package/dist/ui/manifest/index.d.cts +9 -0
  516. package/dist/ui/manifest/index.d.mts +9 -0
  517. package/dist/ui/manifest/index.mjs +13 -0
  518. package/dist/ui/manifest/index.mjs.map +1 -0
  519. package/dist/ui/manifest-generator.cjs +8 -0
  520. package/dist/ui/manifest-generator.d.cts +1 -0
  521. package/dist/ui/manifest-generator.d.mts +1 -0
  522. package/dist/ui/manifest-generator.mjs +3 -0
  523. package/dist/ui/message-catalogs.cjs +8 -0
  524. package/dist/ui/message-catalogs.cjs.map +1 -0
  525. package/dist/ui/message-catalogs.d.cts +5 -0
  526. package/dist/ui/message-catalogs.d.mts +5 -0
  527. package/dist/ui/message-catalogs.mjs +8 -0
  528. package/dist/ui/message-catalogs.mjs.map +1 -0
  529. package/dist/ui/metadata.cjs +0 -1
  530. package/dist/ui/metadata.cjs.map +1 -1
  531. package/dist/ui/metadata.d.cts +1 -1
  532. package/dist/ui/metadata.d.mts +1 -1
  533. package/dist/ui/plugin-path.cjs +37 -0
  534. package/dist/ui/plugin-path.cjs.map +1 -0
  535. package/dist/ui/plugin-path.d.cts +25 -0
  536. package/dist/ui/plugin-path.d.mts +25 -0
  537. package/dist/ui/plugin-path.mjs +35 -0
  538. package/dist/ui/plugin-path.mjs.map +1 -0
  539. package/dist/ui/router-client.cjs +61 -0
  540. package/dist/ui/router-client.cjs.map +1 -0
  541. package/dist/ui/router-client.d.cts +20 -0
  542. package/dist/ui/router-client.d.mts +20 -0
  543. package/dist/ui/router-client.mjs +60 -0
  544. package/dist/ui/router-client.mjs.map +1 -0
  545. package/dist/ui/router-defaults.cjs +48 -0
  546. package/dist/ui/router-defaults.cjs.map +1 -0
  547. package/dist/ui/router-defaults.d.cts +8 -0
  548. package/dist/ui/router-defaults.d.mts +8 -0
  549. package/dist/ui/router-defaults.mjs +45 -0
  550. package/dist/ui/router-defaults.mjs.map +1 -0
  551. package/dist/ui/router-error.cjs +70 -0
  552. package/dist/ui/router-error.cjs.map +1 -0
  553. package/dist/ui/router-error.d.cts +19 -0
  554. package/dist/ui/router-error.d.mts +19 -0
  555. package/dist/ui/router-error.mjs +69 -0
  556. package/dist/ui/router-error.mjs.map +1 -0
  557. package/dist/ui/router-server.cjs +153 -0
  558. package/dist/ui/router-server.cjs.map +1 -0
  559. package/dist/ui/router-server.d.cts +38 -0
  560. package/dist/ui/router-server.d.mts +38 -0
  561. package/dist/ui/router-server.mjs +152 -0
  562. package/dist/ui/router-server.mjs.map +1 -0
  563. package/dist/ui/router.cjs +4 -16
  564. package/dist/ui/router.cjs.map +1 -1
  565. package/dist/ui/router.mjs +4 -15
  566. package/dist/ui/router.mjs.map +1 -1
  567. package/dist/ui/runtime.cjs +5 -1
  568. package/dist/ui/runtime.cjs.map +1 -1
  569. package/dist/ui/runtime.d.cts +2 -1
  570. package/dist/ui/runtime.d.mts +2 -1
  571. package/dist/ui/runtime.mjs +5 -1
  572. package/dist/ui/runtime.mjs.map +1 -1
  573. package/dist/ui/slot.cjs +34 -0
  574. package/dist/ui/slot.cjs.map +1 -0
  575. package/dist/ui/slot.d.cts +43 -0
  576. package/dist/ui/slot.d.mts +43 -0
  577. package/dist/ui/slot.mjs +34 -0
  578. package/dist/ui/slot.mjs.map +1 -0
  579. package/dist/ui/tenant.cjs +300 -0
  580. package/dist/ui/tenant.cjs.map +1 -0
  581. package/dist/ui/tenant.d.cts +122 -0
  582. package/dist/ui/tenant.d.mts +122 -0
  583. package/dist/ui/tenant.mjs +279 -0
  584. package/dist/ui/tenant.mjs.map +1 -0
  585. package/dist/ui/types.d.cts +32 -2
  586. package/dist/ui/types.d.mts +32 -2
  587. package/dist/ui/version-check.cjs +47 -0
  588. package/dist/ui/version-check.cjs.map +1 -0
  589. package/dist/ui/version-check.d.cts +23 -0
  590. package/dist/ui/version-check.d.mts +23 -0
  591. package/dist/ui/version-check.mjs +46 -0
  592. package/dist/ui/version-check.mjs.map +1 -0
  593. package/dist/utils/banner.cjs +2 -2
  594. package/dist/utils/banner.cjs.map +1 -1
  595. package/dist/utils/banner.mjs +2 -2
  596. package/dist/utils/banner.mjs.map +1 -1
  597. package/dist/utils/linkify.cjs +1 -1
  598. package/dist/utils/linkify.cjs.map +1 -1
  599. package/dist/utils/linkify.mjs +1 -0
  600. package/dist/utils/linkify.mjs.map +1 -1
  601. package/dist/utils/run.cjs +6 -6
  602. package/dist/utils/run.cjs.map +1 -1
  603. package/dist/utils/run.mjs +6 -6
  604. package/dist/utils/run.mjs.map +1 -1
  605. package/dist/utils/save-config.cjs +12 -0
  606. package/dist/utils/save-config.cjs.map +1 -1
  607. package/dist/utils/save-config.mjs +12 -0
  608. package/dist/utils/save-config.mjs.map +1 -1
  609. package/dist/utils/snapshot-hash.cjs +10 -0
  610. package/dist/utils/snapshot-hash.cjs.map +1 -0
  611. package/dist/utils/snapshot-hash.mjs +10 -0
  612. package/dist/utils/snapshot-hash.mjs.map +1 -0
  613. package/dist/utils/string.cjs +0 -1
  614. package/dist/utils/string.cjs.map +1 -1
  615. package/dist/utils/theme.cjs +30 -12
  616. package/dist/utils/theme.cjs.map +1 -1
  617. package/dist/utils/theme.mjs +30 -11
  618. package/dist/utils/theme.mjs.map +1 -1
  619. package/dist/version-manifest-deploy.cjs +50 -0
  620. package/dist/version-manifest-deploy.cjs.map +1 -0
  621. package/dist/version-manifest-deploy.mjs +49 -0
  622. package/dist/version-manifest-deploy.mjs.map +1 -0
  623. package/dist/version-manifest-resolve.cjs +42 -0
  624. package/dist/version-manifest-resolve.cjs.map +1 -0
  625. package/dist/version-manifest-resolve.d.cts +38 -0
  626. package/dist/version-manifest-resolve.d.mts +38 -0
  627. package/dist/version-manifest-resolve.mjs +40 -0
  628. package/dist/version-manifest-resolve.mjs.map +1 -0
  629. package/dist/version-status.cjs +18 -0
  630. package/dist/version-status.cjs.map +1 -0
  631. package/dist/version-status.d.cts +22 -0
  632. package/dist/version-status.d.mts +22 -0
  633. package/dist/version-status.mjs +17 -0
  634. package/dist/version-status.mjs.map +1 -0
  635. package/dist/workspace-catalog.cjs +53 -0
  636. package/dist/workspace-catalog.cjs.map +1 -0
  637. package/dist/workspace-catalog.mjs +51 -0
  638. package/dist/workspace-catalog.mjs.map +1 -0
  639. package/dist/workspace.cjs +237 -0
  640. package/dist/workspace.cjs.map +1 -0
  641. package/dist/workspace.mjs +233 -0
  642. package/dist/workspace.mjs.map +1 -0
  643. package/package.json +179 -27
  644. package/skills/add-a-route/SKILL.md +132 -0
  645. package/skills/api-and-auth/SKILL.md +87 -21
  646. package/skills/api-and-auth/references/middleware.md +1 -1
  647. package/skills/cli-reference/SKILL.md +48 -21
  648. package/skills/code-style/SKILL.md +8 -0
  649. package/skills/dev-workflow/SKILL.md +50 -26
  650. package/skills/extends-config/SKILL.md +31 -19
  651. package/skills/init-upgrade/SKILL.md +29 -16
  652. package/skills/plugin-development/SKILL.md +46 -112
  653. package/skills/plugin-development/references/database.md +82 -0
  654. package/skills/plugin-development/references/request-context.md +67 -0
  655. package/skills/publish-sync/SKILL.md +99 -22
  656. package/skills/registry/SKILL.md +82 -0
  657. package/skills/super-app/SKILL.md +25 -15
  658. package/skills/talk-to-the-app/SKILL.md +138 -0
  659. package/skills/ui-integration/SKILL.md +93 -11
  660. package/dist/cli/db-studio.cjs +0 -131
  661. package/dist/cli/db-studio.cjs.map +0 -1
  662. package/dist/cli/db-studio.mjs +0 -127
  663. package/dist/cli/db-studio.mjs.map +0 -1
  664. package/dist/cli/init.d.cts.map +0 -1
  665. package/dist/cli/init.d.mts.map +0 -1
  666. package/dist/components/dev-view.cjs +0 -309
  667. package/dist/components/dev-view.cjs.map +0 -1
  668. package/dist/components/dev-view.mjs +0 -309
  669. package/dist/components/dev-view.mjs.map +0 -1
  670. package/dist/components/streaming-view.cjs +0 -134
  671. package/dist/components/streaming-view.cjs.map +0 -1
  672. package/dist/components/streaming-view.mjs +0 -132
  673. package/dist/components/streaming-view.mjs.map +0 -1
  674. package/dist/config.d.cts.map +0 -1
  675. package/dist/config.d.mts.map +0 -1
  676. package/dist/contract.d.cts.map +0 -1
  677. package/dist/contract.d.mts.map +0 -1
  678. package/dist/contract.meta.d.cts.map +0 -1
  679. package/dist/contract.meta.d.mts.map +0 -1
  680. package/dist/dag.d.cts.map +0 -1
  681. package/dist/dag.d.mts.map +0 -1
  682. package/dist/db.cjs +0 -81
  683. package/dist/db.cjs.map +0 -1
  684. package/dist/db.d.cts +0 -30
  685. package/dist/db.d.cts.map +0 -1
  686. package/dist/db.d.mts +0 -30
  687. package/dist/db.d.mts.map +0 -1
  688. package/dist/db.mjs +0 -75
  689. package/dist/db.mjs.map +0 -1
  690. package/dist/fastkv.d.cts.map +0 -1
  691. package/dist/fastkv.d.mts.map +0 -1
  692. package/dist/integrity.d.cts.map +0 -1
  693. package/dist/integrity.d.mts.map +0 -1
  694. package/dist/merge.d.cts.map +0 -1
  695. package/dist/merge.d.mts.map +0 -1
  696. package/dist/mf.d.cts.map +0 -1
  697. package/dist/mf.d.mts.map +0 -1
  698. package/dist/plugin.d.cts.map +0 -1
  699. package/dist/plugin.d.mts.map +0 -1
  700. package/dist/service-descriptor.d.cts.map +0 -1
  701. package/dist/service-descriptor.d.mts.map +0 -1
  702. package/dist/types.d.cts.map +0 -1
  703. package/dist/types.d.mts.map +0 -1
  704. package/dist/ui/head.d.cts.map +0 -1
  705. package/dist/ui/head.d.mts.map +0 -1
  706. package/dist/ui/metadata.d.cts.map +0 -1
  707. package/dist/ui/metadata.d.mts.map +0 -1
  708. package/dist/ui/router.d.cts.map +0 -1
  709. package/dist/ui/router.d.mts.map +0 -1
  710. package/dist/ui/runtime.d.cts.map +0 -1
  711. package/dist/ui/runtime.d.mts.map +0 -1
  712. package/dist/ui/types.d.cts.map +0 -1
  713. package/dist/ui/types.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api-contract.mjs","names":[],"sources":["../src/api-contract.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { buildAuthTypesGenContent } from \"./auth-types-gen\";\nimport { fetchJsonOrNull, fetchResponse } from \"./http-client\";\nimport type { JsonObject, RuntimeConfig, RuntimePluginConfig } from \"./types\";\n\nexport interface ApiPluginManifest {\n schemaVersion: 1;\n kind: \"every-plugin/manifest\";\n plugin: {\n name: string;\n version: string;\n };\n runtime: {\n remoteEntry: string;\n };\n contract?: {\n kind: \"orpc\";\n types: {\n path: string;\n exportName: string;\n typeName: string;\n sha256?: string;\n };\n };\n additionalExports?: Array<{\n path: string;\n exports: string[];\n sha256?: string;\n }>;\n plugins?: Array<{\n key: string;\n name: string;\n url: string;\n dependsOn?: string[];\n secrets?: string[];\n variables?: JsonObject;\n }>;\n dependsOn?: string[];\n}\n\ninterface ContractSource {\n key: string;\n importName: string;\n sourceFilePath: string;\n generatedPath?: string;\n}\n\nfunction sha256(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction trimTrailingSlash(input: string): string {\n return input.replace(/\\/$/, \"\");\n}\n\nfunction sanitizeIdentifier(input: string): string {\n return input.replace(/[^A-Za-z0-9_]/g, \"_\").replace(/^[^A-Za-z_]+/, \"_\");\n}\n\nfunction toImportPath(fromFile: string, targetFile: string): string {\n const rel = relative(dirname(fromFile), targetFile).replace(/\\\\/g, \"/\");\n return rel.startsWith(\".\") ? rel : `./${rel}`;\n}\n\nfunction writeFileIfChanged(filePath: string, content: string) {\n try {\n if (readFileSync(filePath, \"utf8\") === content) return false;\n } catch {\n // file does not exist yet\n }\n\n writeFileSync(filePath, content);\n return true;\n}\n\nfunction getApiPluginManifestUrl(apiBaseUrl: string): string {\n return `${trimTrailingSlash(apiBaseUrl)}/plugin.manifest.json`;\n}\n\nexport async function fetchApiPluginManifest(apiBaseUrl: string): Promise<ApiPluginManifest> {\n const url = getApiPluginManifestUrl(apiBaseUrl);\n const manifest = await fetchJsonOrNull<ApiPluginManifest>(url, { retries: 0 });\n if (!manifest) {\n throw new Error(`Failed to fetch API plugin manifest from ${url}`);\n }\n if (manifest.schemaVersion !== 1 || manifest.kind !== \"every-plugin/manifest\") {\n throw new Error(\"Unsupported API plugin manifest format\");\n }\n\n return manifest;\n}\n\nfunction localApiContractSource(configDir: string): ContractSource {\n const sourcePath = join(configDir, \"api\", \"src\", \"contract.ts\");\n return {\n key: \"api\",\n importName: \"BaseApiContract\",\n sourceFilePath: sourcePath,\n };\n}\n\nfunction localAuthContractSource(configDir: string): ContractSource {\n const sourcePath = join(configDir, \"plugins\", \"auth\", \"src\", \"contract.ts\");\n return {\n key: \"auth\",\n importName: \"authContract\",\n sourceFilePath: sourcePath,\n };\n}\n\nasync function remoteContractSource(opts: {\n configDir: string;\n runtimeDir: string;\n name: string;\n baseUrl: string;\n generatedSubdir: string;\n}): Promise<ContractSource> {\n const manifest = await fetchApiPluginManifest(opts.baseUrl);\n if (!manifest.contract) {\n throw new Error(\n `Plugin manifest for ${manifest.plugin.name} does not advertise contract types`,\n );\n }\n\n const contractUrl = `${trimTrailingSlash(opts.baseUrl)}/${manifest.contract.types.path.replace(/^\\.\\//, \"\")}`;\n const contractResponse = await fetchResponse(contractUrl);\n if (!contractResponse.ok) {\n throw new Error(\n `Failed to fetch contract types from ${contractUrl}: ${contractResponse.status} ${contractResponse.statusText}`,\n );\n }\n\n const contractTypes = await contractResponse.text();\n if (manifest.contract.types.sha256 && manifest.contract.types.sha256 !== sha256(contractTypes)) {\n throw new Error(\"Fetched contract types failed checksum verification\");\n }\n\n const generatedPath = join(opts.runtimeDir, opts.generatedSubdir, \"contract.d.ts\");\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, contractTypes);\n\n return {\n key: opts.name,\n importName: `${sanitizeIdentifier(opts.name)}Contract`,\n sourceFilePath: generatedPath,\n generatedPath,\n };\n}\n\nasync function fetchAuthExportTypes(opts: {\n baseUrl: string;\n runtimeDir: string;\n manifest: ApiPluginManifest;\n}): Promise<string | null> {\n if (!opts.manifest.additionalExports || opts.manifest.additionalExports.length === 0) {\n return null;\n }\n\n const authExportEntry = opts.manifest.additionalExports.find(\n (entry) => entry.path.includes(\"auth-export\") || entry.path.endsWith(\"auth-export.d.ts\"),\n );\n\n if (!authExportEntry) {\n return null;\n }\n\n const exportUrl = `${trimTrailingSlash(opts.baseUrl)}/${authExportEntry.path.replace(/^\\.\\//, \"\")}`;\n const response = await fetchResponse(exportUrl);\n if (!response.ok) {\n console.warn(\n `[API Contract] Failed to fetch auth export types from ${exportUrl}: ${response.status}`,\n );\n return null;\n }\n\n const content = await response.text();\n if (authExportEntry.sha256 && authExportEntry.sha256 !== sha256(content)) {\n console.warn(`[API Contract] Auth export types checksum mismatch for ${exportUrl}`);\n return null;\n }\n\n const generatedPath = join(opts.runtimeDir, \"auth\", \"auth-export.d.ts\");\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, content);\n\n return generatedPath;\n}\n\nasync function resolveContractSource(opts: {\n configDir: string;\n runtimeDir: string;\n key: string;\n source: RuntimePluginConfig | { url: string; localPath?: string; name: string } | null;\n baseUrl: string;\n generatedSubdir: string;\n localSourceFactory?: (configDir: string) => ContractSource;\n}): Promise<ContractSource> {\n if (opts.key === \"api\") {\n const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n if (localPath != null && localPath !== \"\") {\n return {\n key: opts.key,\n importName: \"BaseApiContract\",\n sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n };\n }\n\n if (!opts.baseUrl) {\n return localApiContractSource(opts.configDir);\n }\n }\n\n if (opts.key === \"auth\" && opts.localSourceFactory) {\n const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n if (localPath != null && localPath !== \"\") {\n return {\n key: opts.key,\n importName: \"authContract\",\n sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n };\n }\n\n if (!opts.baseUrl) {\n return opts.localSourceFactory(opts.configDir);\n }\n }\n\n if (\n opts.source &&\n \"localPath\" in opts.source &&\n opts.source.localPath != null &&\n opts.source.localPath !== \"\"\n ) {\n return {\n key: opts.key,\n importName: `${sanitizeIdentifier(opts.key)}Contract`,\n sourceFilePath: join(opts.source.localPath, \"src\", \"contract.ts\"),\n };\n }\n\n return remoteContractSource({\n configDir: opts.configDir,\n runtimeDir: opts.runtimeDir,\n name: opts.key,\n baseUrl: opts.baseUrl,\n generatedSubdir: opts.generatedSubdir,\n });\n}\n\nfunction writePluginClientGen(opts: {\n configDir: string;\n pluginKey: string;\n depSources: ContractSource[];\n}) {\n const pluginSrcDir = join(opts.configDir, \"plugins\", opts.pluginKey, \"src\");\n if (!existsSync(pluginSrcDir)) return;\n\n const targetPath = join(pluginSrcDir, \"lib\", \"plugins-client.gen.ts\");\n const lines: string[] = [];\n\n for (const source of opts.depSources) {\n const importPath = toImportPath(targetPath, source.sourceFilePath);\n lines.push(`import type { ContractType as ${source.importName} } from \"${importPath}\";`);\n }\n\n lines.push('import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";');\n lines.push(\n \"type ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\",\n );\n lines.push(\"\");\n\n if (opts.depSources.length === 0) {\n lines.push(\"export type PluginsClient = Record<string, never>;\");\n } else {\n lines.push(\"export type PluginsClient = {\");\n for (const source of opts.depSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key)\n ? source.key\n : JSON.stringify(source.key);\n lines.push(` ${key}: ClientFactory<${source.importName}>;`);\n }\n lines.push(\"};\");\n }\n\n mkdirSync(dirname(targetPath), { recursive: true });\n writeFileIfChanged(targetPath, `${lines.join(\"\\n\")}\\n`);\n}\n\nexport function writeGeneratedFiles(opts: {\n configDir: string;\n sources: ContractSource[];\n pluginKeys: string[];\n authSource: ContractSource | null;\n authExportPath?: string | null;\n apiDependsOn?: string[];\n pluginDependsOn?: Record<string, string[]>;\n}) {\n const hasLocalApiWorkspace = existsSync(join(opts.configDir, \"api\", \"src\"));\n const baseSource = opts.sources.find((source) => source.key === \"api\");\n const pluginSources = opts.pluginKeys\n .map((key) => opts.sources.find((entry) => entry.key === key))\n .filter((source): source is ContractSource => Boolean(source));\n\n if (!baseSource) {\n throw new Error(\"API contract source is required to generate the aggregate contract\");\n }\n\n // --- Generate ui/src/lib/api-types.gen.ts ---\n const uiContractPath = join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\");\n const uiLines: string[] = [];\n\n for (const source of opts.sources) {\n const importPath = toImportPath(uiContractPath, source.sourceFilePath);\n uiLines.push(`import type { ContractType as ${source.importName} } from \"${importPath}\";`);\n }\n\n uiLines.push(\"\");\n\n const compositeParts: string[] = [];\n if (opts.authSource) {\n compositeParts.push(`auth: ${opts.authSource.importName}`);\n }\n for (const source of pluginSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key) ? source.key : JSON.stringify(source.key);\n compositeParts.push(`${key}: ${source.importName}`);\n }\n\n if (compositeParts.length === 0) {\n uiLines.push(`export type ApiContract = ${baseSource.importName};`);\n } else {\n uiLines.push(`export type ApiContract = ${baseSource.importName} & {`);\n for (const part of compositeParts) {\n uiLines.push(` ${part};`);\n }\n uiLines.push(\"};\");\n }\n mkdirSync(dirname(uiContractPath), { recursive: true });\n writeFileIfChanged(uiContractPath, `${uiLines.join(\"\\n\")}\\n`);\n\n // --- Generate api/src/lib/plugins-types.gen.ts ---\n // Filtered by apiDependsOn when explicit; includes all plugins + auth when implicit\n if (hasLocalApiWorkspace) {\n const pluginsClientPath = join(opts.configDir, \"api\", \"src\", \"lib\", \"plugins-types.gen.ts\");\n const pluginsClientLines: string[] = [];\n\n const allPluginSources = [...pluginSources];\n if (opts.authSource) {\n allPluginSources.push({ ...opts.authSource, key: \"auth\" });\n }\n\n const apiDepSources = opts.apiDependsOn?.length\n ? allPluginSources.filter((s) => opts.apiDependsOn!.includes(s.key))\n : allPluginSources;\n\n const unresolvedDepKeys =\n opts.apiDependsOn?.filter((depKey) => !allPluginSources.some((s) => s.key === depKey)) ?? [];\n\n for (const source of apiDepSources) {\n const importPath = toImportPath(pluginsClientPath, source.sourceFilePath);\n pluginsClientLines.push(\n `import type { ContractType as ${source.importName} } from \"${importPath}\";`,\n );\n }\n\n pluginsClientLines.push(\n 'import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";',\n );\n pluginsClientLines.push(\n \"type ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\",\n );\n pluginsClientLines.push(\"\");\n\n if (apiDepSources.length === 0 && unresolvedDepKeys.length === 0) {\n pluginsClientLines.push(\"export type PluginsClient = Record<string, never>;\");\n } else {\n pluginsClientLines.push(\"export type PluginsClient = {\");\n for (const source of apiDepSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key)\n ? source.key\n : JSON.stringify(source.key);\n pluginsClientLines.push(` ${key}: ClientFactory<${source.importName}>;`);\n }\n for (const key of unresolvedDepKeys) {\n const keyStr = /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);\n pluginsClientLines.push(` ${keyStr}?: ClientFactory<AnyContractRouter>;`);\n }\n pluginsClientLines.push(\"};\");\n }\n\n mkdirSync(dirname(pluginsClientPath), { recursive: true });\n writeFileIfChanged(pluginsClientPath, `${pluginsClientLines.join(\"\\n\")}\\n`);\n }\n\n // --- Generate per-plugin plugins-client.gen.ts ---\n const allSourcesForLookup = [...pluginSources];\n if (opts.authSource) {\n allSourcesForLookup.push({ ...opts.authSource, key: \"auth\" });\n }\n\n for (const pluginKey of opts.pluginKeys) {\n const deps = opts.pluginDependsOn?.[pluginKey];\n if (!deps?.length) continue;\n\n const depSources = deps\n .map((depKey) => allSourcesForLookup.find((s) => s.key === depKey))\n .filter((s): s is ContractSource => Boolean(s));\n\n writePluginClientGen({\n configDir: opts.configDir,\n pluginKey,\n depSources,\n });\n }\n\n // --- Generate */src/lib/auth-types.gen.ts ---\n const authTypeTargets = [join(opts.configDir, \"ui\", \"src\", \"lib\", \"auth-types.gen.ts\")];\n const apiLibDir = join(opts.configDir, \"api\", \"src\", \"lib\");\n if (existsSync(apiLibDir)) {\n authTypeTargets.push(join(apiLibDir, \"auth-types.gen.ts\"));\n }\n const hostLibDir = join(opts.configDir, \"host\", \"src\", \"lib\");\n if (existsSync(join(opts.configDir, \"host\", \"src\"))) {\n authTypeTargets.push(join(hostLibDir, \"auth-types.gen.ts\"));\n }\n\n // Per-plugin auth-types.gen.ts\n for (const key of opts.pluginKeys) {\n const pluginLibDir = join(opts.configDir, \"plugins\", key, \"src\", \"lib\");\n if (existsSync(join(opts.configDir, \"plugins\", key, \"src\"))) {\n authTypeTargets.push(join(pluginLibDir, \"auth-types.gen.ts\"));\n }\n }\n\n if (opts.authExportPath) {\n for (const authTypesPath of authTypeTargets) {\n const exportImportPath = toImportPath(authTypesPath, opts.authExportPath);\n const contractImportPath = toImportPath(\n authTypesPath,\n join(dirname(opts.authExportPath), \"contract.d.ts\"),\n );\n mkdirSync(dirname(authTypesPath), { recursive: true });\n writeFileIfChanged(\n authTypesPath,\n buildAuthTypesGenContent(exportImportPath, contractImportPath),\n );\n }\n } else if (opts.authSource) {\n for (const authTypesPath of authTypeTargets) {\n const exportImportPath = toImportPath(\n authTypesPath,\n join(opts.configDir, \".bos\", \"generated\", \"auth\", \"auth-export.d.ts\"),\n );\n const contractImportPath = toImportPath(\n authTypesPath,\n join(opts.configDir, \".bos\", \"generated\", \"auth\", \"contract.d.ts\"),\n );\n mkdirSync(dirname(authTypesPath), { recursive: true });\n writeFileIfChanged(\n authTypesPath,\n buildAuthTypesGenContent(exportImportPath, contractImportPath),\n );\n }\n }\n\n return uiContractPath;\n}\n\nexport interface ContractBridgeStatus {\n key: string;\n source: \"local\" | \"remote\" | \"skipped\" | \"failed\";\n url?: string;\n localPath?: string;\n error?: string;\n}\n\nexport async function syncApiContractBridge(opts: {\n configDir: string;\n runtimeConfig: RuntimeConfig;\n apiBaseUrl: string;\n}): Promise<{\n bridgePath: string;\n generatedPath: string | null;\n manifest: ApiPluginManifest | null;\n source: \"local\" | \"remote\";\n status: ContractBridgeStatus[];\n}> {\n const runtimeDir = join(opts.configDir, \".bos\", \"generated\");\n const pluginEntries = Object.entries(opts.runtimeConfig.plugins ?? {}).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n const sources: ContractSource[] = [];\n const status: ContractBridgeStatus[] = [];\n let manifest: ApiPluginManifest | null = null;\n let generatedPath: string | null = null;\n let authSource: ContractSource | null = null;\n let authExportPath: string | null = null;\n const excludedPluginKeys = new Set<string>();\n\n try {\n const baseSource = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key: \"api\",\n source: opts.runtimeConfig.api,\n baseUrl: opts.apiBaseUrl,\n generatedSubdir: \"api\",\n });\n sources.push(baseSource);\n status.push({\n key: \"api\",\n source: opts.runtimeConfig.api.source,\n url: opts.runtimeConfig.api.source !== \"local\" ? opts.apiBaseUrl : undefined,\n localPath:\n opts.runtimeConfig.api.source === \"local\" ? opts.runtimeConfig.api.localPath : undefined,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve api contract: ${message}`);\n status.push({\n key: \"api\",\n source: \"failed\",\n url: opts.apiBaseUrl || undefined,\n error: message,\n });\n }\n\n if (opts.runtimeConfig.auth) {\n try {\n authSource = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key: \"auth\",\n source: opts.runtimeConfig.auth,\n baseUrl: opts.runtimeConfig.auth.url,\n generatedSubdir: \"auth\",\n localSourceFactory: localAuthContractSource,\n });\n sources.push(authSource);\n status.push({\n key: \"auth\",\n source: opts.runtimeConfig.auth.source,\n url: opts.runtimeConfig.auth.source !== \"local\" ? opts.runtimeConfig.auth.url : undefined,\n localPath:\n opts.runtimeConfig.auth.source === \"local\"\n ? opts.runtimeConfig.auth.localPath\n : undefined,\n });\n if (authSource.generatedPath) {\n generatedPath = authSource.generatedPath;\n }\n\n if (opts.runtimeConfig.auth.url && opts.runtimeConfig.auth.source !== \"local\") {\n try {\n const authManifest = await fetchApiPluginManifest(opts.runtimeConfig.auth.url);\n const fetchedAuthExportPath = await fetchAuthExportTypes({\n baseUrl: opts.runtimeConfig.auth.url,\n runtimeDir,\n manifest: authManifest,\n });\n if (fetchedAuthExportPath) {\n authExportPath = fetchedAuthExportPath;\n }\n } catch (error) {\n console.warn(\n `[API Contract] Failed to fetch auth additional exports: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n if (!authExportPath) {\n const localAuthExport = join(opts.configDir, \"plugins\", \"auth\", \"src\", \"auth-export.ts\");\n if (existsSync(localAuthExport)) {\n authExportPath = localAuthExport;\n } else {\n const generatedAuthExport = join(runtimeDir, \"auth\", \"auth-export.d.ts\");\n if (existsSync(generatedAuthExport)) {\n authExportPath = generatedAuthExport;\n }\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve auth contract: ${message}`);\n status.push({\n key: \"auth\",\n source: \"failed\",\n url: opts.runtimeConfig.auth.url || undefined,\n error: message,\n });\n }\n }\n\n for (const [key, plugin] of pluginEntries) {\n if (!plugin.url && !plugin.localPath) {\n console.warn(\n `[API Contract] Skipping plugin \"${key}\" — no URL resolved (local path missing and no production URL configured)`,\n );\n status.push({ key, source: \"skipped\" });\n excludedPluginKeys.add(key);\n }\n }\n\n const resolvablePlugins = pluginEntries.filter(([key]) => !excludedPluginKeys.has(key));\n\n const pluginResults = await Promise.allSettled(\n resolvablePlugins.map(async ([key, plugin]) => {\n const source = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key,\n source: plugin,\n baseUrl: plugin.url,\n generatedSubdir: `plugins/${key}`,\n });\n return {\n key,\n source,\n plugin,\n };\n }),\n );\n\n pluginResults.forEach((result, index) => {\n const [key, plugin] = resolvablePlugins[index];\n if (result.status === \"fulfilled\") {\n sources.push(result.value.source);\n status.push({\n key,\n source: plugin.source,\n url: plugin.source !== \"local\" ? plugin.url : undefined,\n localPath: plugin.source === \"local\" ? plugin.localPath : undefined,\n });\n if (result.value.source.generatedPath) {\n generatedPath = result.value.source.generatedPath;\n }\n } else {\n const message =\n result.reason instanceof Error ? result.reason.message : String(result.reason);\n console.warn(`[API Contract] Failed to resolve plugin \"${key}\": ${message}`);\n status.push({ key, source: \"failed\", url: plugin.url || undefined, error: message });\n excludedPluginKeys.add(key);\n }\n });\n\n const apiStatus = status.find((s) => s.key === \"api\");\n if (apiStatus?.source === \"failed\") {\n throw new Error(\n `Cannot generate contract types without api contract: ${apiStatus.error ?? \"unknown error\"}`,\n );\n }\n\n const allPluginKeys = pluginEntries\n .filter(([key]) => !excludedPluginKeys.has(key))\n .map(([key]) => key);\n\n const pluginDependsOn: Record<string, string[]> = {};\n for (const [key, plugin] of pluginEntries) {\n if (!excludedPluginKeys.has(key) && plugin.dependsOn?.length) {\n pluginDependsOn[key] = plugin.dependsOn;\n }\n }\n\n writeGeneratedFiles({\n configDir: opts.configDir,\n sources,\n pluginKeys: allPluginKeys,\n authSource,\n authExportPath,\n apiDependsOn: opts.runtimeConfig.api.dependsOn,\n pluginDependsOn,\n });\n\n if (opts.runtimeConfig.api.source !== \"local\") {\n manifest = await fetchApiPluginManifest(opts.apiBaseUrl);\n }\n\n return {\n bridgePath: join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\"),\n generatedPath,\n manifest,\n source: opts.runtimeConfig.api.source,\n status,\n };\n}\n"],"mappings":";;;;;;;AAiDA,SAAS,OAAO,OAAuB;CACrC,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;AAEA,SAAS,kBAAkB,OAAuB;CAChD,OAAO,MAAM,QAAQ,OAAO,EAAE;AAChC;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,MAAM,QAAQ,kBAAkB,GAAG,CAAC,CAAC,QAAQ,gBAAgB,GAAG;AACzE;AAEA,SAAS,aAAa,UAAkB,YAA4B;CAClE,MAAM,MAAM,SAAS,QAAQ,QAAQ,GAAG,UAAU,CAAC,CAAC,QAAQ,OAAO,GAAG;CACtE,OAAO,IAAI,WAAW,GAAG,IAAI,MAAM,KAAK;AAC1C;AAEA,SAAS,mBAAmB,UAAkB,SAAiB;CAC7D,IAAI;EACF,IAAI,aAAa,UAAU,MAAM,MAAM,SAAS,OAAO;CACzD,QAAQ,CAER;CAEA,cAAc,UAAU,OAAO;CAC/B,OAAO;AACT;AAEA,SAAS,wBAAwB,YAA4B;CAC3D,OAAO,GAAG,kBAAkB,UAAU,EAAE;AAC1C;AAEA,eAAsB,uBAAuB,YAAgD;CAC3F,MAAM,MAAM,wBAAwB,UAAU;CAC9C,MAAM,WAAW,MAAM,gBAAmC,KAAK,EAAE,SAAS,EAAE,CAAC;CAC7E,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,4CAA4C,KAAK;CAEnE,IAAI,SAAS,kBAAkB,KAAK,SAAS,SAAS,yBACpD,MAAM,IAAI,MAAM,wCAAwC;CAG1D,OAAO;AACT;AAEA,SAAS,uBAAuB,WAAmC;CAEjE,OAAO;EACL,KAAK;EACL,YAAY;EACZ,gBAJiB,KAAK,WAAW,OAAO,OAAO,aAItB;CAC3B;AACF;AAEA,SAAS,wBAAwB,WAAmC;CAElE,OAAO;EACL,KAAK;EACL,YAAY;EACZ,gBAJiB,KAAK,WAAW,WAAW,QAAQ,OAAO,aAIlC;CAC3B;AACF;AAEA,eAAe,qBAAqB,MAMR;CAC1B,MAAM,WAAW,MAAM,uBAAuB,KAAK,OAAO;CAC1D,IAAI,CAAC,SAAS,UACZ,MAAM,IAAI,MACR,uBAAuB,SAAS,OAAO,KAAK,mCAC9C;CAGF,MAAM,cAAc,GAAG,kBAAkB,KAAK,OAAO,EAAE,GAAG,SAAS,SAAS,MAAM,KAAK,QAAQ,SAAS,EAAE;CAC1G,MAAM,mBAAmB,MAAM,cAAc,WAAW;CACxD,IAAI,CAAC,iBAAiB,IACpB,MAAM,IAAI,MACR,uCAAuC,YAAY,IAAI,iBAAiB,OAAO,GAAG,iBAAiB,YACrG;CAGF,MAAM,gBAAgB,MAAM,iBAAiB,KAAK;CAClD,IAAI,SAAS,SAAS,MAAM,UAAU,SAAS,SAAS,MAAM,WAAW,OAAO,aAAa,GAC3F,MAAM,IAAI,MAAM,qDAAqD;CAGvE,MAAM,gBAAgB,KAAK,KAAK,YAAY,KAAK,iBAAiB,eAAe;CACjF,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;CACrD,mBAAmB,eAAe,aAAa;CAE/C,OAAO;EACL,KAAK,KAAK;EACV,YAAY,GAAG,mBAAmB,KAAK,IAAI,EAAE;EAC7C,gBAAgB;EAChB;CACF;AACF;AAEA,eAAe,qBAAqB,MAIT;CACzB,IAAI,CAAC,KAAK,SAAS,qBAAqB,KAAK,SAAS,kBAAkB,WAAW,GACjF,OAAO;CAGT,MAAM,kBAAkB,KAAK,SAAS,kBAAkB,MACrD,UAAU,MAAM,KAAK,SAAS,aAAa,KAAK,MAAM,KAAK,SAAS,kBAAkB,CACzF;CAEA,IAAI,CAAC,iBACH,OAAO;CAGT,MAAM,YAAY,GAAG,kBAAkB,KAAK,OAAO,EAAE,GAAG,gBAAgB,KAAK,QAAQ,SAAS,EAAE;CAChG,MAAM,WAAW,MAAM,cAAc,SAAS;CAC9C,IAAI,CAAC,SAAS,IAAI;EAChB,QAAQ,KACN,yDAAyD,UAAU,IAAI,SAAS,QAClF;EACA,OAAO;CACT;CAEA,MAAM,UAAU,MAAM,SAAS,KAAK;CACpC,IAAI,gBAAgB,UAAU,gBAAgB,WAAW,OAAO,OAAO,GAAG;EACxE,QAAQ,KAAK,0DAA0D,WAAW;EAClF,OAAO;CACT;CAEA,MAAM,gBAAgB,KAAK,KAAK,YAAY,QAAQ,kBAAkB;CACtE,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;CACrD,mBAAmB,eAAe,OAAO;CAEzC,OAAO;AACT;AAEA,eAAe,sBAAsB,MAQT;CAC1B,IAAI,KAAK,QAAQ,OAAO;EACtB,MAAM,YAAY,KAAK,UAAU,eAAe,KAAK,SAAS,KAAK,OAAO,YAAY;EACtF,IAAI,aAAa,QAAQ,cAAc,IACrC,OAAO;GACL,KAAK,KAAK;GACV,YAAY;GACZ,gBAAgB,KAAK,WAAW,OAAO,aAAa;EACtD;EAGF,IAAI,CAAC,KAAK,SACR,OAAO,uBAAuB,KAAK,SAAS;CAEhD;CAEA,IAAI,KAAK,QAAQ,UAAU,KAAK,oBAAoB;EAClD,MAAM,YAAY,KAAK,UAAU,eAAe,KAAK,SAAS,KAAK,OAAO,YAAY;EACtF,IAAI,aAAa,QAAQ,cAAc,IACrC,OAAO;GACL,KAAK,KAAK;GACV,YAAY;GACZ,gBAAgB,KAAK,WAAW,OAAO,aAAa;EACtD;EAGF,IAAI,CAAC,KAAK,SACR,OAAO,KAAK,mBAAmB,KAAK,SAAS;CAEjD;CAEA,IACE,KAAK,UACL,eAAe,KAAK,UACpB,KAAK,OAAO,aAAa,QACzB,KAAK,OAAO,cAAc,IAE1B,OAAO;EACL,KAAK,KAAK;EACV,YAAY,GAAG,mBAAmB,KAAK,GAAG,EAAE;EAC5C,gBAAgB,KAAK,KAAK,OAAO,WAAW,OAAO,aAAa;CAClE;CAGF,OAAO,qBAAqB;EAC1B,WAAW,KAAK;EAChB,YAAY,KAAK;EACjB,MAAM,KAAK;EACX,SAAS,KAAK;EACd,iBAAiB,KAAK;CACxB,CAAC;AACH;AAEA,SAAS,qBAAqB,MAI3B;CACD,MAAM,eAAe,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW,KAAK;CAC1E,IAAI,CAAC,WAAW,YAAY,GAAG;CAE/B,MAAM,aAAa,KAAK,cAAc,OAAO,uBAAuB;CACpE,MAAM,QAAkB,CAAC;CAEzB,KAAK,MAAM,UAAU,KAAK,YAAY;EACpC,MAAM,aAAa,aAAa,YAAY,OAAO,cAAc;EACjE,MAAM,KAAK,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAAG;CACzF;CAEA,MAAM,KAAK,kFAAgF;CAC3F,MAAM,KACJ,mHACF;CACA,MAAM,KAAK,EAAE;CAEb,IAAI,KAAK,WAAW,WAAW,GAC7B,MAAM,KAAK,oDAAoD;MAC1D;EACL,MAAM,KAAK,+BAA+B;EAC1C,KAAK,MAAM,UAAU,KAAK,YAAY;GACpC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAC/C,OAAO,MACP,KAAK,UAAU,OAAO,GAAG;GAC7B,MAAM,KAAK,KAAK,IAAI,kBAAkB,OAAO,WAAW,GAAG;EAC7D;EACA,MAAM,KAAK,IAAI;CACjB;CAEA,UAAU,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CAClD,mBAAmB,YAAY,GAAG,MAAM,KAAK,IAAI,EAAE,GAAG;AACxD;AAEA,SAAgB,oBAAoB,MAQjC;CACD,MAAM,uBAAuB,WAAW,KAAK,KAAK,WAAW,OAAO,KAAK,CAAC;CAC1E,MAAM,aAAa,KAAK,QAAQ,MAAM,WAAW,OAAO,QAAQ,KAAK;CACrE,MAAM,gBAAgB,KAAK,WACxB,KAAK,QAAQ,KAAK,QAAQ,MAAM,UAAU,MAAM,QAAQ,GAAG,CAAC,CAAC,CAC7D,QAAQ,WAAqC,QAAQ,MAAM,CAAC;CAE/D,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,oEAAoE;CAItF,MAAM,iBAAiB,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,kBAAkB;CAClF,MAAM,UAAoB,CAAC;CAE3B,KAAK,MAAM,UAAU,KAAK,SAAS;EACjC,MAAM,aAAa,aAAa,gBAAgB,OAAO,cAAc;EACrE,QAAQ,KAAK,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAAG;CAC3F;CAEA,QAAQ,KAAK,EAAE;CAEf,MAAM,iBAA2B,CAAC;CAClC,IAAI,KAAK,YACP,eAAe,KAAK,SAAS,KAAK,WAAW,YAAY;CAE3D,KAAK,MAAM,UAAU,eAAe;EAClC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAAI,OAAO,MAAM,KAAK,UAAU,OAAO,GAAG;EAC7F,eAAe,KAAK,GAAG,IAAI,IAAI,OAAO,YAAY;CACpD;CAEA,IAAI,eAAe,WAAW,GAC5B,QAAQ,KAAK,6BAA6B,WAAW,WAAW,EAAE;MAC7D;EACL,QAAQ,KAAK,6BAA6B,WAAW,WAAW,KAAK;EACrE,KAAK,MAAM,QAAQ,gBACjB,QAAQ,KAAK,KAAK,KAAK,EAAE;EAE3B,QAAQ,KAAK,IAAI;CACnB;CACA,UAAU,QAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;CACtD,mBAAmB,gBAAgB,GAAG,QAAQ,KAAK,IAAI,EAAE,GAAG;CAI5D,IAAI,sBAAsB;EACxB,MAAM,oBAAoB,KAAK,KAAK,WAAW,OAAO,OAAO,OAAO,sBAAsB;EAC1F,MAAM,qBAA+B,CAAC;EAEtC,MAAM,mBAAmB,CAAC,GAAG,aAAa;EAC1C,IAAI,KAAK,YACP,iBAAiB,KAAK;GAAE,GAAG,KAAK;GAAY,KAAK;EAAO,CAAC;EAG3D,MAAM,gBAAgB,KAAK,cAAc,SACrC,iBAAiB,QAAQ,MAAM,KAAK,aAAc,SAAS,EAAE,GAAG,CAAC,IACjE;EAEJ,MAAM,oBACJ,KAAK,cAAc,QAAQ,WAAW,CAAC,iBAAiB,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,KAAK,CAAC;EAE7F,KAAK,MAAM,UAAU,eAAe;GAClC,MAAM,aAAa,aAAa,mBAAmB,OAAO,cAAc;GACxE,mBAAmB,KACjB,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAC3E;EACF;EAEA,mBAAmB,KACjB,kFACF;EACA,mBAAmB,KACjB,mHACF;EACA,mBAAmB,KAAK,EAAE;EAE1B,IAAI,cAAc,WAAW,KAAK,kBAAkB,WAAW,GAC7D,mBAAmB,KAAK,oDAAoD;OACvE;GACL,mBAAmB,KAAK,+BAA+B;GACvD,KAAK,MAAM,UAAU,eAAe;IAClC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAC/C,OAAO,MACP,KAAK,UAAU,OAAO,GAAG;IAC7B,mBAAmB,KAAK,KAAK,IAAI,kBAAkB,OAAO,WAAW,GAAG;GAC1E;GACA,KAAK,MAAM,OAAO,mBAAmB;IACnC,MAAM,SAAS,wBAAwB,KAAK,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG;IAC3E,mBAAmB,KAAK,KAAK,OAAO,qCAAqC;GAC3E;GACA,mBAAmB,KAAK,IAAI;EAC9B;EAEA,UAAU,QAAQ,iBAAiB,GAAG,EAAE,WAAW,KAAK,CAAC;EACzD,mBAAmB,mBAAmB,GAAG,mBAAmB,KAAK,IAAI,EAAE,GAAG;CAC5E;CAGA,MAAM,sBAAsB,CAAC,GAAG,aAAa;CAC7C,IAAI,KAAK,YACP,oBAAoB,KAAK;EAAE,GAAG,KAAK;EAAY,KAAK;CAAO,CAAC;CAG9D,KAAK,MAAM,aAAa,KAAK,YAAY;EACvC,MAAM,OAAO,KAAK,kBAAkB;EACpC,IAAI,CAAC,MAAM,QAAQ;EAEnB,MAAM,aAAa,KAChB,KAAK,WAAW,oBAAoB,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,CAAC,CAClE,QAAQ,MAA2B,QAAQ,CAAC,CAAC;EAEhD,qBAAqB;GACnB,WAAW,KAAK;GAChB;GACA;EACF,CAAC;CACH;CAGA,MAAM,kBAAkB,CAAC,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,mBAAmB,CAAC;CACtF,MAAM,YAAY,KAAK,KAAK,WAAW,OAAO,OAAO,KAAK;CAC1D,IAAI,WAAW,SAAS,GACtB,gBAAgB,KAAK,KAAK,WAAW,mBAAmB,CAAC;CAE3D,MAAM,aAAa,KAAK,KAAK,WAAW,QAAQ,OAAO,KAAK;CAC5D,IAAI,WAAW,KAAK,KAAK,WAAW,QAAQ,KAAK,CAAC,GAChD,gBAAgB,KAAK,KAAK,YAAY,mBAAmB,CAAC;CAI5D,KAAK,MAAM,OAAO,KAAK,YAAY;EACjC,MAAM,eAAe,KAAK,KAAK,WAAW,WAAW,KAAK,OAAO,KAAK;EACtE,IAAI,WAAW,KAAK,KAAK,WAAW,WAAW,KAAK,KAAK,CAAC,GACxD,gBAAgB,KAAK,KAAK,cAAc,mBAAmB,CAAC;CAEhE;CAEA,IAAI,KAAK,gBACP,KAAK,MAAM,iBAAiB,iBAAiB;EAC3C,MAAM,mBAAmB,aAAa,eAAe,KAAK,cAAc;EACxE,MAAM,qBAAqB,aACzB,eACA,KAAK,QAAQ,KAAK,cAAc,GAAG,eAAe,CACpD;EACA,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;EACrD,mBACE,eACA,yBAAyB,kBAAkB,kBAAkB,CAC/D;CACF;MACK,IAAI,KAAK,YACd,KAAK,MAAM,iBAAiB,iBAAiB;EAC3C,MAAM,mBAAmB,aACvB,eACA,KAAK,KAAK,WAAW,QAAQ,aAAa,QAAQ,kBAAkB,CACtE;EACA,MAAM,qBAAqB,aACzB,eACA,KAAK,KAAK,WAAW,QAAQ,aAAa,QAAQ,eAAe,CACnE;EACA,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;EACrD,mBACE,eACA,yBAAyB,kBAAkB,kBAAkB,CAC/D;CACF;CAGF,OAAO;AACT;AAUA,eAAsB,sBAAsB,MAUzC;CACD,MAAM,aAAa,KAAK,KAAK,WAAW,QAAQ,WAAW;CAC3D,MAAM,gBAAgB,OAAO,QAAQ,KAAK,cAAc,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OACjF,EAAE,cAAc,CAAC,CACnB;CACA,MAAM,UAA4B,CAAC;CACnC,MAAM,SAAiC,CAAC;CACxC,IAAI,WAAqC;CACzC,IAAI,gBAA+B;CACnC,IAAI,aAAoC;CACxC,IAAI,iBAAgC;CACpC,MAAM,qCAAqB,IAAI,IAAY;CAE3C,IAAI;EACF,MAAM,aAAa,MAAM,sBAAsB;GAC7C,WAAW,KAAK;GAChB;GACA,KAAK;GACL,QAAQ,KAAK,cAAc;GAC3B,SAAS,KAAK;GACd,iBAAiB;EACnB,CAAC;EACD,QAAQ,KAAK,UAAU;EACvB,OAAO,KAAK;GACV,KAAK;GACL,QAAQ,KAAK,cAAc,IAAI;GAC/B,KAAK,KAAK,cAAc,IAAI,WAAW,UAAU,KAAK,aAAa;GACnE,WACE,KAAK,cAAc,IAAI,WAAW,UAAU,KAAK,cAAc,IAAI,YAAY;EACnF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,QAAQ,KAAK,kDAAkD,SAAS;EACxE,OAAO,KAAK;GACV,KAAK;GACL,QAAQ;GACR,KAAK,KAAK,cAAc;GACxB,OAAO;EACT,CAAC;CACH;CAEA,IAAI,KAAK,cAAc,MACrB,IAAI;EACF,aAAa,MAAM,sBAAsB;GACvC,WAAW,KAAK;GAChB;GACA,KAAK;GACL,QAAQ,KAAK,cAAc;GAC3B,SAAS,KAAK,cAAc,KAAK;GACjC,iBAAiB;GACjB,oBAAoB;EACtB,CAAC;EACD,QAAQ,KAAK,UAAU;EACvB,OAAO,KAAK;GACV,KAAK;GACL,QAAQ,KAAK,cAAc,KAAK;GAChC,KAAK,KAAK,cAAc,KAAK,WAAW,UAAU,KAAK,cAAc,KAAK,MAAM;GAChF,WACE,KAAK,cAAc,KAAK,WAAW,UAC/B,KAAK,cAAc,KAAK,YACxB;EACR,CAAC;EACD,IAAI,WAAW,eACb,gBAAgB,WAAW;EAG7B,IAAI,KAAK,cAAc,KAAK,OAAO,KAAK,cAAc,KAAK,WAAW,SACpE,IAAI;GACF,MAAM,eAAe,MAAM,uBAAuB,KAAK,cAAc,KAAK,GAAG;GAC7E,MAAM,wBAAwB,MAAM,qBAAqB;IACvD,SAAS,KAAK,cAAc,KAAK;IACjC;IACA,UAAU;GACZ,CAAC;GACD,IAAI,uBACF,iBAAiB;EAErB,SAAS,OAAO;GACd,QAAQ,KACN,2DAA2D,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAClH;EACF;EAGF,IAAI,CAAC,gBAAgB;GACnB,MAAM,kBAAkB,KAAK,KAAK,WAAW,WAAW,QAAQ,OAAO,gBAAgB;GACvF,IAAI,WAAW,eAAe,GAC5B,iBAAiB;QACZ;IACL,MAAM,sBAAsB,KAAK,YAAY,QAAQ,kBAAkB;IACvE,IAAI,WAAW,mBAAmB,GAChC,iBAAiB;GAErB;EACF;CACF,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,QAAQ,KAAK,mDAAmD,SAAS;EACzE,OAAO,KAAK;GACV,KAAK;GACL,QAAQ;GACR,KAAK,KAAK,cAAc,KAAK,OAAO;GACpC,OAAO;EACT,CAAC;CACH;CAGF,KAAK,MAAM,CAAC,KAAK,WAAW,eAC1B,IAAI,CAAC,OAAO,OAAO,CAAC,OAAO,WAAW;EACpC,QAAQ,KACN,mCAAmC,IAAI,0EACzC;EACA,OAAO,KAAK;GAAE;GAAK,QAAQ;EAAU,CAAC;EACtC,mBAAmB,IAAI,GAAG;CAC5B;CAGF,MAAM,oBAAoB,cAAc,QAAQ,CAAC,SAAS,CAAC,mBAAmB,IAAI,GAAG,CAAC;CAoBtF,OAlB4B,QAAQ,WAClC,kBAAkB,IAAI,OAAO,CAAC,KAAK,YAAY;EAS7C,OAAO;GACL;GACA,cAVmB,sBAAsB;IACzC,WAAW,KAAK;IAChB;IACA;IACA,QAAQ;IACR,SAAS,OAAO;IAChB,iBAAiB,WAAW;GAC9B,CAAC;GAIC;EACF;CACF,CAAC,CACH,EAEa,CAAC,SAAS,QAAQ,UAAU;EACvC,MAAM,CAAC,KAAK,UAAU,kBAAkB;EACxC,IAAI,OAAO,WAAW,aAAa;GACjC,QAAQ,KAAK,OAAO,MAAM,MAAM;GAChC,OAAO,KAAK;IACV;IACA,QAAQ,OAAO;IACf,KAAK,OAAO,WAAW,UAAU,OAAO,MAAM;IAC9C,WAAW,OAAO,WAAW,UAAU,OAAO,YAAY;GAC5D,CAAC;GACD,IAAI,OAAO,MAAM,OAAO,eACtB,gBAAgB,OAAO,MAAM,OAAO;EAExC,OAAO;GACL,MAAM,UACJ,OAAO,kBAAkB,QAAQ,OAAO,OAAO,UAAU,OAAO,OAAO,MAAM;GAC/E,QAAQ,KAAK,4CAA4C,IAAI,KAAK,SAAS;GAC3E,OAAO,KAAK;IAAE;IAAK,QAAQ;IAAU,KAAK,OAAO,OAAO;IAAW,OAAO;GAAQ,CAAC;GACnF,mBAAmB,IAAI,GAAG;EAC5B;CACF,CAAC;CAED,MAAM,YAAY,OAAO,MAAM,MAAM,EAAE,QAAQ,KAAK;CACpD,IAAI,WAAW,WAAW,UACxB,MAAM,IAAI,MACR,wDAAwD,UAAU,SAAS,iBAC7E;CAGF,MAAM,gBAAgB,cACnB,QAAQ,CAAC,SAAS,CAAC,mBAAmB,IAAI,GAAG,CAAC,CAAC,CAC/C,KAAK,CAAC,SAAS,GAAG;CAErB,MAAM,kBAA4C,CAAC;CACnD,KAAK,MAAM,CAAC,KAAK,WAAW,eAC1B,IAAI,CAAC,mBAAmB,IAAI,GAAG,KAAK,OAAO,WAAW,QACpD,gBAAgB,OAAO,OAAO;CAIlC,oBAAoB;EAClB,WAAW,KAAK;EAChB;EACA,YAAY;EACZ;EACA;EACA,cAAc,KAAK,cAAc,IAAI;EACrC;CACF,CAAC;CAED,IAAI,KAAK,cAAc,IAAI,WAAW,SACpC,WAAW,MAAM,uBAAuB,KAAK,UAAU;CAGzD,OAAO;EACL,YAAY,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,kBAAkB;EACvE;EACA;EACA,QAAQ,KAAK,cAAc,IAAI;EAC/B;CACF;AACF"}
1
+ {"version":3,"file":"api-contract.mjs","names":[],"sources":["../src/api-contract.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { Context, Effect, Layer, ManagedRuntime, Schema } from \"effect\";\nimport { buildAuthExportStub, buildAuthTypesGenContent } from \"./auth-types-gen\";\nimport { fetchJsonOrNull, fetchResponse } from \"./http-client\";\nimport { isAuthMirrorPluginEntry } from \"./service-descriptor\";\nimport type { JsonObject, RuntimeConfig, RuntimePluginConfig } from \"./types\";\n\nexport interface ApiPluginManifest {\n schemaVersion: 1;\n kind: \"every-plugin/manifest\";\n plugin: {\n name: string;\n version: string;\n };\n runtime: {\n remoteEntry: string;\n };\n contract?: {\n kind: \"orpc\";\n types: {\n path: string;\n exportName: string;\n typeName: string;\n sha256?: string;\n };\n };\n additionalExports?: Array<{\n path: string;\n exports: string[];\n sha256?: string;\n }>;\n plugins?: Array<{\n key: string;\n name: string;\n url: string;\n dependsOn?: string[];\n secrets?: string[];\n variables?: JsonObject;\n }>;\n dependsOn?: string[];\n}\n\nexport class ApiManifestFetchError extends Schema.TaggedError<ApiManifestFetchError>()(\n \"ApiManifestFetchError\",\n { url: Schema.String, message: Schema.String },\n) {}\n\nexport class ApiManifestFormatError extends Schema.TaggedError<ApiManifestFormatError>()(\n \"ApiManifestFormatError\",\n { url: Schema.String, message: Schema.String },\n) {}\n\nexport class MissingContractTypesError extends Schema.TaggedError<MissingContractTypesError>()(\n \"MissingContractTypesError\",\n { pluginName: Schema.String, message: Schema.String },\n) {}\n\nexport class ContractTypesFetchError extends Schema.TaggedError<ContractTypesFetchError>()(\n \"ContractTypesFetchError\",\n { url: Schema.String, message: Schema.String },\n) {}\n\nexport class ContractTypesChecksumError extends Schema.TaggedError<ContractTypesChecksumError>()(\n \"ContractTypesChecksumError\",\n { url: Schema.String, message: Schema.String },\n) {}\n\nexport class AuthExportFetchError extends Schema.TaggedError<AuthExportFetchError>()(\n \"AuthExportFetchError\",\n { url: Schema.String, message: Schema.String },\n) {}\n\nexport type ApiContractError =\n | ApiManifestFetchError\n | ApiManifestFormatError\n | MissingContractTypesError\n | ContractTypesFetchError\n | ContractTypesChecksumError;\n\nexport class ApiContractResolver extends Context.Service<\n ApiContractResolver,\n {\n manifest: (\n apiBaseUrl: string,\n ) => Effect.Effect<ApiPluginManifest, ApiManifestFetchError | ApiManifestFormatError>;\n contractSource: (opts: {\n baseUrl: string;\n runtimeDir: string;\n name: string;\n generatedSubdir: string;\n }) => Effect.Effect<ContractSource, ApiContractError>;\n authExportTypes: (opts: {\n baseUrl: string;\n runtimeDir: string;\n manifest: ApiPluginManifest;\n }) => Effect.Effect<string | null, AuthExportFetchError>;\n }\n>()(\"everything-dev/api-contract/ApiContractResolver\") {\n static readonly layer: Layer.Layer<ApiContractResolver> = Layer.effect(\n ApiContractResolver,\n Effect.sync(() => {\n const manifest = Effect.fn(\"ApiContractResolver.manifest\")(function* (\n apiBaseUrl: string,\n ): Effect.fn.Return<ApiPluginManifest, ApiManifestFetchError | ApiManifestFormatError> {\n const url = getApiPluginManifestUrl(apiBaseUrl);\n const fetched = yield* Effect.tryPromise({\n try: () => fetchJsonOrNull<ApiPluginManifest>(url, { retries: 2 }),\n catch: () =>\n new ApiManifestFetchError({\n url,\n message: `Failed to fetch API plugin manifest from ${url}`,\n }),\n });\n if (!fetched) {\n return yield* new ApiManifestFetchError({\n url,\n message: `Failed to fetch API plugin manifest from ${url}`,\n });\n }\n if (fetched.schemaVersion !== 1 || fetched.kind !== \"every-plugin/manifest\") {\n return yield* new ApiManifestFormatError({\n url,\n message: \"Unsupported API plugin manifest format\",\n });\n }\n return fetched;\n });\n\n const writeContractTypes = Effect.fn(\"ApiContractResolver.writeContractTypes\")(\n function* (opts: {\n contractUrl: string;\n manifest: ApiPluginManifest;\n runtimeDir: string;\n generatedSubdir: string;\n name: string;\n }): Effect.fn.Return<ContractSource, ContractTypesFetchError | ContractTypesChecksumError> {\n const contractResponse = yield* Effect.tryPromise({\n try: () => fetchResponse(opts.contractUrl),\n catch: () =>\n new ContractTypesFetchError({\n url: opts.contractUrl,\n message: `Failed to fetch contract types from ${opts.contractUrl}`,\n }),\n });\n if (!contractResponse.ok) {\n return yield* new ContractTypesFetchError({\n url: opts.contractUrl,\n message: `Failed to fetch contract types from ${opts.contractUrl}: ${contractResponse.status} ${contractResponse.statusText}`,\n });\n }\n\n const contractTypes = yield* Effect.tryPromise({\n try: () => contractResponse.text(),\n catch: () =>\n new ContractTypesFetchError({\n url: opts.contractUrl,\n message: `Failed to fetch contract types from ${opts.contractUrl}`,\n }),\n });\n if (\n opts.manifest.contract?.types.sha256 &&\n opts.manifest.contract.types.sha256 !== sha256(contractTypes)\n ) {\n return yield* new ContractTypesChecksumError({\n url: opts.contractUrl,\n message: \"Fetched contract types failed checksum verification\",\n });\n }\n\n const generatedPath = join(opts.runtimeDir, opts.generatedSubdir, \"contract.d.ts\");\n yield* Effect.sync(() => {\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, contractTypes);\n });\n\n return {\n key: opts.name,\n importName: `${sanitizeIdentifier(opts.name)}Contract`,\n sourceFilePath: generatedPath,\n generatedPath,\n };\n },\n );\n\n const contractSource = Effect.fn(\"ApiContractResolver.contractSource\")(function* (opts: {\n baseUrl: string;\n runtimeDir: string;\n name: string;\n generatedSubdir: string;\n }): Effect.fn.Return<ContractSource, ApiContractError> {\n const fetchedManifest = yield* manifest(opts.baseUrl);\n if (!fetchedManifest.contract) {\n return yield* new MissingContractTypesError({\n pluginName: fetchedManifest.plugin.name,\n message: `Plugin manifest for ${fetchedManifest.plugin.name} does not advertise contract types`,\n });\n }\n const contractUrl = `${trimTrailingSlash(opts.baseUrl)}/${fetchedManifest.contract.types.path.replace(/^\\.\\//, \"\")}`;\n return yield* writeContractTypes({\n contractUrl,\n manifest: fetchedManifest,\n runtimeDir: opts.runtimeDir,\n generatedSubdir: opts.generatedSubdir,\n name: opts.name,\n });\n });\n\n const authExportTypes = Effect.fn(\"ApiContractResolver.authExportTypes\")(function* (opts: {\n baseUrl: string;\n runtimeDir: string;\n manifest: ApiPluginManifest;\n }): Effect.fn.Return<string | null, AuthExportFetchError> {\n const exports = opts.manifest.additionalExports ?? [];\n const entry = exports.find(\n (candidate) =>\n candidate.path.includes(\"auth-export\") || candidate.path.endsWith(\"auth-export.d.ts\"),\n );\n if (!entry) return null;\n\n const exportUrl = `${trimTrailingSlash(opts.baseUrl)}/${entry.path.replace(/^\\.\\//, \"\")}`;\n const response = yield* Effect.tryPromise({\n try: () => fetchResponse(exportUrl),\n catch: () =>\n new AuthExportFetchError({\n url: exportUrl,\n message: `Failed to fetch auth export types from ${exportUrl}`,\n }),\n });\n if (!response.ok) {\n return yield* new AuthExportFetchError({\n url: exportUrl,\n message: `Failed to fetch auth export types from ${exportUrl}: ${response.status}`,\n });\n }\n\n const content = yield* Effect.tryPromise({\n try: () => response.text(),\n catch: () =>\n new AuthExportFetchError({\n url: exportUrl,\n message: `Failed to fetch auth export types from ${exportUrl}`,\n }),\n });\n if (entry.sha256 && entry.sha256 !== sha256(content)) {\n return yield* new AuthExportFetchError({\n url: exportUrl,\n message: `Auth export types checksum mismatch for ${exportUrl}`,\n });\n }\n\n const generatedPath = join(opts.runtimeDir, \"auth\", \"auth-export.d.ts\");\n yield* Effect.sync(() => {\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, content);\n });\n return generatedPath;\n });\n\n return ApiContractResolver.of({ manifest, contractSource, authExportTypes });\n }),\n );\n}\n\nlet resolverRuntime: ManagedRuntime.ManagedRuntime<ApiContractResolver, never> | null = null;\n\nfunction getResolver(): ManagedRuntime.ManagedRuntime<ApiContractResolver, never> {\n if (!resolverRuntime) {\n resolverRuntime = ManagedRuntime.make(ApiContractResolver.layer);\n }\n return resolverRuntime;\n}\n\n/** Test seam: dispose the cached resolver runtime. */\nexport function disposeApiContractResolver(): Promise<void> {\n if (!resolverRuntime) return Promise.resolve();\n const runtime = resolverRuntime;\n resolverRuntime = null;\n return runtime.dispose();\n}\n\ninterface ContractSource {\n key: string;\n importName: string;\n sourceFilePath: string;\n generatedPath?: string;\n}\n\nfunction sha256(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction trimTrailingSlash(input: string): string {\n return input.replace(/\\/$/, \"\");\n}\n\nfunction sanitizeIdentifier(input: string): string {\n return input.replace(/[^A-Za-z0-9_]/g, \"_\").replace(/^[^A-Za-z_]+/, \"_\");\n}\n\nfunction toImportPath(fromFile: string, targetFile: string): string {\n const rel = relative(dirname(fromFile), targetFile).replace(/\\\\/g, \"/\");\n return rel.startsWith(\".\") ? rel : `./${rel}`;\n}\n\nfunction writeFileIfChanged(filePath: string, content: string) {\n try {\n if (readFileSync(filePath, \"utf8\") === content) return false;\n } catch {\n // file does not exist yet\n }\n\n writeFileSync(filePath, content);\n return true;\n}\n\nfunction getApiPluginManifestUrl(apiBaseUrl: string): string {\n return `${trimTrailingSlash(apiBaseUrl)}/plugin.manifest.json`;\n}\n\nexport async function fetchApiPluginManifest(apiBaseUrl: string): Promise<ApiPluginManifest> {\n return getResolver()\n .runPromise(\n Effect.gen(function* () {\n const resolver = yield* ApiContractResolver;\n return yield* resolver.manifest(apiBaseUrl);\n }),\n )\n .catch((error: ApiManifestFetchError | ApiManifestFormatError) => {\n throw new Error(error.message);\n });\n}\n\nfunction localApiContractSource(configDir: string): ContractSource {\n const sourcePath = join(configDir, \"api\", \"src\", \"contract.ts\");\n if (!existsSync(sourcePath)) {\n // Never emit an import to a missing file — fail loudly so the caller\n // marks this source failed instead of generating a broken typecheck.\n throw new Error(\n `local api contract not found at api/src/contract.ts — restore the file or configure a reachable api URL`,\n );\n }\n return {\n key: \"api\",\n importName: \"BaseApiContract\",\n sourceFilePath: sourcePath,\n };\n}\n\nfunction localAuthContractSource(configDir: string): ContractSource {\n const sourcePath = join(configDir, \"plugins\", \"auth\", \"src\", \"contract.ts\");\n if (!existsSync(sourcePath)) {\n throw new Error(\n `local auth contract not found at plugins/auth/src/contract.ts — restore the file or configure a reachable auth URL`,\n );\n }\n return {\n key: \"auth\",\n importName: \"authContract\",\n sourceFilePath: sourcePath,\n };\n}\n\nasync function remoteContractSource(opts: {\n configDir: string;\n runtimeDir: string;\n name: string;\n baseUrl: string;\n generatedSubdir: string;\n}): Promise<ContractSource> {\n return getResolver()\n .runPromise(\n Effect.gen(function* () {\n const resolver = yield* ApiContractResolver;\n return yield* resolver.contractSource({\n baseUrl: opts.baseUrl,\n runtimeDir: opts.runtimeDir,\n name: opts.name,\n generatedSubdir: opts.generatedSubdir,\n });\n }),\n )\n .catch((error: ApiContractError) => {\n throw new Error(error.message);\n });\n}\n\nasync function fetchAuthExportTypes(opts: {\n baseUrl: string;\n runtimeDir: string;\n manifest: ApiPluginManifest;\n}): Promise<string | null> {\n return getResolver()\n .runPromise(\n Effect.gen(function* () {\n const resolver = yield* ApiContractResolver;\n return yield* resolver.authExportTypes({\n baseUrl: opts.baseUrl,\n runtimeDir: opts.runtimeDir,\n manifest: opts.manifest,\n });\n }),\n )\n .catch((error: AuthExportFetchError) => {\n console.warn(`[API Contract] ${error.message}`);\n return null;\n });\n}\n\nasync function resolveContractSource(opts: {\n configDir: string;\n runtimeDir: string;\n key: string;\n source: RuntimePluginConfig | { url: string; localPath?: string; name: string } | null;\n baseUrl: string;\n generatedSubdir: string;\n localSourceFactory?: (configDir: string) => ContractSource;\n}): Promise<ContractSource> {\n if (opts.key === \"api\") {\n const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n if (localPath != null && localPath !== \"\") {\n return {\n key: opts.key,\n importName: \"BaseApiContract\",\n sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n };\n }\n\n if (!opts.baseUrl) {\n return localApiContractSource(opts.configDir);\n }\n }\n\n if (opts.key === \"auth\" && opts.localSourceFactory) {\n const localPath = opts.source && \"localPath\" in opts.source ? opts.source.localPath : undefined;\n if (localPath != null && localPath !== \"\") {\n return {\n key: opts.key,\n importName: \"authContract\",\n sourceFilePath: join(localPath, \"src\", \"contract.ts\"),\n };\n }\n\n if (!opts.baseUrl) {\n return opts.localSourceFactory(opts.configDir);\n }\n }\n\n if (\n opts.source &&\n \"localPath\" in opts.source &&\n opts.source.localPath != null &&\n opts.source.localPath !== \"\"\n ) {\n return {\n key: opts.key,\n importName: `${sanitizeIdentifier(opts.key)}Contract`,\n sourceFilePath: join(opts.source.localPath, \"src\", \"contract.ts\"),\n };\n }\n\n return remoteContractSource({\n configDir: opts.configDir,\n runtimeDir: opts.runtimeDir,\n name: opts.key,\n baseUrl: opts.baseUrl,\n generatedSubdir: opts.generatedSubdir,\n });\n}\n\nfunction writePluginClientGen(opts: {\n configDir: string;\n pluginKey: string;\n depSources: ContractSource[];\n localPath: string;\n}) {\n const pluginSrcDir = join(opts.localPath, \"src\");\n if (!existsSync(pluginSrcDir)) return;\n\n const targetPath = join(pluginSrcDir, \"lib\", \"plugins-client.gen.ts\");\n const lines: string[] = [];\n\n for (const source of opts.depSources) {\n const importPath = toImportPath(targetPath, source.sourceFilePath);\n lines.push(`import type { ContractType as ${source.importName} } from \"${importPath}\";`);\n }\n\n lines.push('import type { RouterContractClient, RouterContract } from \"@orpc/contract\";');\n lines.push('import type { ContractedRouter } from \"@orpc/server\";');\n lines.push(\n \"type PluginClientEntry<C extends RouterContract> = {\\n client: (context?: Record<string, unknown>) => RouterContractClient<C>;\\n router: ContractedRouter<C, any>;\\n};\",\n );\n lines.push(\"\");\n\n if (opts.depSources.length === 0) {\n lines.push(\"export type PluginsClient = Record<string, never>;\");\n } else {\n lines.push(\"export type PluginsClient = {\");\n for (const source of opts.depSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key)\n ? source.key\n : JSON.stringify(source.key);\n lines.push(` ${key}: PluginClientEntry<${source.importName}>;`);\n }\n lines.push(\"};\");\n }\n\n mkdirSync(dirname(targetPath), { recursive: true });\n writeFileIfChanged(targetPath, `${lines.join(\"\\n\")}\\n`);\n}\n\nexport function writeGeneratedFiles(opts: {\n configDir: string;\n sources: ContractSource[];\n pluginKeys: string[];\n authSource: ContractSource | null;\n authExportPath?: string | null;\n apiDependsOn?: string[];\n pluginDependsOn?: Record<string, string[]>;\n pluginLocalPaths?: Record<string, string>;\n authLocalPath?: string;\n authDependsOn?: string[];\n}) {\n const hasLocalApiWorkspace = existsSync(join(opts.configDir, \"api\", \"src\"));\n const baseSource = opts.sources.find((source) => source.key === \"api\");\n const pluginSources = opts.pluginKeys\n .map((key) => opts.sources.find((entry) => entry.key === key))\n .filter((source): source is ContractSource => Boolean(source));\n\n if (!baseSource) {\n throw new Error(\"API contract source is required to generate the aggregate contract\");\n }\n\n // --- Generate ui/src/lib/api-types.gen.ts ---\n const uiContractPath = join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\");\n const uiLines: string[] = [];\n\n for (const source of opts.sources) {\n const importPath = toImportPath(uiContractPath, source.sourceFilePath);\n uiLines.push(`import type { ContractType as ${source.importName} } from \"${importPath}\";`);\n }\n\n uiLines.push(\"\");\n\n const compositeParts: string[] = [];\n if (opts.authSource) {\n compositeParts.push(`auth: ${opts.authSource.importName}`);\n }\n for (const source of pluginSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key) ? source.key : JSON.stringify(source.key);\n compositeParts.push(`${key}: ${source.importName}`);\n }\n\n if (compositeParts.length === 0) {\n uiLines.push(`export type ApiContract = ${baseSource.importName};`);\n } else {\n uiLines.push(`export type ApiContract = ${baseSource.importName} & {`);\n for (const part of compositeParts) {\n uiLines.push(` ${part};`);\n }\n uiLines.push(\"};\");\n }\n mkdirSync(dirname(uiContractPath), { recursive: true });\n writeFileIfChanged(uiContractPath, `${uiLines.join(\"\\n\")}\\n`);\n\n // --- Generate api/src/lib/plugins-types.gen.ts ---\n // Filtered by apiDependsOn when explicit; includes all plugins + auth when implicit\n if (hasLocalApiWorkspace) {\n const pluginsClientPath = join(opts.configDir, \"api\", \"src\", \"lib\", \"plugins-types.gen.ts\");\n const pluginsClientLines: string[] = [];\n\n const allPluginSources = [...pluginSources];\n if (opts.authSource) {\n allPluginSources.push({ ...opts.authSource, key: \"auth\" });\n }\n\n const apiDepSources = opts.apiDependsOn?.length\n ? allPluginSources.filter((s) => opts.apiDependsOn!.includes(s.key))\n : allPluginSources;\n\n const unresolvedDepKeys =\n opts.apiDependsOn?.filter((depKey) => !allPluginSources.some((s) => s.key === depKey)) ?? [];\n\n for (const source of apiDepSources) {\n const importPath = toImportPath(pluginsClientPath, source.sourceFilePath);\n pluginsClientLines.push(\n `import type { ContractType as ${source.importName} } from \"${importPath}\";`,\n );\n }\n\n pluginsClientLines.push(\n 'import type { RouterContractClient, RouterContract } from \"@orpc/contract\";',\n );\n pluginsClientLines.push('import type { ContractedRouter } from \"@orpc/server\";');\n pluginsClientLines.push(\n \"type PluginClientEntry<C extends RouterContract> = {\\n client: (context?: Record<string, unknown>) => RouterContractClient<C>;\\n router: ContractedRouter<C, any>;\\n};\",\n );\n pluginsClientLines.push(\"\");\n\n if (apiDepSources.length === 0 && unresolvedDepKeys.length === 0) {\n pluginsClientLines.push(\"export type PluginsClient = Record<string, never>;\");\n } else {\n pluginsClientLines.push(\"export type PluginsClient = {\");\n for (const source of apiDepSources) {\n const key = /^[$A-Z_][0-9A-Z_$]*$/i.test(source.key)\n ? source.key\n : JSON.stringify(source.key);\n pluginsClientLines.push(` ${key}: PluginClientEntry<${source.importName}>;`);\n }\n for (const key of unresolvedDepKeys) {\n const keyStr = /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);\n pluginsClientLines.push(` ${keyStr}?: PluginClientEntry<RouterContract>;`);\n }\n pluginsClientLines.push(\"};\");\n }\n\n mkdirSync(dirname(pluginsClientPath), { recursive: true });\n writeFileIfChanged(pluginsClientPath, `${pluginsClientLines.join(\"\\n\")}\\n`);\n }\n\n // --- Generate per-plugin plugins-client.gen.ts ---\n const allSourcesForLookup = [...pluginSources];\n if (opts.authSource) {\n allSourcesForLookup.push({ ...opts.authSource, key: \"auth\" });\n }\n\n for (const pluginKey of opts.pluginKeys) {\n const localPath = opts.pluginLocalPaths?.[pluginKey];\n if (!localPath) continue;\n\n const deps = opts.pluginDependsOn?.[pluginKey] ?? [];\n const depSources = deps\n .map((depKey) => allSourcesForLookup.find((s) => s.key === depKey))\n .filter((s): s is ContractSource => Boolean(s));\n\n writePluginClientGen({\n configDir: opts.configDir,\n pluginKey,\n depSources,\n localPath,\n });\n }\n\n if (opts.authLocalPath) {\n const deps = opts.authDependsOn ?? [];\n const depSources = deps\n .map((depKey) => allSourcesForLookup.find((s) => s.key === depKey))\n .filter((s): s is ContractSource => Boolean(s));\n\n writePluginClientGen({\n configDir: opts.configDir,\n pluginKey: \"auth\",\n depSources,\n localPath: opts.authLocalPath,\n });\n }\n\n // --- Generate */src/lib/auth-types.gen.ts ---\n const authTypeTargets = [join(opts.configDir, \"ui\", \"src\", \"lib\", \"auth-types.gen.ts\")];\n const apiLibDir = join(opts.configDir, \"api\", \"src\", \"lib\");\n if (existsSync(apiLibDir)) {\n authTypeTargets.push(join(apiLibDir, \"auth-types.gen.ts\"));\n }\n const hostLibDir = join(opts.configDir, \"host\", \"src\", \"lib\");\n if (existsSync(join(opts.configDir, \"host\", \"src\"))) {\n authTypeTargets.push(join(hostLibDir, \"auth-types.gen.ts\"));\n }\n\n // Per-plugin auth-types.gen.ts\n for (const key of opts.pluginKeys) {\n const localPath = opts.pluginLocalPaths?.[key];\n if (!localPath) continue;\n const pluginSrcDir = join(localPath, \"src\");\n if (existsSync(pluginSrcDir)) {\n authTypeTargets.push(join(pluginSrcDir, \"lib\", \"auth-types.gen.ts\"));\n }\n }\n\n if (opts.authExportPath) {\n for (const authTypesPath of authTypeTargets) {\n const exportImportPath = toImportPath(authTypesPath, opts.authExportPath);\n const contractImportPath = toImportPath(\n authTypesPath,\n join(dirname(opts.authExportPath), \"contract.d.ts\"),\n );\n mkdirSync(dirname(authTypesPath), { recursive: true });\n writeFileIfChanged(\n authTypesPath,\n buildAuthTypesGenContent(exportImportPath, contractImportPath),\n );\n }\n } else if (opts.authSource) {\n const generatedAuthExportPath = join(\n opts.configDir,\n \".bos\",\n \"generated\",\n \"auth\",\n \"auth-export.d.ts\",\n );\n mkdirSync(dirname(generatedAuthExportPath), { recursive: true });\n if (!existsSync(generatedAuthExportPath)) {\n writeFileIfChanged(generatedAuthExportPath, buildAuthExportStub());\n }\n\n for (const authTypesPath of authTypeTargets) {\n const exportImportPath = toImportPath(authTypesPath, generatedAuthExportPath);\n const contractImportPath = toImportPath(\n authTypesPath,\n join(opts.configDir, \".bos\", \"generated\", \"auth\", \"contract.d.ts\"),\n );\n mkdirSync(dirname(authTypesPath), { recursive: true });\n writeFileIfChanged(\n authTypesPath,\n buildAuthTypesGenContent(exportImportPath, contractImportPath),\n );\n }\n }\n\n // --- Sweep stale per-plugin generated files ---\n // A plugin that flips local → remote (or is removed) must not keep gen\n // files importing local source paths, and a removed remote plugin must not\n // keep its fetched contract. Only exact generated paths are removed —\n // never app source.\n const localPluginKeys = new Set(Object.keys(opts.pluginLocalPaths ?? {}));\n if (opts.authLocalPath) localPluginKeys.add(\"auth\");\n const pluginsRoot = join(opts.configDir, \"plugins\");\n if (existsSync(pluginsRoot)) {\n for (const entry of readdirSync(pluginsRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name.startsWith(\"_\") || localPluginKeys.has(entry.name))\n continue;\n for (const genName of [\"plugins-client.gen.ts\", \"auth-types.gen.ts\"]) {\n const genPath = join(pluginsRoot, entry.name, \"src\", \"lib\", genName);\n if (existsSync(genPath)) rmSync(genPath);\n }\n }\n }\n const generatedPluginsRoot = join(opts.configDir, \".bos\", \"generated\", \"plugins\");\n if (existsSync(generatedPluginsRoot)) {\n const configuredKeys = new Set(opts.sources.map((source) => source.key));\n for (const entry of readdirSync(generatedPluginsRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() || configuredKeys.has(entry.name)) continue;\n rmSync(join(generatedPluginsRoot, entry.name), { recursive: true, force: true });\n }\n }\n\n return uiContractPath;\n}\n\nexport interface ContractBridgeStatus {\n key: string;\n source: \"local\" | \"remote\" | \"skipped\" | \"failed\";\n url?: string;\n localPath?: string;\n error?: string;\n}\n\nexport async function syncApiContractBridge(opts: {\n configDir: string;\n runtimeConfig: RuntimeConfig;\n apiBaseUrl: string;\n}): Promise<{\n bridgePath: string;\n generatedPath: string | null;\n manifest: ApiPluginManifest | null;\n source: \"local\" | \"remote\";\n status: ContractBridgeStatus[];\n}> {\n const runtimeDir = join(opts.configDir, \".bos\", \"generated\");\n const isAuthMirrorEntry = (key: string, plugin: RuntimePluginConfig) =>\n isAuthMirrorPluginEntry(opts.runtimeConfig.auth, key, plugin);\n const pluginEntries = Object.entries(opts.runtimeConfig.plugins ?? {})\n .filter(([key, plugin]) => !isAuthMirrorEntry(key, plugin))\n .sort(([a], [b]) => a.localeCompare(b));\n const sources: ContractSource[] = [];\n const status: ContractBridgeStatus[] = [];\n let manifest: ApiPluginManifest | null = null;\n let generatedPath: string | null = null;\n let authSource: ContractSource | null = null;\n let authExportPath: string | null = null;\n const excludedPluginKeys = new Set<string>();\n\n try {\n const baseSource = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key: \"api\",\n source: opts.runtimeConfig.api,\n baseUrl: opts.apiBaseUrl,\n generatedSubdir: \"api\",\n });\n sources.push(baseSource);\n status.push({\n key: \"api\",\n source: opts.runtimeConfig.api.source,\n url: opts.runtimeConfig.api.source !== \"local\" ? opts.apiBaseUrl : undefined,\n localPath:\n opts.runtimeConfig.api.source === \"local\" ? opts.runtimeConfig.api.localPath : undefined,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve api contract: ${message}`);\n status.push({\n key: \"api\",\n source: \"failed\",\n url: opts.apiBaseUrl || undefined,\n error: message,\n });\n }\n\n if (opts.runtimeConfig.auth) {\n try {\n authSource = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key: \"auth\",\n source: opts.runtimeConfig.auth,\n baseUrl: opts.runtimeConfig.auth.url,\n generatedSubdir: \"auth\",\n localSourceFactory: localAuthContractSource,\n });\n sources.push(authSource);\n status.push({\n key: \"auth\",\n source: opts.runtimeConfig.auth.source,\n url: opts.runtimeConfig.auth.source !== \"local\" ? opts.runtimeConfig.auth.url : undefined,\n localPath:\n opts.runtimeConfig.auth.source === \"local\"\n ? opts.runtimeConfig.auth.localPath\n : undefined,\n });\n if (authSource.generatedPath) {\n generatedPath = authSource.generatedPath;\n }\n\n if (opts.runtimeConfig.auth.url && opts.runtimeConfig.auth.source !== \"local\") {\n try {\n const authManifest = await fetchApiPluginManifest(opts.runtimeConfig.auth.url);\n const fetchedAuthExportPath = await fetchAuthExportTypes({\n baseUrl: opts.runtimeConfig.auth.url,\n runtimeDir,\n manifest: authManifest,\n });\n if (fetchedAuthExportPath) {\n authExportPath = fetchedAuthExportPath;\n }\n } catch (error) {\n console.warn(\n `[API Contract] Failed to fetch auth additional exports: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n if (!authExportPath) {\n const localAuthExport = join(opts.configDir, \"plugins\", \"auth\", \"src\", \"auth-export.ts\");\n if (existsSync(localAuthExport)) {\n authExportPath = localAuthExport;\n } else {\n const generatedAuthExport = join(runtimeDir, \"auth\", \"auth-export.d.ts\");\n if (existsSync(generatedAuthExport)) {\n authExportPath = generatedAuthExport;\n }\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[API Contract] Failed to resolve auth contract: ${message}`);\n status.push({\n key: \"auth\",\n source: \"failed\",\n url: opts.runtimeConfig.auth.url || undefined,\n error: message,\n });\n }\n }\n\n for (const [key, plugin] of pluginEntries) {\n if (!plugin.url && !plugin.localPath) {\n console.warn(\n `[API Contract] Skipping plugin \"${key}\" — no URL resolved (local path missing and no production URL configured)`,\n );\n status.push({ key, source: \"skipped\" });\n excludedPluginKeys.add(key);\n }\n }\n\n const resolvablePlugins = pluginEntries.filter(([key]) => !excludedPluginKeys.has(key));\n\n const pluginResults = await Promise.allSettled(\n resolvablePlugins.map(async ([key, plugin]) => {\n const source = await resolveContractSource({\n configDir: opts.configDir,\n runtimeDir,\n key,\n source: plugin,\n baseUrl: plugin.url,\n generatedSubdir: `plugins/${key}`,\n });\n return {\n key,\n source,\n plugin,\n };\n }),\n );\n\n pluginResults.forEach((result, index) => {\n const [key, plugin] = resolvablePlugins[index]!;\n if (result.status === \"fulfilled\") {\n sources.push(result.value.source);\n status.push({\n key,\n source: plugin.source,\n url: plugin.source !== \"local\" ? plugin.url : undefined,\n localPath: plugin.source === \"local\" ? plugin.localPath : undefined,\n });\n if (result.value.source.generatedPath) {\n generatedPath = result.value.source.generatedPath;\n }\n } else {\n const message =\n result.reason instanceof Error ? result.reason.message : String(result.reason);\n console.warn(`[API Contract] Failed to resolve plugin \"${key}\": ${message}`);\n status.push({ key, source: \"failed\", url: plugin.url || undefined, error: message });\n excludedPluginKeys.add(key);\n }\n });\n\n const apiStatus = status.find((s) => s.key === \"api\");\n if (apiStatus?.source === \"failed\") {\n throw new Error(\n `Cannot generate contract types without api contract: ${apiStatus.error ?? \"unknown error\"}`,\n );\n }\n\n const allPluginKeys = pluginEntries\n .filter(([key]) => !excludedPluginKeys.has(key))\n .map(([key]) => key);\n\n const pluginDependsOn: Record<string, string[]> = {};\n const pluginLocalPaths: Record<string, string> = {};\n for (const [key, plugin] of pluginEntries) {\n if (excludedPluginKeys.has(key)) continue;\n if (plugin.dependsOn?.length) {\n pluginDependsOn[key] = plugin.dependsOn;\n }\n if (plugin.localPath) {\n pluginLocalPaths[key] = plugin.localPath;\n }\n }\n\n writeGeneratedFiles({\n configDir: opts.configDir,\n sources,\n pluginKeys: allPluginKeys,\n authSource,\n authExportPath,\n apiDependsOn: opts.runtimeConfig.api.dependsOn,\n pluginDependsOn,\n pluginLocalPaths,\n authLocalPath:\n opts.runtimeConfig.auth?.source === \"local\" ? opts.runtimeConfig.auth.localPath : undefined,\n authDependsOn: opts.runtimeConfig.auth?.dependsOn,\n });\n\n if (opts.runtimeConfig.api.source !== \"local\") {\n manifest = await fetchApiPluginManifest(opts.apiBaseUrl);\n }\n\n return {\n bridgePath: join(opts.configDir, \"ui\", \"src\", \"lib\", \"api-types.gen.ts\"),\n generatedPath,\n manifest,\n source: opts.runtimeConfig.api.source,\n status,\n };\n}\n"],"mappings":";;;;;;;;;AA4CA,IAAa,wBAAb,cAA2C,OAAO,YAAmC,CAAC,CACpF,yBACA;CAAE,KAAK,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC/C,CAAC,CAAC,CAAC;AAEH,IAAa,yBAAb,cAA4C,OAAO,YAAoC,CAAC,CACtF,0BACA;CAAE,KAAK,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC/C,CAAC,CAAC,CAAC;AAEH,IAAa,4BAAb,cAA+C,OAAO,YAAuC,CAAC,CAC5F,6BACA;CAAE,YAAY,OAAO;CAAQ,SAAS,OAAO;AAAO,CACtD,CAAC,CAAC,CAAC;AAEH,IAAa,0BAAb,cAA6C,OAAO,YAAqC,CAAC,CACxF,2BACA;CAAE,KAAK,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC/C,CAAC,CAAC,CAAC;AAEH,IAAa,6BAAb,cAAgD,OAAO,YAAwC,CAAC,CAC9F,8BACA;CAAE,KAAK,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC/C,CAAC,CAAC,CAAC;AAEH,IAAa,uBAAb,cAA0C,OAAO,YAAkC,CAAC,CAClF,wBACA;CAAE,KAAK,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC/C,CAAC,CAAC,CAAC;AASH,IAAa,sBAAb,MAAa,4BAA4B,QAAQ,QAkB/C,CAAC,CAAC,iDAAiD,CAAC,CAAC;CACrD,OAAgB,QAA0C,MAAM,OAC9D,qBACA,OAAO,WAAW;EAChB,MAAM,WAAW,OAAO,GAAG,8BAA8B,CAAC,CAAC,WACzD,YACqF;GACrF,MAAM,MAAM,wBAAwB,UAAU;GAC9C,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,gBAAmC,KAAK,EAAE,SAAS,EAAE,CAAC;IACjE,aACE,IAAI,sBAAsB;KACxB;KACA,SAAS,4CAA4C;IACvD,CAAC;GACL,CAAC;GACD,IAAI,CAAC,SACH,OAAO,OAAO,IAAI,sBAAsB;IACtC;IACA,SAAS,4CAA4C;GACvD,CAAC;GAEH,IAAI,QAAQ,kBAAkB,KAAK,QAAQ,SAAS,yBAClD,OAAO,OAAO,IAAI,uBAAuB;IACvC;IACA,SAAS;GACX,CAAC;GAEH,OAAO;EACT,CAAC;EAED,MAAM,qBAAqB,OAAO,GAAG,wCAAwC,CAAC,CAC5E,WAAW,MAMgF;GACzF,MAAM,mBAAmB,OAAO,OAAO,WAAW;IAChD,WAAW,cAAc,KAAK,WAAW;IACzC,aACE,IAAI,wBAAwB;KAC1B,KAAK,KAAK;KACV,SAAS,uCAAuC,KAAK;IACvD,CAAC;GACL,CAAC;GACD,IAAI,CAAC,iBAAiB,IACpB,OAAO,OAAO,IAAI,wBAAwB;IACxC,KAAK,KAAK;IACV,SAAS,uCAAuC,KAAK,YAAY,IAAI,iBAAiB,OAAO,GAAG,iBAAiB;GACnH,CAAC;GAGH,MAAM,gBAAgB,OAAO,OAAO,WAAW;IAC7C,WAAW,iBAAiB,KAAK;IACjC,aACE,IAAI,wBAAwB;KAC1B,KAAK,KAAK;KACV,SAAS,uCAAuC,KAAK;IACvD,CAAC;GACL,CAAC;GACD,IACE,KAAK,SAAS,UAAU,MAAM,UAC9B,KAAK,SAAS,SAAS,MAAM,WAAW,OAAO,aAAa,GAE5D,OAAO,OAAO,IAAI,2BAA2B;IAC3C,KAAK,KAAK;IACV,SAAS;GACX,CAAC;GAGH,MAAM,gBAAgB,KAAK,KAAK,YAAY,KAAK,iBAAiB,eAAe;GACjF,OAAO,OAAO,WAAW;IACvB,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;IACrD,mBAAmB,eAAe,aAAa;GACjD,CAAC;GAED,OAAO;IACL,KAAK,KAAK;IACV,YAAY,GAAG,mBAAmB,KAAK,IAAI,EAAE;IAC7C,gBAAgB;IAChB;GACF;EACF,CACF;EAEA,MAAM,iBAAiB,OAAO,GAAG,oCAAoC,CAAC,CAAC,WAAW,MAK3B;GACrD,MAAM,kBAAkB,OAAO,SAAS,KAAK,OAAO;GACpD,IAAI,CAAC,gBAAgB,UACnB,OAAO,OAAO,IAAI,0BAA0B;IAC1C,YAAY,gBAAgB,OAAO;IACnC,SAAS,uBAAuB,gBAAgB,OAAO,KAAK;GAC9D,CAAC;GAEH,MAAM,cAAc,GAAG,kBAAkB,KAAK,OAAO,EAAE,GAAG,gBAAgB,SAAS,MAAM,KAAK,QAAQ,SAAS,EAAE;GACjH,OAAO,OAAO,mBAAmB;IAC/B;IACA,UAAU;IACV,YAAY,KAAK;IACjB,iBAAiB,KAAK;IACtB,MAAM,KAAK;GACb,CAAC;EACH,CAAC;EAED,MAAM,kBAAkB,OAAO,GAAG,qCAAqC,CAAC,CAAC,WAAW,MAI1B;GAExD,MAAM,SADU,KAAK,SAAS,qBAAqB,CAAC,EAC/B,CAAC,MACnB,cACC,UAAU,KAAK,SAAS,aAAa,KAAK,UAAU,KAAK,SAAS,kBAAkB,CACxF;GACA,IAAI,CAAC,OAAO,OAAO;GAEnB,MAAM,YAAY,GAAG,kBAAkB,KAAK,OAAO,EAAE,GAAG,MAAM,KAAK,QAAQ,SAAS,EAAE;GACtF,MAAM,WAAW,OAAO,OAAO,WAAW;IACxC,WAAW,cAAc,SAAS;IAClC,aACE,IAAI,qBAAqB;KACvB,KAAK;KACL,SAAS,0CAA0C;IACrD,CAAC;GACL,CAAC;GACD,IAAI,CAAC,SAAS,IACZ,OAAO,OAAO,IAAI,qBAAqB;IACrC,KAAK;IACL,SAAS,0CAA0C,UAAU,IAAI,SAAS;GAC5E,CAAC;GAGH,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,SAAS,KAAK;IACzB,aACE,IAAI,qBAAqB;KACvB,KAAK;KACL,SAAS,0CAA0C;IACrD,CAAC;GACL,CAAC;GACD,IAAI,MAAM,UAAU,MAAM,WAAW,OAAO,OAAO,GACjD,OAAO,OAAO,IAAI,qBAAqB;IACrC,KAAK;IACL,SAAS,2CAA2C;GACtD,CAAC;GAGH,MAAM,gBAAgB,KAAK,KAAK,YAAY,QAAQ,kBAAkB;GACtE,OAAO,OAAO,WAAW;IACvB,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;IACrD,mBAAmB,eAAe,OAAO;GAC3C,CAAC;GACD,OAAO;EACT,CAAC;EAED,OAAO,oBAAoB,GAAG;GAAE;GAAU;GAAgB;EAAgB,CAAC;CAC7E,CAAC,CACH;AACF;AAEA,IAAI,kBAAoF;AAExF,SAAS,cAAyE;CAChF,IAAI,CAAC,iBACH,kBAAkB,eAAe,KAAK,oBAAoB,KAAK;CAEjE,OAAO;AACT;AAiBA,SAAS,OAAO,OAAuB;CACrC,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;AAEA,SAAS,kBAAkB,OAAuB;CAChD,OAAO,MAAM,QAAQ,OAAO,EAAE;AAChC;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,MAAM,QAAQ,kBAAkB,GAAG,CAAC,CAAC,QAAQ,gBAAgB,GAAG;AACzE;AAEA,SAAS,aAAa,UAAkB,YAA4B;CAClE,MAAM,MAAM,SAAS,QAAQ,QAAQ,GAAG,UAAU,CAAC,CAAC,QAAQ,OAAO,GAAG;CACtE,OAAO,IAAI,WAAW,GAAG,IAAI,MAAM,KAAK;AAC1C;AAEA,SAAS,mBAAmB,UAAkB,SAAiB;CAC7D,IAAI;EACF,IAAI,aAAa,UAAU,MAAM,MAAM,SAAS,OAAO;CACzD,QAAQ,CAER;CAEA,cAAc,UAAU,OAAO;CAC/B,OAAO;AACT;AAEA,SAAS,wBAAwB,YAA4B;CAC3D,OAAO,GAAG,kBAAkB,UAAU,EAAE;AAC1C;AAEA,eAAsB,uBAAuB,YAAgD;CAC3F,OAAO,YAAY,CAAC,CACjB,WACC,OAAO,IAAI,aAAa;EAEtB,OAAO,QAAO,OADU,oBACF,CAAC,SAAS,UAAU;CAC5C,CAAC,CACH,CAAC,CACA,OAAO,UAA0D;EAChE,MAAM,IAAI,MAAM,MAAM,OAAO;CAC/B,CAAC;AACL;AAEA,SAAS,uBAAuB,WAAmC;CACjE,MAAM,aAAa,KAAK,WAAW,OAAO,OAAO,aAAa;CAC9D,IAAI,CAAC,WAAW,UAAU,GAGxB,MAAM,IAAI,MACR,yGACF;CAEF,OAAO;EACL,KAAK;EACL,YAAY;EACZ,gBAAgB;CAClB;AACF;AAEA,SAAS,wBAAwB,WAAmC;CAClE,MAAM,aAAa,KAAK,WAAW,WAAW,QAAQ,OAAO,aAAa;CAC1E,IAAI,CAAC,WAAW,UAAU,GACxB,MAAM,IAAI,MACR,oHACF;CAEF,OAAO;EACL,KAAK;EACL,YAAY;EACZ,gBAAgB;CAClB;AACF;AAEA,eAAe,qBAAqB,MAMR;CAC1B,OAAO,YAAY,CAAC,CACjB,WACC,OAAO,IAAI,aAAa;EAEtB,OAAO,QAAO,OADU,oBACF,CAAC,eAAe;GACpC,SAAS,KAAK;GACd,YAAY,KAAK;GACjB,MAAM,KAAK;GACX,iBAAiB,KAAK;EACxB,CAAC;CACH,CAAC,CACH,CAAC,CACA,OAAO,UAA4B;EAClC,MAAM,IAAI,MAAM,MAAM,OAAO;CAC/B,CAAC;AACL;AAEA,eAAe,qBAAqB,MAIT;CACzB,OAAO,YAAY,CAAC,CACjB,WACC,OAAO,IAAI,aAAa;EAEtB,OAAO,QAAO,OADU,oBACF,CAAC,gBAAgB;GACrC,SAAS,KAAK;GACd,YAAY,KAAK;GACjB,UAAU,KAAK;EACjB,CAAC;CACH,CAAC,CACH,CAAC,CACA,OAAO,UAAgC;EACtC,QAAQ,KAAK,kBAAkB,MAAM,SAAS;EAC9C,OAAO;CACT,CAAC;AACL;AAEA,eAAe,sBAAsB,MAQT;CAC1B,IAAI,KAAK,QAAQ,OAAO;EACtB,MAAM,YAAY,KAAK,UAAU,eAAe,KAAK,SAAS,KAAK,OAAO,YAAY;EACtF,IAAI,aAAa,QAAQ,cAAc,IACrC,OAAO;GACL,KAAK,KAAK;GACV,YAAY;GACZ,gBAAgB,KAAK,WAAW,OAAO,aAAa;EACtD;EAGF,IAAI,CAAC,KAAK,SACR,OAAO,uBAAuB,KAAK,SAAS;CAEhD;CAEA,IAAI,KAAK,QAAQ,UAAU,KAAK,oBAAoB;EAClD,MAAM,YAAY,KAAK,UAAU,eAAe,KAAK,SAAS,KAAK,OAAO,YAAY;EACtF,IAAI,aAAa,QAAQ,cAAc,IACrC,OAAO;GACL,KAAK,KAAK;GACV,YAAY;GACZ,gBAAgB,KAAK,WAAW,OAAO,aAAa;EACtD;EAGF,IAAI,CAAC,KAAK,SACR,OAAO,KAAK,mBAAmB,KAAK,SAAS;CAEjD;CAEA,IACE,KAAK,UACL,eAAe,KAAK,UACpB,KAAK,OAAO,aAAa,QACzB,KAAK,OAAO,cAAc,IAE1B,OAAO;EACL,KAAK,KAAK;EACV,YAAY,GAAG,mBAAmB,KAAK,GAAG,EAAE;EAC5C,gBAAgB,KAAK,KAAK,OAAO,WAAW,OAAO,aAAa;CAClE;CAGF,OAAO,qBAAqB;EAC1B,WAAW,KAAK;EAChB,YAAY,KAAK;EACjB,MAAM,KAAK;EACX,SAAS,KAAK;EACd,iBAAiB,KAAK;CACxB,CAAC;AACH;AAEA,SAAS,qBAAqB,MAK3B;CACD,MAAM,eAAe,KAAK,KAAK,WAAW,KAAK;CAC/C,IAAI,CAAC,WAAW,YAAY,GAAG;CAE/B,MAAM,aAAa,KAAK,cAAc,OAAO,uBAAuB;CACpE,MAAM,QAAkB,CAAC;CAEzB,KAAK,MAAM,UAAU,KAAK,YAAY;EACpC,MAAM,aAAa,aAAa,YAAY,OAAO,cAAc;EACjE,MAAM,KAAK,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAAG;CACzF;CAEA,MAAM,KAAK,+EAA6E;CACxF,MAAM,KAAK,yDAAuD;CAClE,MAAM,KACJ,0KACF;CACA,MAAM,KAAK,EAAE;CAEb,IAAI,KAAK,WAAW,WAAW,GAC7B,MAAM,KAAK,oDAAoD;MAC1D;EACL,MAAM,KAAK,+BAA+B;EAC1C,KAAK,MAAM,UAAU,KAAK,YAAY;GACpC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAC/C,OAAO,MACP,KAAK,UAAU,OAAO,GAAG;GAC7B,MAAM,KAAK,KAAK,IAAI,sBAAsB,OAAO,WAAW,GAAG;EACjE;EACA,MAAM,KAAK,IAAI;CACjB;CAEA,UAAU,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CAClD,mBAAmB,YAAY,GAAG,MAAM,KAAK,IAAI,EAAE,GAAG;AACxD;AAEA,SAAgB,oBAAoB,MAWjC;CACD,MAAM,uBAAuB,WAAW,KAAK,KAAK,WAAW,OAAO,KAAK,CAAC;CAC1E,MAAM,aAAa,KAAK,QAAQ,MAAM,WAAW,OAAO,QAAQ,KAAK;CACrE,MAAM,gBAAgB,KAAK,WACxB,KAAK,QAAQ,KAAK,QAAQ,MAAM,UAAU,MAAM,QAAQ,GAAG,CAAC,CAAC,CAC7D,QAAQ,WAAqC,QAAQ,MAAM,CAAC;CAE/D,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,oEAAoE;CAItF,MAAM,iBAAiB,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,kBAAkB;CAClF,MAAM,UAAoB,CAAC;CAE3B,KAAK,MAAM,UAAU,KAAK,SAAS;EACjC,MAAM,aAAa,aAAa,gBAAgB,OAAO,cAAc;EACrE,QAAQ,KAAK,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAAG;CAC3F;CAEA,QAAQ,KAAK,EAAE;CAEf,MAAM,iBAA2B,CAAC;CAClC,IAAI,KAAK,YACP,eAAe,KAAK,SAAS,KAAK,WAAW,YAAY;CAE3D,KAAK,MAAM,UAAU,eAAe;EAClC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAAI,OAAO,MAAM,KAAK,UAAU,OAAO,GAAG;EAC7F,eAAe,KAAK,GAAG,IAAI,IAAI,OAAO,YAAY;CACpD;CAEA,IAAI,eAAe,WAAW,GAC5B,QAAQ,KAAK,6BAA6B,WAAW,WAAW,EAAE;MAC7D;EACL,QAAQ,KAAK,6BAA6B,WAAW,WAAW,KAAK;EACrE,KAAK,MAAM,QAAQ,gBACjB,QAAQ,KAAK,KAAK,KAAK,EAAE;EAE3B,QAAQ,KAAK,IAAI;CACnB;CACA,UAAU,QAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;CACtD,mBAAmB,gBAAgB,GAAG,QAAQ,KAAK,IAAI,EAAE,GAAG;CAI5D,IAAI,sBAAsB;EACxB,MAAM,oBAAoB,KAAK,KAAK,WAAW,OAAO,OAAO,OAAO,sBAAsB;EAC1F,MAAM,qBAA+B,CAAC;EAEtC,MAAM,mBAAmB,CAAC,GAAG,aAAa;EAC1C,IAAI,KAAK,YACP,iBAAiB,KAAK;GAAE,GAAG,KAAK;GAAY,KAAK;EAAO,CAAC;EAG3D,MAAM,gBAAgB,KAAK,cAAc,SACrC,iBAAiB,QAAQ,MAAM,KAAK,aAAc,SAAS,EAAE,GAAG,CAAC,IACjE;EAEJ,MAAM,oBACJ,KAAK,cAAc,QAAQ,WAAW,CAAC,iBAAiB,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,KAAK,CAAC;EAE7F,KAAK,MAAM,UAAU,eAAe;GAClC,MAAM,aAAa,aAAa,mBAAmB,OAAO,cAAc;GACxE,mBAAmB,KACjB,iCAAiC,OAAO,WAAW,WAAW,WAAW,GAC3E;EACF;EAEA,mBAAmB,KACjB,+EACF;EACA,mBAAmB,KAAK,yDAAuD;EAC/E,mBAAmB,KACjB,0KACF;EACA,mBAAmB,KAAK,EAAE;EAE1B,IAAI,cAAc,WAAW,KAAK,kBAAkB,WAAW,GAC7D,mBAAmB,KAAK,oDAAoD;OACvE;GACL,mBAAmB,KAAK,+BAA+B;GACvD,KAAK,MAAM,UAAU,eAAe;IAClC,MAAM,MAAM,wBAAwB,KAAK,OAAO,GAAG,IAC/C,OAAO,MACP,KAAK,UAAU,OAAO,GAAG;IAC7B,mBAAmB,KAAK,KAAK,IAAI,sBAAsB,OAAO,WAAW,GAAG;GAC9E;GACA,KAAK,MAAM,OAAO,mBAAmB;IACnC,MAAM,SAAS,wBAAwB,KAAK,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG;IAC3E,mBAAmB,KAAK,KAAK,OAAO,sCAAsC;GAC5E;GACA,mBAAmB,KAAK,IAAI;EAC9B;EAEA,UAAU,QAAQ,iBAAiB,GAAG,EAAE,WAAW,KAAK,CAAC;EACzD,mBAAmB,mBAAmB,GAAG,mBAAmB,KAAK,IAAI,EAAE,GAAG;CAC5E;CAGA,MAAM,sBAAsB,CAAC,GAAG,aAAa;CAC7C,IAAI,KAAK,YACP,oBAAoB,KAAK;EAAE,GAAG,KAAK;EAAY,KAAK;CAAO,CAAC;CAG9D,KAAK,MAAM,aAAa,KAAK,YAAY;EACvC,MAAM,YAAY,KAAK,mBAAmB;EAC1C,IAAI,CAAC,WAAW;EAGhB,MAAM,cADO,KAAK,kBAAkB,cAAc,CAAC,EAC5B,CACpB,KAAK,WAAW,oBAAoB,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,CAAC,CAClE,QAAQ,MAA2B,QAAQ,CAAC,CAAC;EAEhD,qBAAqB;GACnB,WAAW,KAAK;GAChB;GACA;GACA;EACF,CAAC;CACH;CAEA,IAAI,KAAK,eAAe;EAEtB,MAAM,cADO,KAAK,iBAAiB,CAAC,EACb,CACpB,KAAK,WAAW,oBAAoB,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,CAAC,CAClE,QAAQ,MAA2B,QAAQ,CAAC,CAAC;EAEhD,qBAAqB;GACnB,WAAW,KAAK;GAChB,WAAW;GACX;GACA,WAAW,KAAK;EAClB,CAAC;CACH;CAGA,MAAM,kBAAkB,CAAC,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,mBAAmB,CAAC;CACtF,MAAM,YAAY,KAAK,KAAK,WAAW,OAAO,OAAO,KAAK;CAC1D,IAAI,WAAW,SAAS,GACtB,gBAAgB,KAAK,KAAK,WAAW,mBAAmB,CAAC;CAE3D,MAAM,aAAa,KAAK,KAAK,WAAW,QAAQ,OAAO,KAAK;CAC5D,IAAI,WAAW,KAAK,KAAK,WAAW,QAAQ,KAAK,CAAC,GAChD,gBAAgB,KAAK,KAAK,YAAY,mBAAmB,CAAC;CAI5D,KAAK,MAAM,OAAO,KAAK,YAAY;EACjC,MAAM,YAAY,KAAK,mBAAmB;EAC1C,IAAI,CAAC,WAAW;EAChB,MAAM,eAAe,KAAK,WAAW,KAAK;EAC1C,IAAI,WAAW,YAAY,GACzB,gBAAgB,KAAK,KAAK,cAAc,OAAO,mBAAmB,CAAC;CAEvE;CAEA,IAAI,KAAK,gBACP,KAAK,MAAM,iBAAiB,iBAAiB;EAC3C,MAAM,mBAAmB,aAAa,eAAe,KAAK,cAAc;EACxE,MAAM,qBAAqB,aACzB,eACA,KAAK,QAAQ,KAAK,cAAc,GAAG,eAAe,CACpD;EACA,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;EACrD,mBACE,eACA,yBAAyB,kBAAkB,kBAAkB,CAC/D;CACF;MACK,IAAI,KAAK,YAAY;EAC1B,MAAM,0BAA0B,KAC9B,KAAK,WACL,QACA,aACA,QACA,kBACF;EACA,UAAU,QAAQ,uBAAuB,GAAG,EAAE,WAAW,KAAK,CAAC;EAC/D,IAAI,CAAC,WAAW,uBAAuB,GACrC,mBAAmB,yBAAyB,oBAAoB,CAAC;EAGnE,KAAK,MAAM,iBAAiB,iBAAiB;GAC3C,MAAM,mBAAmB,aAAa,eAAe,uBAAuB;GAC5E,MAAM,qBAAqB,aACzB,eACA,KAAK,KAAK,WAAW,QAAQ,aAAa,QAAQ,eAAe,CACnE;GACA,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;GACrD,mBACE,eACA,yBAAyB,kBAAkB,kBAAkB,CAC/D;EACF;CACF;CAOA,MAAM,kBAAkB,IAAI,IAAI,OAAO,KAAK,KAAK,oBAAoB,CAAC,CAAC,CAAC;CACxE,IAAI,KAAK,eAAe,gBAAgB,IAAI,MAAM;CAClD,MAAM,cAAc,KAAK,KAAK,WAAW,SAAS;CAClD,IAAI,WAAW,WAAW,GACxB,KAAK,MAAM,SAAS,YAAY,aAAa,EAAE,eAAe,KAAK,CAAC,GAAG;EACrE,IAAI,CAAC,MAAM,YAAY,KAAK,MAAM,KAAK,WAAW,GAAG,KAAK,gBAAgB,IAAI,MAAM,IAAI,GACtF;EACF,KAAK,MAAM,WAAW,CAAC,yBAAyB,mBAAmB,GAAG;GACpE,MAAM,UAAU,KAAK,aAAa,MAAM,MAAM,OAAO,OAAO,OAAO;GACnE,IAAI,WAAW,OAAO,GAAG,OAAO,OAAO;EACzC;CACF;CAEF,MAAM,uBAAuB,KAAK,KAAK,WAAW,QAAQ,aAAa,SAAS;CAChF,IAAI,WAAW,oBAAoB,GAAG;EACpC,MAAM,iBAAiB,IAAI,IAAI,KAAK,QAAQ,KAAK,WAAW,OAAO,GAAG,CAAC;EACvE,KAAK,MAAM,SAAS,YAAY,sBAAsB,EAAE,eAAe,KAAK,CAAC,GAAG;GAC9E,IAAI,CAAC,MAAM,YAAY,KAAK,eAAe,IAAI,MAAM,IAAI,GAAG;GAC5D,OAAO,KAAK,sBAAsB,MAAM,IAAI,GAAG;IAAE,WAAW;IAAM,OAAO;GAAK,CAAC;EACjF;CACF;CAEA,OAAO;AACT;AAUA,eAAsB,sBAAsB,MAUzC;CACD,MAAM,aAAa,KAAK,KAAK,WAAW,QAAQ,WAAW;CAC3D,MAAM,qBAAqB,KAAa,WACtC,wBAAwB,KAAK,cAAc,MAAM,KAAK,MAAM;CAC9D,MAAM,gBAAgB,OAAO,QAAQ,KAAK,cAAc,WAAW,CAAC,CAAC,CAAC,CACnE,QAAQ,CAAC,KAAK,YAAY,CAAC,kBAAkB,KAAK,MAAM,CAAC,CAAC,CAC1D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;CACxC,MAAM,UAA4B,CAAC;CACnC,MAAM,SAAiC,CAAC;CACxC,IAAI,WAAqC;CACzC,IAAI,gBAA+B;CACnC,IAAI,aAAoC;CACxC,IAAI,iBAAgC;CACpC,MAAM,qCAAqB,IAAI,IAAY;CAE3C,IAAI;EACF,MAAM,aAAa,MAAM,sBAAsB;GAC7C,WAAW,KAAK;GAChB;GACA,KAAK;GACL,QAAQ,KAAK,cAAc;GAC3B,SAAS,KAAK;GACd,iBAAiB;EACnB,CAAC;EACD,QAAQ,KAAK,UAAU;EACvB,OAAO,KAAK;GACV,KAAK;GACL,QAAQ,KAAK,cAAc,IAAI;GAC/B,KAAK,KAAK,cAAc,IAAI,WAAW,UAAU,KAAK,aAAa;GACnE,WACE,KAAK,cAAc,IAAI,WAAW,UAAU,KAAK,cAAc,IAAI,YAAY;EACnF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,QAAQ,KAAK,kDAAkD,SAAS;EACxE,OAAO,KAAK;GACV,KAAK;GACL,QAAQ;GACR,KAAK,KAAK,cAAc;GACxB,OAAO;EACT,CAAC;CACH;CAEA,IAAI,KAAK,cAAc,MACrB,IAAI;EACF,aAAa,MAAM,sBAAsB;GACvC,WAAW,KAAK;GAChB;GACA,KAAK;GACL,QAAQ,KAAK,cAAc;GAC3B,SAAS,KAAK,cAAc,KAAK;GACjC,iBAAiB;GACjB,oBAAoB;EACtB,CAAC;EACD,QAAQ,KAAK,UAAU;EACvB,OAAO,KAAK;GACV,KAAK;GACL,QAAQ,KAAK,cAAc,KAAK;GAChC,KAAK,KAAK,cAAc,KAAK,WAAW,UAAU,KAAK,cAAc,KAAK,MAAM;GAChF,WACE,KAAK,cAAc,KAAK,WAAW,UAC/B,KAAK,cAAc,KAAK,YACxB;EACR,CAAC;EACD,IAAI,WAAW,eACb,gBAAgB,WAAW;EAG7B,IAAI,KAAK,cAAc,KAAK,OAAO,KAAK,cAAc,KAAK,WAAW,SACpE,IAAI;GACF,MAAM,eAAe,MAAM,uBAAuB,KAAK,cAAc,KAAK,GAAG;GAC7E,MAAM,wBAAwB,MAAM,qBAAqB;IACvD,SAAS,KAAK,cAAc,KAAK;IACjC;IACA,UAAU;GACZ,CAAC;GACD,IAAI,uBACF,iBAAiB;EAErB,SAAS,OAAO;GACd,QAAQ,KACN,2DAA2D,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAClH;EACF;EAGF,IAAI,CAAC,gBAAgB;GACnB,MAAM,kBAAkB,KAAK,KAAK,WAAW,WAAW,QAAQ,OAAO,gBAAgB;GACvF,IAAI,WAAW,eAAe,GAC5B,iBAAiB;QACZ;IACL,MAAM,sBAAsB,KAAK,YAAY,QAAQ,kBAAkB;IACvE,IAAI,WAAW,mBAAmB,GAChC,iBAAiB;GAErB;EACF;CACF,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,QAAQ,KAAK,mDAAmD,SAAS;EACzE,OAAO,KAAK;GACV,KAAK;GACL,QAAQ;GACR,KAAK,KAAK,cAAc,KAAK,OAAO;GACpC,OAAO;EACT,CAAC;CACH;CAGF,KAAK,MAAM,CAAC,KAAK,WAAW,eAC1B,IAAI,CAAC,OAAO,OAAO,CAAC,OAAO,WAAW;EACpC,QAAQ,KACN,mCAAmC,IAAI,0EACzC;EACA,OAAO,KAAK;GAAE;GAAK,QAAQ;EAAU,CAAC;EACtC,mBAAmB,IAAI,GAAG;CAC5B;CAGF,MAAM,oBAAoB,cAAc,QAAQ,CAAC,SAAS,CAAC,mBAAmB,IAAI,GAAG,CAAC;CAoBtF,OAlB4B,QAAQ,WAClC,kBAAkB,IAAI,OAAO,CAAC,KAAK,YAAY;EAS7C,OAAO;GACL;GACA,cAVmB,sBAAsB;IACzC,WAAW,KAAK;IAChB;IACA;IACA,QAAQ;IACR,SAAS,OAAO;IAChB,iBAAiB,WAAW;GAC9B,CAAC;GAIC;EACF;CACF,CAAC,CACH,EAEa,CAAC,SAAS,QAAQ,UAAU;EACvC,MAAM,CAAC,KAAK,UAAU,kBAAkB;EACxC,IAAI,OAAO,WAAW,aAAa;GACjC,QAAQ,KAAK,OAAO,MAAM,MAAM;GAChC,OAAO,KAAK;IACV;IACA,QAAQ,OAAO;IACf,KAAK,OAAO,WAAW,UAAU,OAAO,MAAM;IAC9C,WAAW,OAAO,WAAW,UAAU,OAAO,YAAY;GAC5D,CAAC;GACD,IAAI,OAAO,MAAM,OAAO,eACtB,gBAAgB,OAAO,MAAM,OAAO;EAExC,OAAO;GACL,MAAM,UACJ,OAAO,kBAAkB,QAAQ,OAAO,OAAO,UAAU,OAAO,OAAO,MAAM;GAC/E,QAAQ,KAAK,4CAA4C,IAAI,KAAK,SAAS;GAC3E,OAAO,KAAK;IAAE;IAAK,QAAQ;IAAU,KAAK,OAAO,OAAO;IAAW,OAAO;GAAQ,CAAC;GACnF,mBAAmB,IAAI,GAAG;EAC5B;CACF,CAAC;CAED,MAAM,YAAY,OAAO,MAAM,MAAM,EAAE,QAAQ,KAAK;CACpD,IAAI,WAAW,WAAW,UACxB,MAAM,IAAI,MACR,wDAAwD,UAAU,SAAS,iBAC7E;CAGF,MAAM,gBAAgB,cACnB,QAAQ,CAAC,SAAS,CAAC,mBAAmB,IAAI,GAAG,CAAC,CAAC,CAC/C,KAAK,CAAC,SAAS,GAAG;CAErB,MAAM,kBAA4C,CAAC;CACnD,MAAM,mBAA2C,CAAC;CAClD,KAAK,MAAM,CAAC,KAAK,WAAW,eAAe;EACzC,IAAI,mBAAmB,IAAI,GAAG,GAAG;EACjC,IAAI,OAAO,WAAW,QACpB,gBAAgB,OAAO,OAAO;EAEhC,IAAI,OAAO,WACT,iBAAiB,OAAO,OAAO;CAEnC;CAEA,oBAAoB;EAClB,WAAW,KAAK;EAChB;EACA,YAAY;EACZ;EACA;EACA,cAAc,KAAK,cAAc,IAAI;EACrC;EACA;EACA,eACE,KAAK,cAAc,MAAM,WAAW,UAAU,KAAK,cAAc,KAAK,YAAY;EACpF,eAAe,KAAK,cAAc,MAAM;CAC1C,CAAC;CAED,IAAI,KAAK,cAAc,IAAI,WAAW,SACpC,WAAW,MAAM,uBAAuB,KAAK,UAAU;CAGzD,OAAO;EACL,YAAY,KAAK,KAAK,WAAW,MAAM,OAAO,OAAO,kBAAkB;EACvE;EACA;EACA,QAAQ,KAAK,cAAc,IAAI;EAC/B;CACF;AACF"}
package/dist/app.cjs CHANGED
@@ -9,38 +9,51 @@ let node_net = require("node:net");
9
9
  const PROBE_TIMEOUT_MS = 250;
10
10
  const MAX_PORT_SCAN_STEPS = 1e3;
11
11
  const PARALLEL_PROBE_WINDOW = 8;
12
+ const BLOCK_STEP = 100;
12
13
  var PortAllocationError = class extends effect.Data.TaggedError("PortAllocationError") {};
13
- var PortAllocator = class extends effect.Context.Tag("PortAllocator")() {};
14
- function detectLocalPackages(bosConfig, runtimeConfig) {
14
+ var PortAllocator = class extends effect.Context.Service()("PortAllocator") {};
15
+ function detectLocalPackages(bosConfig, runtimeConfig, root = process.cwd()) {
15
16
  const packages = [];
16
- const configDir = require_config.getProjectRoot();
17
+ const configDir = root;
17
18
  const uiLocalPath = runtimeConfig?.ui.localPath ?? require_config.resolveLocalDevelopmentPath(bosConfig?.app.ui.development, configDir);
18
- if (uiLocalPath && (0, node_fs.existsSync)((0, node_path.join)(uiLocalPath, "package.json"))) packages.push("ui");
19
+ if (uiLocalPath && (0, node_fs.existsSync)((0, node_path.join)(uiLocalPath, "package.json"))) packages.push({
20
+ name: "ui",
21
+ dir: uiLocalPath
22
+ });
19
23
  const apiLocalPath = runtimeConfig?.api.localPath ?? require_config.resolveLocalDevelopmentPath(bosConfig?.app.api.development, configDir);
20
- if (apiLocalPath && (0, node_fs.existsSync)((0, node_path.join)(apiLocalPath, "package.json"))) packages.push("api");
24
+ if (apiLocalPath && (0, node_fs.existsSync)((0, node_path.join)(apiLocalPath, "package.json"))) packages.push({
25
+ name: "api",
26
+ dir: apiLocalPath
27
+ });
21
28
  const hostLocalPath = runtimeConfig?.host?.localPath ?? require_config.resolveLocalDevelopmentPath(bosConfig?.app.host.development, configDir);
22
- if (hostLocalPath && (0, node_fs.existsSync)((0, node_path.join)(hostLocalPath, "package.json"))) packages.push("host");
23
- else if ((0, node_fs.existsSync)((0, node_path.join)(configDir, "host", "package.json"))) packages.push("host");
29
+ if (hostLocalPath && (0, node_fs.existsSync)((0, node_path.join)(hostLocalPath, "package.json"))) packages.push({
30
+ name: "host",
31
+ dir: hostLocalPath
32
+ });
33
+ else if ((0, node_fs.existsSync)((0, node_path.join)(configDir, "host", "package.json"))) packages.push({
34
+ name: "host",
35
+ dir: (0, node_path.join)(configDir, "host")
36
+ });
24
37
  for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig?.plugins ?? {})) {
25
- if (pluginConfig.localPath && (0, node_fs.existsSync)((0, node_path.join)(pluginConfig.localPath, "package.json"))) packages.push(`plugin:${pluginId}`);
26
- if (pluginConfig.ui?.localPath && (0, node_fs.existsSync)((0, node_path.join)(pluginConfig.ui.localPath, "package.json"))) packages.push(`plugin-ui:${pluginId}`);
38
+ if (pluginConfig.localPath && (0, node_fs.existsSync)((0, node_path.join)(pluginConfig.localPath, "package.json"))) packages.push({
39
+ name: `plugin:${pluginId}`,
40
+ dir: pluginConfig.localPath
41
+ });
42
+ if (pluginConfig.ui?.localPath && (0, node_fs.existsSync)((0, node_path.join)(pluginConfig.ui.localPath, "package.json"))) packages.push({
43
+ name: `plugin-ui:${pluginId}`,
44
+ dir: pluginConfig.ui.localPath
45
+ });
27
46
  }
28
47
  const authLocalPath = runtimeConfig?.auth?.localPath ?? require_config.resolveLocalDevelopmentPath(bosConfig?.app.auth?.development, configDir);
29
- if (authLocalPath && (0, node_fs.existsSync)((0, node_path.join)(authLocalPath, "package.json"))) packages.push("auth");
30
- return packages;
31
- }
32
- async function buildRuntimeConfig(bosConfig, options) {
33
- return require_config.buildRuntimeConfig(bosConfig, require_config.getProjectRoot(), options.env ?? "development", {
34
- hostSource: options.hostSource,
35
- uiSource: options.uiSource,
36
- apiSource: options.apiSource,
37
- authSource: options.authSource,
38
- proxy: options.proxy,
39
- plugins: options.plugins
48
+ if (authLocalPath && (0, node_fs.existsSync)((0, node_path.join)(authLocalPath, "package.json"))) packages.push({
49
+ name: "auth",
50
+ dir: authLocalPath
40
51
  });
52
+ return packages;
41
53
  }
54
+ const scheduleTimeout = (ms, fn) => setTimeout(fn, ms);
42
55
  function probePortBindable(port) {
43
- return effect.Effect.async((resume) => {
56
+ return effect.Effect.callback((resume) => {
44
57
  const server = (0, node_net.createServer)();
45
58
  server.once("listening", () => {
46
59
  server.close(() => {
@@ -52,13 +65,13 @@ function probePortBindable(port) {
52
65
  resume(effect.Effect.succeed(false));
53
66
  });
54
67
  server.listen(port, "127.0.0.1");
55
- const timer = setTimeout(() => {
68
+ const timer = scheduleTimeout(PROBE_TIMEOUT_MS, () => {
56
69
  server.removeAllListeners();
57
70
  try {
58
71
  server.close();
59
72
  } catch {}
60
73
  resume(effect.Effect.succeed(false));
61
- }, PROBE_TIMEOUT_MS);
74
+ });
62
75
  server.once("listening", () => clearTimeout(timer));
63
76
  server.once("error", () => clearTimeout(timer));
64
77
  });
@@ -76,7 +89,7 @@ function pickAvailablePort(preferred, usedPorts, budget) {
76
89
  cause: budget ? `No free port in budget [${budget.min}, ${budget.max}] starting from ${preferred}` : `No free port found starting from ${preferred} within ${MAX_PORT_SCAN_STEPS} steps`
77
90
  }));
78
91
  while (true) {
79
- if (port >= ceiling || steps > MAX_PORT_SCAN_STEPS) yield* fail();
92
+ if (port >= ceiling || steps > MAX_PORT_SCAN_STEPS) return yield* fail();
80
93
  const candidates = [];
81
94
  for (let i = 0; i < PARALLEL_PROBE_WINDOW && port + i < ceiling; i++) {
82
95
  const candidate = port + i;
@@ -102,13 +115,73 @@ function pickAvailablePort(preferred, usedPorts, budget) {
102
115
  }
103
116
  const PortAllocatorLive = effect.Layer.sync(PortAllocator, () => {
104
117
  const usedPorts = require_process_registry.claimedPorts();
105
- return { pickAvailable: (preferred, budget) => pickAvailablePort(preferred, usedPorts, budget) };
118
+ return {
119
+ pickAvailable: (preferred, budget) => pickAvailablePort(preferred, usedPorts, budget),
120
+ acquireBlock: (request) => acquireBlockPort(request, usedPorts)
121
+ };
106
122
  });
123
+ function acquireBlockPort(request, usedPorts) {
124
+ const step = request.step ?? BLOCK_STEP;
125
+ const fail = (cause) => effect.Effect.fail(new PortAllocationError({
126
+ preferred: request.base,
127
+ cause
128
+ }));
129
+ return effect.Effect.gen(function* () {
130
+ let base = request.base;
131
+ let steps = 0;
132
+ let firstConflicts = [];
133
+ while (steps <= MAX_PORT_SCAN_STEPS) {
134
+ const shift = base - request.base;
135
+ const candidates = request.entries.map((entry) => ({
136
+ ...entry,
137
+ port: entry.pinned ? entry.preferred : entry.preferred + shift
138
+ }));
139
+ let pinnedHeldByListener;
140
+ for (const candidate of candidates.filter((c) => c.pinned)) {
141
+ if (!(yield* probePortBindable(candidate.port))) {
142
+ pinnedHeldByListener = candidate;
143
+ break;
144
+ }
145
+ usedPorts.delete(candidate.port);
146
+ }
147
+ if (pinnedHeldByListener) return yield* fail(`explicitly-requested port ${pinnedHeldByListener.port} (${pinnedHeldByListener.key}) is occupied by a listener`);
148
+ const unpinned = candidates.filter((c) => !c.pinned);
149
+ const claimConflicts = unpinned.filter((c) => usedPorts.has(c.port)).map((c) => ({
150
+ key: c.key,
151
+ port: c.port,
152
+ claimed: true
153
+ }));
154
+ if (shift === 0) firstConflicts = claimConflicts;
155
+ if (claimConflicts.length === 0) {
156
+ const busy = (yield* effect.Effect.forEach(unpinned, (c) => probePortBindable(c.port).pipe(effect.Effect.map((free) => ({
157
+ ...c,
158
+ free
159
+ }))), { concurrency: "unbounded" })).filter((r) => !r.free);
160
+ if (shift === 0) firstConflicts = busy.map((b) => ({
161
+ key: b.key,
162
+ port: b.port,
163
+ claimed: false
164
+ }));
165
+ if (busy.length === 0) {
166
+ for (const candidate of candidates) usedPorts.add(candidate.port);
167
+ return {
168
+ base,
169
+ ports: Object.fromEntries(candidates.map((c) => [c.key, c.port])),
170
+ conflicts: firstConflicts
171
+ };
172
+ }
173
+ }
174
+ base += step;
175
+ steps += 1;
176
+ }
177
+ return yield* fail(`no free port block within ${MAX_PORT_SCAN_STEPS} steps of base ${request.base} (step ${step})`);
178
+ });
179
+ }
107
180
 
108
181
  //#endregion
109
182
  exports.PortAllocationError = PortAllocationError;
110
183
  exports.PortAllocator = PortAllocator;
111
184
  exports.PortAllocatorLive = PortAllocatorLive;
112
- exports.buildRuntimeConfig = buildRuntimeConfig;
113
185
  exports.detectLocalPackages = detectLocalPackages;
186
+ exports.probePortBindable = probePortBindable;
114
187
  //# sourceMappingURL=app.cjs.map
package/dist/app.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.cjs","names":["Data","Context","getProjectRoot","resolveLocalDevelopmentPath","configBuildRuntimeConfig","Effect","Layer","claimedPorts"],"sources":["../src/app.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { createServer } from \"node:net\";\nimport { join } from \"node:path\";\nimport { Context, Data, Effect, Layer } from \"effect\";\nimport type { DevPortState } from \"./cli/infra\";\nimport {\n buildRuntimeConfig as configBuildRuntimeConfig,\n getProjectRoot,\n resolveLocalDevelopmentPath,\n} from \"./config\";\nimport { claimedPorts } from \"./process-registry\";\nimport type { AppOrchestrator } from \"./service-descriptor\";\nimport type { BosConfig, RuntimeConfig, RuntimePluginConfig } from \"./types\";\n\nexport type { AppOrchestrator };\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\n\nconst PROBE_TIMEOUT_MS = 250;\nconst MAX_PORT_SCAN_STEPS = 1000;\nconst PARALLEL_PROBE_WINDOW = 8;\n\nexport type PortBudget = { min: number; max: number };\n\nexport class PortAllocationError extends Data.TaggedError(\"PortAllocationError\")<{\n preferred: number;\n budget?: PortBudget;\n cause?: unknown;\n}> {}\n\nexport class PortAllocator extends Context.Tag(\"PortAllocator\")<\n PortAllocator,\n {\n pickAvailable: (\n preferred: number,\n budget?: PortBudget,\n ) => Effect.Effect<number, PortAllocationError>;\n }\n>() {}\n\nexport function detectLocalPackages(\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n): string[] {\n const packages: string[] = [];\n const configDir = getProjectRoot();\n\n const uiLocalPath =\n runtimeConfig?.ui.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.ui.development, configDir);\n if (uiLocalPath && existsSync(join(uiLocalPath, \"package.json\"))) {\n packages.push(\"ui\");\n }\n\n const apiLocalPath =\n runtimeConfig?.api.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.api.development, configDir);\n if (apiLocalPath && existsSync(join(apiLocalPath, \"package.json\"))) {\n packages.push(\"api\");\n }\n\n const hostLocalPath =\n runtimeConfig?.host?.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.host.development, configDir);\n if (hostLocalPath && existsSync(join(hostLocalPath, \"package.json\"))) {\n packages.push(\"host\");\n } else if (existsSync(join(configDir, \"host\", \"package.json\"))) {\n packages.push(\"host\");\n }\n\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig?.plugins ?? {})) {\n if (pluginConfig.localPath && existsSync(join(pluginConfig.localPath, \"package.json\"))) {\n packages.push(`plugin:${pluginId}`);\n }\n if (pluginConfig.ui?.localPath && existsSync(join(pluginConfig.ui.localPath, \"package.json\"))) {\n packages.push(`plugin-ui:${pluginId}`);\n }\n }\n\n const authLocalPath =\n runtimeConfig?.auth?.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.auth?.development, configDir);\n if (authLocalPath && existsSync(join(authLocalPath, \"package.json\"))) {\n packages.push(\"auth\");\n }\n\n return packages;\n}\n\nexport async function buildRuntimeConfig(\n bosConfig: BosConfig,\n options: {\n hostSource?: \"local\" | \"remote\";\n uiSource?: \"local\" | \"remote\";\n apiSource?: \"local\" | \"remote\";\n authSource?: \"local\" | \"remote\";\n proxy?: string;\n env?: \"development\" | \"production\";\n plugins?: Record<string, RuntimePluginConfig>;\n },\n): Promise<RuntimeConfig> {\n return configBuildRuntimeConfig(bosConfig, getProjectRoot(), options.env ?? \"development\", {\n hostSource: options.hostSource,\n uiSource: options.uiSource,\n apiSource: options.apiSource,\n authSource: options.authSource,\n proxy: options.proxy,\n plugins: options.plugins,\n });\n}\n\nfunction probePortBindable(port: number): Effect.Effect<boolean> {\n return Effect.async<boolean>((resume) => {\n const server = createServer();\n\n server.once(\"listening\", () => {\n server.close(() => {\n resume(Effect.succeed(true));\n });\n });\n\n server.once(\"error\", () => {\n server.removeAllListeners();\n // EADDRINUSE, EACCES, or any other bind error → not available\n resume(Effect.succeed(false));\n });\n\n server.listen(port, \"127.0.0.1\");\n\n const timer = setTimeout(() => {\n server.removeAllListeners();\n try {\n server.close();\n } catch {\n // ignore\n }\n resume(Effect.succeed(false));\n }, PROBE_TIMEOUT_MS);\n\n server.once(\"listening\", () => clearTimeout(timer));\n server.once(\"error\", () => clearTimeout(timer));\n });\n}\n\nfunction pickAvailablePort(\n preferred: number,\n usedPorts: Set<number>,\n budget?: PortBudget,\n): Effect.Effect<number, PortAllocationError> {\n return Effect.gen(function* () {\n const within = (candidate: number): boolean =>\n !budget || (candidate >= budget.min && candidate <= budget.max);\n\n let port = preferred;\n if (!within(port)) {\n port = budget ? budget.min : port;\n }\n\n const ceiling = budget ? budget.max + 1 : Number.MAX_SAFE_INTEGER;\n let steps = 0;\n\n const fail = () =>\n Effect.fail(\n new PortAllocationError({\n preferred,\n budget,\n cause: budget\n ? `No free port in budget [${budget.min}, ${budget.max}] starting from ${preferred}`\n : `No free port found starting from ${preferred} within ${MAX_PORT_SCAN_STEPS} steps`,\n }),\n );\n\n while (true) {\n if (port >= ceiling || steps > MAX_PORT_SCAN_STEPS) {\n yield* fail();\n }\n\n const candidates: number[] = [];\n for (let i = 0; i < PARALLEL_PROBE_WINDOW && port + i < ceiling; i++) {\n const candidate = port + i;\n if (!usedPorts.has(candidate)) {\n candidates.push(candidate);\n }\n }\n\n if (candidates.length === 0) {\n port += PARALLEL_PROBE_WINDOW;\n steps += PARALLEL_PROBE_WINDOW;\n continue;\n }\n\n const results = yield* Effect.forEach(\n candidates,\n (c) => probePortBindable(c).pipe(Effect.map((free) => ({ port: c, free }))),\n { concurrency: \"unbounded\" },\n );\n\n const firstFree = results.find((r) => r.free);\n if (firstFree) {\n usedPorts.add(firstFree.port);\n return firstFree.port;\n }\n\n port += PARALLEL_PROBE_WINDOW;\n steps += PARALLEL_PROBE_WINDOW;\n }\n });\n}\n\nexport const PortAllocatorLive: Layer.Layer<PortAllocator> = Layer.sync(PortAllocator, () => {\n const usedPorts = claimedPorts();\n return {\n pickAvailable: (preferred, budget) => pickAvailablePort(preferred, usedPorts, budget),\n };\n});\n\nfunction withLocalRuntimeUrl<\n T extends { url: string; entry: string; port?: number; localPath?: string },\n>(entry: T, port: number): T {\n const url = `http://localhost:${port}`;\n return {\n ...entry,\n url,\n entry: `${url}/mf-manifest.json`,\n port,\n };\n}\n\nexport interface DevPortOptions {\n hostPort?: number;\n apiPort?: number;\n uiPort?: number;\n authPort?: number;\n pluginPortStart?: number;\n ssr?: boolean;\n portBudget?: PortBudget;\n}\n\nexport interface PreparedDevRuntime {\n runtimeConfig: RuntimeConfig;\n devPorts: DevPortState;\n}\n\nexport function prepareDevelopmentRuntimeConfig(\n runtimeConfig: RuntimeConfig,\n options?: DevPortOptions,\n): Effect.Effect<PreparedDevRuntime, PortAllocationError, PortAllocator> {\n return Effect.gen(function* () {\n const allocator = yield* PortAllocator;\n const budget = options?.portBudget;\n\n const pickedHostPort = yield* allocator.pickAvailable(\n options?.hostPort ?? DEFAULT_HOST_PORT,\n budget,\n );\n\n const hostIsLocal = runtimeConfig.host.source === \"local\";\n const next: RuntimeConfig = {\n ...runtimeConfig,\n host: hostIsLocal\n ? {\n ...runtimeConfig.host,\n url: `http://localhost:${pickedHostPort}`,\n port: pickedHostPort,\n }\n : { ...runtimeConfig.host },\n ui: { ...runtimeConfig.ui },\n api: { ...runtimeConfig.api },\n auth: runtimeConfig.auth ? { ...runtimeConfig.auth } : undefined,\n plugins: runtimeConfig.plugins ? { ...runtimeConfig.plugins } : undefined,\n };\n\n const devPorts: DevPortState = {\n host: hostIsLocal ? pickedHostPort : undefined,\n api: undefined,\n ui: undefined,\n auth: undefined,\n pluginPortStart: undefined,\n };\n\n if (next.api.source === \"local\" && next.api.localPath) {\n const apiPort = yield* allocator.pickAvailable(\n options?.apiPort ?? next.api.port ?? DEFAULT_API_PORT,\n budget,\n );\n next.api = withLocalRuntimeUrl(next.api, apiPort);\n devPorts.api = apiPort;\n }\n\n if (next.auth?.source === \"local\" && next.auth.localPath) {\n const authPort = yield* allocator.pickAvailable(\n options?.authPort ?? next.auth.port ?? DEFAULT_AUTH_PORT,\n budget,\n );\n next.auth = withLocalRuntimeUrl(next.auth, authPort);\n devPorts.auth = authPort;\n }\n\n if (next.ui.source === \"local\" && next.ui.localPath) {\n const uiPort = yield* allocator.pickAvailable(\n options?.uiPort ?? next.ui.port ?? DEFAULT_UI_PORT,\n budget,\n );\n next.ui = withLocalRuntimeUrl(next.ui, uiPort);\n devPorts.ui = uiPort;\n if (options?.ssr) {\n const ssrPort = yield* allocator.pickAvailable(uiPort + 1, budget);\n next.ui.ssrUrl = `http://localhost:${ssrPort}`;\n } else {\n next.ui.ssrUrl = undefined;\n }\n }\n\n if (next.plugins) {\n const entries = Object.entries(next.plugins).sort(([a], [b]) => a.localeCompare(b));\n let pluginBasePort = options?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let firstLocalPluginPort: number | undefined;\n\n for (const [pluginId, plugin] of entries) {\n if (plugin.source === \"local\" && plugin.localPath) {\n const pluginPort = yield* allocator.pickAvailable(plugin.port ?? pluginBasePort, budget);\n next.plugins[pluginId] = withLocalRuntimeUrl(plugin, pluginPort);\n if (firstLocalPluginPort === undefined) firstLocalPluginPort = pluginPort;\n pluginBasePort = pluginPort + 1;\n }\n\n if (plugin.ui?.source === \"local\" && plugin.ui.localPath) {\n const pluginUiPort = yield* allocator.pickAvailable(\n plugin.ui.port ?? pluginBasePort,\n budget,\n );\n next.plugins[pluginId] = {\n ...next.plugins[pluginId]!,\n ui: withLocalRuntimeUrl(plugin.ui, pluginUiPort),\n };\n if (firstLocalPluginPort === undefined) firstLocalPluginPort = pluginUiPort;\n pluginBasePort = pluginUiPort + 1;\n }\n }\n\n devPorts.pluginPortStart = firstLocalPluginPort;\n }\n\n return { runtimeConfig: next, devPorts };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app.cjs","names":["Data","Context","resolveLocalDevelopmentPath","existsSync","join","Effect","createServer","Layer","claimedPorts"],"sources":["../src/app.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { createServer } from \"node:net\";\nimport { join } from \"node:path\";\nimport { Context, Data, Effect, Layer } from \"effect\";\nimport { resolveLocalDevelopmentPath } from \"./config\";\nimport { claimedPorts } from \"./process-registry\";\nimport type { AppOrchestrator } from \"./service-descriptor\";\nimport type { BosConfig, RuntimeConfig } from \"./types\";\n\nexport type { AppOrchestrator };\n\nconst PROBE_TIMEOUT_MS = 250;\nconst MAX_PORT_SCAN_STEPS = 1000;\nconst PARALLEL_PROBE_WINDOW = 8;\nconst BLOCK_STEP = 100;\n\nexport type PortBudget = { min: number; max: number };\n\nexport class PortAllocationError extends Data.TaggedError(\"PortAllocationError\")<{\n preferred: number;\n budget?: PortBudget;\n cause?: unknown;\n}> {}\n\nexport interface PortBlockEntry {\n key: string;\n preferred: number;\n pinned: boolean;\n}\n\nexport interface PortBlockRequest {\n base: number;\n step?: number;\n entries: PortBlockEntry[];\n}\n\nexport interface PortBlockAllocation {\n base: number;\n ports: Record<string, number>;\n conflicts: Array<{ key: string; port: number; claimed: boolean }>;\n}\n\nexport class PortAllocator extends Context.Service<\n PortAllocator,\n {\n pickAvailable: (\n preferred: number,\n budget?: PortBudget,\n ) => Effect.Effect<number, PortAllocationError>;\n acquireBlock: (\n request: PortBlockRequest,\n ) => Effect.Effect<PortBlockAllocation, PortAllocationError>;\n }\n>()(\"PortAllocator\") {}\n\nexport interface LocalPackage {\n readonly name: string;\n readonly dir: string;\n}\n\nexport function detectLocalPackages(\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n root: string = process.cwd(),\n): LocalPackage[] {\n const packages: LocalPackage[] = [];\n const configDir = root;\n\n const uiLocalPath =\n runtimeConfig?.ui.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.ui.development, configDir);\n if (uiLocalPath && existsSync(join(uiLocalPath, \"package.json\"))) {\n packages.push({ name: \"ui\", dir: uiLocalPath });\n }\n\n const apiLocalPath =\n runtimeConfig?.api.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.api.development, configDir);\n if (apiLocalPath && existsSync(join(apiLocalPath, \"package.json\"))) {\n packages.push({ name: \"api\", dir: apiLocalPath });\n }\n\n const hostLocalPath =\n runtimeConfig?.host?.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.host.development, configDir);\n if (hostLocalPath && existsSync(join(hostLocalPath, \"package.json\"))) {\n packages.push({ name: \"host\", dir: hostLocalPath });\n } else if (existsSync(join(configDir, \"host\", \"package.json\"))) {\n packages.push({ name: \"host\", dir: join(configDir, \"host\") });\n }\n\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig?.plugins ?? {})) {\n if (pluginConfig.localPath && existsSync(join(pluginConfig.localPath, \"package.json\"))) {\n packages.push({ name: `plugin:${pluginId}`, dir: pluginConfig.localPath });\n }\n if (pluginConfig.ui?.localPath && existsSync(join(pluginConfig.ui.localPath, \"package.json\"))) {\n packages.push({ name: `plugin-ui:${pluginId}`, dir: pluginConfig.ui.localPath });\n }\n }\n\n const authLocalPath =\n runtimeConfig?.auth?.localPath ??\n resolveLocalDevelopmentPath(bosConfig?.app.auth?.development, configDir);\n if (authLocalPath && existsSync(join(authLocalPath, \"package.json\"))) {\n packages.push({ name: \"auth\", dir: authLocalPath });\n }\n\n return packages;\n}\n\nconst scheduleTimeout = (ms: number, fn: () => void): ReturnType<typeof setTimeout> =>\n setTimeout(fn, ms);\n\nexport function probePortBindable(port: number): Effect.Effect<boolean> {\n return Effect.callback<boolean>((resume) => {\n const server = createServer();\n\n server.once(\"listening\", () => {\n server.close(() => {\n resume(Effect.succeed(true));\n });\n });\n\n server.once(\"error\", () => {\n server.removeAllListeners();\n // EADDRINUSE, EACCES, or any other bind error → not available\n resume(Effect.succeed(false));\n });\n\n server.listen(port, \"127.0.0.1\");\n\n const timer = scheduleTimeout(PROBE_TIMEOUT_MS, () => {\n server.removeAllListeners();\n try {\n server.close();\n } catch {\n // ignore\n }\n resume(Effect.succeed(false));\n });\n\n server.once(\"listening\", () => clearTimeout(timer));\n server.once(\"error\", () => clearTimeout(timer));\n });\n}\n\nfunction pickAvailablePort(\n preferred: number,\n usedPorts: Set<number>,\n budget?: PortBudget,\n): Effect.Effect<number, PortAllocationError> {\n return Effect.gen(function* () {\n const within = (candidate: number): boolean =>\n !budget || (candidate >= budget.min && candidate <= budget.max);\n\n let port = preferred;\n if (!within(port)) {\n port = budget ? budget.min : port;\n }\n\n const ceiling = budget ? budget.max + 1 : Number.MAX_SAFE_INTEGER;\n let steps = 0;\n\n const fail = () =>\n Effect.fail(\n new PortAllocationError({\n preferred,\n budget,\n cause: budget\n ? `No free port in budget [${budget.min}, ${budget.max}] starting from ${preferred}`\n : `No free port found starting from ${preferred} within ${MAX_PORT_SCAN_STEPS} steps`,\n }),\n );\n\n while (true) {\n if (port >= ceiling || steps > MAX_PORT_SCAN_STEPS) {\n return yield* fail();\n }\n\n const candidates: number[] = [];\n for (let i = 0; i < PARALLEL_PROBE_WINDOW && port + i < ceiling; i++) {\n const candidate = port + i;\n if (!usedPorts.has(candidate)) {\n candidates.push(candidate);\n }\n }\n\n if (candidates.length === 0) {\n port += PARALLEL_PROBE_WINDOW;\n steps += PARALLEL_PROBE_WINDOW;\n continue;\n }\n\n const results = yield* Effect.forEach(\n candidates,\n (c) => probePortBindable(c).pipe(Effect.map((free) => ({ port: c, free }))),\n { concurrency: \"unbounded\" },\n );\n\n const firstFree = results.find((r) => r.free);\n if (firstFree) {\n usedPorts.add(firstFree.port);\n return firstFree.port;\n }\n\n port += PARALLEL_PROBE_WINDOW;\n steps += PARALLEL_PROBE_WINDOW;\n }\n });\n}\n\nexport const PortAllocatorLive: Layer.Layer<PortAllocator> = Layer.sync(PortAllocator, () => {\n const usedPorts = claimedPorts();\n return {\n pickAvailable: (preferred, budget) => pickAvailablePort(preferred, usedPorts, budget),\n acquireBlock: (request) => acquireBlockPort(request, usedPorts),\n };\n});\n\n// acquireBlockPort validates and acquires a whole port block atomically: every\n// entry is probed before any is yielded; on any conflict the entire block\n// steps (base += step) and retries. Pinned entries (explicit CLI flags) are\n// absolute — an actual listener on one fails loudly instead of silently\n// drifting a port the user named; a registry claim without a listener is\n// stale (PID reuse across container restarts) and never wedges allocation.\nfunction acquireBlockPort(\n request: PortBlockRequest,\n usedPorts: Set<number>,\n): Effect.Effect<PortBlockAllocation, PortAllocationError> {\n const step = request.step ?? BLOCK_STEP;\n const fail = (cause: string) =>\n Effect.fail(\n new PortAllocationError({\n preferred: request.base,\n cause,\n }),\n );\n\n return Effect.gen(function* () {\n let base = request.base;\n let steps = 0;\n let firstConflicts: PortBlockAllocation[\"conflicts\"] = [];\n while (steps <= MAX_PORT_SCAN_STEPS) {\n const shift = base - request.base;\n const candidates = request.entries.map((entry) => ({\n ...entry,\n port: entry.pinned ? entry.preferred : entry.preferred + shift,\n }));\n\n // Pinned entries are absolute (ADR 0012): an actual listener on one\n // fails loudly instead of drifting a port the user named. Verified\n // against the real socket every iteration — a registry claim without\n // a listener is stale (PID reuse across container restarts) and must\n // never wedge a pinned allocation.\n let pinnedHeldByListener: (typeof candidates)[number] | undefined;\n for (const candidate of candidates.filter((c) => c.pinned)) {\n const bindable = yield* probePortBindable(candidate.port);\n if (!bindable) {\n pinnedHeldByListener = candidate;\n break;\n }\n usedPorts.delete(candidate.port);\n }\n if (pinnedHeldByListener) {\n return yield* fail(\n `explicitly-requested port ${pinnedHeldByListener.port} (${pinnedHeldByListener.key}) is occupied by a listener`,\n );\n }\n\n const unpinned = candidates.filter((c) => !c.pinned);\n const claimConflicts = unpinned\n .filter((c) => usedPorts.has(c.port))\n .map((c) => ({ key: c.key, port: c.port, claimed: true }));\n if (shift === 0) {\n firstConflicts = claimConflicts;\n }\n\n if (claimConflicts.length === 0) {\n const results = yield* Effect.forEach(\n unpinned,\n (c) => probePortBindable(c.port).pipe(Effect.map((free) => ({ ...c, free }))),\n { concurrency: \"unbounded\" },\n );\n const busy = results.filter((r) => !r.free);\n if (shift === 0) {\n firstConflicts = busy.map((b) => ({ key: b.key, port: b.port, claimed: false }));\n }\n if (busy.length === 0) {\n for (const candidate of candidates) usedPorts.add(candidate.port);\n return {\n base,\n ports: Object.fromEntries(candidates.map((c) => [c.key, c.port])),\n conflicts: firstConflicts,\n };\n }\n }\n\n base += step;\n steps += 1;\n }\n return yield* fail(\n `no free port block within ${MAX_PORT_SCAN_STEPS} steps of base ${request.base} (step ${step})`,\n );\n });\n}\n"],"mappings":";;;;;;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;AAC5B,MAAM,wBAAwB;AAC9B,MAAM,aAAa;AAInB,IAAa,sBAAb,cAAyCA,YAAK,YAAY,qBAAqB,CAAC,CAI7E,CAAC;AAoBJ,IAAa,gBAAb,cAAmCC,eAAQ,QAWzC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAOtB,SAAgB,oBACd,WACA,eACA,OAAe,QAAQ,IAAI,GACX;CAChB,MAAM,WAA2B,CAAC;CAClC,MAAM,YAAY;CAElB,MAAM,cACJ,eAAe,GAAG,aAClBC,2CAA4B,WAAW,IAAI,GAAG,aAAa,SAAS;CACtE,IAAI,mBAAeC,wBAAWC,gBAAK,aAAa,cAAc,CAAC,GAC7D,SAAS,KAAK;EAAE,MAAM;EAAM,KAAK;CAAY,CAAC;CAGhD,MAAM,eACJ,eAAe,IAAI,aACnBF,2CAA4B,WAAW,IAAI,IAAI,aAAa,SAAS;CACvE,IAAI,oBAAgBC,wBAAWC,gBAAK,cAAc,cAAc,CAAC,GAC/D,SAAS,KAAK;EAAE,MAAM;EAAO,KAAK;CAAa,CAAC;CAGlD,MAAM,gBACJ,eAAe,MAAM,aACrBF,2CAA4B,WAAW,IAAI,KAAK,aAAa,SAAS;CACxE,IAAI,qBAAiBC,wBAAWC,gBAAK,eAAe,cAAc,CAAC,GACjE,SAAS,KAAK;EAAE,MAAM;EAAQ,KAAK;CAAc,CAAC;MAC7C,QAAID,wBAAWC,gBAAK,WAAW,QAAQ,cAAc,CAAC,GAC3D,SAAS,KAAK;EAAE,MAAM;EAAQ,SAAKA,gBAAK,WAAW,MAAM;CAAE,CAAC;CAG9D,KAAK,MAAM,CAAC,UAAU,iBAAiB,OAAO,QAAQ,eAAe,WAAW,CAAC,CAAC,GAAG;EACnF,IAAI,aAAa,iBAAaD,wBAAWC,gBAAK,aAAa,WAAW,cAAc,CAAC,GACnF,SAAS,KAAK;GAAE,MAAM,UAAU;GAAY,KAAK,aAAa;EAAU,CAAC;EAE3E,IAAI,aAAa,IAAI,iBAAaD,wBAAWC,gBAAK,aAAa,GAAG,WAAW,cAAc,CAAC,GAC1F,SAAS,KAAK;GAAE,MAAM,aAAa;GAAY,KAAK,aAAa,GAAG;EAAU,CAAC;CAEnF;CAEA,MAAM,gBACJ,eAAe,MAAM,aACrBF,2CAA4B,WAAW,IAAI,MAAM,aAAa,SAAS;CACzE,IAAI,qBAAiBC,wBAAWC,gBAAK,eAAe,cAAc,CAAC,GACjE,SAAS,KAAK;EAAE,MAAM;EAAQ,KAAK;CAAc,CAAC;CAGpD,OAAO;AACT;AAEA,MAAM,mBAAmB,IAAY,OACnC,WAAW,IAAI,EAAE;AAEnB,SAAgB,kBAAkB,MAAsC;CACtE,OAAOC,cAAO,UAAmB,WAAW;EAC1C,MAAM,aAASC,uBAAa;EAE5B,OAAO,KAAK,mBAAmB;GAC7B,OAAO,YAAY;IACjB,OAAOD,cAAO,QAAQ,IAAI,CAAC;GAC7B,CAAC;EACH,CAAC;EAED,OAAO,KAAK,eAAe;GACzB,OAAO,mBAAmB;GAE1B,OAAOA,cAAO,QAAQ,KAAK,CAAC;EAC9B,CAAC;EAED,OAAO,OAAO,MAAM,WAAW;EAE/B,MAAM,QAAQ,gBAAgB,wBAAwB;GACpD,OAAO,mBAAmB;GAC1B,IAAI;IACF,OAAO,MAAM;GACf,QAAQ,CAER;GACA,OAAOA,cAAO,QAAQ,KAAK,CAAC;EAC9B,CAAC;EAED,OAAO,KAAK,mBAAmB,aAAa,KAAK,CAAC;EAClD,OAAO,KAAK,eAAe,aAAa,KAAK,CAAC;CAChD,CAAC;AACH;AAEA,SAAS,kBACP,WACA,WACA,QAC4C;CAC5C,OAAOA,cAAO,IAAI,aAAa;EAC7B,MAAM,UAAU,cACd,CAAC,UAAW,aAAa,OAAO,OAAO,aAAa,OAAO;EAE7D,IAAI,OAAO;EACX,IAAI,CAAC,OAAO,IAAI,GACd,OAAO,SAAS,OAAO,MAAM;EAG/B,MAAM,UAAU,SAAS,OAAO,MAAM,IAAI,OAAO;EACjD,IAAI,QAAQ;EAEZ,MAAM,aACJA,cAAO,KACL,IAAI,oBAAoB;GACtB;GACA;GACA,OAAO,SACH,2BAA2B,OAAO,IAAI,IAAI,OAAO,IAAI,kBAAkB,cACvE,oCAAoC,UAAU,UAAU,oBAAoB;EAClF,CAAC,CACH;EAEF,OAAO,MAAM;GACX,IAAI,QAAQ,WAAW,QAAQ,qBAC7B,OAAO,OAAO,KAAK;GAGrB,MAAM,aAAuB,CAAC;GAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,yBAAyB,OAAO,IAAI,SAAS,KAAK;IACpE,MAAM,YAAY,OAAO;IACzB,IAAI,CAAC,UAAU,IAAI,SAAS,GAC1B,WAAW,KAAK,SAAS;GAE7B;GAEA,IAAI,WAAW,WAAW,GAAG;IAC3B,QAAQ;IACR,SAAS;IACT;GACF;GAQA,MAAM,aAAY,OANKA,cAAO,QAC5B,aACC,MAAM,kBAAkB,CAAC,CAAC,CAAC,KAAKA,cAAO,KAAK,UAAU;IAAE,MAAM;IAAG;GAAK,EAAE,CAAC,GAC1E,EAAE,aAAa,YAAY,CAC7B,EAEyB,CAAC,MAAM,MAAM,EAAE,IAAI;GAC5C,IAAI,WAAW;IACb,UAAU,IAAI,UAAU,IAAI;IAC5B,OAAO,UAAU;GACnB;GAEA,QAAQ;GACR,SAAS;EACX;CACF,CAAC;AACH;AAEA,MAAa,oBAAgDE,aAAM,KAAK,qBAAqB;CAC3F,MAAM,YAAYC,sCAAa;CAC/B,OAAO;EACL,gBAAgB,WAAW,WAAW,kBAAkB,WAAW,WAAW,MAAM;EACpF,eAAe,YAAY,iBAAiB,SAAS,SAAS;CAChE;AACF,CAAC;AAQD,SAAS,iBACP,SACA,WACyD;CACzD,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,QAAQ,UACZH,cAAO,KACL,IAAI,oBAAoB;EACtB,WAAW,QAAQ;EACnB;CACF,CAAC,CACH;CAEF,OAAOA,cAAO,IAAI,aAAa;EAC7B,IAAI,OAAO,QAAQ;EACnB,IAAI,QAAQ;EACZ,IAAI,iBAAmD,CAAC;EACxD,OAAO,SAAS,qBAAqB;GACnC,MAAM,QAAQ,OAAO,QAAQ;GAC7B,MAAM,aAAa,QAAQ,QAAQ,KAAK,WAAW;IACjD,GAAG;IACH,MAAM,MAAM,SAAS,MAAM,YAAY,MAAM,YAAY;GAC3D,EAAE;GAOF,IAAI;GACJ,KAAK,MAAM,aAAa,WAAW,QAAQ,MAAM,EAAE,MAAM,GAAG;IAE1D,IAAI,EAAC,OADmB,kBAAkB,UAAU,IAAI,IACzC;KACb,uBAAuB;KACvB;IACF;IACA,UAAU,OAAO,UAAU,IAAI;GACjC;GACA,IAAI,sBACF,OAAO,OAAO,KACZ,6BAA6B,qBAAqB,KAAK,IAAI,qBAAqB,IAAI,4BACtF;GAGF,MAAM,WAAW,WAAW,QAAQ,MAAM,CAAC,EAAE,MAAM;GACnD,MAAM,iBAAiB,SACpB,QAAQ,MAAM,UAAU,IAAI,EAAE,IAAI,CAAC,CAAC,CACpC,KAAK,OAAO;IAAE,KAAK,EAAE;IAAK,MAAM,EAAE;IAAM,SAAS;GAAK,EAAE;GAC3D,IAAI,UAAU,GACZ,iBAAiB;GAGnB,IAAI,eAAe,WAAW,GAAG;IAM/B,MAAM,QAAO,OALUA,cAAO,QAC5B,WACC,MAAM,kBAAkB,EAAE,IAAI,CAAC,CAAC,KAAKA,cAAO,KAAK,UAAU;KAAE,GAAG;KAAG;IAAK,EAAE,CAAC,GAC5E,EAAE,aAAa,YAAY,CAC7B,EACoB,CAAC,QAAQ,MAAM,CAAC,EAAE,IAAI;IAC1C,IAAI,UAAU,GACZ,iBAAiB,KAAK,KAAK,OAAO;KAAE,KAAK,EAAE;KAAK,MAAM,EAAE;KAAM,SAAS;IAAM,EAAE;IAEjF,IAAI,KAAK,WAAW,GAAG;KACrB,KAAK,MAAM,aAAa,YAAY,UAAU,IAAI,UAAU,IAAI;KAChE,OAAO;MACL;MACA,OAAO,OAAO,YAAY,WAAW,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;MAChE,WAAW;KACb;IACF;GACF;GAEA,QAAQ;GACR,SAAS;EACX;EACA,OAAO,OAAO,KACZ,6BAA6B,oBAAoB,iBAAiB,QAAQ,KAAK,SAAS,KAAK,EAC/F;CACF,CAAC;AACH"}
package/dist/app.d.cts ADDED
@@ -0,0 +1,3 @@
1
+ import "./types.cjs";
2
+ import { AppOrchestrator } from "./service-descriptor.cjs";
3
+ import { Context, Effect, Layer } from "effect";
package/dist/app.d.mts ADDED
@@ -0,0 +1,3 @@
1
+ import "./types.mjs";
2
+ import { AppOrchestrator } from "./service-descriptor.mjs";
3
+ import { Context, Effect, Layer } from "effect";