@mantajs/core 0.1.7 → 0.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/dist/adapters/auth-mock.d.ts +44 -0
  2. package/dist/adapters/auth-mock.d.ts.map +1 -0
  3. package/dist/adapters/auth-mock.js +160 -0
  4. package/dist/adapters/auth-mock.js.map +1 -0
  5. package/dist/adapters/cache-memory.d.ts +11 -0
  6. package/dist/adapters/cache-memory.d.ts.map +1 -0
  7. package/dist/adapters/cache-memory.js +32 -0
  8. package/dist/adapters/cache-memory.js.map +1 -0
  9. package/dist/adapters/database-memory.d.ts +24 -0
  10. package/dist/adapters/database-memory.d.ts.map +1 -0
  11. package/dist/adapters/database-memory.js +141 -0
  12. package/dist/adapters/database-memory.js.map +1 -0
  13. package/dist/adapters/eventbus-memory.d.ts +37 -0
  14. package/dist/adapters/eventbus-memory.d.ts.map +1 -0
  15. package/dist/adapters/eventbus-memory.js +166 -0
  16. package/dist/adapters/eventbus-memory.js.map +1 -0
  17. package/dist/adapters/file-memory.d.ts +24 -0
  18. package/dist/adapters/file-memory.d.ts.map +1 -0
  19. package/dist/adapters/file-memory.js +77 -0
  20. package/dist/adapters/file-memory.js.map +1 -0
  21. package/dist/adapters/http-memory.d.ts +23 -0
  22. package/dist/adapters/http-memory.d.ts.map +1 -0
  23. package/dist/adapters/http-memory.js +149 -0
  24. package/dist/adapters/http-memory.js.map +1 -0
  25. package/dist/adapters/index.d.ts +14 -0
  26. package/dist/adapters/index.d.ts.map +1 -0
  27. package/dist/adapters/index.js +15 -0
  28. package/dist/adapters/index.js.map +1 -0
  29. package/dist/adapters/job-scheduler-memory.d.ts +20 -0
  30. package/dist/adapters/job-scheduler-memory.d.ts.map +1 -0
  31. package/dist/adapters/job-scheduler-memory.js +103 -0
  32. package/dist/adapters/job-scheduler-memory.js.map +1 -0
  33. package/dist/adapters/locking-memory.d.ts +20 -0
  34. package/dist/adapters/locking-memory.d.ts.map +1 -0
  35. package/dist/adapters/locking-memory.js +85 -0
  36. package/dist/adapters/locking-memory.js.map +1 -0
  37. package/dist/adapters/logger-test.d.ts +30 -0
  38. package/dist/adapters/logger-test.d.ts.map +1 -0
  39. package/dist/adapters/logger-test.js +77 -0
  40. package/dist/adapters/logger-test.js.map +1 -0
  41. package/dist/adapters/notification-memory.d.ts +27 -0
  42. package/dist/adapters/notification-memory.d.ts.map +1 -0
  43. package/dist/adapters/notification-memory.js +69 -0
  44. package/dist/adapters/notification-memory.js.map +1 -0
  45. package/dist/adapters/relational-query-memory.d.ts +47 -0
  46. package/dist/adapters/relational-query-memory.d.ts.map +1 -0
  47. package/dist/adapters/relational-query-memory.js +263 -0
  48. package/dist/adapters/relational-query-memory.js.map +1 -0
  49. package/dist/adapters/repository-factory-memory.d.ts +17 -0
  50. package/dist/adapters/repository-factory-memory.d.ts.map +1 -0
  51. package/dist/adapters/repository-factory-memory.js +32 -0
  52. package/dist/adapters/repository-factory-memory.js.map +1 -0
  53. package/dist/adapters/repository-memory.d.ts +30 -0
  54. package/dist/adapters/repository-memory.d.ts.map +1 -0
  55. package/dist/adapters/repository-memory.js +183 -0
  56. package/dist/adapters/repository-memory.js.map +1 -0
  57. package/dist/ai/index.d.ts +53 -0
  58. package/dist/ai/index.d.ts.map +1 -0
  59. package/dist/ai/index.js +48 -0
  60. package/dist/ai/index.js.map +1 -0
  61. package/dist/app/index.d.ts +97 -0
  62. package/dist/app/index.d.ts.map +1 -0
  63. package/dist/app/index.js +217 -0
  64. package/dist/app/index.js.map +1 -0
  65. package/dist/app/request-context.d.ts +35 -0
  66. package/dist/app/request-context.d.ts.map +1 -0
  67. package/dist/app/request-context.js +32 -0
  68. package/dist/app/request-context.js.map +1 -0
  69. package/dist/auth/auth-module-service.d.ts +62 -0
  70. package/dist/auth/auth-module-service.d.ts.map +1 -0
  71. package/dist/auth/auth-module-service.js +210 -0
  72. package/dist/auth/auth-module-service.js.map +1 -0
  73. package/dist/auth/index.d.ts +7 -0
  74. package/dist/auth/index.d.ts.map +1 -0
  75. package/dist/auth/index.js +5 -0
  76. package/dist/auth/index.js.map +1 -0
  77. package/dist/auth/middleware.d.ts +19 -0
  78. package/dist/auth/middleware.d.ts.map +1 -0
  79. package/dist/auth/middleware.js +61 -0
  80. package/dist/auth/middleware.js.map +1 -0
  81. package/dist/auth/models/auth-identity.d.ts +11 -0
  82. package/dist/auth/models/auth-identity.d.ts.map +1 -0
  83. package/dist/auth/models/auth-identity.js +12 -0
  84. package/dist/auth/models/auth-identity.js.map +1 -0
  85. package/dist/auth/providers/emailpass.d.ts +7 -0
  86. package/dist/auth/providers/emailpass.d.ts.map +1 -0
  87. package/dist/auth/providers/emailpass.js +94 -0
  88. package/dist/auth/providers/emailpass.js.map +1 -0
  89. package/dist/auth/providers/types.d.ts +66 -0
  90. package/dist/auth/providers/types.d.ts.map +1 -0
  91. package/dist/auth/providers/types.js +3 -0
  92. package/dist/auth/providers/types.js.map +1 -0
  93. package/dist/auth/types.d.ts +36 -0
  94. package/dist/auth/types.d.ts.map +1 -0
  95. package/dist/auth/types.js +3 -0
  96. package/dist/auth/types.js.map +1 -0
  97. package/dist/command/define-command-graph.d.ts +63 -0
  98. package/dist/command/define-command-graph.d.ts.map +1 -0
  99. package/dist/command/define-command-graph.js +80 -0
  100. package/dist/command/define-command-graph.js.map +1 -0
  101. package/dist/command/dml-to-zod.d.ts +34 -0
  102. package/dist/command/dml-to-zod.d.ts.map +1 -0
  103. package/dist/command/dml-to-zod.js +140 -0
  104. package/dist/command/dml-to-zod.js.map +1 -0
  105. package/dist/command/generate-entity-commands.d.ts +68 -0
  106. package/dist/command/generate-entity-commands.d.ts.map +1 -0
  107. package/dist/command/generate-entity-commands.js +350 -0
  108. package/dist/command/generate-entity-commands.js.map +1 -0
  109. package/dist/command/index.d.ts +54 -0
  110. package/dist/command/index.d.ts.map +1 -0
  111. package/dist/command/index.js +338 -0
  112. package/dist/command/index.js.map +1 -0
  113. package/dist/command/types.d.ts +131 -0
  114. package/dist/command/types.d.ts.map +1 -0
  115. package/dist/command/types.js +2 -0
  116. package/dist/command/types.js.map +1 -0
  117. package/dist/config/built-in-presets.d.ts +20 -0
  118. package/dist/config/built-in-presets.d.ts.map +1 -0
  119. package/dist/config/built-in-presets.js +70 -0
  120. package/dist/config/built-in-presets.js.map +1 -0
  121. package/dist/config/config-manager.d.ts +117 -0
  122. package/dist/config/config-manager.d.ts.map +1 -0
  123. package/dist/config/config-manager.js +245 -0
  124. package/dist/config/config-manager.js.map +1 -0
  125. package/dist/config/define-config.d.ts +20 -0
  126. package/dist/config/define-config.d.ts.map +1 -0
  127. package/dist/config/define-config.js +64 -0
  128. package/dist/config/define-config.js.map +1 -0
  129. package/dist/config/feature-flags.d.ts +48 -0
  130. package/dist/config/feature-flags.d.ts.map +1 -0
  131. package/dist/config/feature-flags.js +97 -0
  132. package/dist/config/feature-flags.js.map +1 -0
  133. package/dist/config/index.d.ts +9 -0
  134. package/dist/config/index.d.ts.map +1 -0
  135. package/dist/config/index.js +8 -0
  136. package/dist/config/index.js.map +1 -0
  137. package/dist/config/presets.d.ts +38 -0
  138. package/dist/config/presets.d.ts.map +1 -0
  139. package/dist/config/presets.js +29 -0
  140. package/dist/config/presets.js.map +1 -0
  141. package/dist/config/types.d.ts +707 -0
  142. package/dist/config/types.d.ts.map +1 -0
  143. package/dist/config/types.js +112 -0
  144. package/dist/config/types.js.map +1 -0
  145. package/dist/context/index.d.ts +95 -0
  146. package/dist/context/index.d.ts.map +1 -0
  147. package/dist/context/index.js +26 -0
  148. package/dist/context/index.js.map +1 -0
  149. package/dist/context/registry.d.ts +32 -0
  150. package/dist/context/registry.d.ts.map +1 -0
  151. package/dist/context/registry.js +142 -0
  152. package/dist/context/registry.js.map +1 -0
  153. package/dist/db/index.d.ts +2 -0
  154. package/dist/db/index.d.ts.map +1 -0
  155. package/dist/db/index.js +4 -0
  156. package/dist/db/index.js.map +1 -0
  157. package/dist/db/schema.d.ts +839 -0
  158. package/dist/db/schema.d.ts.map +1 -0
  159. package/dist/db/schema.js +106 -0
  160. package/dist/db/schema.js.map +1 -0
  161. package/dist/dml/entity.d.ts +132 -0
  162. package/dist/dml/entity.d.ts.map +1 -0
  163. package/dist/dml/entity.js +110 -0
  164. package/dist/dml/entity.js.map +1 -0
  165. package/dist/dml/from-zod.d.ts +13 -0
  166. package/dist/dml/from-zod.d.ts.map +1 -0
  167. package/dist/dml/from-zod.js +81 -0
  168. package/dist/dml/from-zod.js.map +1 -0
  169. package/dist/dml/generator/index.d.ts +62 -0
  170. package/dist/dml/generator/index.d.ts.map +1 -0
  171. package/dist/dml/generator/index.js +208 -0
  172. package/dist/dml/generator/index.js.map +1 -0
  173. package/dist/dml/index.d.ts +11 -0
  174. package/dist/dml/index.d.ts.map +1 -0
  175. package/dist/dml/index.js +13 -0
  176. package/dist/dml/index.js.map +1 -0
  177. package/dist/dml/infer.d.ts +36 -0
  178. package/dist/dml/infer.d.ts.map +1 -0
  179. package/dist/dml/infer.js +5 -0
  180. package/dist/dml/infer.js.map +1 -0
  181. package/dist/dml/model.d.ts +58 -0
  182. package/dist/dml/model.d.ts.map +1 -0
  183. package/dist/dml/model.js +95 -0
  184. package/dist/dml/model.js.map +1 -0
  185. package/dist/dml/modifiers.d.ts +9 -0
  186. package/dist/dml/modifiers.d.ts.map +1 -0
  187. package/dist/dml/modifiers.js +25 -0
  188. package/dist/dml/modifiers.js.map +1 -0
  189. package/dist/dml/properties/array.d.ts +7 -0
  190. package/dist/dml/properties/array.d.ts.map +1 -0
  191. package/dist/dml/properties/array.js +5 -0
  192. package/dist/dml/properties/array.js.map +1 -0
  193. package/dist/dml/properties/autoincrement.d.ts +7 -0
  194. package/dist/dml/properties/autoincrement.d.ts.map +1 -0
  195. package/dist/dml/properties/autoincrement.js +5 -0
  196. package/dist/dml/properties/autoincrement.js.map +1 -0
  197. package/dist/dml/properties/base.d.ts +124 -0
  198. package/dist/dml/properties/base.d.ts.map +1 -0
  199. package/dist/dml/properties/base.js +76 -0
  200. package/dist/dml/properties/base.js.map +1 -0
  201. package/dist/dml/properties/big-number.d.ts +7 -0
  202. package/dist/dml/properties/big-number.d.ts.map +1 -0
  203. package/dist/dml/properties/big-number.js +5 -0
  204. package/dist/dml/properties/big-number.js.map +1 -0
  205. package/dist/dml/properties/boolean.d.ts +7 -0
  206. package/dist/dml/properties/boolean.d.ts.map +1 -0
  207. package/dist/dml/properties/boolean.js +5 -0
  208. package/dist/dml/properties/boolean.js.map +1 -0
  209. package/dist/dml/properties/computed.d.ts +9 -0
  210. package/dist/dml/properties/computed.d.ts.map +1 -0
  211. package/dist/dml/properties/computed.js +22 -0
  212. package/dist/dml/properties/computed.js.map +1 -0
  213. package/dist/dml/properties/date-time.d.ts +7 -0
  214. package/dist/dml/properties/date-time.d.ts.map +1 -0
  215. package/dist/dml/properties/date-time.js +5 -0
  216. package/dist/dml/properties/date-time.js.map +1 -0
  217. package/dist/dml/properties/enum.d.ts +12 -0
  218. package/dist/dml/properties/enum.d.ts.map +1 -0
  219. package/dist/dml/properties/enum.js +14 -0
  220. package/dist/dml/properties/enum.js.map +1 -0
  221. package/dist/dml/properties/float.d.ts +7 -0
  222. package/dist/dml/properties/float.d.ts.map +1 -0
  223. package/dist/dml/properties/float.js +5 -0
  224. package/dist/dml/properties/float.js.map +1 -0
  225. package/dist/dml/properties/index.d.ts +15 -0
  226. package/dist/dml/properties/index.d.ts.map +1 -0
  227. package/dist/dml/properties/index.js +15 -0
  228. package/dist/dml/properties/index.js.map +1 -0
  229. package/dist/dml/properties/json.d.ts +7 -0
  230. package/dist/dml/properties/json.d.ts.map +1 -0
  231. package/dist/dml/properties/json.js +6 -0
  232. package/dist/dml/properties/json.js.map +1 -0
  233. package/dist/dml/properties/nullable.d.ts +23 -0
  234. package/dist/dml/properties/nullable.d.ts.map +1 -0
  235. package/dist/dml/properties/nullable.js +46 -0
  236. package/dist/dml/properties/nullable.js.map +1 -0
  237. package/dist/dml/properties/number.d.ts +10 -0
  238. package/dist/dml/properties/number.d.ts.map +1 -0
  239. package/dist/dml/properties/number.js +13 -0
  240. package/dist/dml/properties/number.js.map +1 -0
  241. package/dist/dml/properties/primary-key.d.ts +14 -0
  242. package/dist/dml/properties/primary-key.d.ts.map +1 -0
  243. package/dist/dml/properties/primary-key.js +23 -0
  244. package/dist/dml/properties/primary-key.js.map +1 -0
  245. package/dist/dml/properties/text.d.ts +15 -0
  246. package/dist/dml/properties/text.d.ts.map +1 -0
  247. package/dist/dml/properties/text.js +19 -0
  248. package/dist/dml/properties/text.js.map +1 -0
  249. package/dist/dml/relations/belongs-to.d.ts +20 -0
  250. package/dist/dml/relations/belongs-to.d.ts.map +1 -0
  251. package/dist/dml/relations/belongs-to.js +29 -0
  252. package/dist/dml/relations/belongs-to.js.map +1 -0
  253. package/dist/dml/relations/has-many.d.ts +16 -0
  254. package/dist/dml/relations/has-many.d.ts.map +1 -0
  255. package/dist/dml/relations/has-many.js +25 -0
  256. package/dist/dml/relations/has-many.js.map +1 -0
  257. package/dist/dml/relations/has-one.d.ts +26 -0
  258. package/dist/dml/relations/has-one.d.ts.map +1 -0
  259. package/dist/dml/relations/has-one.js +46 -0
  260. package/dist/dml/relations/has-one.js.map +1 -0
  261. package/dist/dml/relations/many-to-many.d.ts +9 -0
  262. package/dist/dml/relations/many-to-many.d.ts.map +1 -0
  263. package/dist/dml/relations/many-to-many.js +11 -0
  264. package/dist/dml/relations/many-to-many.js.map +1 -0
  265. package/dist/errors/manta-error.d.ts +68 -0
  266. package/dist/errors/manta-error.d.ts.map +1 -0
  267. package/dist/errors/manta-error.js +80 -0
  268. package/dist/errors/manta-error.js.map +1 -0
  269. package/dist/events/index.d.ts +3 -0
  270. package/dist/events/index.d.ts.map +1 -0
  271. package/dist/events/index.js +3 -0
  272. package/dist/events/index.js.map +1 -0
  273. package/dist/events/message-aggregator.d.ts +25 -0
  274. package/dist/events/message-aggregator.d.ts.map +1 -0
  275. package/dist/events/message-aggregator.js +35 -0
  276. package/dist/events/message-aggregator.js.map +1 -0
  277. package/dist/events/types.d.ts +42 -0
  278. package/dist/events/types.d.ts.map +1 -0
  279. package/dist/events/types.js +3 -0
  280. package/dist/events/types.js.map +1 -0
  281. package/dist/index.d.ts +55 -0
  282. package/dist/index.d.ts.map +1 -0
  283. package/dist/index.js +53 -0
  284. package/dist/index.js.map +1 -0
  285. package/dist/job/index.d.ts +52 -0
  286. package/dist/job/index.d.ts.map +1 -0
  287. package/dist/job/index.js +31 -0
  288. package/dist/job/index.js.map +1 -0
  289. package/dist/link/index.d.ts +97 -0
  290. package/dist/link/index.d.ts.map +1 -0
  291. package/dist/link/index.js +185 -0
  292. package/dist/link/index.js.map +1 -0
  293. package/dist/middleware/define-middleware.d.ts +54 -0
  294. package/dist/middleware/define-middleware.d.ts.map +1 -0
  295. package/dist/middleware/define-middleware.js +40 -0
  296. package/dist/middleware/define-middleware.js.map +1 -0
  297. package/dist/middleware/index.d.ts +56 -0
  298. package/dist/middleware/index.d.ts.map +1 -0
  299. package/dist/middleware/index.js +50 -0
  300. package/dist/middleware/index.js.map +1 -0
  301. package/dist/module/index.d.ts +56 -0
  302. package/dist/module/index.d.ts.map +1 -0
  303. package/dist/module/index.js +52 -0
  304. package/dist/module/index.js.map +1 -0
  305. package/dist/module/versioning.d.ts +27 -0
  306. package/dist/module/versioning.d.ts.map +1 -0
  307. package/dist/module/versioning.js +64 -0
  308. package/dist/module/versioning.js.map +1 -0
  309. package/dist/naming.d.ts +39 -0
  310. package/dist/naming.d.ts.map +1 -0
  311. package/dist/naming.js +95 -0
  312. package/dist/naming.js.map +1 -0
  313. package/dist/ports/analytics.d.ts +7 -0
  314. package/dist/ports/analytics.d.ts.map +1 -0
  315. package/dist/ports/analytics.js +3 -0
  316. package/dist/ports/analytics.js.map +1 -0
  317. package/dist/ports/auth.d.ts +27 -0
  318. package/dist/ports/auth.d.ts.map +1 -0
  319. package/dist/ports/auth.js +3 -0
  320. package/dist/ports/auth.js.map +1 -0
  321. package/dist/ports/cache.d.ts +35 -0
  322. package/dist/ports/cache.d.ts.map +1 -0
  323. package/dist/ports/cache.js +3 -0
  324. package/dist/ports/cache.js.map +1 -0
  325. package/dist/ports/database.d.ts +40 -0
  326. package/dist/ports/database.d.ts.map +1 -0
  327. package/dist/ports/database.js +3 -0
  328. package/dist/ports/database.js.map +1 -0
  329. package/dist/ports/event-bus.d.ts +85 -0
  330. package/dist/ports/event-bus.d.ts.map +1 -0
  331. package/dist/ports/event-bus.js +3 -0
  332. package/dist/ports/event-bus.js.map +1 -0
  333. package/dist/ports/file.d.ts +62 -0
  334. package/dist/ports/file.d.ts.map +1 -0
  335. package/dist/ports/file.js +3 -0
  336. package/dist/ports/file.js.map +1 -0
  337. package/dist/ports/http.d.ts +20 -0
  338. package/dist/ports/http.d.ts.map +1 -0
  339. package/dist/ports/http.js +3 -0
  340. package/dist/ports/http.js.map +1 -0
  341. package/dist/ports/in-memory-progress-channel.d.ts +9 -0
  342. package/dist/ports/in-memory-progress-channel.d.ts.map +1 -0
  343. package/dist/ports/in-memory-progress-channel.js +19 -0
  344. package/dist/ports/in-memory-progress-channel.js.map +1 -0
  345. package/dist/ports/in-memory-queue.d.ts +24 -0
  346. package/dist/ports/in-memory-queue.d.ts.map +1 -0
  347. package/dist/ports/in-memory-queue.js +63 -0
  348. package/dist/ports/in-memory-queue.js.map +1 -0
  349. package/dist/ports/index.d.ts +27 -0
  350. package/dist/ports/index.d.ts.map +1 -0
  351. package/dist/ports/index.js +6 -0
  352. package/dist/ports/index.js.map +1 -0
  353. package/dist/ports/job-scheduler.d.ts +42 -0
  354. package/dist/ports/job-scheduler.d.ts.map +1 -0
  355. package/dist/ports/job-scheduler.js +3 -0
  356. package/dist/ports/job-scheduler.js.map +1 -0
  357. package/dist/ports/locking.d.ts +43 -0
  358. package/dist/ports/locking.d.ts.map +1 -0
  359. package/dist/ports/locking.js +3 -0
  360. package/dist/ports/locking.js.map +1 -0
  361. package/dist/ports/logger.d.ts +65 -0
  362. package/dist/ports/logger.d.ts.map +1 -0
  363. package/dist/ports/logger.js +3 -0
  364. package/dist/ports/logger.js.map +1 -0
  365. package/dist/ports/notification.d.ts +71 -0
  366. package/dist/ports/notification.d.ts.map +1 -0
  367. package/dist/ports/notification.js +3 -0
  368. package/dist/ports/notification.js.map +1 -0
  369. package/dist/ports/progress-channel.d.ts +46 -0
  370. package/dist/ports/progress-channel.d.ts.map +1 -0
  371. package/dist/ports/progress-channel.js +6 -0
  372. package/dist/ports/progress-channel.js.map +1 -0
  373. package/dist/ports/queue.d.ts +21 -0
  374. package/dist/ports/queue.d.ts.map +1 -0
  375. package/dist/ports/queue.js +15 -0
  376. package/dist/ports/queue.js.map +1 -0
  377. package/dist/ports/relational-query.d.ts +37 -0
  378. package/dist/ports/relational-query.d.ts.map +1 -0
  379. package/dist/ports/relational-query.js +3 -0
  380. package/dist/ports/relational-query.js.map +1 -0
  381. package/dist/ports/repository-factory.d.ts +21 -0
  382. package/dist/ports/repository-factory.d.ts.map +1 -0
  383. package/dist/ports/repository-factory.js +4 -0
  384. package/dist/ports/repository-factory.js.map +1 -0
  385. package/dist/ports/repository.d.ts +73 -0
  386. package/dist/ports/repository.d.ts.map +1 -0
  387. package/dist/ports/repository.js +3 -0
  388. package/dist/ports/repository.js.map +1 -0
  389. package/dist/ports/schema-generator.d.ts +15 -0
  390. package/dist/ports/schema-generator.d.ts.map +1 -0
  391. package/dist/ports/schema-generator.js +4 -0
  392. package/dist/ports/schema-generator.js.map +1 -0
  393. package/dist/ports/search.d.ts +7 -0
  394. package/dist/ports/search.d.ts.map +1 -0
  395. package/dist/ports/search.js +3 -0
  396. package/dist/ports/search.js.map +1 -0
  397. package/dist/ports/types.d.ts +112 -0
  398. package/dist/ports/types.d.ts.map +1 -0
  399. package/dist/ports/types.js +26 -0
  400. package/dist/ports/types.js.map +1 -0
  401. package/dist/ports/workflow-store.d.ts +111 -0
  402. package/dist/ports/workflow-store.d.ts.map +1 -0
  403. package/dist/ports/workflow-store.js +5 -0
  404. package/dist/ports/workflow-store.js.map +1 -0
  405. package/dist/query/define-query-graph.d.ts +55 -0
  406. package/dist/query/define-query-graph.d.ts.map +1 -0
  407. package/dist/query/define-query-graph.js +59 -0
  408. package/dist/query/define-query-graph.js.map +1 -0
  409. package/dist/query/define-query.d.ts +79 -0
  410. package/dist/query/define-query.d.ts.map +1 -0
  411. package/dist/query/define-query.js +77 -0
  412. package/dist/query/define-query.js.map +1 -0
  413. package/dist/query/extend-query-graph.d.ts +36 -0
  414. package/dist/query/extend-query-graph.d.ts.map +1 -0
  415. package/dist/query/extend-query-graph.js +34 -0
  416. package/dist/query/extend-query-graph.js.map +1 -0
  417. package/dist/query/index.d.ts +181 -0
  418. package/dist/query/index.d.ts.map +1 -0
  419. package/dist/query/index.js +288 -0
  420. package/dist/query/index.js.map +1 -0
  421. package/dist/service/define.d.ts +97 -0
  422. package/dist/service/define.d.ts.map +1 -0
  423. package/dist/service/define.js +45 -0
  424. package/dist/service/define.js.map +1 -0
  425. package/dist/service/index.d.ts +52 -0
  426. package/dist/service/index.d.ts.map +1 -0
  427. package/dist/service/index.js +281 -0
  428. package/dist/service/index.js.map +1 -0
  429. package/dist/service/instantiate.d.ts +15 -0
  430. package/dist/service/instantiate.d.ts.map +1 -0
  431. package/dist/service/instantiate.js +143 -0
  432. package/dist/service/instantiate.js.map +1 -0
  433. package/dist/service/snapshot-repository.d.ts +31 -0
  434. package/dist/service/snapshot-repository.d.ts.map +1 -0
  435. package/dist/service/snapshot-repository.js +114 -0
  436. package/dist/service/snapshot-repository.js.map +1 -0
  437. package/dist/service/types.d.ts +39 -0
  438. package/dist/service/types.d.ts.map +1 -0
  439. package/dist/service/types.js +3 -0
  440. package/dist/service/types.js.map +1 -0
  441. package/dist/strict-mode/index.d.ts +42 -0
  442. package/dist/strict-mode/index.d.ts.map +1 -0
  443. package/dist/strict-mode/index.js +84 -0
  444. package/dist/strict-mode/index.js.map +1 -0
  445. package/dist/subscriber/index.d.ts +117 -0
  446. package/dist/subscriber/index.d.ts.map +1 -0
  447. package/dist/subscriber/index.js +76 -0
  448. package/dist/subscriber/index.js.map +1 -0
  449. package/dist/testing/relational-query-suite.d.ts +22 -0
  450. package/dist/testing/relational-query-suite.d.ts.map +1 -0
  451. package/dist/testing/relational-query-suite.js +233 -0
  452. package/dist/testing/relational-query-suite.js.map +1 -0
  453. package/dist/user/auto-routes.d.ts +32 -0
  454. package/dist/user/auto-routes.d.ts.map +1 -0
  455. package/dist/user/auto-routes.js +424 -0
  456. package/dist/user/auto-routes.js.map +1 -0
  457. package/dist/user/define-user.d.ts +54 -0
  458. package/dist/user/define-user.d.ts.map +1 -0
  459. package/dist/user/define-user.js +103 -0
  460. package/dist/user/define-user.js.map +1 -0
  461. package/dist/user/index.d.ts +7 -0
  462. package/dist/user/index.d.ts.map +1 -0
  463. package/dist/user/index.js +5 -0
  464. package/dist/user/index.js.map +1 -0
  465. package/dist/user/models/user.d.ts +15 -0
  466. package/dist/user/models/user.d.ts.map +1 -0
  467. package/dist/user/models/user.js +16 -0
  468. package/dist/user/models/user.js.map +1 -0
  469. package/dist/user/user-module-service.d.ts +55 -0
  470. package/dist/user/user-module-service.d.ts.map +1 -0
  471. package/dist/user/user-module-service.js +100 -0
  472. package/dist/user/user-module-service.js.map +1 -0
  473. package/dist/workflows/ai-step.d.ts +2 -0
  474. package/dist/workflows/ai-step.d.ts.map +1 -0
  475. package/dist/workflows/ai-step.js +54 -0
  476. package/dist/workflows/ai-step.js.map +1 -0
  477. package/dist/workflows/create-step.d.ts +16 -0
  478. package/dist/workflows/create-step.d.ts.map +1 -0
  479. package/dist/workflows/create-step.js +194 -0
  480. package/dist/workflows/create-step.js.map +1 -0
  481. package/dist/workflows/create-workflow.d.ts +16 -0
  482. package/dist/workflows/create-workflow.d.ts.map +1 -0
  483. package/dist/workflows/create-workflow.js +21 -0
  484. package/dist/workflows/create-workflow.js.map +1 -0
  485. package/dist/workflows/define-workflow.d.ts +55 -0
  486. package/dist/workflows/define-workflow.d.ts.map +1 -0
  487. package/dist/workflows/define-workflow.js +72 -0
  488. package/dist/workflows/define-workflow.js.map +1 -0
  489. package/dist/workflows/emit-event-step.d.ts +17 -0
  490. package/dist/workflows/emit-event-step.d.ts.map +1 -0
  491. package/dist/workflows/emit-event-step.js +46 -0
  492. package/dist/workflows/emit-event-step.js.map +1 -0
  493. package/dist/workflows/for-each.d.ts +6 -0
  494. package/dist/workflows/for-each.d.ts.map +1 -0
  495. package/dist/workflows/for-each.js +79 -0
  496. package/dist/workflows/for-each.js.map +1 -0
  497. package/dist/workflows/index.d.ts +15 -0
  498. package/dist/workflows/index.d.ts.map +1 -0
  499. package/dist/workflows/index.js +12 -0
  500. package/dist/workflows/index.js.map +1 -0
  501. package/dist/workflows/manager.d.ts +99 -0
  502. package/dist/workflows/manager.d.ts.map +1 -0
  503. package/dist/workflows/manager.js +450 -0
  504. package/dist/workflows/manager.js.map +1 -0
  505. package/dist/workflows/orphan-reaper.d.ts +50 -0
  506. package/dist/workflows/orphan-reaper.d.ts.map +1 -0
  507. package/dist/workflows/orphan-reaper.js +69 -0
  508. package/dist/workflows/orphan-reaper.js.map +1 -0
  509. package/dist/workflows/progress-helper.d.ts +20 -0
  510. package/dist/workflows/progress-helper.d.ts.map +1 -0
  511. package/dist/workflows/progress-helper.js +48 -0
  512. package/dist/workflows/progress-helper.js.map +1 -0
  513. package/dist/workflows/step.d.ts +103 -0
  514. package/dist/workflows/step.d.ts.map +1 -0
  515. package/dist/workflows/step.js +949 -0
  516. package/dist/workflows/step.js.map +1 -0
  517. package/dist/workflows/types.d.ts +215 -0
  518. package/dist/workflows/types.d.ts.map +1 -0
  519. package/dist/workflows/types.js +9 -0
  520. package/dist/workflows/types.js.map +1 -0
  521. package/dist/workflows/yield.d.ts +12 -0
  522. package/dist/workflows/yield.d.ts.map +1 -0
  523. package/dist/workflows/yield.js +29 -0
  524. package/dist/workflows/yield.js.map +1 -0
  525. package/docs/00-overview.md +254 -0
  526. package/docs/01-getting-started.md +224 -0
  527. package/docs/02-models.md +163 -0
  528. package/docs/03-services.md +208 -0
  529. package/docs/04-users.md +165 -0
  530. package/docs/05-commands.md +501 -0
  531. package/docs/06-queries.md +342 -0
  532. package/docs/07-events.md +248 -0
  533. package/docs/08-links.md +182 -0
  534. package/docs/09-agents.md +142 -0
  535. package/docs/10-spa.md +327 -0
  536. package/docs/11-config.md +481 -0
  537. package/docs/12-constraints.md +183 -0
  538. package/docs/13-testing.md +345 -0
  539. package/docs/14-adapters.md +204 -0
  540. package/docs/15-hosts.md +163 -0
  541. package/docs/16-reference.md +274 -0
  542. package/docs/17-dashboard.md +619 -0
  543. package/docs/AGENT.md +501 -0
  544. package/package.json +49 -52
  545. package/.medusa/server/src/admin/index.js +0 -5493
  546. package/.medusa/server/src/admin/index.mjs +0 -5491
  547. package/.medusa/server/src/api/admin/companies/[id]/route.js +0 -39
  548. package/.medusa/server/src/api/admin/companies/middlewares.js +0 -41
  549. package/.medusa/server/src/api/admin/companies/route.js +0 -37
  550. package/.medusa/server/src/api/admin/companies/validators.js +0 -29
  551. package/.medusa/server/src/api/admin/employees/middlewares.js +0 -15
  552. package/.medusa/server/src/api/admin/employees/route.js +0 -21
  553. package/.medusa/server/src/api/middlewares.js +0 -9
  554. package/.medusa/server/src/index.js +0 -5
  555. package/.medusa/server/src/modules/company/index.js +0 -13
  556. package/.medusa/server/src/modules/company/migrations/Migration20260126141741.js +0 -26
  557. package/.medusa/server/src/modules/company/models/company.js +0 -24
  558. package/.medusa/server/src/modules/company/models/employee.js +0 -15
  559. package/.medusa/server/src/modules/company/models/index.js +0 -11
  560. package/.medusa/server/src/modules/company/service.js +0 -11
  561. package/.medusa/server/src/workflows/create-company.js +0 -10
  562. package/.medusa/server/src/workflows/delete-company.js +0 -10
  563. package/.medusa/server/src/workflows/steps/create-company.js +0 -16
  564. package/.medusa/server/src/workflows/steps/delete-company.js +0 -30
  565. package/.medusa/server/src/workflows/steps/update-company.js +0 -30
  566. package/.medusa/server/src/workflows/update-company.js +0 -10
