@kelpie/server 0.5.2 → 0.7.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 (406) hide show
  1. package/README.md +5 -2
  2. package/dist/app.d.ts +13 -0
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +9 -0
  5. package/dist/app.js.map +1 -1
  6. package/dist/boot.d.ts +42 -0
  7. package/dist/boot.d.ts.map +1 -0
  8. package/dist/boot.js +57 -0
  9. package/dist/boot.js.map +1 -0
  10. package/dist/index.d.ts +20 -8
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +13 -4
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/actor.d.ts +9 -1
  15. package/dist/lib/actor.d.ts.map +1 -1
  16. package/dist/lib/actor.js +13 -0
  17. package/dist/lib/actor.js.map +1 -1
  18. package/dist/lib/config.d.ts +51 -6
  19. package/dist/lib/config.d.ts.map +1 -1
  20. package/dist/lib/config.js +11 -5
  21. package/dist/lib/config.js.map +1 -1
  22. package/dist/lib/email.d.ts +15 -63
  23. package/dist/lib/email.d.ts.map +1 -1
  24. package/dist/lib/email.js +13 -65
  25. package/dist/lib/email.js.map +1 -1
  26. package/dist/lib/fromEnv.d.ts +60 -0
  27. package/dist/lib/fromEnv.d.ts.map +1 -0
  28. package/dist/lib/fromEnv.js +94 -0
  29. package/dist/lib/fromEnv.js.map +1 -0
  30. package/dist/lib/ids.d.ts +6 -0
  31. package/dist/lib/ids.d.ts.map +1 -1
  32. package/dist/lib/ids.js +6 -0
  33. package/dist/lib/ids.js.map +1 -1
  34. package/dist/lib/kelpieConfigFile.d.ts +129 -0
  35. package/dist/lib/kelpieConfigFile.d.ts.map +1 -0
  36. package/dist/lib/kelpieConfigFile.js +112 -0
  37. package/dist/lib/kelpieConfigFile.js.map +1 -0
  38. package/dist/lib/logger.d.ts +38 -7
  39. package/dist/lib/logger.d.ts.map +1 -1
  40. package/dist/lib/logger.js +58 -20
  41. package/dist/lib/logger.js.map +1 -1
  42. package/dist/modules/agent-tasks/index.d.ts.map +1 -1
  43. package/dist/modules/agent-tasks/index.js +4 -1
  44. package/dist/modules/agent-tasks/index.js.map +1 -1
  45. package/dist/modules/agent-tasks/prompt.d.ts +36 -6
  46. package/dist/modules/agent-tasks/prompt.d.ts.map +1 -1
  47. package/dist/modules/agent-tasks/prompt.js +33 -4
  48. package/dist/modules/agent-tasks/prompt.js.map +1 -1
  49. package/dist/modules/agent-tasks/service.d.ts.map +1 -1
  50. package/dist/modules/agent-tasks/service.js +3 -2
  51. package/dist/modules/agent-tasks/service.js.map +1 -1
  52. package/dist/modules/agent-tasks/wire.d.ts +11 -0
  53. package/dist/modules/agent-tasks/wire.d.ts.map +1 -1
  54. package/dist/modules/agent-tasks/wire.js +1 -0
  55. package/dist/modules/agent-tasks/wire.js.map +1 -1
  56. package/dist/modules/auth/index.d.ts.map +1 -1
  57. package/dist/modules/auth/index.js +8 -7
  58. package/dist/modules/auth/index.js.map +1 -1
  59. package/dist/modules/companies/events.d.ts +22 -0
  60. package/dist/modules/companies/events.d.ts.map +1 -0
  61. package/dist/modules/companies/events.js +8 -0
  62. package/dist/modules/companies/events.js.map +1 -0
  63. package/dist/modules/companies/index.d.ts.map +1 -1
  64. package/dist/modules/companies/index.js +2 -0
  65. package/dist/modules/companies/index.js.map +1 -1
  66. package/dist/modules/companies/service.d.ts +1 -0
  67. package/dist/modules/companies/service.d.ts.map +1 -1
  68. package/dist/modules/companies/service.js +8 -11
  69. package/dist/modules/companies/service.js.map +1 -1
  70. package/dist/modules/core.d.ts.map +1 -1
  71. package/dist/modules/core.js +4 -0
  72. package/dist/modules/core.js.map +1 -1
  73. package/dist/modules/deals/events.d.ts +31 -0
  74. package/dist/modules/deals/events.d.ts.map +1 -0
  75. package/dist/modules/deals/events.js +12 -0
  76. package/dist/modules/deals/events.js.map +1 -0
  77. package/dist/modules/deals/index.d.ts.map +1 -1
  78. package/dist/modules/deals/index.js +2 -0
  79. package/dist/modules/deals/index.js.map +1 -1
  80. package/dist/modules/deals/service.d.ts +1 -0
  81. package/dist/modules/deals/service.d.ts.map +1 -1
  82. package/dist/modules/deals/service.js +9 -18
  83. package/dist/modules/deals/service.js.map +1 -1
  84. package/dist/modules/decisions/events.d.ts +21 -0
  85. package/dist/modules/decisions/events.d.ts.map +1 -0
  86. package/dist/modules/decisions/events.js +11 -0
  87. package/dist/modules/decisions/events.js.map +1 -0
  88. package/dist/modules/decisions/index.d.ts.map +1 -1
  89. package/dist/modules/decisions/index.js +2 -0
  90. package/dist/modules/decisions/index.js.map +1 -1
  91. package/dist/modules/decisions/service.d.ts +1 -0
  92. package/dist/modules/decisions/service.d.ts.map +1 -1
  93. package/dist/modules/decisions/service.js +4 -7
  94. package/dist/modules/decisions/service.js.map +1 -1
  95. package/dist/modules/eventCatalogs.d.ts +35 -0
  96. package/dist/modules/eventCatalogs.d.ts.map +1 -0
  97. package/dist/modules/eventCatalogs.js +35 -0
  98. package/dist/modules/eventCatalogs.js.map +1 -0
  99. package/dist/modules/forms/events.d.ts +37 -0
  100. package/dist/modules/forms/events.d.ts.map +1 -0
  101. package/dist/modules/forms/events.js +15 -0
  102. package/dist/modules/forms/events.js.map +1 -0
  103. package/dist/modules/forms/index.d.ts.map +1 -1
  104. package/dist/modules/forms/index.js +2 -0
  105. package/dist/modules/forms/index.js.map +1 -1
  106. package/dist/modules/forms/service.d.ts +1 -0
  107. package/dist/modules/forms/service.d.ts.map +1 -1
  108. package/dist/modules/forms/service.js +8 -11
  109. package/dist/modules/forms/service.js.map +1 -1
  110. package/dist/modules/forms/submission.d.ts +5 -0
  111. package/dist/modules/forms/submission.d.ts.map +1 -1
  112. package/dist/modules/forms/submission.js +54 -28
  113. package/dist/modules/forms/submission.js.map +1 -1
  114. package/dist/modules/handbook/events.d.ts +28 -0
  115. package/dist/modules/handbook/events.d.ts.map +1 -0
  116. package/dist/modules/handbook/events.js +14 -0
  117. package/dist/modules/handbook/events.js.map +1 -0
  118. package/dist/modules/handbook/index.d.ts.map +1 -1
  119. package/dist/modules/handbook/index.js +2 -0
  120. package/dist/modules/handbook/index.js.map +1 -1
  121. package/dist/modules/handbook/service.d.ts +1 -0
  122. package/dist/modules/handbook/service.d.ts.map +1 -1
  123. package/dist/modules/handbook/service.js +8 -15
  124. package/dist/modules/handbook/service.js.map +1 -1
  125. package/dist/modules/hiring/candidates.d.ts +1 -0
  126. package/dist/modules/hiring/candidates.d.ts.map +1 -1
  127. package/dist/modules/hiring/candidates.js +8 -11
  128. package/dist/modules/hiring/candidates.js.map +1 -1
  129. package/dist/modules/hiring/events.d.ts +35 -0
  130. package/dist/modules/hiring/events.d.ts.map +1 -0
  131. package/dist/modules/hiring/events.js +11 -0
  132. package/dist/modules/hiring/events.js.map +1 -0
  133. package/dist/modules/hiring/index.d.ts.map +1 -1
  134. package/dist/modules/hiring/index.js +2 -0
  135. package/dist/modules/hiring/index.js.map +1 -1
  136. package/dist/modules/hiring/roles.d.ts +1 -0
  137. package/dist/modules/hiring/roles.d.ts.map +1 -1
  138. package/dist/modules/hiring/roles.js +8 -11
  139. package/dist/modules/hiring/roles.js.map +1 -1
  140. package/dist/modules/import-export/drafts.d.ts +9 -0
  141. package/dist/modules/import-export/drafts.d.ts.map +1 -1
  142. package/dist/modules/import-export/drafts.js +25 -0
  143. package/dist/modules/import-export/drafts.js.map +1 -1
  144. package/dist/modules/import-export/events.d.ts +22 -0
  145. package/dist/modules/import-export/events.d.ts.map +1 -0
  146. package/dist/modules/import-export/events.js +12 -0
  147. package/dist/modules/import-export/events.js.map +1 -0
  148. package/dist/modules/import-export/exportRows.d.ts +9 -0
  149. package/dist/modules/import-export/exportRows.d.ts.map +1 -1
  150. package/dist/modules/import-export/exportRows.js +10 -1
  151. package/dist/modules/import-export/exportRows.js.map +1 -1
  152. package/dist/modules/import-export/index.d.ts.map +1 -1
  153. package/dist/modules/import-export/index.js +2 -0
  154. package/dist/modules/import-export/index.js.map +1 -1
  155. package/dist/modules/import-export/plan.d.ts +23 -1
  156. package/dist/modules/import-export/plan.d.ts.map +1 -1
  157. package/dist/modules/import-export/plan.js +62 -3
  158. package/dist/modules/import-export/plan.js.map +1 -1
  159. package/dist/modules/import-export/presets.d.ts.map +1 -1
  160. package/dist/modules/import-export/presets.js +25 -0
  161. package/dist/modules/import-export/presets.js.map +1 -1
  162. package/dist/modules/import-export/repository.d.ts +17 -0
  163. package/dist/modules/import-export/repository.d.ts.map +1 -1
  164. package/dist/modules/import-export/repository.js +21 -1
  165. package/dist/modules/import-export/repository.js.map +1 -1
  166. package/dist/modules/import-export/routes.d.ts.map +1 -1
  167. package/dist/modules/import-export/routes.js +5 -1
  168. package/dist/modules/import-export/routes.js.map +1 -1
  169. package/dist/modules/import-export/schema.d.ts +55 -0
  170. package/dist/modules/import-export/schema.d.ts.map +1 -1
  171. package/dist/modules/import-export/schema.js +13 -1
  172. package/dist/modules/import-export/schema.js.map +1 -1
  173. package/dist/modules/import-export/service.d.ts +9 -1
  174. package/dist/modules/import-export/service.d.ts.map +1 -1
  175. package/dist/modules/import-export/service.js +104 -17
  176. package/dist/modules/import-export/service.js.map +1 -1
  177. package/dist/modules/import-export/tools.d.ts.map +1 -1
  178. package/dist/modules/import-export/tools.js +7 -1
  179. package/dist/modules/import-export/tools.js.map +1 -1
  180. package/dist/modules/import-export/writes.d.ts +16 -0
  181. package/dist/modules/import-export/writes.d.ts.map +1 -1
  182. package/dist/modules/import-export/writes.js +77 -2
  183. package/dist/modules/import-export/writes.js.map +1 -1
  184. package/dist/modules/notes/events.d.ts +22 -0
  185. package/dist/modules/notes/events.d.ts.map +1 -0
  186. package/dist/modules/notes/events.js +12 -0
  187. package/dist/modules/notes/events.js.map +1 -0
  188. package/dist/modules/notes/index.d.ts.map +1 -1
  189. package/dist/modules/notes/index.js +2 -0
  190. package/dist/modules/notes/index.js.map +1 -1
  191. package/dist/modules/notes/service.d.ts +1 -0
  192. package/dist/modules/notes/service.d.ts.map +1 -1
  193. package/dist/modules/notes/service.js +4 -7
  194. package/dist/modules/notes/service.js.map +1 -1
  195. package/dist/modules/opportunities/events.d.ts +31 -0
  196. package/dist/modules/opportunities/events.d.ts.map +1 -0
  197. package/dist/modules/opportunities/events.js +12 -0
  198. package/dist/modules/opportunities/events.js.map +1 -0
  199. package/dist/modules/opportunities/index.d.ts.map +1 -1
  200. package/dist/modules/opportunities/index.js +2 -0
  201. package/dist/modules/opportunities/index.js.map +1 -1
  202. package/dist/modules/opportunities/service.d.ts +1 -0
  203. package/dist/modules/opportunities/service.d.ts.map +1 -1
  204. package/dist/modules/opportunities/service.js +9 -18
  205. package/dist/modules/opportunities/service.js.map +1 -1
  206. package/dist/modules/partnerships/events.d.ts +31 -0
  207. package/dist/modules/partnerships/events.d.ts.map +1 -0
  208. package/dist/modules/partnerships/events.js +12 -0
  209. package/dist/modules/partnerships/events.js.map +1 -0
  210. package/dist/modules/partnerships/index.d.ts.map +1 -1
  211. package/dist/modules/partnerships/index.js +2 -0
  212. package/dist/modules/partnerships/index.js.map +1 -1
  213. package/dist/modules/partnerships/service.d.ts +1 -0
  214. package/dist/modules/partnerships/service.d.ts.map +1 -1
  215. package/dist/modules/partnerships/service.js +9 -18
  216. package/dist/modules/partnerships/service.js.map +1 -1
  217. package/dist/modules/people/events.d.ts +28 -0
  218. package/dist/modules/people/events.d.ts.map +1 -0
  219. package/dist/modules/people/events.js +18 -0
  220. package/dist/modules/people/events.js.map +1 -0
  221. package/dist/modules/people/index.d.ts.map +1 -1
  222. package/dist/modules/people/index.js +2 -0
  223. package/dist/modules/people/index.js.map +1 -1
  224. package/dist/modules/people/service.d.ts +1 -0
  225. package/dist/modules/people/service.d.ts.map +1 -1
  226. package/dist/modules/people/service.js +8 -11
  227. package/dist/modules/people/service.js.map +1 -1
  228. package/dist/modules/pipelines/service.d.ts +4 -0
  229. package/dist/modules/pipelines/service.d.ts.map +1 -1
  230. package/dist/modules/pipelines/service.js +31 -8
  231. package/dist/modules/pipelines/service.js.map +1 -1
  232. package/dist/modules/plans/events.d.ts +21 -0
  233. package/dist/modules/plans/events.d.ts.map +1 -0
  234. package/dist/modules/plans/events.js +11 -0
  235. package/dist/modules/plans/events.js.map +1 -0
  236. package/dist/modules/plans/index.d.ts.map +1 -1
  237. package/dist/modules/plans/index.js +2 -0
  238. package/dist/modules/plans/index.js.map +1 -1
  239. package/dist/modules/plans/service.d.ts +1 -0
  240. package/dist/modules/plans/service.d.ts.map +1 -1
  241. package/dist/modules/plans/service.js +6 -14
  242. package/dist/modules/plans/service.js.map +1 -1
  243. package/dist/modules/positions/events.d.ts +22 -0
  244. package/dist/modules/positions/events.d.ts.map +1 -0
  245. package/dist/modules/positions/events.js +8 -0
  246. package/dist/modules/positions/events.js.map +1 -0
  247. package/dist/modules/positions/index.d.ts.map +1 -1
  248. package/dist/modules/positions/index.js +2 -0
  249. package/dist/modules/positions/index.js.map +1 -1
  250. package/dist/modules/positions/service.d.ts +1 -0
  251. package/dist/modules/positions/service.d.ts.map +1 -1
  252. package/dist/modules/positions/service.js +8 -11
  253. package/dist/modules/positions/service.js.map +1 -1
  254. package/dist/modules/raises/events.d.ts +31 -0
  255. package/dist/modules/raises/events.d.ts.map +1 -0
  256. package/dist/modules/raises/events.js +12 -0
  257. package/dist/modules/raises/events.js.map +1 -0
  258. package/dist/modules/raises/index.d.ts.map +1 -1
  259. package/dist/modules/raises/index.js +2 -0
  260. package/dist/modules/raises/index.js.map +1 -1
  261. package/dist/modules/raises/service.d.ts +1 -0
  262. package/dist/modules/raises/service.d.ts.map +1 -1
  263. package/dist/modules/raises/service.js +9 -18
  264. package/dist/modules/raises/service.js.map +1 -1
  265. package/dist/modules/reseal.d.ts +55 -0
  266. package/dist/modules/reseal.d.ts.map +1 -1
  267. package/dist/modules/reseal.js +90 -1
  268. package/dist/modules/reseal.js.map +1 -1
  269. package/dist/modules/smtp-email/index.d.ts +69 -0
  270. package/dist/modules/smtp-email/index.d.ts.map +1 -0
  271. package/dist/modules/smtp-email/index.js +82 -0
  272. package/dist/modules/smtp-email/index.js.map +1 -0
  273. package/dist/modules/webhooks/index.d.ts.map +1 -1
  274. package/dist/modules/webhooks/index.js +5 -1
  275. package/dist/modules/webhooks/index.js.map +1 -1
  276. package/dist/modules/webhooks/payloads.d.ts +22 -7
  277. package/dist/modules/webhooks/payloads.d.ts.map +1 -1
  278. package/dist/modules/webhooks/payloads.js +63 -44
  279. package/dist/modules/webhooks/payloads.js.map +1 -1
  280. package/dist/modules/workspace/events.d.ts +52 -0
  281. package/dist/modules/workspace/events.d.ts.map +1 -0
  282. package/dist/modules/workspace/events.js +16 -0
  283. package/dist/modules/workspace/events.js.map +1 -0
  284. package/dist/modules/workspace/index.d.ts.map +1 -1
  285. package/dist/modules/workspace/index.js +6 -2
  286. package/dist/modules/workspace/index.js.map +1 -1
  287. package/dist/modules/workspace/service.d.ts +1 -0
  288. package/dist/modules/workspace/service.d.ts.map +1 -1
  289. package/dist/modules/workspace/service.js +13 -15
  290. package/dist/modules/workspace/service.js.map +1 -1
  291. package/dist/runtime/events.d.ts +86 -108
  292. package/dist/runtime/events.d.ts.map +1 -1
  293. package/dist/runtime/events.js +123 -52
  294. package/dist/runtime/events.js.map +1 -1
  295. package/dist/runtime/module.d.ts +54 -2
  296. package/dist/runtime/module.d.ts.map +1 -1
  297. package/dist/runtime/registry.d.ts +23 -0
  298. package/dist/runtime/registry.d.ts.map +1 -1
  299. package/dist/runtime/registry.js +102 -2
  300. package/dist/runtime/registry.js.map +1 -1
  301. package/dist/runtime/transaction.d.ts +29 -4
  302. package/dist/runtime/transaction.d.ts.map +1 -1
  303. package/dist/runtime/transaction.js +48 -7
  304. package/dist/runtime/transaction.js.map +1 -1
  305. package/dist/testing/app.d.ts +5 -1
  306. package/dist/testing/app.d.ts.map +1 -1
  307. package/dist/testing/app.js +13 -3
  308. package/dist/testing/app.js.map +1 -1
  309. package/dist/testing/database.d.ts.map +1 -1
  310. package/dist/testing/database.js +6 -3
  311. package/dist/testing/database.js.map +1 -1
  312. package/dist/testing/services.d.ts +21 -1
  313. package/dist/testing/services.d.ts.map +1 -1
  314. package/dist/testing/services.js +20 -5
  315. package/dist/testing/services.js.map +1 -1
  316. package/migrations/0019_sharp_red_skull.sql +4 -0
  317. package/migrations/0020_early_nemesis.sql +2 -0
  318. package/migrations/meta/0019_snapshot.json +5138 -0
  319. package/migrations/meta/0020_snapshot.json +5138 -0
  320. package/migrations/meta/_journal.json +14 -0
  321. package/package.json +5 -2
  322. package/src/app.ts +26 -0
  323. package/src/boot.ts +89 -0
  324. package/src/index.ts +52 -9
  325. package/src/lib/actor.ts +15 -1
  326. package/src/lib/config.ts +65 -7
  327. package/src/lib/email.ts +22 -92
  328. package/src/lib/fromEnv.ts +143 -0
  329. package/src/lib/ids.ts +6 -0
  330. package/src/lib/kelpieConfigFile.ts +291 -0
  331. package/src/lib/logger.ts +92 -34
  332. package/src/modules/agent-tasks/index.ts +4 -1
  333. package/src/modules/agent-tasks/prompt.ts +57 -9
  334. package/src/modules/agent-tasks/service.ts +3 -2
  335. package/src/modules/agent-tasks/wire.ts +12 -0
  336. package/src/modules/auth/index.ts +11 -9
  337. package/src/modules/companies/events.ts +25 -0
  338. package/src/modules/companies/index.ts +2 -0
  339. package/src/modules/companies/service.ts +8 -11
  340. package/src/modules/core.ts +4 -0
  341. package/src/modules/deals/events.ts +34 -0
  342. package/src/modules/deals/index.ts +2 -0
  343. package/src/modules/deals/service.ts +17 -18
  344. package/src/modules/decisions/events.ts +24 -0
  345. package/src/modules/decisions/index.ts +2 -0
  346. package/src/modules/decisions/service.ts +8 -7
  347. package/src/modules/eventCatalogs.ts +35 -0
  348. package/src/modules/forms/events.ts +37 -0
  349. package/src/modules/forms/index.ts +2 -0
  350. package/src/modules/forms/service.ts +12 -11
  351. package/src/modules/forms/submission.ts +80 -29
  352. package/src/modules/handbook/events.ts +31 -0
  353. package/src/modules/handbook/index.ts +2 -0
  354. package/src/modules/handbook/service.ts +8 -15
  355. package/src/modules/hiring/candidates.ts +8 -11
  356. package/src/modules/hiring/events.ts +36 -0
  357. package/src/modules/hiring/index.ts +2 -0
  358. package/src/modules/hiring/roles.ts +8 -11
  359. package/src/modules/import-export/drafts.ts +27 -0
  360. package/src/modules/import-export/events.ts +25 -0
  361. package/src/modules/import-export/exportRows.ts +10 -1
  362. package/src/modules/import-export/index.ts +2 -0
  363. package/src/modules/import-export/plan.ts +107 -5
  364. package/src/modules/import-export/presets.ts +25 -0
  365. package/src/modules/import-export/repository.ts +35 -1
  366. package/src/modules/import-export/routes.ts +5 -0
  367. package/src/modules/import-export/schema.ts +13 -0
  368. package/src/modules/import-export/service.ts +153 -19
  369. package/src/modules/import-export/tools.ts +9 -0
  370. package/src/modules/import-export/writes.ts +116 -3
  371. package/src/modules/notes/events.ts +25 -0
  372. package/src/modules/notes/index.ts +2 -0
  373. package/src/modules/notes/service.ts +8 -7
  374. package/src/modules/opportunities/events.ts +34 -0
  375. package/src/modules/opportunities/index.ts +2 -0
  376. package/src/modules/opportunities/service.ts +17 -18
  377. package/src/modules/partnerships/events.ts +34 -0
  378. package/src/modules/partnerships/index.ts +2 -0
  379. package/src/modules/partnerships/service.ts +17 -18
  380. package/src/modules/people/events.ts +36 -0
  381. package/src/modules/people/index.ts +2 -0
  382. package/src/modules/people/service.ts +97 -87
  383. package/src/modules/pipelines/service.ts +47 -8
  384. package/src/modules/plans/events.ts +24 -0
  385. package/src/modules/plans/index.ts +2 -0
  386. package/src/modules/plans/service.ts +14 -14
  387. package/src/modules/positions/events.ts +25 -0
  388. package/src/modules/positions/index.ts +2 -0
  389. package/src/modules/positions/service.ts +8 -11
  390. package/src/modules/raises/events.ts +34 -0
  391. package/src/modules/raises/index.ts +2 -0
  392. package/src/modules/raises/service.ts +17 -18
  393. package/src/modules/reseal.ts +144 -1
  394. package/src/modules/smtp-email/index.ts +119 -0
  395. package/src/modules/webhooks/index.ts +5 -1
  396. package/src/modules/webhooks/payloads.ts +94 -48
  397. package/src/modules/workspace/events.ts +46 -0
  398. package/src/modules/workspace/index.ts +6 -2
  399. package/src/modules/workspace/service.ts +37 -15
  400. package/src/runtime/events.ts +268 -107
  401. package/src/runtime/module.ts +55 -2
  402. package/src/runtime/registry.ts +169 -1
  403. package/src/runtime/transaction.ts +94 -17
  404. package/src/testing/app.ts +18 -4
  405. package/src/testing/database.ts +6 -3
  406. package/src/testing/services.ts +34 -5
