@voltro/cli 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/THIRD-PARTY-NOTICES.md +88 -2
  3. package/dist/{apiBuild-D22_EpoR.js → apiBuild-BESZbTjA.js} +4 -4
  4. package/dist/apiBuild-C8d74T6g.js +2 -0
  5. package/dist/bin.js +3 -3
  6. package/dist/checkCommand-BPAtyWs8.js +2420 -0
  7. package/dist/checkCommand-DBvZvCh1.js +2 -0
  8. package/dist/cliRuntime-Oh517vCV.js +96 -0
  9. package/dist/{commands-jBX8no1I.js → commands-82BDEktg.js} +6476 -7672
  10. package/dist/dbCommand-CaIVTp-a.js +2 -0
  11. package/dist/{dbCommand-uuNCrFAb.js → dbCommand-bCBbk6tz.js} +3 -3
  12. package/dist/{dev-DcbIJrWg.js → dev-Cg4BKLmi.js} +3034 -2619
  13. package/dist/dev-DeEJj5T4.js +3 -0
  14. package/dist/fileConventions-Cof68_BL.js +33 -0
  15. package/dist/{frameworkTableAssembly-BwHU9Euq.js → frameworkTableAssembly-4Db40V23.js} +2 -2
  16. package/dist/frameworkTableAssembly-BTNirAAk.js +2 -0
  17. package/dist/index.js +1 -1
  18. package/dist/{inspect-CUCCzw2I.js → inspect-BMvQpwqy.js} +211 -190
  19. package/dist/inspect-DHeaMZak.js +2 -0
  20. package/dist/{inspectMetrics-BU90mvJN.js → inspectMetrics-DHYygE4s.js} +999 -961
  21. package/dist/{manifestBuild-BnzAxp2O.js → manifestBuild-C4R1EdHn.js} +1 -1
  22. package/dist/manifestBuild-Ck_90gZy.js +2 -0
  23. package/dist/sdkgen-CW5NbYF0.js +582 -0
  24. package/dist/{seedRunner-D6eu-u5U.js → seedRunner-Bqxgp7HZ.js} +60 -59
  25. package/dist/serveCommand-BXl8mhZD.js +1489 -0
  26. package/dist/serveEntry.js +3 -3
  27. package/dist/{start-BGXIf6zT.js → start-CsCIaW4-.js} +282 -269
  28. package/dist/startEntry.js +2 -2
  29. package/package.json +17 -17
  30. package/templates/AGENTS.md +2 -1
  31. package/templates/agent-docs/_index.md +2 -1
  32. package/templates/agent-docs/_manifest.json +10 -1
  33. package/templates/agent-docs/ai.md +135 -0
  34. package/templates/agent-docs/cli.md +124 -6
  35. package/templates/agent-docs/configuration.md +32 -0
  36. package/templates/agent-docs/data.md +282 -0
  37. package/templates/agent-docs/database/migrations.md +47 -0
  38. package/templates/agent-docs/database/misc.md +57 -0
  39. package/templates/agent-docs/database/schema.md +3 -1
  40. package/templates/agent-docs/deployment.md +56 -0
  41. package/templates/agent-docs/internationalization.md +161 -1
  42. package/templates/agent-docs/local-first-mobile.md +414 -0
  43. package/templates/agent-docs/routing.md +93 -2
  44. package/templates/agent-docs/schema-driven-ui.md +12 -0
  45. package/templates/agent-docs/templates/apibackends.md +1 -1
  46. package/templates/agent-docs/testing.md +42 -0
  47. package/templates/agent-docs/whats-new.md +165 -131
  48. package/templates/agent-docs/workflows.md +11 -0
  49. package/templates/apps/api-ai/package.json +7 -7
  50. package/templates/apps/api-auth/package.json +8 -8
  51. package/templates/apps/api-backend/package.json +7 -7
  52. package/templates/apps/api-backend-deactivation/package.json +7 -7
  53. package/templates/apps/api-backend-mail/package.json +8 -8
  54. package/templates/apps/api-backend-mariadb/package.json +9 -9
  55. package/templates/apps/api-backend-sqlite/.env.example +19 -0
  56. package/templates/apps/api-backend-sqlite/README.md +38 -0
  57. package/templates/apps/api-backend-sqlite/app.config.ts +35 -0
  58. package/templates/apps/api-backend-sqlite/database/schema.ts +54 -0
  59. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.server.ts +19 -0
  60. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +37 -0
  61. package/templates/apps/api-backend-sqlite/package.json +30 -0
  62. package/templates/apps/api-backend-sqlite/queries/notes.query.server.ts +14 -0
  63. package/templates/apps/api-backend-sqlite/queries/notes.query.ts +20 -0
  64. package/templates/apps/api-backend-sqlite/template.json +6 -0
  65. package/templates/apps/api-backend-sqlite/tests/notes.create.test.ts +50 -0
  66. package/templates/apps/api-backend-sqlite/tsconfig.json +5 -0
  67. package/templates/apps/api-backend-storage/package.json +8 -8
  68. package/templates/apps/api-cms/README.md +104 -0
  69. package/templates/apps/api-cms/actions/content.get.action.server.ts +27 -0
  70. package/templates/apps/api-cms/actions/content.get.action.ts +19 -0
  71. package/templates/apps/api-cms/actions/content.types.action.server.ts +26 -0
  72. package/templates/apps/api-cms/actions/content.types.action.ts +40 -0
  73. package/templates/apps/api-cms/actions/me.action.server.ts +18 -0
  74. package/templates/apps/api-cms/actions/me.action.ts +16 -0
  75. package/templates/apps/api-cms/app.config.ts +61 -0
  76. package/templates/apps/api-cms/content/blogPost.contentType.ts +39 -0
  77. package/templates/apps/api-cms/content/index.ts +18 -0
  78. package/templates/apps/api-cms/content/page.contentType.ts +24 -0
  79. package/templates/apps/api-cms/database/schema.ts +64 -0
  80. package/templates/apps/api-cms/mutations/content.publish.mutation.server.ts +19 -0
  81. package/templates/apps/api-cms/mutations/content.publish.mutation.ts +15 -0
  82. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.server.ts +36 -0
  83. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +32 -0
  84. package/templates/apps/api-cms/mutations/content.unpublish.mutation.server.ts +19 -0
  85. package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +11 -0
  86. package/templates/apps/api-cms/package.json +32 -0
  87. package/templates/apps/api-cms/queries/content.list.query.server.ts +0 -0
  88. package/templates/apps/api-cms/queries/content.list.query.ts +27 -0
  89. package/templates/apps/api-cms/template.json +6 -0
  90. package/templates/apps/api-cms/tests/content.descriptors.test.ts +64 -0
  91. package/templates/apps/api-cms/tests/content.write.test.ts +85 -0
  92. package/templates/apps/api-cms/tsconfig.json +5 -0
  93. package/templates/apps/api-data-advanced/package.json +8 -8
  94. package/templates/apps/api-durable/package.json +8 -8
  95. package/templates/apps/api-feature-flags/package.json +9 -9
  96. package/templates/apps/api-governance/package.json +8 -8
  97. package/templates/apps/api-kv/package.json +8 -8
  98. package/templates/apps/api-moderation/package.json +8 -8
  99. package/templates/apps/api-observability/package.json +8 -8
  100. package/templates/apps/api-ratelimit/package.json +8 -8
  101. package/templates/apps/api-rbac/package.json +8 -8
  102. package/templates/apps/api-rest/package.json +7 -7
  103. package/templates/apps/api-saas/package.json +11 -11
  104. package/templates/apps/api-saas-starter/README.md +103 -0
  105. package/templates/apps/api-saas-starter/actions/me.action.server.ts +18 -0
  106. package/templates/apps/api-saas-starter/actions/me.action.ts +20 -0
  107. package/templates/apps/api-saas-starter/app.config.ts +87 -0
  108. package/templates/apps/api-saas-starter/database/schema.ts +57 -0
  109. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.server.ts +26 -0
  110. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +18 -0
  111. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.server.ts +29 -0
  112. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +18 -0
  113. package/templates/apps/api-saas-starter/package.json +32 -0
  114. package/templates/apps/api-saas-starter/queries/invites.list.query.server.ts +14 -0
  115. package/templates/apps/api-saas-starter/queries/invites.list.query.ts +17 -0
  116. package/templates/apps/api-saas-starter/queries/projects.list.query.server.ts +14 -0
  117. package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -0
  118. package/templates/apps/api-saas-starter/template.json +6 -0
  119. package/templates/apps/api-saas-starter/tests/projects.create.test.ts +62 -0
  120. package/templates/apps/api-saas-starter/tests/session.test.ts +33 -0
  121. package/templates/apps/api-saas-starter/tsconfig.json +5 -0
  122. package/templates/apps/api-search/package.json +8 -8
  123. package/templates/apps/api-status/README.md +88 -0
  124. package/templates/apps/api-status/app.config.ts +36 -0
  125. package/templates/apps/api-status/authz.ts +33 -0
  126. package/templates/apps/api-status/database/schema.ts +70 -0
  127. package/templates/apps/api-status/mutations/components.create.mutation.server.ts +19 -0
  128. package/templates/apps/api-status/mutations/components.create.mutation.ts +16 -0
  129. package/templates/apps/api-status/mutations/incidents.create.mutation.server.ts +25 -0
  130. package/templates/apps/api-status/mutations/incidents.create.mutation.ts +22 -0
  131. package/templates/apps/api-status/mutations/incidents.resolve.mutation.server.ts +24 -0
  132. package/templates/apps/api-status/mutations/incidents.resolve.mutation.ts +19 -0
  133. package/templates/apps/api-status/mutations/incidents.update.mutation.server.ts +26 -0
  134. package/templates/apps/api-status/mutations/incidents.update.mutation.ts +21 -0
  135. package/templates/apps/api-status/package.json +30 -0
  136. package/templates/apps/api-status/queries/components.list.query.server.ts +14 -0
  137. package/templates/apps/api-status/queries/components.list.query.ts +13 -0
  138. package/templates/apps/api-status/queries/incidents.live.query.server.ts +14 -0
  139. package/templates/apps/api-status/queries/incidents.live.query.ts +20 -0
  140. package/templates/apps/api-status/queries/updates.list.query.server.ts +14 -0
  141. package/templates/apps/api-status/queries/updates.list.query.ts +17 -0
  142. package/templates/apps/api-status/template.json +6 -0
  143. package/templates/apps/api-status/tests/status.test.ts +70 -0
  144. package/templates/apps/api-status/tsconfig.json +5 -0
  145. package/templates/apps/api-versioning/package.json +8 -8
  146. package/templates/apps/api-webhooks/package.json +9 -9
  147. package/templates/apps/changelog/package.json +6 -6
  148. package/templates/apps/edge-functions/package.json +2 -2
  149. package/templates/apps/frontend-admin/package.json +8 -8
  150. package/templates/apps/frontend-app/package.json +8 -8
  151. package/templates/apps/frontend-auth/README.md +78 -0
  152. package/templates/apps/frontend-auth/app.config.ts +34 -0
  153. package/templates/apps/frontend-auth/package.json +32 -0
  154. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +35 -0
  155. package/templates/apps/frontend-auth/src/components/PasswordStrength.tsx +33 -0
  156. package/templates/apps/frontend-auth/src/config.ts +11 -0
  157. package/templates/apps/frontend-auth/src/globals.css +105 -0
  158. package/templates/apps/frontend-auth/src/globals.d.ts +6 -0
  159. package/templates/apps/frontend-auth/src/lib/auth.ts +34 -0
  160. package/templates/apps/frontend-auth/src/lib/redirect.test.ts +24 -0
  161. package/templates/apps/frontend-auth/src/lib/redirect.ts +29 -0
  162. package/templates/apps/frontend-auth/src/locales/de.ts +66 -0
  163. package/templates/apps/frontend-auth/src/locales/en.ts +76 -0
  164. package/templates/apps/frontend-auth/src/locales/index.ts +14 -0
  165. package/templates/apps/frontend-auth/src/pages/forgot/page.tsx +51 -0
  166. package/templates/apps/frontend-auth/src/pages/layout.tsx +12 -0
  167. package/templates/apps/frontend-auth/src/pages/login/page.test.tsx +53 -0
  168. package/templates/apps/frontend-auth/src/pages/login/page.tsx +67 -0
  169. package/templates/apps/frontend-auth/src/pages/logout/page.tsx +28 -0
  170. package/templates/apps/frontend-auth/src/pages/magic/page.tsx +51 -0
  171. package/templates/apps/frontend-auth/src/pages/page.tsx +26 -0
  172. package/templates/apps/frontend-auth/src/pages/reset/page.test.tsx +51 -0
  173. package/templates/apps/frontend-auth/src/pages/reset/page.tsx +63 -0
  174. package/templates/apps/frontend-auth/src/pages/signup/page.tsx +60 -0
  175. package/templates/apps/frontend-auth/src/pages/verify/page.tsx +50 -0
  176. package/templates/apps/frontend-auth/template.json +6 -0
  177. package/templates/apps/frontend-auth/tsconfig.json +5 -0
  178. package/templates/apps/frontend-blank/package.json +7 -7
  179. package/templates/apps/frontend-cms/README.md +47 -0
  180. package/templates/apps/frontend-cms/app.config.ts +37 -0
  181. package/templates/apps/frontend-cms/package.json +33 -0
  182. package/templates/apps/frontend-cms/src/config.ts +8 -0
  183. package/templates/apps/frontend-cms/src/globals.css +105 -0
  184. package/templates/apps/frontend-cms/src/globals.d.ts +6 -0
  185. package/templates/apps/frontend-cms/src/lib/api.ts +58 -0
  186. package/templates/apps/frontend-cms/src/locales/de.ts +50 -0
  187. package/templates/apps/frontend-cms/src/locales/en.ts +55 -0
  188. package/templates/apps/frontend-cms/src/locales/index.ts +14 -0
  189. package/templates/apps/frontend-cms/src/pages/(app)/error.tsx +18 -0
  190. package/templates/apps/frontend-cms/src/pages/(app)/layout.test.tsx +31 -0
  191. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +62 -0
  192. package/templates/apps/frontend-cms/src/pages/(app)/not-found.tsx +14 -0
  193. package/templates/apps/frontend-cms/src/pages/(app)/page.test.tsx +110 -0
  194. package/templates/apps/frontend-cms/src/pages/(app)/page.tsx +159 -0
  195. package/templates/apps/frontend-cms/src/pages/layout.tsx +12 -0
  196. package/templates/apps/frontend-cms/src/pages/login/page.test.tsx +58 -0
  197. package/templates/apps/frontend-cms/src/pages/login/page.tsx +93 -0
  198. package/templates/apps/frontend-cms/template.json +6 -0
  199. package/templates/apps/frontend-cms/tsconfig.json +5 -0
  200. package/templates/apps/frontend-contact/package.json +7 -7
  201. package/templates/apps/frontend-dashboard/package.json +7 -7
  202. package/templates/apps/frontend-docs/package.json +7 -7
  203. package/templates/apps/frontend-i18n/package.json +6 -6
  204. package/templates/apps/frontend-landing/package.json +7 -7
  205. package/templates/apps/frontend-portal/README.md +71 -0
  206. package/templates/apps/frontend-portal/app.config.ts +37 -0
  207. package/templates/apps/frontend-portal/package.json +32 -0
  208. package/templates/apps/frontend-portal/src/config.ts +8 -0
  209. package/templates/apps/frontend-portal/src/globals.css +93 -0
  210. package/templates/apps/frontend-portal/src/globals.d.ts +6 -0
  211. package/templates/apps/frontend-portal/src/lib/api.ts +62 -0
  212. package/templates/apps/frontend-portal/src/locales/de.ts +86 -0
  213. package/templates/apps/frontend-portal/src/locales/en.ts +93 -0
  214. package/templates/apps/frontend-portal/src/locales/index.ts +14 -0
  215. package/templates/apps/frontend-portal/src/pages/(portal)/api-keys/page.test.tsx +71 -0
  216. package/templates/apps/frontend-portal/src/pages/(portal)/api-keys/page.tsx +124 -0
  217. package/templates/apps/frontend-portal/src/pages/(portal)/billing/page.test.tsx +86 -0
  218. package/templates/apps/frontend-portal/src/pages/(portal)/billing/page.tsx +97 -0
  219. package/templates/apps/frontend-portal/src/pages/(portal)/error.tsx +19 -0
  220. package/templates/apps/frontend-portal/src/pages/(portal)/invoices/page.tsx +45 -0
  221. package/templates/apps/frontend-portal/src/pages/(portal)/layout.test.tsx +31 -0
  222. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +63 -0
  223. package/templates/apps/frontend-portal/src/pages/(portal)/not-found.tsx +15 -0
  224. package/templates/apps/frontend-portal/src/pages/(portal)/page.tsx +39 -0
  225. package/templates/apps/frontend-portal/src/pages/(portal)/profile/page.tsx +79 -0
  226. package/templates/apps/frontend-portal/src/pages/layout.tsx +12 -0
  227. package/templates/apps/frontend-portal/src/pages/login/page.test.tsx +58 -0
  228. package/templates/apps/frontend-portal/src/pages/login/page.tsx +96 -0
  229. package/templates/apps/frontend-portal/template.json +6 -0
  230. package/templates/apps/frontend-portal/tsconfig.json +5 -0
  231. package/templates/apps/frontend-saas/README.md +73 -0
  232. package/templates/apps/frontend-saas/app.config.ts +46 -0
  233. package/templates/apps/frontend-saas/package.json +32 -0
  234. package/templates/apps/frontend-saas/src/config.ts +8 -0
  235. package/templates/apps/frontend-saas/src/globals.css +85 -0
  236. package/templates/apps/frontend-saas/src/globals.d.ts +6 -0
  237. package/templates/apps/frontend-saas/src/lib/api.ts +47 -0
  238. package/templates/apps/frontend-saas/src/locales/de.ts +72 -0
  239. package/templates/apps/frontend-saas/src/locales/en.ts +81 -0
  240. package/templates/apps/frontend-saas/src/locales/index.ts +14 -0
  241. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +30 -0
  242. package/templates/apps/frontend-saas/src/pages/(marketing)/login/page.test.tsx +58 -0
  243. package/templates/apps/frontend-saas/src/pages/(marketing)/login/page.tsx +96 -0
  244. package/templates/apps/frontend-saas/src/pages/(marketing)/page.tsx +27 -0
  245. package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +72 -0
  246. package/templates/apps/frontend-saas/src/pages/dashboard/error.tsx +20 -0
  247. package/templates/apps/frontend-saas/src/pages/dashboard/layout.test.tsx +32 -0
  248. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +69 -0
  249. package/templates/apps/frontend-saas/src/pages/dashboard/not-found.tsx +17 -0
  250. package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +113 -0
  251. package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +76 -0
  252. package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +73 -0
  253. package/templates/apps/frontend-saas/src/pages/layout.tsx +12 -0
  254. package/templates/apps/frontend-saas/template.json +6 -0
  255. package/templates/apps/frontend-saas/tsconfig.json +5 -0
  256. package/templates/apps/frontend-spa/package.json +7 -7
  257. package/templates/apps/frontend-ssr/package.json +7 -7
  258. package/templates/apps/frontend-ssr-api/package.json +8 -8
  259. package/templates/apps/frontend-static-blog/package.json +6 -6
  260. package/templates/apps/frontend-status/README.md +51 -0
  261. package/templates/apps/frontend-status/app.config.ts +39 -0
  262. package/templates/apps/frontend-status/package.json +32 -0
  263. package/templates/apps/frontend-status/src/config.ts +7 -0
  264. package/templates/apps/frontend-status/src/globals.css +70 -0
  265. package/templates/apps/frontend-status/src/globals.d.ts +6 -0
  266. package/templates/apps/frontend-status/src/lib/status.ts +81 -0
  267. package/templates/apps/frontend-status/src/locales/de.ts +41 -0
  268. package/templates/apps/frontend-status/src/locales/en.ts +45 -0
  269. package/templates/apps/frontend-status/src/locales/index.ts +13 -0
  270. package/templates/apps/frontend-status/src/pages/layout.tsx +27 -0
  271. package/templates/apps/frontend-status/src/pages/page.test.tsx +123 -0
  272. package/templates/apps/frontend-status/src/pages/page.tsx +136 -0
  273. package/templates/apps/frontend-status/template.json +6 -0
  274. package/templates/apps/frontend-status/tsconfig.json +11 -0
  275. package/templates/baselines/compose/docker-compose.prod.yml +15 -0
  276. package/templates/baselines/compose-mariadb/docker-compose.prod.yml +15 -0
  277. package/dist/apiBuild-BrjrVJJh.js +0 -2
  278. package/dist/dbCommand-DrzXimKf.js +0 -2
  279. package/dist/dev-DNkso403.js +0 -3
  280. package/dist/fileConventions-3bffWssN.js +0 -30
  281. package/dist/frameworkTableAssembly-lrjZtk0G.js +0 -2
  282. package/dist/inspect-gt8bq-Tz.js +0 -2
  283. package/dist/manifestBuild-ifczArzr.js +0 -2
  284. package/dist/serveCommand-DfkisVWP.js +0 -1310