@@ -0,0 +1,949 @@
1
+ // Step API — direct, module-aware, typed.
2
+ //
3
+ // step.product.create({ title: 'Widget' }, ctx) → auto-compensated
4
+ // step.product.activate(id, ctx) → auto-compensation via SnapshotRepository
5
+ // step.product.delete(id, ctx) → smart delete: cascade + dismiss based on link types
6
+ // step.product.link.inventoryItem(pId, iId, ctx) → link via pivot, auto-compensated
7
+ // step.emit('product.created', data, ctx) → fire-and-forget event
8
+ //
9
+ // `step` is a Proxy. When you access step.product, it returns a module helper
10
+ // that resolves the service from ctx.app at call time.
11
+ import { and, eq, isNull } from 'drizzle-orm';
12
+ import { MantaError } from '../errors/manta-error.js';
13
+ import { getRegisteredLinks } from '../link/index.js';
14
+ import { pluralize } from '../naming.js';
15
+ import { createForEach } from './for-each.js';
16
+ import { workflowContextStorage } from './manager.js';
17
+ import { CancelledError, createProgress } from './progress-helper.js';
18
+ import { isWorkflowYield, WorkflowYield } from './yield.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Helpers
21
+ // ---------------------------------------------------------------------------
22
+ function capitalize(s) {
23
+ return s.charAt(0).toUpperCase() + s.slice(1);
24
+ }
25
+ /**
26
+ * Resolve registered links from the app context (preferred) or global registry (fallback).
27
+ * The app's __linkRegistry is set by the bootstrap and avoids module instance mismatch.
28
+ */
29
+ function resolveLinks(ctx) {
30
+ try {
31
+ const registry = ctx.app.resolve('__linkRegistry');
32
+ if (registry && registry.length > 0)
33
+ return registry;
34
+ }
35
+ catch {
36
+ /* not registered */
37
+ }
38
+ return getRegisteredLinks();
39
+ }
40
+ /**
41
+ * Get the Drizzle db instance from the step context.
42
+ */
43
+ // biome-ignore lint/suspicious/noExplicitAny: Drizzle db is dynamically typed across adapters
44
+ function getDb(ctx) {
45
+ return ctx.app.infra.db;
46
+ }
47
+ /**
48
+ * Resolve a generated Drizzle pgTable by name.
49
+ * Tables are generated at boot from DML entities and links, registered as __generatedTables.
50
+ */
51
+ function getLinkTable(ctx, tableName) {
52
+ try {
53
+ const tables = ctx.app.resolve('__generatedTables');
54
+ const table = tables.get(tableName);
55
+ if (table)
56
+ return table;
57
+ }
58
+ catch {
59
+ /* not registered */
60
+ }
61
+ throw new MantaError('INVALID_STATE', `Link table "${tableName}" not found. Ensure the link is defined via defineLink() in src/links/ and that migrations are up to date (manta db:generate && manta db:migrate).`);
62
+ }
63
+ /**
64
+ * Get a column from a Drizzle table by name.
65
+ * Returns any because the column is passed to Drizzle query builders (eq, select, etc.)
66
+ * which require their internal column types we can't express from a string key.
67
+ */
68
+ // biome-ignore lint/suspicious/noExplicitAny: Drizzle column dynamic access — see JSDoc
69
+ function getColumn(table, columnName) {
70
+ return table[columnName];
71
+ }
72
+ function resolveService(ctx, entity) {
73
+ const moduleName = entity.toLowerCase();
74
+ const modules = ctx.app.modules;
75
+ // Try by module name first (catalog, inventory, etc.)
76
+ const direct = modules[moduleName] ?? modules[entity];
77
+ if (direct)
78
+ return direct;
79
+ // Try by entity name — search all modules for one whose __entity.name matches
80
+ for (const [_key, svc] of Object.entries(modules)) {
81
+ const s = svc;
82
+ if (s?.__entity && s.__entity.name === entity) {
83
+ return s;
84
+ }
85
+ }
86
+ // Fallback: resolve from app registry
87
+ try {
88
+ return ctx.app.resolve(`${moduleName}ModuleService`);
89
+ }
90
+ catch {
91
+ const available = Object.keys(ctx.app.modules).join(', ');
92
+ throw new MantaError('UNKNOWN_MODULES', `Service for "${entity}" not found. Available modules: [${available}]. Check that the module is in src/modules/ and exports a defineService().`);
93
+ }
94
+ }
95
+ /**
96
+ * Run a step within the workflow context: checkpoint, execute, register compensation.
97
+ * Also reports step lifecycle to `wfCtx.store` (durable run store) on a best-effort
98
+ * basis — store errors MUST NOT fail the workflow.
99
+ */
100
+ async function runStep(name, ctx, handler, compensate) {
101
+ const wfCtx = workflowContextStorage.getStore() ?? ctx.__wfCtx ?? null;
102
+ if (!wfCtx) {
103
+ return handler();
104
+ }
105
+ const count = (wfCtx.stepCounter.get(name) ?? 0) + 1;
106
+ wfCtx.stepCounter.set(name, count);
107
+ const stepKey = count === 1 ? name : `${name}-${count}`;
108
+ if (wfCtx.checkpoints.has(stepKey)) {
109
+ const cached = wfCtx.checkpoints.get(stepKey);
110
+ if (compensate) {
111
+ wfCtx.completedSteps.push({
112
+ name: stepKey,
113
+ output: cached,
114
+ compensate: async (out) => compensate(out),
115
+ });
116
+ }
117
+ return cached;
118
+ }
119
+ // Cooperative cancel check at step boundary (see WORKFLOW_PROGRESS.md §10.3).
120
+ if (wfCtx.signal?.aborted) {
121
+ throw new CancelledError(`Workflow ${wfCtx.runId} cancelled before step "${stepKey}"`);
122
+ }
123
+ const previousStepName = wfCtx.stepName;
124
+ wfCtx.stepName = stepKey;
125
+ if (wfCtx.store) {
126
+ try {
127
+ await wfCtx.store.updateStep(wfCtx.runId, stepKey, {
128
+ status: 'running',
129
+ started_at: new Date(),
130
+ });
131
+ }
132
+ catch {
133
+ /* store errors are non-fatal */
134
+ }
135
+ }
136
+ let output;
137
+ try {
138
+ output = await handler();
139
+ }
140
+ catch (err) {
141
+ // Yield is NOT a failure — the manager catches WorkflowYield above the
142
+ // retry loop and schedules a continuation. We persist resume_state here
143
+ // so the next invocation's step can read it via `ctx.resumeState`.
144
+ if (isWorkflowYield(err)) {
145
+ if (wfCtx.store) {
146
+ try {
147
+ await wfCtx.store.updateStep(wfCtx.runId, stepKey, {
148
+ status: 'paused',
149
+ resume_state: err.resumeState,
150
+ });
151
+ }
152
+ catch {
153
+ /* store errors are non-fatal; manager retries on resume */
154
+ }
155
+ }
156
+ wfCtx.stepName = previousStepName;
157
+ throw err;
158
+ }
159
+ if (wfCtx.store) {
160
+ const cancelled = err?.code === 'WORKFLOW_CANCELLED' ||
161
+ err?.name === 'CancelledError';
162
+ try {
163
+ await wfCtx.store.updateStep(wfCtx.runId, stepKey, {
164
+ status: cancelled ? 'cancelled' : 'failed',
165
+ completed_at: new Date(),
166
+ error: cancelled ? undefined : { message: err?.message ?? String(err) },
167
+ });
168
+ }
169
+ catch {
170
+ /* non-fatal */
171
+ }
172
+ }
173
+ wfCtx.stepName = previousStepName;
174
+ throw err;
175
+ }
176
+ if (compensate) {
177
+ wfCtx.completedSteps.push({
178
+ name: stepKey,
179
+ output,
180
+ compensate: async (out) => compensate(out),
181
+ });
182
+ }
183
+ else {
184
+ wfCtx.completedSteps.push({ name: stepKey, output });
185
+ }
186
+ wfCtx.checkpoints.set(stepKey, output);
187
+ if (wfCtx.saveCheckpoint)
188
+ await wfCtx.saveCheckpoint(stepKey, output);
189
+ if (wfCtx.store) {
190
+ try {
191
+ await wfCtx.store.updateStep(wfCtx.runId, stepKey, {
192
+ status: 'succeeded',
193
+ completed_at: new Date(),
194
+ });
195
+ }
196
+ catch {
197
+ /* non-fatal */
198
+ }
199
+ }
200
+ wfCtx.stepName = previousStepName;
201
+ return output;
202
+ }
203
+ // ---------------------------------------------------------------------------
204
+ // Auto-resolve: find the last created entity ID from workflow context
205
+ // ---------------------------------------------------------------------------
206
+ function findLastCreatedId(ctx, entityName) {
207
+ const wfCtx = workflowContextStorage.getStore() ?? ctx.__wfCtx ?? null;
208
+ if (!wfCtx)
209
+ return null;
210
+ const stepName = `create-${entityName.toLowerCase()}`;
211
+ // Scan completed steps in reverse to find the most recent create for this entity
212
+ for (let i = wfCtx.completedSteps.length - 1; i >= 0; i--) {
213
+ const step = wfCtx.completedSteps[i];
214
+ if (step.name.startsWith(stepName)) {
215
+ const output = step.output;
216
+ if (output?.id)
217
+ return output.id;
218
+ }
219
+ }
220
+ // Also check checkpoints (for crash recovery)
221
+ for (const [key, value] of wfCtx.checkpoints) {
222
+ if (key.startsWith(stepName)) {
223
+ const output = value;
224
+ if (output?.id)
225
+ return output.id;
226
+ }
227
+ }
228
+ return null;
229
+ }
230
+ function _findCascadeLinks(ctx, entityModule, entityName) {
231
+ return resolveLinks(ctx).filter((link) => (link.leftModule === entityModule || link.leftEntity === entityName) && link.cascadeLeft === true);
232
+ }
233
+ // ---------------------------------------------------------------------------
234
+ // Step implementations
235
+ // ---------------------------------------------------------------------------
236
+ async function stepCreate(entity, data, ctx) {
237
+ const suffix = capitalize(pluralize(entity));
238
+ return runStep(`create-${entity.toLowerCase()}`, ctx, async () => {
239
+ const service = resolveService(ctx, entity);
240
+ const method = service[`create${suffix}`];
241
+ if (!method)
242
+ throw new MantaError('NOT_FOUND', `Service for "${entity}" has no create${suffix} method`);
243
+ const result = (await method.call(service, data));
244
+ // Tag with entity name so step.link() can auto-resolve
245
+ Object.defineProperty(result, ENTITY_TAG, { value: entity, enumerable: false });
246
+ return result;
247
+ }, async (output) => {
248
+ const service = resolveService(ctx, entity);
249
+ const deleteMethod = service[`delete${suffix}`];
250
+ if (deleteMethod && output.id)
251
+ await deleteMethod.call(service, [output.id]);
252
+ });
253
+ }
254
+ async function stepUpdate(entity, id, data, ctx) {
255
+ const suffix = capitalize(pluralize(entity));
256
+ const entityCap = capitalize(entity);
257
+ let previousData;
258
+ try {
259
+ const service = resolveService(ctx, entity);
260
+ const retrieveMethod = service[`retrieve${entityCap}`];
261
+ if (retrieveMethod)
262
+ previousData = (await retrieveMethod.call(service, id));
263
+ }
264
+ catch {
265
+ /* best effort */
266
+ }
267
+ return runStep(`update-${entity.toLowerCase()}`, ctx, async () => {
268
+ const service = resolveService(ctx, entity);
269
+ const method = service[`update${suffix}`];
270
+ if (!method)
271
+ throw new MantaError('NOT_FOUND', `Service for "${entity}" has no update${suffix} method`);
272
+ const result = (await method.call(service, { id, ...data }));
273
+ Object.defineProperty(result, ENTITY_TAG, { value: entity, enumerable: false });
274
+ return result;
275
+ }, previousData
276
+ ? async () => {
277
+ const service = resolveService(ctx, entity);
278
+ const method = service[`update${suffix}`];
279
+ if (method)
280
+ await method.call(service, { id, ...previousData });
281
+ }
282
+ : undefined);
283
+ }
284
+ async function stepDelete(entity, id, ctx) {
285
+ const suffix = capitalize(pluralize(entity));
286
+ const entityModule = entity.toLowerCase();
287
+ return runStep(`delete-${entityModule}`, ctx, async () => {
288
+ const service = resolveService(ctx, entity);
289
+ const db = getDb(ctx);
290
+ const deletedLinks = [];
291
+ const deletedChildren = [];
292
+ const dismissedLinks = [];
293
+ const allLinks = resolveLinks(ctx).filter((l) => l.leftModule === entityModule || l.leftEntity === entity);
294
+ for (const link of allLinks) {
295
+ const linkTable = getLinkTable(ctx, link.tableName);
296
+ const leftCol = getColumn(linkTable, link.leftFk);
297
+ const rightCol = getColumn(linkTable, link.rightFk);
298
+ const idCol = getColumn(linkTable, 'id');
299
+ const deletedAtCol = getColumn(linkTable, 'deleted_at');
300
+ const rows = await db
301
+ .select({
302
+ id: idCol,
303
+ child_id: rightCol,
304
+ })
305
+ .from(linkTable)
306
+ .where(and(eq(leftCol, id), isNull(deletedAtCol)));
307
+ if (link.cascadeLeft) {
308
+ const childEntity = link.rightEntity;
309
+ const childSuffix = capitalize(pluralize(childEntity));
310
+ let childService = null;
311
+ try {
312
+ childService = resolveService(ctx, childEntity);
313
+ }
314
+ catch {
315
+ /* not loaded */
316
+ }
317
+ for (const row of rows) {
318
+ const childId = row.child_id;
319
+ if (childService) {
320
+ const softDel = childService[`softDelete${childSuffix}`];
321
+ if (softDel) {
322
+ await softDel.call(childService, [childId]);
323
+ deletedChildren.push({ entity: childEntity, id: childId });
324
+ }
325
+ }
326
+ const linkId = row.id;
327
+ await db.update(linkTable).set({ deleted_at: new Date() }).where(eq(idCol, linkId));
328
+ deletedLinks.push({ tableName: link.tableName, linkId });
329
+ }
330
+ }
331
+ else {
332
+ for (const row of rows) {
333
+ const linkId = row.id;
334
+ await db.delete(linkTable).where(eq(idCol, linkId));
335
+ dismissedLinks.push({ tableName: link.tableName, linkId });
336
+ }
337
+ }
338
+ }
339
+ const softDel = service[`softDelete${suffix}`];
340
+ if (softDel)
341
+ await softDel.call(service, [id]);
342
+ return { id, deletedLinks, deletedChildren, dismissedLinks };
343
+ }, async (output) => {
344
+ const service = resolveService(ctx, entity);
345
+ const db = getDb(ctx);
346
+ const restoreMethod = service[`restore${suffix}`];
347
+ if (restoreMethod)
348
+ await restoreMethod.call(service, [output.id]);
349
+ for (const child of output.deletedChildren) {
350
+ try {
351
+ const childService = resolveService(ctx, child.entity);
352
+ const childSuffix = capitalize(pluralize(child.entity));
353
+ const childRestore = childService[`restore${childSuffix}`];
354
+ if (childRestore)
355
+ await childRestore.call(childService, [child.id]);
356
+ }
357
+ catch {
358
+ /* best effort */
359
+ }
360
+ }
361
+ for (const link of output.deletedLinks) {
362
+ const linkTable = getLinkTable(ctx, link.tableName);
363
+ const idCol = getColumn(linkTable, 'id');
364
+ await db.update(linkTable).set({ deleted_at: null }).where(eq(idCol, link.linkId));
365
+ }
366
+ for (const link of output.dismissedLinks) {
367
+ const linkTable = getLinkTable(ctx, link.tableName);
368
+ await db
369
+ .insert(linkTable)
370
+ .values({
371
+ id: link.linkId,
372
+ created_at: new Date(),
373
+ updated_at: new Date(),
374
+ })
375
+ .onConflictDoNothing();
376
+ }
377
+ });
378
+ }
379
+ // stepCascadeDelete removed — stepDelete handles cascade automatically
380
+ // ---------------------------------------------------------------------------
381
+ // Entity ref — tagged objects returned by step.service.*.create/update
382
+ // ---------------------------------------------------------------------------
383
+ /** Symbol used to tag objects with their entity name (set by create/update steps). */
384
+ export const ENTITY_TAG = Symbol.for('manta:entity');
385
+ function isTaggedEntity(obj) {
386
+ return typeof obj === 'object' && obj !== null && ENTITY_TAG in obj;
387
+ }
388
+ function resolveEntityRef(arg) {
389
+ if (isTaggedEntity(arg)) {
390
+ return { entity: arg[ENTITY_TAG], id: arg.id };
391
+ }
392
+ if (typeof arg === 'object' && arg !== null && 'entity' in arg && 'id' in arg) {
393
+ return arg;
394
+ }
395
+ throw new MantaError('INVALID_DATA', 'step.link() arguments must be entity objects (from step.service.*.create()) ' +
396
+ 'or explicit refs { entity: "product", id: "prod_123" }.');
397
+ }
398
+ /**
399
+ * Find a link definition between two entities (order-agnostic).
400
+ * Returns the link and whether the arguments are in the same order as the link definition.
401
+ */
402
+ function findLinkDef(ctx, entityA, entityB) {
403
+ const links = resolveLinks(ctx);
404
+ const aLower = entityA.toLowerCase();
405
+ const bLower = entityB.toLowerCase();
406
+ // Try A=left, B=right
407
+ const forward = links.find((l) => (l.leftEntity === entityA || l.leftEntity.toLowerCase() === aLower) &&
408
+ (l.rightEntity === entityB || l.rightEntity.toLowerCase() === bLower));
409
+ if (forward)
410
+ return { link: forward, leftId: 'a' };
411
+ // Try B=left, A=right
412
+ const reverse = links.find((l) => (l.leftEntity === entityB || l.leftEntity.toLowerCase() === bLower) &&
413
+ (l.rightEntity === entityA || l.rightEntity.toLowerCase() === aLower));
414
+ if (reverse)
415
+ return { link: reverse, leftId: 'b' };
416
+ return null;
417
+ }
418
+ /**
419
+ * List available link partners for an entity (for error messages).
420
+ */
421
+ function availableLinksFor(ctx, entity) {
422
+ const links = resolveLinks(ctx);
423
+ const eLower = entity.toLowerCase();
424
+ const partners = [];
425
+ for (const l of links) {
426
+ if (l.leftEntity === entity || l.leftEntity.toLowerCase() === eLower)
427
+ partners.push(l.rightEntity);
428
+ if (l.rightEntity === entity || l.rightEntity.toLowerCase() === eLower)
429
+ partners.push(l.leftEntity);
430
+ }
431
+ return [...new Set(partners)];
432
+ }
433
+ // ---------------------------------------------------------------------------
434
+ // step.link() — first-level link step
435
+ // ---------------------------------------------------------------------------
436
+ /**
437
+ * Create a link between two entities.
438
+ *
439
+ * Accepts:
440
+ * step.link(product, item) — tagged objects from create()
441
+ * step.link(product, item, { quantity: 10 }) — with extra columns
442
+ * step.link(product, { entity: 'inventory_item', id: 'inv_123' })
443
+ * step.link({ entity: 'product', id: 'p1' }, { entity: 'inventory_item', id: 'p2' }, { qty: 1 })
444
+ *
445
+ * Validations:
446
+ * 1. Link must exist in defineLink registry
447
+ * 2. Required extra columns must be provided
448
+ * 3. Unknown extra columns are rejected
449
+ */
450
+ async function stepLink(a, b, extraColumns, ctx) {
451
+ const refA = resolveEntityRef(a);
452
+ const refB = resolveEntityRef(b);
453
+ // 1. Find link definition (order-agnostic)
454
+ const found = findLinkDef(ctx, refA.entity, refB.entity);
455
+ if (!found) {
456
+ const partnersA = availableLinksFor(ctx, refA.entity);
457
+ const partnersB = availableLinksFor(ctx, refB.entity);
458
+ const hint = partnersA.length > 0
459
+ ? `Available links for ${refA.entity}: [${partnersA.join(', ')}].`
460
+ : partnersB.length > 0
461
+ ? `Available links for ${refB.entity}: [${partnersB.join(', ')}].`
462
+ : 'No links defined. Add a defineLink() in src/links/.';
463
+ throw new MantaError('NOT_FOUND', `Cannot link ${refA.entity} to ${refB.entity} — no defineLink found. ${hint}`);
464
+ }
465
+ const { link: linkDef, leftId: leftSide } = found;
466
+ const leftId = leftSide === 'a' ? refA.id : refB.id;
467
+ const rightId = leftSide === 'a' ? refB.id : refA.id;
468
+ // 2. Validate extra columns
469
+ const definedExtras = linkDef.extraColumns ?? {};
470
+ const definedKeys = Object.keys(definedExtras);
471
+ const providedKeys = Object.keys(extraColumns ?? {});
472
+ // Check for unknown columns
473
+ for (const key of providedKeys) {
474
+ if (!definedKeys.includes(key)) {
475
+ throw new MantaError('INVALID_DATA', `Unknown column "${key}" on link ${refA.entity} ↔ ${refB.entity}. ` +
476
+ (definedKeys.length > 0
477
+ ? `Available extra columns: [${definedKeys.join(', ')}].`
478
+ : 'This link has no extra columns.'));
479
+ }
480
+ }
481
+ // Check for required extra columns (those without defaults)
482
+ for (const key of definedKeys) {
483
+ const def = definedExtras[key];
484
+ const hasDefault = def && ('default_value' in def || 'is_nullable' in def);
485
+ if (!hasDefault && !(extraColumns && key in extraColumns)) {
486
+ throw new MantaError('INVALID_DATA', `Link ${refA.entity} ↔ ${refB.entity} requires extra column "${key}". ` +
487
+ `Pass it as the third argument: step.link(a, b, { ${key}: value }).`);
488
+ }
489
+ }
490
+ const leftKey = linkDef.leftEntity.toLowerCase();
491
+ const rightKey = linkDef.rightEntity.toLowerCase();
492
+ const linkId = `link_${leftId}_${rightId}`;
493
+ return runStep(`link-${leftKey}-${rightKey}`, ctx, async () => {
494
+ const db = getDb(ctx);
495
+ const linkTable = getLinkTable(ctx, linkDef.tableName);
496
+ await db.insert(linkTable).values({
497
+ id: linkId,
498
+ [linkDef.leftFk]: leftId,
499
+ [linkDef.rightFk]: rightId,
500
+ ...(extraColumns ?? {}),
501
+ created_at: new Date(),
502
+ updated_at: new Date(),
503
+ });
504
+ return { linkId };
505
+ }, async () => {
506
+ const db = getDb(ctx);
507
+ const linkTable = getLinkTable(ctx, linkDef.tableName);
508
+ const idCol = getColumn(linkTable, 'id');
509
+ await db.delete(linkTable).where(eq(idCol, linkId));
510
+ });
511
+ }
512
+ /**
513
+ * Legacy: Create a link with explicit entity names and IDs.
514
+ * Used by the old bound proxy in defineCommand.
515
+ */
516
+ function stepLinkExplicit(leftEntity, leftId, rightEntity, rightId, ctx, extraColumns) {
517
+ return stepLink({ entity: leftEntity, id: leftId }, { entity: rightEntity, id: rightId }, extraColumns, ctx);
518
+ }
519
+ // ---------------------------------------------------------------------------
520
+ // step.unlink() — remove a link between two entities
521
+ // ---------------------------------------------------------------------------
522
+ /**
523
+ * Remove a link between two entities (delete from pivot table).
524
+ * Compensation re-creates the link.
525
+ *
526
+ * @example
527
+ * step.unlink(customer, group)
528
+ * step.unlink({ entity: 'customer', id: 'cus_1' }, { entity: 'customer_group', id: 'grp_1' })
529
+ */
530
+ function _stepUnlink(a, b, ctx) {
531
+ const refA = resolveEntityRef(a);
532
+ const refB = resolveEntityRef(b);
533
+ const found = findLinkDef(ctx, refA.entity, refB.entity);
534
+ if (!found) {
535
+ throw new MantaError('NOT_FOUND', `No defineLink found between "${refA.entity}" and "${refB.entity}". Create one in src/links/ or src/modules/{mod}/links/.`);
536
+ }
537
+ const link = found.link;
538
+ const leftId = link.leftEntity.toLowerCase() === refA.entity.toLowerCase() ? refA.id : refB.id;
539
+ const rightId = link.leftEntity.toLowerCase() === refA.entity.toLowerCase() ? refB.id : refA.id;
540
+ const leftKey = link.leftEntity.toLowerCase();
541
+ const rightKey = link.rightEntity.toLowerCase();
542
+ return runStep(`unlink-${leftKey}-${rightKey}`, ctx, async () => {
543
+ const db = getDb(ctx);
544
+ const linkTable = getLinkTable(ctx, link.tableName);
545
+ const leftFkCol = getColumn(linkTable, link.leftFk);
546
+ const rightFkCol = getColumn(linkTable, link.rightFk);
547
+ await db.delete(linkTable).where(and(eq(leftFkCol, leftId), eq(rightFkCol, rightId)));
548
+ return { success: true };
549
+ }, async () => {
550
+ // Compensation: re-create the link
551
+ const db = getDb(ctx);
552
+ const linkTable = getLinkTable(ctx, link.tableName);
553
+ await db.insert(linkTable).values({
554
+ id: `link_${leftId}_${rightId}`,
555
+ [link.leftFk]: leftId,
556
+ [link.rightFk]: rightId,
557
+ created_at: new Date(),
558
+ updated_at: new Date(),
559
+ });
560
+ });
561
+ }
562
+ async function stepInvoke(moduleName, methodName, args, ctx) {
563
+ return runStep(`invoke-${moduleName}-${methodName}`, ctx, async () => {
564
+ const service = resolveService(ctx, moduleName);
565
+ const method = service[methodName];
566
+ if (!method)
567
+ throw new MantaError('NOT_FOUND', `Service "${moduleName}" has no method "${methodName}"`);
568
+ // Clear snapshots before executing so we only track this method's mutations
569
+ const snapshotRepo = service.__snapshotRepo;
570
+ if (snapshotRepo)
571
+ snapshotRepo.clearSnapshots();
572
+ return method.apply(service, args);
573
+ }, async () => {
574
+ // Auto-compensation via SnapshotRepository — rollback all mutations made during the method
575
+ const service = resolveService(ctx, moduleName);
576
+ const snapshotRepo = service.__snapshotRepo;
577
+ if (snapshotRepo?.hasSnapshots)
578
+ await snapshotRepo.rollback();
579
+ });
580
+ }
581
+ async function stepEmit(eventName, data, ctx) {
582
+ return runStep(`emit-${eventName}`, ctx, async () => {
583
+ const eventBus = ctx.app.infra.eventBus;
584
+ await eventBus.emit({ eventName, data, metadata: { timestamp: Date.now() } });
585
+ });
586
+ }
587
+ // ---------------------------------------------------------------------------
588
+ // Module Proxy — step.product.create(...), step.product.activate(...), etc.
589
+ // ---------------------------------------------------------------------------
590
+ function createLinkProxy(entityName) {
591
+ const leftEntity = entityName;
592
+ return new Proxy({}, {
593
+ get(_target, rightEntityProp) {
594
+ // step.product.link.inventoryItem(ctx) — IDs auto-resolved
595
+ // step.product.link.inventoryItem(extraColumns, ctx) — with extra columns
596
+ return (...args) => {
597
+ const rightEntity = rightEntityProp.charAt(0).toUpperCase() + rightEntityProp.slice(1);
598
+ const ctx = args[args.length - 1];
599
+ const leftId = findLastCreatedId(ctx, leftEntity);
600
+ const rightId = findLastCreatedId(ctx, rightEntity);
601
+ if (!leftId)
602
+ throw new MantaError('INVALID_DATA', `Cannot link: no ${leftEntity} created yet in this workflow. Call step.service.${leftEntity.toLowerCase()}.create() first.`);
603
+ if (!rightId)
604
+ throw new MantaError('INVALID_DATA', `Cannot link: no ${rightEntity} created yet in this workflow. Call step.service.${rightEntity.toLowerCase()}.create() first.`);
605
+ return stepLinkExplicit(leftEntity, leftId, rightEntity, rightId, ctx);
606
+ };
607
+ },
608
+ });
609
+ }
610
+ function createModuleProxy(entityName) {
611
+ const entity = entityName.charAt(0).toUpperCase() + entityName.slice(1);
612
+ return new Proxy({}, {
613
+ get(_target, methodName) {
614
+ switch (methodName) {
615
+ case 'create':
616
+ return (data, ctx) => stepCreate(entity, data, ctx);
617
+ case 'update':
618
+ return (id, data, ctx) => stepUpdate(entity, id, data, ctx);
619
+ case 'delete':
620
+ return (id, ctx) => stepDelete(entity, id, ctx);
621
+ case 'link':
622
+ return createLinkProxy(entity);
623
+ default:
624
+ // Any other method → resolve from service (compensable methods like activate, archive)
625
+ return (...args) => {
626
+ const ctx = args[args.length - 1];
627
+ const methodArgs = args.slice(0, -1);
628
+ return stepInvoke(entityName, methodName, methodArgs, ctx);
629
+ };
630
+ }
631
+ },
632
+ });
633
+ }
634
+ // ---------------------------------------------------------------------------
635
+ // Dismiss link step
636
+ // ---------------------------------------------------------------------------
637
+ async function stepDismissLink(leftEntity, leftId, rightEntity, rightId, ctx) {
638
+ const leftKey = leftEntity.toLowerCase();
639
+ const rightKey = rightEntity.toLowerCase();
640
+ const links = resolveLinks(ctx);
641
+ const linkDef = links.find((l) => (l.leftEntity === leftEntity || l.leftEntity.toLowerCase() === leftKey) &&
642
+ (l.rightEntity === rightEntity || l.rightEntity.toLowerCase() === rightKey));
643
+ if (!linkDef)
644
+ throw new MantaError('NOT_FOUND', `No link defined between "${leftEntity}" and "${rightEntity}"`);
645
+ return runStep(`dismiss-link-${leftKey}-${rightKey}`, ctx, async () => {
646
+ const db = getDb(ctx);
647
+ const linkTable = getLinkTable(ctx, linkDef.tableName);
648
+ const leftCol = getColumn(linkTable, linkDef.leftFk);
649
+ const rightCol = getColumn(linkTable, linkDef.rightFk);
650
+ await db.delete(linkTable).where(and(eq(leftCol, leftId), eq(rightCol, rightId)));
651
+ }, async () => {
652
+ const db = getDb(ctx);
653
+ const linkTable = getLinkTable(ctx, linkDef.tableName);
654
+ const linkId = `link_${leftId}_${rightId}`;
655
+ await db.insert(linkTable).values({
656
+ id: linkId,
657
+ [linkDef.leftFk]: leftId,
658
+ [linkDef.rightFk]: rightId,
659
+ created_at: new Date(),
660
+ updated_at: new Date(),
661
+ });
662
+ });
663
+ }
664
+ // ---------------------------------------------------------------------------
665
+ // Public API — step Proxy
666
+ //
667
+ // 4 categories:
668
+ // step.service.catalog.create({...}, ctx) — service CRUD + compensable methods
669
+ // step.command.createProduct({...}, ctx) — sub-workflow (command invocation)
670
+ // step.action('name', { invoke, compensate }) — custom external action
671
+ // step.emit('event.name', data, ctx) — fire-and-forget event
672
+ // ---------------------------------------------------------------------------
673
+ function stepAction(name, config) {
674
+ if (!config.compensate) {
675
+ throw new MantaError('INVALID_DATA', `step.action("${name}") requires a compensate function. Usage: step.action("${name}", { invoke: async (input) => {...}, compensate: async (result) => {...} })`);
676
+ }
677
+ return async (input, ctx) => {
678
+ // Inject progress/signal/forEach/yield into the ctx passed to the user's invoke/compensate.
679
+ // Without this, `ctx.forEach` stays undefined inside step.action handlers — which
680
+ // breaks any long-running step that relies on it (e.g. rebuildCarts → PostHog replay).
681
+ const wfCtx = workflowContextStorage.getStore() ?? ctx.__wfCtx ?? null;
682
+ // Unique stepKey for resumeState lookup — mirrors the counter logic in
683
+ // runStep. Safe to peek ahead: runStep increments the same counter so
684
+ // our lookup uses the same key runStep will use.
685
+ const stepKey = wfCtx ? buildStepKey(wfCtx, name) : name;
686
+ const yieldFn = ((state) => {
687
+ throw new WorkflowYield(state);
688
+ });
689
+ const augmentedCtx = wfCtx
690
+ ? {
691
+ ...ctx,
692
+ __wfCtx: wfCtx,
693
+ signal: wfCtx.signal ?? ctx.signal,
694
+ progress: createProgress(wfCtx),
695
+ forEach: createForEach(wfCtx),
696
+ yield: yieldFn,
697
+ resumeState: wfCtx.resumeStates?.get(stepKey),
698
+ budgetMs: wfCtx.budgetMs,
699
+ }
700
+ : ctx;
701
+ return runStep(name, augmentedCtx, () => config.invoke(input, augmentedCtx), (output) => config.compensate(output, augmentedCtx));
702
+ };
703
+ }
704
+ /**
705
+ * Compute the stepKey runStep will use for a given step name, WITHOUT
706
+ * bumping the counter (runStep will bump it itself). Lets the action wrapper
707
+ * look up `resumeState` by the same key runStep uses.
708
+ */
709
+ function buildStepKey(wfCtx, name) {
710
+ const count = (wfCtx.stepCounter.get(name) ?? 0) + 1;
711
+ return count === 1 ? name : `${name}-${count}`;
712
+ }
713
+ /**
714
+ * Service proxy — step.service.catalog.create(), step.service.catalog.activate()
715
+ * Accessed via step.service.MODULE_NAME
716
+ */
717
+ function createServiceNamespace() {
718
+ return new Proxy({}, {
719
+ get(_target, moduleName) {
720
+ return createModuleProxy(moduleName);
721
+ },
722
+ });
723
+ }
724
+ // ---------------------------------------------------------------------------
725
+ // Link namespace — step.link.<linkName>.{ list, create, delete, update }
726
+ // Pivot-backed CRUD on link tables. Intra-module FK-backed links throw
727
+ // NOT_SUPPORTED — will be implemented when the first use case appears.
728
+ // ---------------------------------------------------------------------------
729
+ /** Convert 'customerAddress' → 'customer_address' (matches ResolvedLink.tableName). */
730
+ function linkNameToTableName(name) {
731
+ return name.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
732
+ }
733
+ /** Convert 'customer_address' → 'customerAddress' (used for available-link hints). */
734
+ function tableNameToLinkName(tableName) {
735
+ return tableName.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
736
+ }
737
+ /** Resolve a ResolvedLink by its user-facing camelCase name. Throws if not found or FK-backed. */
738
+ function resolveLinkByName(ctx, name) {
739
+ const expected = linkNameToTableName(name);
740
+ const links = resolveLinks(ctx);
741
+ const link = links.find((l) => l.tableName === expected);
742
+ if (!link) {
743
+ const available = links.map((l) => tableNameToLinkName(l.tableName)).join(', ');
744
+ throw new MantaError('NOT_FOUND', `Link "${name}" not found. Available links: [${available}]. Define it via defineLink() in src/links/ or src/modules/*/links/.`);
745
+ }
746
+ if (link.isDirectFk) {
747
+ throw new MantaError('NOT_SUPPORTED', `Link "${name}" is FK-backed (intra-module ${link.cardinality}). step.link.${name}.* is only implemented for pivot-backed links currently. Use step.service.<entity>.update() to manipulate the FK column directly.`);
748
+ }
749
+ return link;
750
+ }
751
+ /** Build a drizzle WHERE clause from a plain {col: value} object. */
752
+ // biome-ignore lint/suspicious/noExplicitAny: drizzle column types are dynamic
753
+ function buildWhere(table, where) {
754
+ const conditions = Object.entries(where).map(([key, value]) => {
755
+ const col = getColumn(table, key);
756
+ return value === null ? isNull(col) : eq(col, value);
757
+ });
758
+ if (conditions.length === 0)
759
+ return undefined;
760
+ if (conditions.length === 1)
761
+ return conditions[0];
762
+ return and(...conditions);
763
+ }
764
+ /**
765
+ * Link proxy — step.link.customerAddress.list({ customer_id, type: 'billing' })
766
+ *
767
+ * API (parallel to a model service CRUD):
768
+ * list(where) → pivot rows matching the where clause
769
+ * create(data) → insert a pivot row (data must include both FKs + any required extras)
770
+ * update(where, patch) → update extra columns on matching pivot rows
771
+ * delete(where) → delete matching pivot rows
772
+ *
773
+ * For pivot-backed links only. FK-backed intra-module links throw NOT_SUPPORTED
774
+ * at resolution time with a clear message.
775
+ */
776
+ function createLinkNamespace() {
777
+ return new Proxy({}, {
778
+ get(_target, linkName) {
779
+ return {
780
+ list: async (where, ctx) => {
781
+ const link = resolveLinkByName(ctx, linkName);
782
+ return runStep(`link-list-${link.tableName}`, ctx, async () => {
783
+ const db = getDb(ctx);
784
+ const table = getLinkTable(ctx, link.tableName);
785
+ const whereClause = buildWhere(table, where ?? {});
786
+ const query = db.select().from(table);
787
+ const rows = whereClause ? await query.where(whereClause) : await query;
788
+ return rows;
789
+ });
790
+ },
791
+ create: async (data, ctx) => {
792
+ const link = resolveLinkByName(ctx, linkName);
793
+ if (!(link.leftFk in data) || !(link.rightFk in data)) {
794
+ throw new MantaError('INVALID_DATA', `step.link.${linkName}.create requires both "${link.leftFk}" and "${link.rightFk}" in the payload.`);
795
+ }
796
+ const leftId = data[link.leftFk];
797
+ const rightId = data[link.rightFk];
798
+ const linkId = `link_${leftId}_${rightId}`;
799
+ return runStep(`link-create-${link.tableName}`, ctx, async () => {
800
+ const db = getDb(ctx);
801
+ const table = getLinkTable(ctx, link.tableName);
802
+ const now = new Date();
803
+ await db.insert(table).values({
804
+ id: linkId,
805
+ ...data,
806
+ created_at: now,
807
+ updated_at: now,
808
+ });
809
+ return { id: linkId, ...data };
810
+ }, async () => {
811
+ const db = getDb(ctx);
812
+ const table = getLinkTable(ctx, link.tableName);
813
+ const idCol = getColumn(table, 'id');
814
+ await db.delete(table).where(eq(idCol, linkId));
815
+ });
816
+ },
817
+ update: async (where, patch, ctx) => {
818
+ const link = resolveLinkByName(ctx, linkName);
819
+ const extraKeys = Object.keys(link.extraColumns ?? {});
820
+ if (extraKeys.length === 0) {
821
+ throw new MantaError('NOT_SUPPORTED', `Link "${linkName}" has no extra columns to update. step.link.${linkName}.update requires defined extraColumns on defineLink().`);
822
+ }
823
+ for (const key of Object.keys(patch)) {
824
+ if (!extraKeys.includes(key)) {
825
+ throw new MantaError('INVALID_DATA', `Unknown column "${key}" on link "${linkName}". Available extras: [${extraKeys.join(', ')}].`);
826
+ }
827
+ }
828
+ return runStep(`link-update-${link.tableName}`, ctx, async () => {
829
+ const db = getDb(ctx);
830
+ const table = getLinkTable(ctx, link.tableName);
831
+ const whereClause = buildWhere(table, where ?? {});
832
+ if (!whereClause) {
833
+ throw new MantaError('INVALID_DATA', `step.link.${linkName}.update requires a non-empty where clause.`);
834
+ }
835
+ await db
836
+ .update(table)
837
+ .set({ ...patch, updated_at: new Date() })
838
+ .where(whereClause);
839
+ return { ok: true };
840
+ });
841
+ },
842
+ delete: async (where, ctx) => {
843
+ const link = resolveLinkByName(ctx, linkName);
844
+ return runStep(`link-delete-${link.tableName}`, ctx, async () => {
845
+ const db = getDb(ctx);
846
+ const table = getLinkTable(ctx, link.tableName);
847
+ const whereClause = buildWhere(table, where ?? {});
848
+ if (!whereClause) {
849
+ throw new MantaError('INVALID_DATA', `step.link.${linkName}.delete requires a non-empty where clause.`);
850
+ }
851
+ await db.delete(table).where(whereClause);
852
+ return { ok: true };
853
+ });
854
+ },
855
+ };
856
+ },
857
+ });
858
+ }
859
+ /**
860
+ * Command proxy — step.command.createProduct(), step.command.catalog.activateProduct()
861
+ * Resolves commands from CommandRegistry and executes them as sub-workflows.
862
+ */
863
+ function createCommandNamespace() {
864
+ return new Proxy({}, {
865
+ get(_target, commandName) {
866
+ // step.command.createProduct(input, ctx) → resolves command and runs it
867
+ return async (input, ctx) => {
868
+ return runStep(`command-${commandName}`, ctx, async () => {
869
+ // Resolve the command callable from the app
870
+ const camelCase = commandName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
871
+ const commands = ctx.app.commands;
872
+ const callable = commands[camelCase] ?? commands[commandName];
873
+ if (!callable) {
874
+ throw new MantaError('NOT_FOUND', `Command "${commandName}" not found in app.commands`);
875
+ }
876
+ return callable(input);
877
+ });
878
+ };
879
+ },
880
+ });
881
+ }
882
+ // ---------------------------------------------------------------------------
883
+ // Agent step — step.agent.NAME(input, ctx)
884
+ // AI SDK imports are in a separate file (ai-step.ts) to avoid compile-time
885
+ // dependency on the 'ai' package. Loaded dynamically via await import().
886
+ // ---------------------------------------------------------------------------
887
+ // biome-ignore lint/suspicious/noExplicitAny: AgentDefinition generic
888
+ async function stepAgent(agentDef, input, ctx) {
889
+ const parsed = agentDef.input.parse(input);
890
+ const promptText = agentDef.instructions({ input: parsed });
891
+ return runStep(`agent-${agentDef.name}`, ctx, async () => {
892
+ // Dynamic import to avoid compile-time dependency on AI SDK
893
+ const mod = await import('./ai-step.js');
894
+ return mod.executeAgent(agentDef, parsed, promptText);
895
+ });
896
+ }
897
+ /**
898
+ * Agent proxy — step.agent.categorizeProduct(input, ctx)
899
+ * Resolves agent definitions from __agentRegistry in app.
900
+ */
901
+ function createAgentNamespace() {
902
+ return new Proxy({}, {
903
+ get(_target, agentName) {
904
+ return async (input, ctx) => {
905
+ // Resolve agent definition from registry
906
+ // biome-ignore lint/suspicious/noExplicitAny: dynamic registry
907
+ let registry = null;
908
+ try {
909
+ registry = ctx.app.resolve('__agentRegistry');
910
+ }
911
+ catch {
912
+ throw new MantaError('NOT_FOUND', `Agent "${agentName}" not found. No agents registered. Create agents in src/agents/.`);
913
+ }
914
+ // Convert camelCase to kebab-case for lookup
915
+ const kebab = agentName.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
916
+ const agentDef = registry.get(kebab) ?? registry.get(agentName);
917
+ if (!agentDef) {
918
+ const available = [...registry.keys()].join(', ');
919
+ throw new MantaError('NOT_FOUND', `Agent "${agentName}" not found. Available agents: [${available}]. Create it in src/agents/${kebab}.ts.`);
920
+ }
921
+ return stepAgent(agentDef, input, ctx);
922
+ };
923
+ },
924
+ });
925
+ }
926
+ const stepBase = {
927
+ emit: stepEmit,
928
+ action: stepAction,
929
+ service: createServiceNamespace(),
930
+ command: createCommandNamespace(),
931
+ link: createLinkNamespace(),
932
+ agent: createAgentNamespace(),
933
+ // Low-level access (used by framework internals)
934
+ create: stepCreate,
935
+ update: stepUpdate,
936
+ delete: stepDelete,
937
+ linkExplicit: stepLinkExplicit,
938
+ dismissLink: stepDismissLink,
939
+ invoke: stepInvoke,
940
+ };
941
+ export const step = new Proxy(stepBase, {
942
+ get(target, prop) {
943
+ if (prop in target)
944
+ return target[prop];
945
+ // Fallback: treat unknown property as module name (backward compat during migration)
946
+ return createModuleProxy(prop);
947
+ },
948
+ });
949
+ //# sourceMappingURL=step.js.map