@@ -5,15 +5,15 @@ import type { Logger } from './logger.ts';
5
5
  * and account-change notifications, nothing else. Kelpie never sends outreach
6
6
  * email.
7
7
  *
8
- * Roadmap decision 4: the provider is configured, never hardcoded. Core ships
9
- * the port and two providers, `log` and `smtp`. Both need no vendor account a
10
- * deployment doesn't already have, which is what keeps them in core rather than
11
- * a module, per `modules.md`'s split test. A provider that does need one
12
- * (Resend, Postmark, Mailtrap, SendGrid) is a commercial integration under that
13
- * same test and belongs in a module: it supplies its own `EmailSender` from its
14
- * own config, and an assembly's entry point wires it into `services.email` in
15
- * place of `createEmailSender`, the same way `kelpie-cloud/src/server.ts` wires
16
- * this one today.
8
+ * The assembly names one named provider in `kelpie.config.ts`'s
9
+ * `email.provider`. The module runtime resolves the name against a registry
10
+ * every module can contribute to via `context.provideEmailSender(name, sender)`.
11
+ * `'log'` is a built-in name the runtime always registers, so a bare install
12
+ * has something to point at. `'smtp'` is registered by the built-in
13
+ * `smtp-email` core module. Other names come from third-party provider modules
14
+ * (Resend, Postmark, SES) that follow the same registry pattern. Transport is
15
+ * arbitrary: the module builds one behind the `EmailSender` interface and
16
+ * hands it to core, which knows only how to `send`.
17
17
  */