@@ -1,1310 +0,0 @@
1
- import { ot as e, t } from "./inspectMetrics-BU90mvJN.js";
2
- import { s as n } from "./seedRunner-D6eu-u5U.js";
3
- import { r, t as i } from "./appModuleLoader-C9r9mxZt.js";
4
- import { A as a, B as o, C as s, Ct as c, D as l, E as u, F as d, G as f, H as p, I as ee, J as te, K as ne, L as re, M as ie, N as ae, O as oe, P as se, Q as m, R as ce, S as h, St as le, T as g, U as ue, V as de, W as fe, X as _, Y as pe, Z as me, _ as v, _t as he, b as ge, c as _e, dt as y, et as ve, ft as b, g as ye, gt as be, h as xe, ht as Se, i as x, j as Ce, k as we, lt as Te, mt as Ee, nt as S, o as C, pt as w, q as De, r as Oe, rt as ke, t as Ae, tt as je, u as Me, ut as Ne, v as Pe, vt as T, x as Fe, xt as Ie, y as E, yt as Le, z as D } from "./dev-DcbIJrWg.js";
5
- import { _ as O, f as Re, m as ze, n as Be, p as Ve, u as He, v as Ue } from "./frameworkTableAssembly-BwHU9Euq.js";
6
- import { u as We } from "./fileConventions-3bffWssN.js";
7
- import { p as Ge } from "./inspect-CUCCzw2I.js";
8
- import { r as Ke, u as qe } from "./apiBuild-D22_EpoR.js";
9
- import { t as Je } from "./bootTiming-BdyP9nYw.js";
10
- import { n as Ye } from "./cliArgs-qdZSElM3.js";
11
- import { basename as k, join as A } from "node:path";
12
- import { pathToFileURL as Xe } from "node:url";
13
- import { Cause as Ze, Effect as j, Layer as M, ManagedRuntime as Qe } from "effect";
14
- import { createLogger as N } from "@voltro/logger";
15
- import { existsSync as $e } from "node:fs";
16
- import { AggregateRegistry as et, Dispatcher as tt, apiKeyManagementRoutes as nt, applySoftDeleteScope as rt, applyTenantScope as it, attachAnalyticsMirror as at, awaitServerListening as ot, bindMutation as P, bindStream as st, bindSubscription as F, buildTracingLayer as I, cancelWakeup as ct, compileCron as lt, dataStoreApiKeyStore as ut, dataStoreIdempotencyStore as L, formatServerOnlyLeaks as dt, formatUnresolvedSources as ft, frameworkApiKeyStrategy as pt, getCredentialExpiry as mt, installPolicyGuardResolver as ht, loadResourceTuples as gt, makeActionRunner as _t, makeAdvisoryLockCoordinator as vt, makeApiKeyService as yt, makeApiKeyUsageBuffer as bt, makeApiKeyUsageFlusher as xt, makeAsyncKv as St, makeCoordinatedScheduler as Ct, makeEffectStoreLayer as wt, makeLazyWorkflowFacade as Tt, makeMutationOutputCodec as R, makeMutationRunner as Et, makeOneShotQueryRunner as Dt, makeQueryDescriptorProducer as Ot, makeQueryReauthorizer as kt, makeQuerySubscriber as At, makeSchemaRegistry as jt, makeWorkflowFacade as Mt, makeWorkflowFacadeWithCallerContext as Nt, makeWorkflowLayers as Pt, noopKv as z, onProcessShutdown as Ft, recordCredentialExpiry as It, recordSubscriptionDelivery as Lt, recordWorkflowRun as Rt, registerWakeup as zt, resolveSecretsBackend as Bt, runProvidedEffect as Vt, setSecretsBackend as Ht, setSystemStoreHandle as Ut, setTupleSource as Wt, singleCoordinator as Gt, startRpcServer as Kt, startScheduler as B, unresolvedSources as qt, workflowToRpc as V, wrapStoreWithBootCodec as Jt } from "@voltro/runtime";
17
- import { RpcGroup as Yt } from "@effect/rpc";
18
- import { SqlClient as Xt } from "@effect/sql";
19
- import { and as Zt, ensureTableRegistered as Qt, eq as H, or as $t } from "@voltro/database";
20
- import { appStorageProvider as U, fromNodeReadable as en, getObjectStream as tn, putObjectStream as W, toNodeReadable as nn } from "@voltro/plugin-storage";
21
- import { AuthMiddleware as G, ConnectionInfoMiddleware as rn, actionToRpc as K, anonymousSubject as an, isWireReachable as on, mutationToRpc as sn, queryToRpc as q, streamToRpc as cn, workflowCancelDescriptor as ln, workflowDomainEventsQueryDescriptor as un, workflowEventDeliveriesQueryDescriptor as J, workflowResumeDescriptor as dn, workflowRunEventsQueryDescriptor as Y, workflowRunQueryDescriptor as fn, workflowRunStepsQueryDescriptor as pn, workflowRunsQueryDescriptor as X, workflowSignalDescriptor as mn, workflowUpdateDescriptor as Z } from "@voltro/protocol";
22
- import { assertProductionSessionSecret as hn, sessionExpiryFromHeaders as gn } from "@voltro/protocol/session";
23
- import { createHash as _n, timingSafeEqual as vn } from "node:crypto";
24
- import { declaredSnapshot as yn, describeOutcome as bn, runPlannedMigrations as xn } from "@voltro/database/sql";
25
- import { getAuthSessionStrategy as Sn } from "@voltro/plugin-auth";
26
- import { collectPublicApiRoutes as Cn, restRoutesToHttpRoutes as wn } from "@voltro/protocol/rest";
27
- import { buildDeliverWebhookExecute as Tn, buildWebhooksService as En, defaultIncomingPath as Dn, deliverWebhookWorkflow as On, mountIncomingWebhook as kn } from "@voltro/plugin-webhooks";
28
- import { channelFor as An, getBroadcastPlugin as jn } from "@voltro/plugin-broadcast";
29
- import { packBundle as Mn, runExport as Nn, runImport as Pn, storageBlobSink as Fn, storageRefsBlobSource as In, unpackBundle as Ln, unpackBundleToDir as Rn } from "@voltro/data-transfer";
30
- //#region src/bootRefusal.ts
31
- var zn = "VoltroBootRefusal", Bn = (e) => {
32
- let t = Error(e);
33
- return t.name = zn, t;
34
- }, Vn = "/_voltro/admin/import", Hn = "/_voltro/admin/export", Q = (e, t) => ({
35
- status: e,
36
- contentType: "application/json; charset=utf-8",
37
- body: JSON.stringify(t)
38
- }), Un = (e) => {
39
- let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
40
- return n ? n[1] : null;
41
- }, Wn = (e, t) => vn(_n("sha256").update(e).digest(), _n("sha256").update(t).digest()), Gn = (e, t) => {
42
- if (e.method.toUpperCase() !== "POST") return Q(405, { error: "method not allowed" });
43
- if (!t || t.length < 16) return Q(503, { error: "data transfer misconfigured (no/weak secret)" });
44
- let n = Un(e.headers);
45
- return !n || !Wn(n, t) ? Q(401, { error: "unauthorized" }) : null;
46
- }, Kn = N({ scope: "voltro:admin-import" }), qn = "VBUNDLE2", Jn = async function* (e) {
47
- yield e;
48
- }, Yn = (e) => async (t) => {
49
- let n = Gn(t, e.secret);
50
- if (n) return n;
51
- let r = t.headers["x-import-mode"], i = t.headers["x-import-on-conflict"], a = t.headers["x-import-atomic"] === "1" || t.headers["x-import-atomic"] === "true", o = t.headers["x-import-force"] === "1" || t.headers["x-import-force"] === "true", s = t.rawBody.byteLength >= 8 && Buffer.from(t.rawBody.subarray(0, 8)).toString("latin1") === qn, c, l;
52
- if (s) c = Jn(t.rawBody), l = "upload";
53
- else {
54
- let n;
55
- try {
56
- n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
57
- } catch {
58
- return Q(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
59
- }
60
- if (typeof n.bundleKey != "string" || !n.bundleKey) return Q(400, { error: "body.bundleKey (string) is required for the storage transport" });
61
- if (!e.openArchive) return Q(501, { error: "storage transport not configured on this instance" });
62
- c = e.openArchive(n.bundleKey), l = "storage";
63
- }
64
- let u = await import("node:os"), d = await import("node:fs/promises"), f = await import("node:path"), p = await d.mkdtemp(f.join(u.tmpdir(), "voltro-admin-import-"));
65
- try {
66
- e.assetSink ? await Ln(c, {
67
- dir: p,
68
- blobs: e.assetSink
69
- }) : await Rn(c, p);
70
- let t = await j.runPromiseExit(Pn({
71
- store: e.store,
72
- bundleDir: p,
73
- ...r ? { mode: r } : {},
74
- ...i ? { onConflict: i } : {},
75
- ...a ? { atomic: a } : {},
76
- ...e.snapshot ? { targetSnapshot: e.snapshot } : {},
77
- force: o,
78
- onWarn: (e) => Kn.warn("admin.import", { message: e }),
79
- ...e.assetSink ? { assetsAlreadyRestored: !0 } : {}
80
- }));
81
- if (t._tag === "Failure") {
82
- let e = t.cause._tag === "Fail" ? t.cause.error : void 0;
83
- if (e && e._tag === "SchemaDriftError") {
84
- let t = e;
85
- return Kn.warn("admin.import refused (schema drift)", {
86
- transport: l,
87
- bundle: t.bundleFingerprint.slice(0, 16),
88
- target: t.targetFingerprint.slice(0, 16)
89
- }), Q(409, {
90
- error: "schema drift",
91
- bundleFingerprint: t.bundleFingerprint,
92
- targetFingerprint: t.targetFingerprint,
93
- diff: t.diff,
94
- hint: "re-export against the current schema, or resend with x-import-force: 1"
95
- });
96
- }
97
- throw Error(String(e?.message ?? e ?? "import failed"));
98
- }
99
- let n = t.value, s = n.tables.reduce((e, t) => e + t.rowCount, 0);
100
- return Kn.info("admin.import", {
101
- transport: l,
102
- tables: n.tables.length,
103
- rows: s,
104
- mode: r ?? "upsert",
105
- atomic: a
106
- }), Q(200, {
107
- tables: n.tables.length,
108
- rows: s,
109
- transport: l
110
- });
111
- } catch (e) {
112
- return Kn.warn("admin.import failed", {
113
- transport: l,
114
- error: e?.message ?? String(e)
115
- }), Q(500, {
116
- error: "import failed",
117
- message: e?.message ?? String(e)
118
- });
119
- } finally {
120
- await d.rm(p, {
121
- recursive: !0,
122
- force: !0
123
- });
124
- }
125
- }, Xn = N({ scope: "voltro:admin-export" }), Zn = async (e) => {
126
- let t = [];
127
- for await (let n of e) t.push(Buffer.from(n));
128
- return new Uint8Array(Buffer.concat(t));
129
- }, Qn = (e) => typeof e.tenant == "string" && e.tenant ? {
130
- kind: "tenant",
131
- tenantId: e.tenant
132
- } : Array.isArray(e.tables) && e.tables.length ? {
133
- kind: "tables",
134
- tables: e.tables.filter((e) => typeof e == "string")
135
- } : { kind: "all" }, $n = (e) => async (t) => {
136
- let n = Gn(t, e.secret);
137
- if (n) return n;
138
- let r;
139
- try {
140
- r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
141
- } catch {
142
- return Q(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
143
- }
144
- let i = {};
145
- if (typeof r.profile == "string" && r.profile) {
146
- if (!e.loadProfile) return Q(501, { error: "server-side profiles not configured on this instance" });
147
- try {
148
- i = await e.loadProfile(r.profile);
149
- } catch (e) {
150
- return Q(400, {
151
- error: `profile '${r.profile}' could not be loaded`,
152
- message: e?.message ?? String(e)
153
- });
154
- }
155
- }
156
- let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, s = i.scope ?? Qn(r), c = typeof r.bundleKey == "string" && r.bundleKey.length > 0, l = r.assets === !0 && e.assetSource ? { blobs: e.assetSource } : {}, u = await import("node:os"), d = await import("node:fs/promises"), f = await import("node:path"), p = await d.mkdtemp(f.join(u.tmpdir(), "voltro-admin-export-"));
157
- try {
158
- let t = await j.runPromise(Nn({
159
- store: e.store,
160
- snapshot: e.snapshot,
161
- dialect: e.dialect,
162
- outDir: p,
163
- ...i.subset ? { subset: i.subset } : {
164
- scope: s,
165
- ...e.tenantTables && e.tenantTables.length > 0 ? { tenantTables: e.tenantTables } : {}
166
- },
167
- consistency: a,
168
- ...o ? { compression: o } : {},
169
- ...i.masking ? { masking: i.masking } : {}
170
- })), n = t.tables.reduce((e, t) => e + t.rowCount, 0), u = t.masking?.transformed.length ?? 0;
171
- if (c) {
172
- if (!e.putArchive) return Q(501, { error: "storage transport not configured on this instance" });
173
- let i = r.bundleKey;
174
- return await e.putArchive(i, () => Mn({
175
- dir: p,
176
- ...l
177
- })), Xn.info("admin.export", {
178
- transport: "storage",
179
- tables: t.tables.length,
180
- rows: n,
181
- masked: u,
182
- bundleKey: i
183
- }), Q(200, {
184
- bundleKey: i,
185
- tables: t.tables.length,
186
- rows: n,
187
- masked: u,
188
- transport: "storage"
189
- });
190
- }
191
- let d = await Zn(Mn({
192
- dir: p,
193
- ...l
194
- }));
195
- return Xn.info("admin.export", {
196
- transport: "download",
197
- tables: t.tables.length,
198
- rows: n,
199
- masked: u,
200
- bytes: d.byteLength
201
- }), {
202
- status: 200,
203
- contentType: "application/octet-stream",
204
- body: d,
205
- headers: {
206
- "x-export-tables": String(t.tables.length),
207
- "x-export-rows": String(n),
208
- "x-export-masked": String(u)
209
- }
210
- };
211
- } catch (e) {
212
- return Xn.warn("admin.export failed", { error: e?.message ?? String(e) }), Q(500, {
213
- error: "export failed",
214
- message: e?.message ?? String(e)
215
- });
216
- } finally {
217
- await d.rm(p, {
218
- recursive: !0,
219
- force: !0
220
- });
221
- }
222
- }, er = async (e) => {
223
- let { resolve: t } = await import("node:path"), { existsSync: n } = await import("node:fs"), r = [
224
- e,
225
- `${e}.profile.ts`,
226
- `data-profiles/${e}.ts`,
227
- `data-profiles/${e}.profile.ts`
228
- ].map((e) => t(process.cwd(), e)), i = r.find((e) => n(e));
229
- if (!i) throw Error(`data profile '${e}' not found (looked for: ${r.join(", ")})`);
230
- let a = await import(i), o = a.default ?? a.profile;
231
- if (!o) throw Error(`data profile '${i}' has no default export`);
232
- return o;
233
- }, tr = (e, t, n = {}) => (async function* () {
234
- let r = await nn((await j.runPromise(tn(e, t).pipe(j.timeout(n.openTimeout ?? "30 seconds")))).stream), i = n.stallMs ?? 12e4, a, o = () => {
235
- a && clearTimeout(a), a = setTimeout(() => r.destroy(/* @__PURE__ */ Error(`storage read stalled for ${i}ms reading '${t}'`)), i);
236
- };
237
- try {
238
- o();
239
- for await (let e of r) o(), yield e instanceof Uint8Array ? e : new Uint8Array(e);
240
- } finally {
241
- a && clearTimeout(a), r.destroy();
242
- }
243
- })(), nr = {
244
- get: async () => void 0,
245
- set: async () => {},
246
- setWithTags: async () => {},
247
- remove: async () => !1,
248
- has: async () => !1,
249
- clear: async () => {},
250
- invalidateTag: async () => 0,
251
- wrap: async (e, t, n) => n()
252
- }, rr = async (e) => {
253
- Ut({
254
- dataStore: e.store,
255
- schemaRegistry: e.schemaRegistry
256
- });
257
- let t = new tt({
258
- store: e.store,
259
- ...e.snapshotCache ? { cache: e.snapshotCache } : {},
260
- recordDelivery: (e) => Lt({
261
- label: e.label,
262
- kind: e.kind,
263
- durationMs: e.durationMs,
264
- rowCount: e.rowCount
265
- })
266
- }), n = e.cache ?? nr, r = e.kv ?? z, i, o, d, f, ne, ie = /* @__PURE__ */ new Map(), ae = () => `wfctx_${globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`}`, oe = async (t, n, r) => {
267
- let i = {
268
- ...r,
269
- source: r.source ?? `workflow:${t}`
270
- };
271
- ie.set(n, i);
272
- try {
273
- let r = await e.store.query({
274
- table: "_voltro_workflow_start_contexts",
275
- order: [],
276
- predicate: H("executionId", n),
277
- projection: ["id"],
278
- skip: void 0,
279
- take: 1
280
- }), a = {
281
- workflowName: t,
282
- executionId: n,
283
- subject: i.subject ?? null,
284
- traceId: i.traceId ?? null,
285
- source: i.source ?? null,
286
- parentExecutionId: i.parentExecutionId ?? null,
287
- parentClosePolicy: i.parentClosePolicy ?? null,
288
- createdAt: /* @__PURE__ */ new Date()
289
- };
290
- r[0] === void 0 ? await e.store.insert("_voltro_workflow_start_contexts", {
291
- id: ae(),
292
- ...a
293
- }) : await e.store.update("_voltro_workflow_start_contexts", r[0].id, a);
294
- } catch (e) {
295
- process.stderr.write(`[workflow] failed to persist start context for ${t}/${n}: ${e?.message ?? String(e)}\n`);
296
- }
297
- }, se = async (t, n) => {
298
- let r = ie.get(n);
299
- if (r !== void 0) return r;
300
- try {
301
- let t = (await e.store.query({
302
- table: "_voltro_workflow_start_contexts",
303
- order: [],
304
- predicate: H("executionId", n),
305
- projection: void 0,
306
- skip: void 0,
307
- take: 1
308
- }))[0];
309
- if (t === void 0) return;
310
- let r = {
311
- ...t.subject === null ? {} : { subject: t.subject },
312
- ...t.traceId === null ? {} : { traceId: t.traceId },
313
- ...t.source === null ? {} : { source: t.source },
314
- ...t.parentExecutionId === null ? {} : { parentExecutionId: t.parentExecutionId },
315
- ...t.parentClosePolicy === null ? {} : { parentClosePolicy: t.parentClosePolicy }
316
- };
317
- return ie.set(n, r), r;
318
- } catch (e) {
319
- process.stderr.write(`[workflow] failed to load start context for ${n}: ${e?.message ?? String(e)}\n`);
320
- return;
321
- }
322
- }, m = (e.discovered.workflows?.length ?? 0) > 0 ? Tt(() => i) : void 0, ce = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, le = ce || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", ue = e.tenantIsolation === "namespace", fe = (e.log ?? N({ scope: "voltro:serve" })).child("webhooks"), pe, v = e.discovered.webhooks;
323
- if (v && v.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
324
- let t = e.workflowEngineLayer, i = Ee({
325
- store: e.store,
326
- schemaRegistry: e.schemaRegistry,
327
- cache: n,
328
- kv: r
329
- }), a = v.outgoing.map((e) => e.descriptor);
330
- pe = En(i, async (e) => {
331
- let n = On.execute(e).pipe(j.provide(On.toLayer(Tn(i, { events: a })).pipe(M.provideMerge(t))));
332
- j.runPromise(n).catch((t) => {
333
- fe.error("deliverWebhook workflow crashed", {
334
- deliveryId: e.deliveryId,
335
- targetId: e.targetId
336
- }, t);
337
- });
338
- }, { events: a });
339
- }
340
- let he = /* @__PURE__ */ new Map();
341
- if (v) for (let e of v.incoming) {
342
- let t = e.descriptor.path ?? Dn(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = kn(e.descriptor, {
343
- resolveSecret: async () => process.env[n] ?? null,
344
- resolveWorkflows: () => m === void 0 ? void 0 : Nt(m, {
345
- traceId: `incoming:${e.descriptor.id}`,
346
- source: `incoming:${e.descriptor.id}`
347
- }),
348
- log: (e) => {
349
- let t = {
350
- webhookId: e.webhookId,
351
- status: e.status,
352
- signatureOk: String(e.signatureOk),
353
- idempotency: e.idempotency,
354
- durationMs: e.durationMs
355
- };
356
- e.status >= 500 ? fe.error("incoming delivery failed", t) : e.status >= 400 ? fe.warn("incoming delivery rejected", t) : fe.info("incoming delivery handled", t);
357
- }
358
- });
359
- he.set(t, { handle: r });
360
- }
361
- ht(), Wt((t) => gt(e.store, t.subjectId, t.resourceType, t.resourceId));
362
- let _e = (e.discovered.outboxHandlers?.length ?? 0) > 0 ? _({
363
- handlers: e.discovered.outboxHandlers ?? [],
364
- store: e.store,
365
- log: (e.log ?? N({ scope: "voltro:serve" })).child("outbox")
366
- }) : void 0, y = te({
367
- definitions: (e.discovered.connections ?? []).map((e) => e.definition),
368
- store: e.store,
369
- publicUrl: De(e.port ?? 4e3),
370
- log: (e.log ?? N({ scope: "voltro:serve" })).child("connections")
371
- });
372
- Fe({
373
- events: e.discovered.events ?? [],
374
- rpcTags: [
375
- ...e.discovered.queries.map((e) => e.descriptor.name),
376
- ...e.discovered.mutations.map((e) => e.descriptor.name),
377
- ...e.discovered.actions.map((e) => e.descriptor.name),
378
- ...(e.discovered.streams ?? []).map((e) => e.descriptor.name)
379
- ]
380
- });
381
- let ve = (e.log ?? N({ scope: "voltro:serve" })).child("events"), ye = e.broadcastNamespace ?? Pe(e.plugins, void 0), be = E(e.plugins, ye, ve), xe = e.membership?.instanceId ?? process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Se = e.membership ?? ge(e.plugins, {
382
- instanceId: xe,
383
- namespace: ye,
384
- meta: { mode: "serve" },
385
- logger: ve
386
- }), x = h({
387
- events: e.discovered.events ?? [],
388
- origin: xe,
389
- ...be.publishRemote === void 0 ? {} : { publishRemote: be.publishRemote }
390
- }), we = (e.discovered.events ?? []).length > 0 ? await be.attach(x.bus) : null, S = w({
391
- store: e.store,
392
- schemaRegistry: e.schemaRegistry,
393
- cache: n,
394
- kv: r,
395
- ...pe === void 0 ? {} : { webhooksService: pe },
396
- ...m === void 0 ? {} : { workflowsProxy: m },
397
- eventTriggers: e.discovered.eventTriggers ?? [],
398
- namespaceIsolationOn: ue,
399
- ..._e === void 0 ? {} : { outbox: { nudge: _e.nudge } },
400
- ...y.active ? { connections: { registry: y.registry } } : {},
401
- eventBus: x.bus
402
- }), C = M.succeed(et, re), Oe = (t, n) => {
403
- let r = t.pipe(j.provide(wt(n)));
404
- return (e.baseLayer ? r.pipe(j.provide(e.baseLayer)) : r).pipe(j.provide(C));
405
- }, ke = (e, t) => Vt(Oe(e, t)), Ae = Et({
406
- store: e.store,
407
- buildContext: (e, t, n) => S(e, t, n),
408
- runEffect: ke,
409
- undoCapture: Ce()
410
- }), je = a(), Me = _t({
411
- buildContext: (e) => S(e),
412
- runEffect: ke
413
- }), Ne = {
414
- buildContext: (e) => S(e),
415
- finalize: (t, n) => rt(it(t, e.tenantScopedTables, n.subject.tenantId), e.softDeleteScopedTables),
416
- provideEffect: Oe
417
- }, T = Ot(Ne), Ie = Dt({
418
- ...Ne,
419
- queryRows: (t) => e.store.query(t)
420
- }), Le = At({
421
- ...Ne,
422
- subscribeDescriptor: (e, n, r) => t.subscribe(e, n, r),
423
- subscribeComputed: (e, n, r) => t.subscribeComputed(e, n, r)
424
- }), D = (e) => e.filter((e) => on(e.descriptor)), O = {};
425
- for (let n of [
426
- ...D(e.discovered.queries),
427
- ...je.queries,
428
- ...y.queries
429
- ]) O[n.descriptor.name] = (e) => F(T(n, e), t, `subscription.${n.descriptor.name}`, void 0, void 0, kt(n, e));
430
- for (let t of [
431
- ...D(e.discovered.mutations),
432
- ...je.mutations,
433
- ...y.mutations
434
- ]) {
435
- let n = R(t.descriptor.output);
436
- O[t.descriptor.name] = (r) => P(async (e, n) => Ae(t, e, n), r, `mutation.${t.descriptor.name}`, n, e.idempotency);
437
- }
438
- for (let t of [...D(e.discovered.actions), ...y.actions]) {
439
- let n = R(t.descriptor.output);
440
- O[t.descriptor.name] = (r) => P(async (e, n) => Me(t, e, n), r, `action.${t.descriptor.name}`, n, e.idempotency);
441
- }
442
- let Re = () => `public-${Math.random().toString(36).slice(2, 10)}`, ze = [
443
- ...e.discovered.queries.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
444
- descriptor: e.descriptor,
445
- invoke: (t, n) => Ie(e, t, {
446
- subject: n.subject,
447
- traceId: Re()
448
- }),
449
- subscribe: (t, n, r) => Le(e, t, {
450
- subject: n.subject,
451
- traceId: Re()
452
- }, r)
453
- })),
454
- ...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
455
- descriptor: e.descriptor,
456
- invoke: (t, n) => Ae(e, t, {
457
- subject: n.subject,
458
- traceId: Re()
459
- })
460
- })),
461
- ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
462
- descriptor: e.descriptor,
463
- invoke: (t, n) => Me(e, t, {
464
- subject: n.subject,
465
- traceId: Re()
466
- })
467
- }))
468
- ], Be = ze.length > 0 ? wn(Cn(ze), {
469
- store: e.store,
470
- resolveSubject: (t) => e.resolveSubject(t, -1)
471
- }) : [], Ve = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, He = Ve && Ve.length >= 16 ? [{
472
- method: "POST",
473
- path: Vn,
474
- handle: Yn({
475
- secret: Ve,
476
- store: e.store,
477
- ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
478
- assetSink: Fn(U()),
479
- openArchive: (e) => tr(U(), e)
480
- })
481
- }, {
482
- method: "POST",
483
- path: Hn,
484
- handle: $n({
485
- secret: Ve,
486
- store: e.store,
487
- snapshot: e.dataTransferSnapshot ?? { tables: [] },
488
- dialect: e.dataTransferDialect ?? "memory",
489
- tenantTables: [...e.tenantScopedTables],
490
- loadProfile: er,
491
- assetSource: In(U(), e.store),
492
- putArchive: async (e, t) => {
493
- let { Readable: n } = await import("node:stream"), r = U(), i = en("storage", () => n.from(t()));
494
- await j.runPromise(W(r, e, i, { contentType: "application/octet-stream" }));
495
- }
496
- })
497
- }] : [], Ue = [
498
- ...e.httpRoutes ?? [],
499
- ...Be,
500
- ...He,
501
- ...y.httpRoutes
502
- ];
503
- Object.assign(O, x.handlers);
504
- for (let t of D(e.discovered.streams ?? [])) O[t.descriptor.name] = (n) => st((r) => {
505
- let i = S(r), a = t.executor(n, i);
506
- if (j.isEffect(a)) {
507
- let t = a.pipe(j.provide(wt(i.store)));
508
- return (e.baseLayer ? t.pipe(j.provide(e.baseLayer)) : t).pipe(j.provide(C));
509
- }
510
- return typeof a == "object" && a && typeof a.then == "function" ? j.promise(() => a) : a;
511
- }, `stream.${t.descriptor.name}`);
512
- for (let t of e.discovered.workflows ?? []) O[t.definition.name] = (e) => P(async (e, n) => {
513
- let r = n;
514
- return Nt(m, {
515
- subject: r.subject,
516
- traceId: r.traceId,
517
- source: "workflow-rpc"
518
- }).start(t.definition.name, e);
519
- }, e, `workflow.${t.definition.name}`);
520
- ce && (O[fn.name] = (e) => F(T({
521
- descriptor: fn,
522
- executor: (e) => {
523
- let t = e.id;
524
- return {
525
- table: "_voltro_workflow_runs",
526
- order: [{
527
- column: "startedAt",
528
- direction: "desc"
529
- }],
530
- predicate: $t(H("id", t), H("executionId", t)),
531
- take: 1,
532
- skip: void 0,
533
- projection: void 0
534
- };
535
- }
536
- }, e), t, `subscription.${fn.name}`), O[X.name] = (e) => F(T({
537
- descriptor: X,
538
- executor: (e) => {
539
- let t = e, n = [...t.tag === void 0 ? [] : [H("tag", t.tag)], ...t.status === void 0 ? [] : [H("status", t.status)]], r = Number.isFinite(t.limit) && t.limit !== void 0 ? Math.min(Math.max(Math.floor(t.limit), 1), 500) : 100;
540
- return {
541
- table: "_voltro_workflow_runs",
542
- order: [{
543
- column: "startedAt",
544
- direction: "desc"
545
- }],
546
- predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : Zt(...n),
547
- take: r,
548
- skip: void 0,
549
- projection: void 0
550
- };
551
- }
552
- }, e), t, `subscription.${X.name}`), O[pn.name] = (e) => F(T({
553
- descriptor: pn,
554
- executor: (e) => {
555
- let t = e.runId;
556
- return {
557
- table: "_voltro_workflow_run_steps",
558
- order: [{
559
- column: "startedAt",
560
- direction: "asc"
561
- }],
562
- predicate: H("runId", t),
563
- take: 1e3,
564
- skip: void 0,
565
- projection: void 0
566
- };
567
- }
568
- }, e), t, `subscription.${pn.name}`), O[Y.name] = (e) => F(T({
569
- descriptor: Y,
570
- executor: (e) => {
571
- let t = e.runId;
572
- return {
573
- table: "_voltro_workflow_run_events",
574
- order: [{
575
- column: "occurredAt",
576
- direction: "asc"
577
- }],
578
- predicate: H("runId", t),
579
- take: 1e3,
580
- skip: void 0,
581
- projection: void 0
582
- };
583
- }
584
- }, e), t, `subscription.${Y.name}`), O[un.name] = (e) => F(T({
585
- descriptor: un,
586
- executor: (e) => {
587
- let t = e;
588
- return {
589
- table: "_voltro_workflow_events",
590
- order: [{
591
- column: "occurredAt",
592
- direction: "desc"
593
- }],
594
- predicate: t.name === void 0 ? void 0 : H("name", t.name),
595
- take: Math.max(1, Math.min(500, t.limit ?? 100)),
596
- skip: void 0,
597
- projection: void 0
598
- };
599
- }
600
- }, e), t, `subscription.${un.name}`), O[J.name] = (e) => F(T({
601
- descriptor: J,
602
- executor: (e) => {
603
- let t = e.eventId;
604
- return {
605
- table: "_voltro_workflow_event_deliveries",
606
- order: [{
607
- column: "createdAt",
608
- direction: "asc"
609
- }],
610
- predicate: H("eventId", t),
611
- take: 500,
612
- skip: void 0,
613
- projection: void 0
614
- };
615
- }
616
- }, e), t, `subscription.${J.name}`), O[ln.name] = (t) => P(async (t, n) => {
617
- let r = t;
618
- return await b(e.store, n.subject, { executionId: r.executionId }), await m.cancel(r.workflowName, r.executionId), await Ze(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
619
- }, t, `action.${ln.name}`), O[dn.name] = (t) => P(async (t, n) => {
620
- let r = t;
621
- return await b(e.store, n.subject, { executionId: r.executionId }), await m.resume(r.workflowName, r.executionId), { ok: !0 };
622
- }, t, `action.${dn.name}`), O[mn.name] = (t) => P(async (t, n) => {
623
- let r = t;
624
- return await b(e.store, n.subject, { id: r.id }), m.signal({ id: r.id }, r.signalName, r.payload);
625
- }, t, `action.${mn.name}`), O[Z.name] = (t) => P(async (t, n) => {
626
- let r = t;
627
- return await b(e.store, n.subject, { id: r.id }), m.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
628
- }, t, `action.${Z.name}`));
629
- let We = [
630
- ...D(e.discovered.queries).map((e) => q(e.descriptor)),
631
- ...D(e.discovered.mutations).map((e) => sn(e.descriptor)),
632
- ...D(e.discovered.actions).map((e) => K(e.descriptor)),
633
- ...je.queries.map((e) => q(e.descriptor)),
634
- ...je.mutations.map((e) => sn(e.descriptor)),
635
- ...y.queries.map((e) => q(e.descriptor)),
636
- ...y.mutations.map((e) => sn(e.descriptor)),
637
- ...y.actions.map((e) => K(e.descriptor)),
638
- ...D(e.discovered.streams ?? []).map((e) => cn(e.descriptor)),
639
- ...x.rpcs,
640
- ...(e.discovered.workflows ?? []).map((e) => V(e.definition)),
641
- ...ce ? [
642
- q(fn),
643
- q(X),
644
- q(pn),
645
- q(Y),
646
- q(un),
647
- q(J),
648
- K(ln),
649
- K(dn),
650
- K(mn),
651
- K(Z)
652
- ] : []
653
- ], Ge = Yt.make(...We).middleware(G).middleware(rn), Ke = M.succeed(G, G.of(({ headers: t, clientId: n }) => j.promise(() => e.resolveSubject(t, n)))), qe = M.succeed(rn, rn.of(({ headers: e, clientId: t }) => j.sync(() => {
654
- let n = mt(t) ?? gn(e);
655
- return {
656
- clientId: t,
657
- ...e["idempotency-key"] ? { idempotencyKey: e["idempotency-key"] } : {},
658
- ...n === void 0 ? {} : { credentialExpiresAt: n }
659
- };
660
- }))), Je = e.dormancyTenantId ?? "default", Ye = e.dormancy === "sleep" ? {
661
- register: (t, n, r) => zt(e.store, {
662
- tenantId: r ?? Je,
663
- kind: "workflow",
664
- refId: t,
665
- wakeAt: n
666
- }),
667
- cancel: (t, n) => ct(e.store, {
668
- tenantId: n ?? Je,
669
- kind: "workflow",
670
- refId: t
671
- }).then(() => {})
672
- } : void 0, k = le ? await import("@voltro/workflow") : void 0, A = k?.makeWorkflowRunRecorder({
673
- store: e.store,
674
- ...Ye === void 0 ? {} : { wakeups: Ye }
675
- }), Xe = async (t, n) => {
676
- await k.closeWorkflowChildrenForParent({
677
- store: e.store,
678
- parentExecutionId: t,
679
- parentStatus: n,
680
- recorder: A,
681
- log: { warn: (e, t) => {
682
- process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
683
- } },
684
- interruptChild: async (t, n) => {
685
- let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
686
- if (!r) throw Error(`Unknown child workflow: ${t}`);
687
- if (!o) throw Error("Workflow runtime is not ready");
688
- await o.runPromise(r.definition.interrupt(n));
689
- }
690
- });
691
- }, Ze = async (t, n, r) => {
692
- let i = (await e.store.query({
693
- table: "_voltro_workflow_runs",
694
- order: [],
695
- predicate: H("executionId", n),
696
- projection: void 0,
697
- skip: void 0,
698
- take: 1
699
- }))[0];
700
- if (i === void 0) return;
701
- let a = await e.store.update("_voltro_workflow_runs", i.id, {
702
- status: "cancelled",
703
- cancelled: !0,
704
- completedAt: /* @__PURE__ */ new Date()
705
- }), o = i.subject?.tenantId ?? void 0;
706
- a && await A.recordEvent({
707
- runId: i.id,
708
- eventType: "run-cancelled",
709
- payload: {
710
- reason: r,
711
- workflowName: t,
712
- executionId: n,
713
- ...o == null ? {} : { tenantId: o }
714
- }
715
- }), a && await Xe(n, "cancelled");
716
- }, $e = [...Pt(e.discovered.workflows ?? [], {
717
- buildContext: (t, n) => e.buildContextForWorkflow?.(t, n) ?? S({
718
- subject: t.subject,
719
- traceId: t.traceId
720
- }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId }),
721
- resolveStartContext: se
722
- }, (t, n, r) => {
723
- let i = k.getWorkflowVersionMetadata(t.definition);
724
- return k.wrapWorkflowExecuteWithRunRecording({
725
- name: t.definition.name,
726
- store: e.store,
727
- subject: r.subject,
728
- source: r.source ?? null,
729
- traceId: r.traceId,
730
- workflowVersion: i.version,
731
- workflowCompatibleVersions: i.compatibleWith,
732
- workflowPatches: i.patches,
733
- parentExecutionId: r?.parentExecutionId ?? null,
734
- parentClosePolicy: r?.parentClosePolicy ?? null,
735
- onParentClose: ({ executionId: e, status: t }) => Xe(e, t),
736
- recorder: A,
737
- recordRun: Rt
738
- }, n);
739
- }), ...e.discovered.workflowWorkers ?? []], nt = $e.length > 0 ? M.mergeAll(...$e) : M.empty;
740
- if (((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster") && e.workflowEngineLayer !== void 0) {
741
- let t = nt.pipe(M.provideMerge(e.workflowEngineLayer));
742
- o = Qe.make(e.baseLayer === void 0 ? t : t.pipe(M.provideMerge(e.baseLayer))), await o.runPromise(j.void);
743
- let n = await import("@voltro/workflow/cluster"), r = (e) => o.runPromise(n.redriveFailedRun(e));
744
- f = await c({
745
- provider: jn(e.plugins ?? [])?.broadcast?.provider,
746
- crossReplica: jn(e.plugins ?? [])?.broadcast?.crossReplica ?? !1,
747
- namespace: ye,
748
- replicaId: crypto.randomUUID(),
749
- pollStorage: () => o.runPromise(n.pollWorkflowStorage),
750
- log: (e.log ?? N({ scope: "voltro:serve" })).child("workflow")
751
- }), d = async (t) => {
752
- let n = await u({
753
- store: e.store,
754
- workflows: e.discovered.workflows ?? [],
755
- runRedrive: r
756
- }, t.runId);
757
- return n.statusReset && await A.recordEvent({
758
- runId: t.runId,
759
- eventType: "run-redriven",
760
- payload: {
761
- reason: "inspect.redrive",
762
- activitiesReset: n.outcome.activitiesReset
763
- }
764
- }), {
765
- redriven: n.outcome.redriven,
766
- activitiesReset: n.outcome.activitiesReset,
767
- reason: n.outcome.reason
768
- };
769
- }, i = (e.discovered.workflows?.length ?? 0) > 0 ? Mt({
770
- workflows: e.discovered.workflows ?? [],
771
- runEffect: (e) => o.runPromise(e),
772
- onEnqueue: () => f?.publishWake(),
773
- rememberStartContext: oe,
774
- signal: async (t, n, r) => {
775
- let i = await k.sendWorkflowSignal({
776
- store: e.store,
777
- recorder: A,
778
- target: t,
779
- signalName: n,
780
- payload: r
781
- });
782
- return await o.runPromise(k.completeSuspendingSignal({
783
- store: e.store,
784
- target: t,
785
- signalName: n,
786
- payload: r
787
- })).catch(() => {}), i;
788
- },
789
- update: (t, n, r, i) => k.sendWorkflowUpdate({
790
- store: e.store,
791
- recorder: A,
792
- target: t,
793
- updateName: n,
794
- payload: r,
795
- ...i === void 0 ? {} : { options: i }
796
- }),
797
- listRuns: (t) => g(e.store, t),
798
- retry: (t, n) => l({
799
- store: e.store,
800
- workflows: e.discovered.workflows ?? [],
801
- runPromise: (e) => o.runPromise(e)
802
- }, t, n),
803
- redrive: (t) => u({
804
- store: e.store,
805
- workflows: e.discovered.workflows ?? [],
806
- runRedrive: r
807
- }, t).then((e) => e.outcome)
808
- }) : void 0;
809
- }
810
- let at = M.mergeAll(Ge.toLayer(O), Ke, qe), lt = Te(O, e.discovered.queries.map((e) => e.descriptor.name), ce), ut = M.mergeAll(Ge.toLayer(lt), Ke, qe), L = e.observability, dt = await I({
811
- ...L && L.spanProcessors.length > 0 ? { extraSpanProcessors: L.spanProcessors } : {},
812
- ...L && L.metricReaders.length > 0 ? { extraMetricReaders: L.metricReaders } : {},
813
- ...L && Object.keys(L.resourceAttributes).length > 0 ? { resourceAttributes: L.resourceAttributes } : {},
814
- ...L && L.sampler !== void 0 ? { sampler: L.sampler } : {}
815
- }), ft = !1, pt = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, { server: yt, shutdown: bt } = Kt({
816
- group: Ge,
817
- handlersLayer: at,
818
- httpHandlersLayer: ut,
819
- port: e.port ?? 4e3,
820
- ...e.host === void 0 ? {} : { host: e.host },
821
- path: e.path ?? "/ws",
822
- tracerLayer: dt.layer,
823
- healthCheck: {
824
- isReady: () => ft,
825
- ...pt ? { ping: pt } : {}
826
- },
827
- ...Ue.length > 0 ? { httpRoutes: Ue } : {},
828
- ...e.getStore === void 0 ? {} : { getStore: e.getStore },
829
- ...he.size > 0 ? { webhookRoutes: he } : {},
830
- ...e.inspectRoute === void 0 ? {} : { inspectRoute: e.inspectRoute }
831
- });
832
- if (await ot(yt), (e.discovered.schedules?.length ?? 0) > 0) {
833
- let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? vt(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : Gt;
834
- ne = await B(e.discovered.schedules ?? [], {
835
- store: e.store,
836
- coordinator: t,
837
- defaultTrigger: e.scheduleDefaultTrigger ?? "self",
838
- replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
839
- armSelf: e.scheduleArmSelf ?? !0,
840
- dormancy: e.dormancy ?? "always-on",
841
- ...e.dormancyTenantId === void 0 ? {} : { dormancyTenantId: e.dormancyTenantId },
842
- buildContext: ({ traceId: t, scheduleName: n, subject: r }) => S({
843
- subject: r,
844
- traceId: t
845
- }, e.store, void 0, `schedule:${n}`),
846
- log: {
847
- info: (e, t) => {
848
- process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
849
- },
850
- warn: (e, t) => {
851
- process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
852
- },
853
- error: (e, t) => {
854
- process.stderr.write(`[schedule] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
855
- },
856
- debug: () => {}
857
- },
858
- ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
859
- ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
860
- }), e.onSchedulerReady?.(ne);
861
- }
862
- let xt = e.log ?? N({ scope: "voltro:serve" }), St, Ct;
863
- if ((e.discovered.subscribers?.length ?? 0) > 0 && (St = me(e.discovered.subscribers ?? [], e.store, xt.child("subscribe"), e.schemaRegistry, x.bus)), (e.discovered.reactions?.length ?? 0) > 0) {
864
- let t = xt.child("reaction");
865
- Ct = de(e.discovered.reactions ?? [], e.store, {
866
- runAct: async (n, r) => {
867
- if (n.kind === "workflow") {
868
- if (m === void 0) {
869
- t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
870
- return;
871
- }
872
- let e = r.new ?? r.old ?? {};
873
- await Nt(m, {
874
- traceId: `reaction:${n.workflow}`,
875
- source: `reaction:${n.workflow}`
876
- }).start(n.workflow, e);
877
- return;
878
- }
879
- await p(n.agent, r, {
880
- findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
881
- runAction: (e, t, n) => Promise.resolve(Me(e, t, n)),
882
- makeSubject: (e) => an(e),
883
- now: () => Date.now(),
884
- log: t
885
- });
886
- },
887
- checkBudget: async (n, r) => {
888
- try {
889
- let { requireAiBudget: t } = await import("@voltro/ai");
890
- return (await j.runPromise(j.either(t(e.store, {
891
- tenantId: n,
892
- limitUsd: r
893
- }))))._tag === "Right";
894
- } catch (e) {
895
- return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
896
- }
897
- }
898
- }, t);
899
- }
900
- let jt;
901
- return (e.discovered.aggregates?.length ?? 0) > 0 && (jt = await ee({
902
- discovered: e.discovered.aggregates ?? [],
903
- store: e.store,
904
- log: xt.child("aggregate"),
905
- ...e.analytics === void 0 ? {} : { analytics: e.analytics },
906
- ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
907
- ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
908
- }), C = M.succeed(et, jt.registry)), ft = !0, e.bootTiming?.mark("ready"), {
909
- dispatcher: t,
910
- server: yt,
911
- scheduler: ne,
912
- eventsSnapshot: s(x.bus, x.declared),
913
- membersSnapshot: () => ({
914
- members: Se.membership.list(),
915
- capturedAt: Date.now()
916
- }),
917
- redriveWorkflowRun: (e) => d ? d(e) : Promise.reject(/* @__PURE__ */ Error("redrive: this app registers no workflows")),
918
- close: async () => {
919
- ft = !1, await we?.detach(), await Se.detach(), jt?.detach(), Ct?.(), St?.(), await ne?.shutdown(), t.close(), await f?.detach(), await o?.dispose(), await new Promise((e) => yt.close(() => e())), await bt();
920
- }
921
- };
922
- }, $ = N({ scope: "voltro:serve" }), ir = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", ar = Ye, or = async (e) => {
923
- let t = qe(process.cwd());
924
- if ($e(t)) {
925
- let n;
926
- try {
927
- let e = await import(Xe(t).href);
928
- typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
929
- } catch (e) {
930
- $.warn("serve bundle failed to load — using the standard serve path", {}, e);
931
- }
932
- if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
933
- }
934
- return sr(e);
935
- }, sr = async (a) => {
936
- let s = Je();
937
- process.env.NODE_ENV || (process.env.NODE_ENV = "production");
938
- try {
939
- hn();
940
- } catch (e) {
941
- throw Bn(e instanceof Error ? e.message : String(e));
942
- }
943
- let c = process.cwd(), l = Number(process.env.PORT ?? ar(a, "--port") ?? 4e3), u = await _e(c);
944
- Ht(Bt(u?.secrets)), await e({
945
- rawEnv: u?.env,
946
- appType: "api",
947
- root: c,
948
- log: $,
949
- generateTypes: !1
950
- }), s.mark("config");
951
- let p = (process.env.DB_DIALECT ?? u?.store ?? "memory").toLowerCase(), ee = (p === "mariadb" || p === "postgres" || p === "mssql") && (process.env.CDC ?? "1") !== "0", te = p === "mariadb" ? "mariadb" : p === "mssql" ? "mssql" : void 0, re = Ke(c);
952
- if (!i() && $e(re)) try {
953
- let e = await import(Xe(re).href);
954
- if (e.modules) {
955
- let t = {};
956
- for (let [n, r] of Object.entries(e.modules)) t[A(c, n)] = r;
957
- r(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
958
- }
959
- } catch (e) {
960
- $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
961
- }
962
- let h = await xe(c), g = await Me(h, { cdc: ee && te !== void 0 });
963
- {
964
- let e = /* @__PURE__ */ new Set([
965
- ...g.queries.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
966
- ...g.mutations.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
967
- ...g.actions.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name)
968
- ]);
969
- O(Ue(u?.plugins ?? []), [
970
- ...g.queries.map((e) => e.descriptor.name),
971
- ...g.mutations.map((e) => e.descriptor.name),
972
- ...g.actions.map((e) => e.descriptor.name),
973
- ...g.streams.map((e) => e.descriptor.name)
974
- ], e);
975
- let t = ne(g.serverOnlyLeaks, f(process.env, "strict"), dt, "`voltro serve`");
976
- if (t.action === "fail") throw Bn(t.message ?? "");
977
- t.action === "warn" && $.warn(t.message ?? "");
978
- }
979
- let de = h.filter((e) => ae.test(e)), _ = de.length > 0 ? await se(de, $.child("webhooks")) : {
980
- outgoing: [],
981
- incoming: [],
982
- providers: []
983
- }, me = d(g.events), b = _.outgoing.length + _.incoming.length + _.providers.length + me.length === 0 ? void 0 : {
984
- ..._,
985
- outgoing: [..._.outgoing, ...me]
986
- }, Ce = Be({
987
- mix: g.featureMix,
988
- plugins: u?.plugins ?? [],
989
- cdc: ee && te !== void 0,
990
- ...te ? { cdcDialect: te } : {}
991
- }), Te = u?.analytics !== void 0 && u.analytics.kind !== "noop" && p !== "memory" ? (await n(p)).makeSqlLayer(C()) : void 0, Ee = await je({
992
- spec: u?.analytics,
993
- sqlLayer: Te,
994
- log: $
995
- }), w = (() => {
996
- let e = new Set(g.tables.map((e) => e.tableName)), t = [...g.tables];
997
- for (let n of [...Ce, ...Ee.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
998
- return t;
999
- })();
1000
- for (let e of w) Qt(e);
1001
- {
1002
- let e = ft(qt(g.queries.map((e) => ({
1003
- name: e.descriptor.name,
1004
- source: e.descriptor.source
1005
- })), new Set(w.flatMap((e) => {
1006
- let t = e.tableName;
1007
- return t === void 0 ? [] : [t];
1008
- }))));
1009
- e !== void 0 && $.warn(e);
1010
- }
1011
- let De = (process.env.NODE_ENV ?? "").toLowerCase();
1012
- if (ir(De, p, process.env.VOLTRO_AUTO_MIGRATE)) {
1013
- let e = (await n(p)).makeSqlLayer(C()), t = await j.runPromise(Xt.SqlClient.pipe(j.flatMap((e) => xn(e, w, {
1014
- appliedBy: `serve:${De}`,
1015
- environment: "prod",
1016
- dialectId: p
1017
- })), j.provide(e)));
1018
- t.kind === "prod-mismatch" && ($.error(bn(t, p)), $.error("serve: refusing to boot — apply the schema first (voltro db apply in a pre-deploy step), or set VOLTRO_AUTO_MIGRATE=0 to bypass this check."), process.exit(1)), $.info(bn(t, p));
1019
- }
1020
- let Fe = jt(w);
1021
- s.mark("discover");
1022
- let E = await x(u, void 0), qe = Jt(E, p);
1023
- for (let e of Le({
1024
- dialect: String(u?.store ?? process.env.DB_DIALECT ?? "postgres"),
1025
- changeStrategy: (process.env.CDC ?? "1") === "0" ? "inline" : "cdc",
1026
- dbUrl: process.env.DB_URL,
1027
- tables: g.tables.map((e) => ({
1028
- tableName: e.tableName,
1029
- isReactive: e.isReactive === !0
1030
- })),
1031
- querySources: g.queries.flatMap((e) => {
1032
- let t = e.descriptor.source;
1033
- return t === void 0 ? [] : typeof t == "string" ? [t] : [...t];
1034
- })
1035
- })) e.level === "warn" ? $.warn(e.message) : $.info(e.message);
1036
- {
1037
- let e = T(he({
1038
- tables: g.tables.map((e) => ({ tableName: e.tableName })),
1039
- queries: g.queries.map((e) => ({
1040
- name: e.descriptor.name,
1041
- source: e.descriptor.source
1042
- }))
1043
- }));
1044
- e !== void 0 && $.warn(e);
1045
- }
1046
- u?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = u.cache), u?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = u.cacheRedisUrl), u?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = u.cacheRedisDriver), u?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = u.cacheKeyPrefix);
1047
- let { service: Ye, invalidationBus: N, snapshotCache: et, cache: tt, backend: rt, dispose: it } = await be({ env: process.env });
1048
- $.info(`cache backend resolved: ${rt}` + (rt === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), E.onChange((e) => {
1049
- j.runFork(N.publish(e.table));
1050
- }), u?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = u.kv), u?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = u.kvRedisUrl), u?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = u.kvKeyPrefix);
1051
- let { kv: ot, service: P } = await St({ store: E });
1052
- s.mark("store");
1053
- let st = at({
1054
- store: E,
1055
- sink: Ee.sink,
1056
- log: $
1057
- }), F = Se({
1058
- store: E,
1059
- dialect: p
1060
- }), I = u?.plugins ?? [], ct = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, mt, ht;
1061
- p !== "memory" && (mt = Qe.make((await n(p)).makeSqlLayer(C())), ht = await mt.runPromise(Xt.SqlClient));
1062
- let gt = Ct({
1063
- coordinator: [
1064
- "postgres",
1065
- "mariadb",
1066
- "mysql",
1067
- "mssql"
1068
- ].includes(p) ? vt(E, ct, $) : Gt,
1069
- replicaId: ct,
1070
- log: $
1071
- }), _t = [], wt = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Tt = jn(u?.plugins ?? [])?.broadcast?.provider, R = Pe(u?.plugins, u?.name ?? k(c));
1072
- {
1073
- let e = v(u?.plugins, u?.name ?? k(c));
1074
- e !== void 0 && $.warn(e);
1075
- }
1076
- let Et = ge(u?.plugins, {
1077
- instanceId: wt,
1078
- namespace: R,
1079
- meta: { mode: "serve" },
1080
- logger: $
1081
- }), Dt = {
1082
- ...ht ? { sql: ht } : {},
1083
- instanceId: wt,
1084
- membership: Et.membership,
1085
- ...Tt === void 0 ? {} : { broadcast: Tt },
1086
- broadcastChannels: { presence: An(R, "presence") },
1087
- scheduleCoordinated: (e, t, n) => {
1088
- let r = gt(e, t, n);
1089
- return _t.push(r), r;
1090
- }
1091
- };
1092
- for (let e of I) e.bindDataStore?.(E, Dt);
1093
- let Ot = I.filter((e) => typeof e.onChangeEvent == "function");
1094
- if (Ot.length > 0) {
1095
- let e = E.changeScope ?? "local";
1096
- E.onChange((t) => {
1097
- let n = fe(t, e);
1098
- for (let e of Ot) j.runFork(e.onChangeEvent(n).pipe(j.catchAllCause((t) => j.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: Ze.pretty(t) })))));
1099
- });
1100
- }
1101
- let kt = we({
1102
- plugins: I,
1103
- appName: u?.name ?? "voltro-api",
1104
- appType: "api",
1105
- voltroVersion: process.env.npm_package_version ?? "0.0.0",
1106
- log: $
1107
- });
1108
- I.length && await kt.activate(), s.mark("plugins");
1109
- let At = await kt.gatherObservability(), Mt = {
1110
- info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1111
- warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1112
- debug: () => {}
1113
- }, Nt, Pt = await ye(E, u, p, R, Mt, (e, t) => {
1114
- Nt?.refreshAll(`broadcast gap: missed ${t} change(s) from ${e}`);
1115
- }), z = u?.apiKeys, Lt = (typeof z == "object" ? z.prefix : void 0) ?? "voltro_", Rt = z ? ut(E) : void 0, zt = Rt ? bt({ flush: xt(Rt) }) : void 0;
1116
- zt && Ft(() => zt.shutdown());
1117
- let Vt = Rt ? yt(Rt, {
1118
- prefix: Lt,
1119
- ...zt ? { usage: zt } : {}
1120
- }) : void 0, Ut = Vt ? [pt(Vt, { prefix: Lt })] : [], Wt = Oe([...u?.auth?.strategies ?? [], ...Ut], Sn(u?.plugins ?? []), u?.auth?.anonymousTenantRequired ?? !1, u?.auth?.resolveScopes, () => qe), Kt = [...u?.restRoutes ?? [], ...Vt ? nt(Vt, (typeof z == "object" ? z.managementPath : void 0) ?? "/v1/api-keys") : []], B = u?.idempotency, V = B ? {
1121
- store: L(E),
1122
- header: (typeof B == "object" ? B.header : void 0) ?? "Idempotency-Key",
1123
- ttlMs: (typeof B == "object" ? B.ttlMs : void 0) ?? 864e5
1124
- } : void 0, Yt = Kt.length > 0 ? wn(Kt, {
1125
- store: E,
1126
- resolveSubject: async (e) => (await Wt({
1127
- headers: e,
1128
- clientId: -1
1129
- })).subject,
1130
- ...V ? { idempotency: V } : {}
1131
- }) : [], Zt = I.map((e) => e.services).filter((e) => e !== void 0), H = M.mergeAll(y({
1132
- analyticsLayer: Ee.layer,
1133
- cacheService: Ye,
1134
- kvService: P,
1135
- pluginServices: Zt,
1136
- userLayers: u?.layers ?? []
1137
- }), Ne(u?.http ?? {})), $t = u?.scheduling ?? {}, U = $t.trigger ?? "self", en = /* @__PURE__ */ new Set([
1138
- "postgres",
1139
- "mysql",
1140
- "mariadb",
1141
- "mssql"
1142
- ]), tn = $t.coordination ?? (en.has(p) ? "advisoryLock" : "single"), W = tn === "cluster" && en.has(p), nn = W ? "cluster" : tn === "advisoryLock" && en.has(p) ? "advisoryLock" : "single";
1143
- tn === "cluster" && !W && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), tn === "advisoryLock" && !en.has(p) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
1144
- let G, rn = g.workflows.length > 0 || g.workflowWorkers.length > 0 || g.eventTriggers.length > 0 || (b?.outgoing.length ?? 0) > 0 || W, K;
1145
- if (rn) {
1146
- if (p === "mssql") {
1147
- let e = await ve(process.cwd());
1148
- e && $.warn(e);
1149
- }
1150
- let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: r, resolveRunnerStorage: i, resolveFailoverTuning: a }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), o = W ? g.schedules.filter((e) => (e.trigger ?? U) === "self").map((e) => t({
1151
- name: e.name,
1152
- cron: lt(e),
1153
- execute: async () => {
1154
- await G?.fireFromCluster(e.name);
1155
- }
1156
- })) : [];
1157
- K = p === "memory" ? e.layerMemory : await (async () => {
1158
- let e = await n(p), t = i({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
1159
- return $.info(`workflow engine: cluster-${t}, dialect=${e.id}` + (t === "memory" ? " — single-process durable replay, no cross-pod shard handoff" + (e.id !== "sqlite" && e.id !== "turso" ? " (VOLTRO_WORKFLOW_RUNNER_STORAGE=memory: SqlRunnerStorage/cluster_runners + GET_LOCK skipped)" : "") : "")), r({
1160
- sqlClientLayer: e.makeSqlLayer(C()),
1161
- runnerStorage: t,
1162
- dialectId: e.id,
1163
- ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
1164
- ...a(),
1165
- ...o.length > 0 ? { extraShardingLayers: o } : {}
1166
- });
1167
- })();
1168
- }
1169
- let an = oe(I, t()), on = h.filter((e) => /\.subscribe\.tsx?$/.test(e)), sn = on.length > 0 ? await m(on, $) : [], q = h.filter((e) => /\.reaction\.tsx?$/.test(e)), cn = q.length > 0 ? await ue(q, $) : [], ln = h.filter((e) => We.test(e)), un = ln.length > 0 ? await pe(ln, $) : [], J = h.filter((e) => /\.aggregate\.tsx?$/.test(e)), dn = J.length > 0 ? await ce(J, $) : [], Y = D();
1170
- if (dn.length > 0 && p !== "memory") try {
1171
- Y = o((await n(p)).makeSqlLayer(C()));
1172
- } catch (e) {
1173
- $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
1174
- }
1175
- let fn = p === "memory" ? Gt : vt(E, `aggregate@${process.pid}`, $), pn = [], X = [], mn = h.filter((e) => He.test(e));
1176
- if (mn.length > 0) {
1177
- let e = $.child("agent"), t = h.filter((e) => Re.test(e));
1178
- t.length > 0 && await ze(t, e);
1179
- let n = await Ve(mn, e);
1180
- for (let e of n.agents) for (let t of ie(e)) (t.kind === "action" ? pn : X).push({
1181
- file: t.file,
1182
- descriptor: t.descriptor,
1183
- executor: t.executor
1184
- });
1185
- n.agents.length > 0 && e.info("synthesized agent routes", { agents: n.agents.map((e) => e.descriptor.name) });
1186
- }
1187
- s.mark("workflow");
1188
- let Z = await rr({
1189
- bootTiming: s,
1190
- broadcastNamespace: R,
1191
- membership: {
1192
- ...Et,
1193
- instanceId: wt
1194
- },
1195
- ...u?.plugins === void 0 ? {} : { plugins: u.plugins },
1196
- ...V ? { idempotency: {
1197
- store: V.store,
1198
- ttlMs: V.ttlMs
1199
- } } : {},
1200
- discovered: {
1201
- queries: [...g.queries, ...X],
1202
- mutations: g.mutations,
1203
- actions: [...g.actions, ...pn],
1204
- streams: g.streams,
1205
- events: g.events,
1206
- workflows: g.workflows,
1207
- workflowWorkers: g.workflowWorkers,
1208
- eventTriggers: g.eventTriggers,
1209
- schedules: g.schedules,
1210
- subscribers: sn,
1211
- outboxHandlers: un,
1212
- connections: g.connections,
1213
- reactions: cn,
1214
- aggregates: dn,
1215
- ...b === void 0 ? {} : { webhooks: b }
1216
- },
1217
- log: $,
1218
- analytics: Ee.sink,
1219
- aggregateStorage: Y,
1220
- aggregateCoordinator: fn,
1221
- store: E,
1222
- kv: ot,
1223
- cache: tt,
1224
- snapshotCache: et,
1225
- schemaRegistry: Fe,
1226
- tenantScopedTables: g.tenantScopedTables,
1227
- softDeleteScopedTables: g.softDeleteScopedTables,
1228
- dataTransferSnapshot: yn(w),
1229
- dataTransferDialect: p,
1230
- tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? u?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
1231
- resolveSubject: async (e, t) => {
1232
- let n = await Wt({
1233
- headers: e,
1234
- clientId: t
1235
- });
1236
- return It(t, n.credentialExpiresAt), n.subject;
1237
- },
1238
- httpRoutes: [...I.flatMap((e) => e.httpRoutes ?? []), ...Yt],
1239
- getStore: () => qe,
1240
- ...H ? { baseLayer: H } : {},
1241
- ...K === void 0 ? {} : { workflowEngineLayer: K },
1242
- scheduleDefaultTrigger: U,
1243
- scheduleCoordination: nn,
1244
- scheduleArmSelf: !W,
1245
- dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : u?.dormancy ?? "always-on",
1246
- scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
1247
- ...an === void 0 ? {} : { scheduleFireInterceptor: an },
1248
- onSchedulerReady: (e) => {
1249
- G = e;
1250
- },
1251
- inspectRoute: { handle: (e, t, n, r) => Ge(e, {
1252
- kind: "api",
1253
- meta: {
1254
- name: u?.name ?? "voltro-api",
1255
- voltroVersion: Ae,
1256
- port: l,
1257
- mode: "start",
1258
- store: p,
1259
- cdc: ee ? "on" : "off"
1260
- },
1261
- rpc: Ie(g, c),
1262
- workflows: le(g, c),
1263
- events: () => Z.eventsSnapshot(),
1264
- members: () => Z.membersSnapshot(),
1265
- inspectFireSchedule: async ({ name: e, trigger: t }) => {
1266
- if (!G) throw Error("scheduler not started — this app registers no self-triggered schedules (all schedules are trigger:'external', or there are none).");
1267
- return { runId: await G.fireNow(e, t) ?? null };
1268
- },
1269
- inspectRedriveWorkflowRun: (e) => Z.redriveWorkflowRun(e)
1270
- }, t, {
1271
- method: n,
1272
- ...r === void 0 ? {} : { body: r }
1273
- }) ?? {
1274
- status: 404,
1275
- contentType: "application/json",
1276
- body: JSON.stringify({ error: "not an inspect route" })
1277
- } },
1278
- observability: At,
1279
- port: l,
1280
- ...u?.transport?.wsPath ? { path: u.transport.wsPath } : {}
1281
- });
1282
- return Nt = Z.dispatcher, ke(S([
1283
- g.queries,
1284
- g.mutations,
1285
- g.actions,
1286
- g.streams
1287
- ]), (e) => {
1288
- $.warn(e);
1289
- }), $.info(`API listening on :${l}`, {
1290
- dialect: p,
1291
- queries: g.queries.length,
1292
- mutations: g.mutations.length,
1293
- actions: g.actions.length,
1294
- streams: g.streams.length,
1295
- workflows: g.workflows.length,
1296
- workflowWorkers: g.workflowWorkers.length,
1297
- schedules: g.schedules.length,
1298
- scheduleCoordination: nn
1299
- }), s.finish($), Ft(async () => {
1300
- for (let e of _t) e.stop();
1301
- st.detach(), F.stop(), it(), mt?.dispose();
1302
- try {
1303
- await kt.deactivate(), await Pt?.close(), await Ee.dispose(), await Z.close(), await E.close?.();
1304
- } catch (e) {
1305
- console.error("serve: shutdown step failed, exiting anyway:", e);
1306
- }
1307
- }), await new Promise(() => {}), 0;
1308
- };
1309
- //#endregion
1310
- export { or as n, er as r, sr as t };