18
18
  export interface EmailMessage {
19
19
  readonly to: string;
@@ -23,64 +23,16 @@ export interface EmailMessage {
23
23
  export interface EmailSender {
24
24
  send(message: EmailMessage): Promise<void>;
25
25
  }
26
- declare const smtpEmailConfigSchema: z.ZodObject<{
27
- EMAIL_PROVIDER: z.ZodLiteral<"smtp">;
26
+ export declare const emailConfigSchema: z.ZodObject<{
27
+ EMAIL_PROVIDER: z.ZodString;
28
28
  EMAIL_FROM: z.ZodString;
29
- SMTP_HOST: z.ZodString;
30
- SMTP_PORT: z.ZodCoercedNumber<unknown>;
31
- SMTP_SECURE: z.ZodPipe<z.ZodEnum<{
32
- false: "false";
33
- true: "true";
34
- }>, z.ZodTransform<boolean, "false" | "true">>;
35
- SMTP_USER: z.ZodString;
36
- SMTP_PASSWORD: z.ZodString;
37
29
  }, z.core.$strip>;
38
- export declare const emailConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
39
- EMAIL_PROVIDER: z.ZodLiteral<"log">;
40
- EMAIL_FROM: z.ZodString;
41
- }, z.core.$strip>, z.ZodObject<{
42
- EMAIL_PROVIDER: z.ZodLiteral<"smtp">;
43
- EMAIL_FROM: z.ZodString;
44
- SMTP_HOST: z.ZodString;
45
- SMTP_PORT: z.ZodCoercedNumber<unknown>;
46
- SMTP_SECURE: z.ZodPipe<z.ZodEnum<{
47
- false: "false";
48
- true: "true";
49
- }>, z.ZodTransform<boolean, "false" | "true">>;
50
- SMTP_USER: z.ZodString;
51
- SMTP_PASSWORD: z.ZodString;
52
- }, z.core.$strip>], "EMAIL_PROVIDER">;
53
30
  export type EmailConfig = z.infer<typeof emailConfigSchema>;
54
- export type SmtpEmailConfig = z.infer<typeof smtpEmailConfigSchema>;
55
31
  /**
56
- * Writes the message to the log instead of sending it. For self-hosted
57
- * development, where the reset link in the log is exactly what you want.
58
- *
59
- * This is a deliberate choice, not a fallback: `EMAIL_PROVIDER` has no default,
60
- * so nobody reaches this provider without naming it.
32
+ * Writes the message to the log instead of sending it. The registry default,
33
+ * swapped out for a real sender by picking a different provider name in
34
+ * `email.provider` (`'smtp'` for the built-in SMTP module, or any name a
35
+ * third-party provider module registers).
61
36
  */
62
37
  export declare function createLogEmailSender(logger: Logger, from: string): EmailSender;
63
- /**
64
- * What `createSmtpEmailSender` sends a message through. A real deployment gets
65
- * one backed by `nodemailer`; a test injects one that records calls, so the
66
- * sender is verifiable without a container running a real SMTP conversation.
67
- */
68
- export interface SmtpTransport {
69
- sendMail(message: {
70
- from: string;
71
- to: string;
72
- subject: string;
73
- text: string;
74
- }): Promise<unknown>;
75
- }
76
- /** Sends over SMTP. `transport` defaults to a real connection built from `config`. */
77
- export declare function createSmtpEmailSender(config: SmtpEmailConfig, logger: Logger, transport?: SmtpTransport): EmailSender;
78
- /**
79
- * Builds the configured sender.
80
- *
81
- * @throws Never. An unknown provider cannot reach here: the config schema is a
82
- * discriminated union, so boot rejects it first.
83
- */
84
- export declare function createEmailSender(config: EmailConfig, logger: Logger): EmailSender;
85
- export {};
86
38
  //# sourceMappingURL=email.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/lib/email.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C;AAOD,QAAA,MAAM,qBAAqB;;;;;;;;;;;iBAQzB,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;qCAG5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAC3D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAa9E;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACjG;AAWD,sFAAsF;AACtF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,aAAiD,GAC3D,WAAW,CAiBb;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAOlF"}
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/lib/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C;AAED,eAAO,MAAM,iBAAiB;;;iBAS5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAa9E"}
package/dist/lib/email.js CHANGED
@@ -1,34 +1,24 @@
1
- import nodemailer from 'nodemailer';
2
1
  import { z } from 'zod';
3
- import { describeThrown } from './errors.js';
4
- const logEmailConfigSchema = z.object({
5
- EMAIL_PROVIDER: z.literal('log'),
2
+ export const emailConfigSchema = z.object({
3
+ /**
4
+ * The named provider `registerModules` resolves against its registry. `'log'`
5
+ * is a built-in, always present. Any other name needs a module that
6
+ * registered it via `context.provideEmailSender(name, sender)`. Free-string
7
+ * so a self-hoster can add a module core has never heard of.
8
+ */
9
+ EMAIL_PROVIDER: z.string().min(1),
6
10
  EMAIL_FROM: z.string().min(1),
7
11
  });
8
- const smtpEmailConfigSchema = z.object({
9
- EMAIL_PROVIDER: z.literal('smtp'),
10
- EMAIL_FROM: z.string().min(1),
11
- SMTP_HOST: z.string().min(1),
12
- SMTP_PORT: z.coerce.number().int().positive().max(65535),
13
- SMTP_SECURE: z.enum(['true', 'false']).transform((value) => value === 'true'),
14
- SMTP_USER: z.string().min(1),
15
- SMTP_PASSWORD: z.string().min(1),
16
- });
17
- export const emailConfigSchema = z.discriminatedUnion('EMAIL_PROVIDER', [
18
- logEmailConfigSchema,
19
- smtpEmailConfigSchema,
20
- ]);
21
12
  /**
22
- * Writes the message to the log instead of sending it. For self-hosted
23
- * development, where the reset link in the log is exactly what you want.
24
- *
25
- * This is a deliberate choice, not a fallback: `EMAIL_PROVIDER` has no default,
26
- * so nobody reaches this provider without naming it.
13
+ * Writes the message to the log instead of sending it. The registry default,
14
+ * swapped out for a real sender by picking a different provider name in
15
+ * `email.provider` (`'smtp'` for the built-in SMTP module, or any name a
16
+ * third-party provider module registers).
27
17
  */
28
18
  export function createLogEmailSender(logger, from) {
29
19
  return {
30
20
  send(message) {
31
- logger.info('email not sent: provider is "log"', {
21
+ logger.info('email not sent: no provider module registered', {
32
22
  from,
33
23
  to: message.to,
34
24
  subject: message.subject,
@@ -38,46 +28,4 @@ export function createLogEmailSender(logger, from) {
38
28
  },
39
29
  };
40
30
  }
41
- function createNodemailerTransport(config) {
42
- return nodemailer.createTransport({
43
- host: config.SMTP_HOST,
44
- port: config.SMTP_PORT,
45
- secure: config.SMTP_SECURE,
46
- auth: { user: config.SMTP_USER, pass: config.SMTP_PASSWORD },
47
- });
48
- }
49
- /** Sends over SMTP. `transport` defaults to a real connection built from `config`. */
50
- export function createSmtpEmailSender(config, logger, transport = createNodemailerTransport(config)) {
51
- return {
52
- async send(message) {
53
- try {
54
- await transport.sendMail({
55
- from: config.EMAIL_FROM,
56
- to: message.to,
57
- subject: message.subject,
58
- text: message.body,
59
- });
60
- }
61
- catch (cause) {
62
- const reason = describeThrown(cause);
63
- logger.error('smtp send failed', { to: message.to, reason });
64
- throw new Error(`Failed to send email to ${message.to} over SMTP: ${reason}`, { cause });
65
- }
66
- },
67
- };
68
- }
69
- /**
70
- * Builds the configured sender.
71
- *
72
- * @throws Never. An unknown provider cannot reach here: the config schema is a
73
- * discriminated union, so boot rejects it first.
74
- */
75
- export function createEmailSender(config, logger) {
76
- switch (config.EMAIL_PROVIDER) {
77
- case 'log':
78
- return createLogEmailSender(logger, config.EMAIL_FROM);
79
- case 'smtp':
80
- return createSmtpEmailSender(config, logger);
81
- }
82
- }
83
31
  //# sourceMappingURL=email.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/lib/email.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/lib/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA8BvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC9B,CAAC,CAAA;AAIF;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,IAAY;IAC/D,OAAO;QACL,IAAI,CAAC,OAAO;YACV,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE;gBAC3D,IAAI;gBACJ,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC,CAAA;YAEF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type { ZodType } from 'zod';
2
+ import type { Environment } from './config.ts';
3
+ /**
4
+ * A marker a `kelpie.config.ts` file uses to say "read this leaf from the
5
+ * environment." The assembly's config file is the shape and the defaults;
6
+ * `fromEnv` marks the leaves a deployment may override without a code change.
7
+ *
8
+ * Every marker names an env var, the Zod schema that parses it, and optionally
9
+ * a default. Without a default the marker is required: the env var must be set,
10
+ * or boot fails with the other configuration problems.
11
+ *
12
+ * The resolver walks the config object, replaces each marker with the parsed
13
+ * value, and returns the fully-resolved object. Nothing in the app reads
14
+ * `process.env` for these fields after boot.
15
+ */
16
+ declare const FROM_ENV_MARKER: unique symbol;
17
+ export interface FromEnvMarker<T> {
18
+ readonly [FROM_ENV_MARKER]: true;
19
+ readonly envKey: string;
20
+ readonly schema: ZodType<T>;
21
+ readonly defaultValue: T | undefined;
22
+ readonly hasDefault: boolean;
23
+ }
24
+ /** A leaf in the config file: either a literal already-typed value, or a marker. */
25
+ export type ConfigValue<T> = T | FromEnvMarker<T>;
26
+ export declare function fromEnv<T>(envKey: string, schema: ZodType<T>): FromEnvMarker<T>;
27
+ export declare function fromEnv<T>(envKey: string, schema: ZodType<T>, defaultValue: T): FromEnvMarker<T>;
28
+ export declare function isFromEnvMarker(value: unknown): value is FromEnvMarker<unknown>;
29
+ /** One problem discovered while resolving markers. Path is the dotted field. */
30
+ export interface FromEnvProblem {
31
+ readonly path: string;
32
+ readonly message: string;
33
+ }
34
+ export interface ResolveResult<T> {
35
+ readonly value: T | undefined;
36
+ readonly problems: readonly FromEnvProblem[];
37
+ }
38
+ /**
39
+ * Resolves one marker against an environment.
40
+ *
41
+ * Missing and no default: one required problem.
42
+ * Missing with default: the default, unvalidated. A hardcoded default is
43
+ * trusted because the developer wrote it in the assembly file.
44
+ * Present: parsed through the marker's schema. Parse failures become problems.
45
+ */
46
+ export declare function resolveMarker<T>(marker: FromEnvMarker<T>, environment: Environment, path: string): ResolveResult<T>;
47
+ /**
48
+ * Walks any value, replacing every `FromEnvMarker` with its resolved value.
49
+ * Objects and arrays are walked recursively; other values pass through.
50
+ *
51
+ * Collects problems from every marker rather than throwing at the first one,
52
+ * so a self-hoster fixes their environment once rather than a variable at a
53
+ * time.
54
+ */
55
+ export declare function resolveMarkers(input: unknown, environment: Environment, path?: string): {
56
+ readonly value: unknown;
57
+ readonly problems: readonly FromEnvProblem[];
58
+ };
59
+ export {};
60
+ //# sourceMappingURL=fromEnv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromEnv.d.ts","sourceRoot":"","sources":["../../src/lib/fromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAElC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;;;;;;;;;;GAYG;AAEH,QAAA,MAAM,eAAe,eAA+B,CAAA;AAEpD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IAC3B,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAC7B;AAED,oFAAoF;AACpF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;AAEjD,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;AAChF,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;AAajG,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAE/E;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAA;CAC7C;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CA2BnH;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,WAAW,EACxB,IAAI,SAAK,GACR;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,CAiC3E"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * A marker a `kelpie.config.ts` file uses to say "read this leaf from the
3
+ * environment." The assembly's config file is the shape and the defaults;
4
+ * `fromEnv` marks the leaves a deployment may override without a code change.
5
+ *
6
+ * Every marker names an env var, the Zod schema that parses it, and optionally
7
+ * a default. Without a default the marker is required: the env var must be set,
8
+ * or boot fails with the other configuration problems.
9
+ *
10
+ * The resolver walks the config object, replaces each marker with the parsed
11
+ * value, and returns the fully-resolved object. Nothing in the app reads
12
+ * `process.env` for these fields after boot.
13
+ */
14
+ const FROM_ENV_MARKER = Symbol.for('kelpie.fromEnv');
15
+ export function fromEnv(envKey, schema, defaultValue) {
16
+ const hasDefault = arguments.length >= 3;
17
+ return {
18
+ [FROM_ENV_MARKER]: true,
19
+ envKey,
20
+ schema,
21
+ defaultValue: hasDefault ? defaultValue : undefined,
22
+ hasDefault,
23
+ };
24
+ }
25
+ export function isFromEnvMarker(value) {
26
+ return typeof value === 'object' && value !== null && value[FROM_ENV_MARKER] === true;
27
+ }
28
+ /**
29
+ * Resolves one marker against an environment.
30
+ *
31
+ * Missing and no default: one required problem.
32
+ * Missing with default: the default, unvalidated. A hardcoded default is
33
+ * trusted because the developer wrote it in the assembly file.
34
+ * Present: parsed through the marker's schema. Parse failures become problems.
35
+ */
36
+ export function resolveMarker(marker, environment, path) {
37
+ const raw = environment[marker.envKey];
38
+ if (raw === undefined) {
39
+ if (marker.hasDefault) {
40
+ return { value: marker.defaultValue, problems: [] };
41
+ }
42
+ return {
43
+ value: undefined,
44
+ problems: [{ path, message: `${marker.envKey} is required` }],
45
+ };
46
+ }
47
+ const result = marker.schema.safeParse(raw);
48
+ if (!result.success) {
49
+ return {
50
+ value: undefined,
51
+ problems: result.error.issues.map((issue) => ({
52
+ path,
53
+ message: `${marker.envKey}: ${issue.message}`,
54
+ })),
55
+ };
56
+ }
57
+ return { value: result.data, problems: [] };
58
+ }
59
+ /**
60
+ * Walks any value, replacing every `FromEnvMarker` with its resolved value.
61
+ * Objects and arrays are walked recursively; other values pass through.
62
+ *
63
+ * Collects problems from every marker rather than throwing at the first one,
64
+ * so a self-hoster fixes their environment once rather than a variable at a
65
+ * time.
66
+ */
67
+ export function resolveMarkers(input, environment, path = '') {
68
+ if (isFromEnvMarker(input)) {
69
+ return resolveMarker(input, environment, path);
70
+ }
71
+ if (Array.isArray(input)) {
72
+ const problems = [];
73
+ const value = input.map((item, index) => {
74
+ const childPath = `${path}[${String(index)}]`;
75
+ const result = resolveMarkers(item, environment, childPath);
76
+ problems.push(...result.problems);
77
+ return result.value;
78
+ });
79
+ return { value, problems };
80
+ }
81
+ if (typeof input === 'object' && input !== null) {
82
+ const problems = [];
83
+ const value = {};
84
+ for (const [key, child] of Object.entries(input)) {
85
+ const childPath = path.length > 0 ? `${path}.${key}` : key;
86
+ const result = resolveMarkers(child, environment, childPath);
87
+ problems.push(...result.problems);
88
+ value[key] = result.value;
89
+ }
90
+ return { value, problems };
91
+ }
92
+ return { value: input, problems: [] };
93
+ }
94
+ //# sourceMappingURL=fromEnv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromEnv.js","sourceRoot":"","sources":["../../src/lib/fromEnv.ts"],"names":[],"mappings":"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"}
package/dist/lib/ids.d.ts CHANGED
@@ -50,6 +50,12 @@ export declare const idPrefixes: {
50
50
  * a bucket is bookkeeping the rate limiter owns, not a resource with routes.
51
51
  */
52
52
  readonly rateLimitBucket: 'rl';
53
+ /**
54
+ * One published domain event. Stamped on the envelope so downstream consumers
55
+ * (webhooks, MCP subscribers, an eventual outbox) have a stable idempotency
56
+ * key. Not persisted by core.
57
+ */
58
+ readonly event: 'ev';
53
59
  };
54
60
  export type ObjectKind = keyof typeof idPrefixes;
55
61
  export type IdFactory = (kind: ObjectKind) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/lib/ids.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,UAAU;aACrB,SAAS,EAAE,IAAI;aACf,IAAI,EAAE,KAAK;aACX,OAAO,EAAE,KAAK;aACd,kBAAkB,EAAE,KAAK;IACzB,wFAAwF;aACxF,sBAAsB,EAAE,KAAK;aAC7B,UAAU,EAAE,KAAK;aACjB,MAAM,EAAE,KAAK;aACb,MAAM,EAAE,KAAK;aACb,MAAM,EAAE,KAAK;aACb,OAAO,EAAE,KAAK;aACd,QAAQ,EAAE,KAAK;aACf,aAAa,EAAE,OAAO;aACtB,IAAI,EAAE,MAAM;aACZ,WAAW,EAAE,KAAK;aAClB,WAAW,EAAE,KAAK;aAClB,KAAK,EAAE,KAAK;aACZ,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,MAAM;aACjB,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,KAAK;aACf,IAAI,EAAE,MAAM;aACZ,QAAQ,EAAE,KAAK;aACf,YAAY,EAAE,IAAI;aAClB,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,IAAI;aACf,cAAc,EAAE,KAAK;aACrB,OAAO,EAAE,IAAI;IACb,8EAA8E;aAC9E,eAAe,EAAE,KAAK;aACtB,iBAAiB,EAAE,IAAI;aACvB,QAAQ,EAAE,KAAK;aACf,SAAS,EAAE,KAAK;IAChB,6FAA6F;aAC7F,aAAa,EAAE,MAAM;IACrB;;;;;OAKG;aACH,cAAc,EAAE,MAAM;IACtB;;;OAGG;aACH,eAAe,EAAE,IAAI;CACb,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,CAAA;AAEhD,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,GAAE,MAAM,MAAa,GAAG,SAAS,CAE5E"}
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/lib/ids.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,UAAU;aACrB,SAAS,EAAE,IAAI;aACf,IAAI,EAAE,KAAK;aACX,OAAO,EAAE,KAAK;aACd,kBAAkB,EAAE,KAAK;IACzB,wFAAwF;aACxF,sBAAsB,EAAE,KAAK;aAC7B,UAAU,EAAE,KAAK;aACjB,MAAM,EAAE,KAAK;aACb,MAAM,EAAE,KAAK;aACb,MAAM,EAAE,KAAK;aACb,OAAO,EAAE,KAAK;aACd,QAAQ,EAAE,KAAK;aACf,aAAa,EAAE,OAAO;aACtB,IAAI,EAAE,MAAM;aACZ,WAAW,EAAE,KAAK;aAClB,WAAW,EAAE,KAAK;aAClB,KAAK,EAAE,KAAK;aACZ,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,MAAM;aACjB,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,KAAK;aACf,IAAI,EAAE,MAAM;aACZ,QAAQ,EAAE,KAAK;aACf,YAAY,EAAE,IAAI;aAClB,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,IAAI;aACf,cAAc,EAAE,KAAK;aACrB,OAAO,EAAE,IAAI;IACb,8EAA8E;aAC9E,eAAe,EAAE,KAAK;aACtB,iBAAiB,EAAE,IAAI;aACvB,QAAQ,EAAE,KAAK;aACf,SAAS,EAAE,KAAK;IAChB,6FAA6F;aAC7F,aAAa,EAAE,MAAM;IACrB;;;;;OAKG;aACH,cAAc,EAAE,MAAM;IACtB;;;OAGG;aACH,eAAe,EAAE,IAAI;IACrB;;;;OAIG;aACH,KAAK,EAAE,IAAI;CACH,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,CAAA;AAEhD,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,GAAE,MAAM,MAAa,GAAG,SAAS,CAE5E"}
package/dist/lib/ids.js CHANGED
@@ -51,6 +51,12 @@ export const idPrefixes = {
51
51
  * a bucket is bookkeeping the rate limiter owns, not a resource with routes.
52
52
  */
53
53
  rateLimitBucket: 'rl',
54
+ /**
55
+ * One published domain event. Stamped on the envelope so downstream consumers
56
+ * (webhooks, MCP subscribers, an eventual outbox) have a stable idempotency
57
+ * key. Not persisted by core.
58
+ */
59
+ event: 'ev',
54
60
  };
55
61
  /**
56
62
  * Builds the id factory. The ULID generator is injected so tests can pin ids;
@@ -1 +1 @@
1
- {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/lib/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,KAAK;IACd,kBAAkB,EAAE,KAAK;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,KAAK;IAC7B,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,aAAa,EAAE,OAAO;IACtB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;IAClB,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,KAAK;IACrB,OAAO,EAAE,IAAI;IACb,8EAA8E;IAC9E,eAAe,EAAE,KAAK;IACtB,iBAAiB,EAAE,IAAI;IACvB,QAAQ,EAAE,KAAK;IACf,SAAS,EAAE,KAAK;IAChB,6FAA6F;IAC7F,aAAa,EAAE,MAAM;IACrB;;;;;OAKG;IACH,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,eAAe,EAAE,IAAI;CACb,CAAA;AAMV;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,YAAY,GAAiB,IAAI;IAC/D,OAAO,CAAC,IAAgB,EAAU,EAAE,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,YAAY,EAAE,EAAE,CAAA;AAC9E,CAAC"}
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/lib/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,KAAK;IACd,kBAAkB,EAAE,KAAK;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,KAAK;IAC7B,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,aAAa,EAAE,OAAO;IACtB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;IAClB,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,KAAK;IACrB,OAAO,EAAE,IAAI;IACb,8EAA8E;IAC9E,eAAe,EAAE,KAAK;IACtB,iBAAiB,EAAE,IAAI;IACvB,QAAQ,EAAE,KAAK;IACf,SAAS,EAAE,KAAK;IAChB,6FAA6F;IAC7F,aAAa,EAAE,MAAM;IACrB;;;;;OAKG;IACH,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,eAAe,EAAE,IAAI;IACrB;;;;OAIG;IACH,KAAK,EAAE,IAAI;CACH,CAAA;AAMV;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,YAAY,GAAiB,IAAI;IAC/D,OAAO,CAAC,IAAgB,EAAU,EAAE,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,YAAY,EAAE,EAAE,CAAA;AAC9E,CAAC"}
@@ -0,0 +1,129 @@
1
+ import type { KelpieModule } from '../runtime/module.ts';
2
+ import { type Environment, type KelpieConfig, type LogLevel, type RuntimeMode } from './config.ts';
3
+ import { type ConfigValue } from './fromEnv.ts';
4
+ import type { LoggingDestination } from './logger.ts';
5
+ /**
6
+ * The shape a `kelpie.config.ts` file declares.
7
+ *
8
+ * Every leaf is either a literal value the assembly commits to git, or a
9
+ * `fromEnv(...)` marker the deployment fills in. The resolver walks this
10
+ * object, replaces markers with parsed values, and returns a fully-populated
11
+ * `KelpieConfig`.
12
+ *
13
+ * The file is the map. `fromEnv(...)` marks the leaves a deployment overrides.
14
+ * Nothing in the app reads `process.env` for these fields after boot.
15
+ */
16
+ export interface KelpieConfigInput {
17
+ readonly runtimeMode: ConfigValue<RuntimeMode>;
18
+ readonly port: ConfigValue<number>;
19
+ readonly databaseUrl: ConfigValue<string>;
20
+ readonly logging: LoggingInput;
21
+ /** Optional; unset in development, set to the built web bundle in a deployment. */
22
+ readonly webBundleDirectory?: ConfigValue<string | undefined>;
23
+ /** Optional; unset in development, set to the deploy-time module override file. */
24
+ readonly moduleConfigPath?: ConfigValue<string | undefined>;
25
+ /**
26
+ * Human-readable name of this deployment ("dev", "demo", "cloud"). Optional.
27
+ * Read by the browser through `GET /v1/public/config` so a non-production UI
28
+ * can name the site it is on. Ignored when `runtimeMode` is `production`.
29
+ */
30
+ readonly siteName?: ConfigValue<string | undefined>;
31
+ /** Optional; defaults to 0 (no proxy in front). */
32
+ readonly trustedProxyHopCount?: ConfigValue<number>;
33
+ /**
34
+ * The deployment's base URL. Every emailed link (password reset, email
35
+ * verification, invite) is built from it. Required by the workspace and auth
36
+ * modules. Optional here so an older assembly can omit it and let those
37
+ * modules fall back to the `context.config(appUrlConfigSchema)` path.
38
+ */
39
+ readonly appBaseUrl?: ConfigValue<string>;
40
+ /**
41
+ * Keys that seal stored secrets (webhook signing secrets, agent-task auth
42
+ * headers). Required by the webhooks and agent-tasks modules. Optional here
43
+ * for the same reason `appBaseUrl` is.
44
+ */
45
+ readonly secretEncryption?: SecretEncryptionInput;
46
+ readonly email: EmailInput;
47
+ /** Optional; each unset field falls back to the same defaults `loadConfig` used. */
48
+ readonly rateLimit?: RateLimitInput;
49
+ /**
50
+ * Env-keyed values the assembly can lock in code, or defer to the
51
+ * environment. Modules read this through `context.config(schema)`; each
52
+ * module's own Zod schema still names the keys and validates them.
53
+ *
54
+ * A key present here overrides the same key in `process.env`. A key absent
55
+ * here falls through to `process.env` unchanged, so the section is a
56
+ * progressive migration: lock what you want to lock, leave the rest.
57
+ *
58
+ * Literal: `SECRET_ENCRYPTION_KEY: 'a-committed-key'` (don't do this for
59
+ * secrets — the point is you can, if the value is not a secret).
60
+ * Marker: `SECRET_ENCRYPTION_KEY: fromEnv('SECRET_ENCRYPTION_KEY', z.string())`
61
+ * defers to the environment, same as today.
62
+ */
63
+ readonly env?: Readonly<Record<string, ConfigValue<string | undefined>>>;
64
+ /** The module list the assembly composes. Same shape it had before. */
65
+ readonly modules: readonly KelpieModule[];
66
+ }
67
+ /**
68
+ * The `logging` sub-tree of the assembly config.
69
+ *
70
+ * `level` is the minimum severity to emit. `destinations` is the ordered list
71
+ * of destinations each line writes to; stdout is the default entry in the
72
+ * template assembly, and a self-hoster adds another by extending
73
+ * `LoggingDestination` in `@kelpie/server` and putting a matching entry here.
74
+ */
75
+ export interface LoggingInput {
76
+ readonly level: ConfigValue<LogLevel>;
77
+ readonly destinations: readonly LoggingDestination[];
78
+ }
79
+ /**
80
+ * The `email` sub-tree of the assembly config.
81
+ *
82
+ * `provider` names one entry in the runtime's provider registry. `'log'` is a
83
+ * built-in the runtime always registers; `'smtp'` is registered by the
84
+ * built-in `smtp-email` core module; third-party provider modules register
85
+ * their own names (an API-based provider might register `'resend'` or
86
+ * `'postmark'`, and so on). Free-string so a self-hoster can install a
87
+ * module core has never heard of.
88
+ *
89
+ * `from` is the address on every outgoing message. Provider-specific config
90
+ * (SMTP host and credentials, an API key) belongs to the provider module,
91
+ * which reads it through `context.config(...)`; putting it here would tie the
92
+ * assembly config to a single transport.
93
+ */
94
+ export interface EmailInput {
95
+ readonly provider: ConfigValue<string>;
96
+ readonly from: ConfigValue<string>;
97
+ }
98
+ export interface SecretEncryptionInput {
99
+ readonly key: ConfigValue<string>;
100
+ /** Absent (or blank) is normal; only set while rotating away from an older key. */
101
+ readonly previousKey?: ConfigValue<string | undefined>;
102
+ }
103
+ export interface RateLimitBudgetInput {
104
+ readonly limit?: ConfigValue<number>;
105
+ readonly windowSeconds?: ConfigValue<number>;
106
+ }
107
+ export interface RateLimitInput {
108
+ readonly forms?: RateLimitBudgetInput;
109
+ readonly auth?: RateLimitBudgetInput;
110
+ readonly loginAccount?: RateLimitBudgetInput;
111
+ readonly api?: RateLimitBudgetInput;
112
+ }
113
+ /**
114
+ * Identity helper for the assembly's config file. It exists for the type-check
115
+ * only: `defineKelpieConfig({...})` makes TypeScript check the object against
116
+ * `KelpieConfigInput` at the call site, so a wrong-shape field is caught in
117
+ * the assembly rather than at boot.
118
+ */
119
+ export declare function defineKelpieConfig(input: KelpieConfigInput): KelpieConfigInput;
120
+ /**
121
+ * Resolves an assembly's config against an environment.
122
+ *
123
+ * Every `fromEnv` marker is resolved. Missing required variables and parse
124
+ * failures are collected together, so a self-hoster fixes them in one pass.
125
+ *
126
+ * @throws ConfigurationError listing every problem.
127
+ */
128
+ export declare function resolveKelpieConfig(input: KelpieConfigInput, environment: Environment): KelpieConfig;
129
+ //# sourceMappingURL=kelpieConfigFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kelpieConfigFile.d.ts","sourceRoot":"","sources":["../../src/lib/kelpieConfigFile.ts"],"names":[],"mappings":"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"}