@shware/workflow 0.0.0-stage → 0.0.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 (442) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -2
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/apns-relay.cjs +105 -0
  5. package/dist/apns-relay.cjs.map +1 -0
  6. package/dist/apns-relay.d.cts +28 -0
  7. package/dist/apns-relay.d.cts.map +1 -0
  8. package/dist/apns-relay.d.mts +28 -0
  9. package/dist/apns-relay.d.mts.map +1 -0
  10. package/dist/apns-relay.mjs +104 -0
  11. package/dist/apns-relay.mjs.map +1 -0
  12. package/dist/apns.cjs +121 -0
  13. package/dist/apns.cjs.map +1 -0
  14. package/dist/apns.d.cts +63 -0
  15. package/dist/apns.d.cts.map +1 -0
  16. package/dist/apns.d.mts +63 -0
  17. package/dist/apns.d.mts.map +1 -0
  18. package/dist/apns.mjs +116 -0
  19. package/dist/apns.mjs.map +1 -0
  20. package/dist/client.cjs +125 -0
  21. package/dist/client.cjs.map +1 -0
  22. package/dist/client.d.cts +108 -0
  23. package/dist/client.d.cts.map +1 -0
  24. package/dist/client.d.mts +108 -0
  25. package/dist/client.d.mts.map +1 -0
  26. package/dist/client.mjs +122 -0
  27. package/dist/client.mjs.map +1 -0
  28. package/dist/cloudflare/bindings.cjs +28 -0
  29. package/dist/cloudflare/bindings.cjs.map +1 -0
  30. package/dist/cloudflare/bindings.d.cts +144 -0
  31. package/dist/cloudflare/bindings.d.cts.map +1 -0
  32. package/dist/cloudflare/bindings.d.mts +144 -0
  33. package/dist/cloudflare/bindings.d.mts.map +1 -0
  34. package/dist/cloudflare/bindings.mjs +25 -0
  35. package/dist/cloudflare/bindings.mjs.map +1 -0
  36. package/dist/cloudflare/channels.cjs +164 -0
  37. package/dist/cloudflare/channels.cjs.map +1 -0
  38. package/dist/cloudflare/channels.d.cts +29 -0
  39. package/dist/cloudflare/channels.d.cts.map +1 -0
  40. package/dist/cloudflare/channels.d.mts +29 -0
  41. package/dist/cloudflare/channels.d.mts.map +1 -0
  42. package/dist/cloudflare/channels.mjs +161 -0
  43. package/dist/cloudflare/channels.mjs.map +1 -0
  44. package/dist/cloudflare/d1-env.cjs +17 -0
  45. package/dist/cloudflare/d1-env.cjs.map +1 -0
  46. package/dist/cloudflare/d1-env.d.cts +12 -0
  47. package/dist/cloudflare/d1-env.d.cts.map +1 -0
  48. package/dist/cloudflare/d1-env.d.mts +12 -0
  49. package/dist/cloudflare/d1-env.d.mts.map +1 -0
  50. package/dist/cloudflare/d1-env.mjs +16 -0
  51. package/dist/cloudflare/d1-env.mjs.map +1 -0
  52. package/dist/cloudflare/index.cjs +54 -0
  53. package/dist/cloudflare/index.d.cts +19 -0
  54. package/dist/cloudflare/index.d.mts +19 -0
  55. package/dist/cloudflare/index.mjs +16 -0
  56. package/dist/cloudflare/router.cjs +516 -0
  57. package/dist/cloudflare/router.cjs.map +1 -0
  58. package/dist/cloudflare/router.d.cts +157 -0
  59. package/dist/cloudflare/router.d.cts.map +1 -0
  60. package/dist/cloudflare/router.d.mts +157 -0
  61. package/dist/cloudflare/router.d.mts.map +1 -0
  62. package/dist/cloudflare/router.mjs +503 -0
  63. package/dist/cloudflare/router.mjs.map +1 -0
  64. package/dist/cloudflare/runner.cjs +225 -0
  65. package/dist/cloudflare/runner.cjs.map +1 -0
  66. package/dist/cloudflare/runner.d.cts +73 -0
  67. package/dist/cloudflare/runner.d.cts.map +1 -0
  68. package/dist/cloudflare/runner.d.mts +73 -0
  69. package/dist/cloudflare/runner.d.mts.map +1 -0
  70. package/dist/cloudflare/runner.mjs +224 -0
  71. package/dist/cloudflare/runner.mjs.map +1 -0
  72. package/dist/cloudflare/schema.sql +127 -0
  73. package/dist/cloudflare/senders.cjs +114 -0
  74. package/dist/cloudflare/senders.cjs.map +1 -0
  75. package/dist/cloudflare/senders.d.cts +68 -0
  76. package/dist/cloudflare/senders.d.cts.map +1 -0
  77. package/dist/cloudflare/senders.d.mts +68 -0
  78. package/dist/cloudflare/senders.d.mts.map +1 -0
  79. package/dist/cloudflare/senders.mjs +108 -0
  80. package/dist/cloudflare/senders.mjs.map +1 -0
  81. package/dist/cloudflare/worker.cjs +228 -0
  82. package/dist/cloudflare/worker.cjs.map +1 -0
  83. package/dist/cloudflare/worker.d.cts +92 -0
  84. package/dist/cloudflare/worker.d.cts.map +1 -0
  85. package/dist/cloudflare/worker.d.mts +92 -0
  86. package/dist/cloudflare/worker.d.mts.map +1 -0
  87. package/dist/cloudflare/worker.mjs +224 -0
  88. package/dist/cloudflare/worker.mjs.map +1 -0
  89. package/dist/cloudflare/workers.d.cjs +0 -0
  90. package/dist/cloudflare/workers.d.cts +44 -0
  91. package/dist/cloudflare/workers.d.cts.map +1 -0
  92. package/dist/cloudflare/workers.d.mts +44 -0
  93. package/dist/cloudflare/workers.d.mts.map +1 -0
  94. package/dist/config.cjs +151 -0
  95. package/dist/config.cjs.map +1 -0
  96. package/dist/config.d.cts +149 -0
  97. package/dist/config.d.cts.map +1 -0
  98. package/dist/config.d.mts +149 -0
  99. package/dist/config.d.mts.map +1 -0
  100. package/dist/config.mjs +143 -0
  101. package/dist/config.mjs.map +1 -0
  102. package/dist/contract.cjs +212 -0
  103. package/dist/contract.cjs.map +1 -0
  104. package/dist/contract.d.cts +90 -0
  105. package/dist/contract.d.cts.map +1 -0
  106. package/dist/contract.d.mts +90 -0
  107. package/dist/contract.d.mts.map +1 -0
  108. package/dist/contract.mjs +206 -0
  109. package/dist/contract.mjs.map +1 -0
  110. package/dist/dsl/action.cjs +29 -0
  111. package/dist/dsl/action.cjs.map +1 -0
  112. package/dist/dsl/action.d.cts +64 -0
  113. package/dist/dsl/action.d.cts.map +1 -0
  114. package/dist/dsl/action.d.mts +64 -0
  115. package/dist/dsl/action.d.mts.map +1 -0
  116. package/dist/dsl/action.mjs +28 -0
  117. package/dist/dsl/action.mjs.map +1 -0
  118. package/dist/dsl/base.cjs +34 -0
  119. package/dist/dsl/base.cjs.map +1 -0
  120. package/dist/dsl/base.d.cts +45 -0
  121. package/dist/dsl/base.d.cts.map +1 -0
  122. package/dist/dsl/base.d.mts +45 -0
  123. package/dist/dsl/base.d.mts.map +1 -0
  124. package/dist/dsl/base.mjs +30 -0
  125. package/dist/dsl/base.mjs.map +1 -0
  126. package/dist/dsl/bundle.cjs +207 -0
  127. package/dist/dsl/bundle.cjs.map +1 -0
  128. package/dist/dsl/bundle.d.cts +19 -0
  129. package/dist/dsl/bundle.d.cts.map +1 -0
  130. package/dist/dsl/bundle.d.mts +19 -0
  131. package/dist/dsl/bundle.d.mts.map +1 -0
  132. package/dist/dsl/bundle.mjs +206 -0
  133. package/dist/dsl/bundle.mjs.map +1 -0
  134. package/dist/dsl/condition.cjs +177 -0
  135. package/dist/dsl/condition.cjs.map +1 -0
  136. package/dist/dsl/condition.d.cts +140 -0
  137. package/dist/dsl/condition.d.cts.map +1 -0
  138. package/dist/dsl/condition.d.mts +140 -0
  139. package/dist/dsl/condition.d.mts.map +1 -0
  140. package/dist/dsl/condition.mjs +156 -0
  141. package/dist/dsl/condition.mjs.map +1 -0
  142. package/dist/dsl/flow.cjs +228 -0
  143. package/dist/dsl/flow.cjs.map +1 -0
  144. package/dist/dsl/flow.d.cts +223 -0
  145. package/dist/dsl/flow.d.cts.map +1 -0
  146. package/dist/dsl/flow.d.mts +223 -0
  147. package/dist/dsl/flow.d.mts.map +1 -0
  148. package/dist/dsl/flow.mjs +226 -0
  149. package/dist/dsl/flow.mjs.map +1 -0
  150. package/dist/dsl/index.cjs +38 -0
  151. package/dist/dsl/index.d.cts +10 -0
  152. package/dist/dsl/index.d.mts +10 -0
  153. package/dist/dsl/index.mjs +9 -0
  154. package/dist/dsl/refs.cjs +59 -0
  155. package/dist/dsl/refs.cjs.map +1 -0
  156. package/dist/dsl/refs.d.cts +88 -0
  157. package/dist/dsl/refs.d.cts.map +1 -0
  158. package/dist/dsl/refs.d.mts +88 -0
  159. package/dist/dsl/refs.d.mts.map +1 -0
  160. package/dist/dsl/refs.mjs +55 -0
  161. package/dist/dsl/refs.mjs.map +1 -0
  162. package/dist/dsl/template.cjs +65 -0
  163. package/dist/dsl/template.cjs.map +1 -0
  164. package/dist/dsl/template.d.cts +75 -0
  165. package/dist/dsl/template.d.cts.map +1 -0
  166. package/dist/dsl/template.d.mts +75 -0
  167. package/dist/dsl/template.d.mts.map +1 -0
  168. package/dist/dsl/template.mjs +63 -0
  169. package/dist/dsl/template.mjs.map +1 -0
  170. package/dist/dsl/trigger.cjs +40 -0
  171. package/dist/dsl/trigger.cjs.map +1 -0
  172. package/dist/dsl/trigger.d.cts +65 -0
  173. package/dist/dsl/trigger.d.cts.map +1 -0
  174. package/dist/dsl/trigger.d.mts +65 -0
  175. package/dist/dsl/trigger.d.mts.map +1 -0
  176. package/dist/dsl/trigger.mjs +39 -0
  177. package/dist/dsl/trigger.mjs.map +1 -0
  178. package/dist/dsl/workflow.cjs +121 -0
  179. package/dist/dsl/workflow.cjs.map +1 -0
  180. package/dist/dsl/workflow.d.cts +59 -0
  181. package/dist/dsl/workflow.d.cts.map +1 -0
  182. package/dist/dsl/workflow.d.mts +59 -0
  183. package/dist/dsl/workflow.d.mts.map +1 -0
  184. package/dist/dsl/workflow.mjs +120 -0
  185. package/dist/dsl/workflow.mjs.map +1 -0
  186. package/dist/engine/actions.cjs +27 -0
  187. package/dist/engine/actions.cjs.map +1 -0
  188. package/dist/engine/actions.d.cts +40 -0
  189. package/dist/engine/actions.d.cts.map +1 -0
  190. package/dist/engine/actions.d.mts +40 -0
  191. package/dist/engine/actions.d.mts.map +1 -0
  192. package/dist/engine/actions.mjs +26 -0
  193. package/dist/engine/actions.mjs.map +1 -0
  194. package/dist/engine/bucket.cjs +72 -0
  195. package/dist/engine/bucket.cjs.map +1 -0
  196. package/dist/engine/bucket.d.cts +32 -0
  197. package/dist/engine/bucket.d.cts.map +1 -0
  198. package/dist/engine/bucket.d.mts +32 -0
  199. package/dist/engine/bucket.d.mts.map +1 -0
  200. package/dist/engine/bucket.mjs +69 -0
  201. package/dist/engine/bucket.mjs.map +1 -0
  202. package/dist/engine/condition.cjs +166 -0
  203. package/dist/engine/condition.cjs.map +1 -0
  204. package/dist/engine/condition.d.cts +52 -0
  205. package/dist/engine/condition.d.cts.map +1 -0
  206. package/dist/engine/condition.d.mts +52 -0
  207. package/dist/engine/condition.d.mts.map +1 -0
  208. package/dist/engine/condition.mjs +161 -0
  209. package/dist/engine/condition.mjs.map +1 -0
  210. package/dist/engine/index.cjs +20 -0
  211. package/dist/engine/index.d.cts +8 -0
  212. package/dist/engine/index.d.mts +8 -0
  213. package/dist/engine/index.mjs +7 -0
  214. package/dist/engine/interpreter.cjs +428 -0
  215. package/dist/engine/interpreter.cjs.map +1 -0
  216. package/dist/engine/interpreter.d.cts +6 -0
  217. package/dist/engine/interpreter.d.cts.map +1 -0
  218. package/dist/engine/interpreter.d.mts +6 -0
  219. package/dist/engine/interpreter.d.mts.map +1 -0
  220. package/dist/engine/interpreter.mjs +427 -0
  221. package/dist/engine/interpreter.mjs.map +1 -0
  222. package/dist/engine/ports.cjs +0 -0
  223. package/dist/engine/ports.d.cts +252 -0
  224. package/dist/engine/ports.d.cts.map +1 -0
  225. package/dist/engine/ports.d.mts +252 -0
  226. package/dist/engine/ports.d.mts.map +1 -0
  227. package/dist/engine/ports.mjs +1 -0
  228. package/dist/engine/recipient.cjs +23 -0
  229. package/dist/engine/recipient.cjs.map +1 -0
  230. package/dist/engine/recipient.d.cts +13 -0
  231. package/dist/engine/recipient.d.cts.map +1 -0
  232. package/dist/engine/recipient.d.mts +13 -0
  233. package/dist/engine/recipient.d.mts.map +1 -0
  234. package/dist/engine/recipient.mjs +22 -0
  235. package/dist/engine/recipient.mjs.map +1 -0
  236. package/dist/engine/time-scale.cjs +54 -0
  237. package/dist/engine/time-scale.cjs.map +1 -0
  238. package/dist/engine/time-scale.d.cts +31 -0
  239. package/dist/engine/time-scale.d.cts.map +1 -0
  240. package/dist/engine/time-scale.d.mts +31 -0
  241. package/dist/engine/time-scale.d.mts.map +1 -0
  242. package/dist/engine/time-scale.mjs +52 -0
  243. package/dist/engine/time-scale.mjs.map +1 -0
  244. package/dist/engine/time-window.cjs +149 -0
  245. package/dist/engine/time-window.cjs.map +1 -0
  246. package/dist/engine/time-window.d.cts +22 -0
  247. package/dist/engine/time-window.d.cts.map +1 -0
  248. package/dist/engine/time-window.d.mts +22 -0
  249. package/dist/engine/time-window.d.mts.map +1 -0
  250. package/dist/engine/time-window.mjs +147 -0
  251. package/dist/engine/time-window.mjs.map +1 -0
  252. package/dist/fcm.cjs +125 -0
  253. package/dist/fcm.cjs.map +1 -0
  254. package/dist/fcm.d.cts +48 -0
  255. package/dist/fcm.d.cts.map +1 -0
  256. package/dist/fcm.d.mts +48 -0
  257. package/dist/fcm.d.mts.map +1 -0
  258. package/dist/fcm.mjs +121 -0
  259. package/dist/fcm.mjs.map +1 -0
  260. package/dist/hash.cjs +245 -0
  261. package/dist/hash.cjs.map +1 -0
  262. package/dist/hash.d.cts +30 -0
  263. package/dist/hash.d.cts.map +1 -0
  264. package/dist/hash.d.mts +30 -0
  265. package/dist/hash.d.mts.map +1 -0
  266. package/dist/hash.mjs +239 -0
  267. package/dist/hash.mjs.map +1 -0
  268. package/dist/index.cjs +100 -0
  269. package/dist/index.d.cts +18 -0
  270. package/dist/index.d.mts +18 -0
  271. package/dist/index.mjs +17 -0
  272. package/dist/ir.cjs +366 -0
  273. package/dist/ir.cjs.map +1 -0
  274. package/dist/ir.d.cts +486 -0
  275. package/dist/ir.d.cts.map +1 -0
  276. package/dist/ir.d.mts +486 -0
  277. package/dist/ir.d.mts.map +1 -0
  278. package/dist/ir.mjs +344 -0
  279. package/dist/ir.mjs.map +1 -0
  280. package/dist/jwt.cjs +22 -0
  281. package/dist/jwt.cjs.map +1 -0
  282. package/dist/jwt.d.cts +9 -0
  283. package/dist/jwt.d.cts.map +1 -0
  284. package/dist/jwt.d.mts +9 -0
  285. package/dist/jwt.d.mts.map +1 -0
  286. package/dist/jwt.mjs +20 -0
  287. package/dist/jwt.mjs.map +1 -0
  288. package/dist/plan.cjs +223 -0
  289. package/dist/plan.cjs.map +1 -0
  290. package/dist/plan.d.cts +68 -0
  291. package/dist/plan.d.cts.map +1 -0
  292. package/dist/plan.d.mts +68 -0
  293. package/dist/plan.d.mts.map +1 -0
  294. package/dist/plan.mjs +221 -0
  295. package/dist/plan.mjs.map +1 -0
  296. package/dist/postgres-js.cjs +42 -0
  297. package/dist/postgres-js.cjs.map +1 -0
  298. package/dist/postgres-js.d.cts +28 -0
  299. package/dist/postgres-js.d.cts.map +1 -0
  300. package/dist/postgres-js.d.mts +28 -0
  301. package/dist/postgres-js.d.mts.map +1 -0
  302. package/dist/postgres-js.mjs +38 -0
  303. package/dist/postgres-js.mjs.map +1 -0
  304. package/dist/provenance.cjs +67 -0
  305. package/dist/provenance.cjs.map +1 -0
  306. package/dist/provenance.d.cts +41 -0
  307. package/dist/provenance.d.cts.map +1 -0
  308. package/dist/provenance.d.mts +41 -0
  309. package/dist/provenance.d.mts.map +1 -0
  310. package/dist/provenance.mjs +65 -0
  311. package/dist/provenance.mjs.map +1 -0
  312. package/dist/push.cjs +14 -0
  313. package/dist/push.cjs.map +1 -0
  314. package/dist/push.d.cts +16 -0
  315. package/dist/push.d.cts.map +1 -0
  316. package/dist/push.d.mts +16 -0
  317. package/dist/push.d.mts.map +1 -0
  318. package/dist/push.mjs +13 -0
  319. package/dist/push.mjs.map +1 -0
  320. package/dist/react-email.cjs +48 -0
  321. package/dist/react-email.cjs.map +1 -0
  322. package/dist/react-email.d.cts +7 -0
  323. package/dist/react-email.d.cts.map +1 -0
  324. package/dist/react-email.d.mts +7 -0
  325. package/dist/react-email.d.mts.map +1 -0
  326. package/dist/react-email.mjs +47 -0
  327. package/dist/react-email.mjs.map +1 -0
  328. package/dist/reporting/classify.cjs +42 -0
  329. package/dist/reporting/classify.cjs.map +1 -0
  330. package/dist/reporting/classify.d.cts +60 -0
  331. package/dist/reporting/classify.d.cts.map +1 -0
  332. package/dist/reporting/classify.d.mts +60 -0
  333. package/dist/reporting/classify.d.mts.map +1 -0
  334. package/dist/reporting/classify.mjs +38 -0
  335. package/dist/reporting/classify.mjs.map +1 -0
  336. package/dist/reporting/observer.cjs +63 -0
  337. package/dist/reporting/observer.cjs.map +1 -0
  338. package/dist/reporting/observer.d.cts +18 -0
  339. package/dist/reporting/observer.d.cts.map +1 -0
  340. package/dist/reporting/observer.d.mts +18 -0
  341. package/dist/reporting/observer.d.mts.map +1 -0
  342. package/dist/reporting/observer.mjs +62 -0
  343. package/dist/reporting/observer.mjs.map +1 -0
  344. package/dist/reporting/tracking.cjs +153 -0
  345. package/dist/reporting/tracking.cjs.map +1 -0
  346. package/dist/reporting/tracking.d.cts +43 -0
  347. package/dist/reporting/tracking.d.cts.map +1 -0
  348. package/dist/reporting/tracking.d.mts +43 -0
  349. package/dist/reporting/tracking.d.mts.map +1 -0
  350. package/dist/reporting/tracking.mjs +151 -0
  351. package/dist/reporting/tracking.mjs.map +1 -0
  352. package/dist/runtime.cjs +19 -0
  353. package/dist/runtime.cjs.map +1 -0
  354. package/dist/runtime.d.cts +30 -0
  355. package/dist/runtime.d.cts.map +1 -0
  356. package/dist/runtime.d.mts +30 -0
  357. package/dist/runtime.d.mts.map +1 -0
  358. package/dist/runtime.mjs +18 -0
  359. package/dist/runtime.mjs.map +1 -0
  360. package/dist/store/d1.cjs +185 -0
  361. package/dist/store/d1.cjs.map +1 -0
  362. package/dist/store/d1.d.cts +55 -0
  363. package/dist/store/d1.d.cts.map +1 -0
  364. package/dist/store/d1.d.mts +55 -0
  365. package/dist/store/d1.d.mts.map +1 -0
  366. package/dist/store/d1.mjs +184 -0
  367. package/dist/store/d1.mjs.map +1 -0
  368. package/dist/store/facts.cjs +60 -0
  369. package/dist/store/facts.cjs.map +1 -0
  370. package/dist/store/facts.d.cts +38 -0
  371. package/dist/store/facts.d.cts.map +1 -0
  372. package/dist/store/facts.d.mts +38 -0
  373. package/dist/store/facts.d.mts.map +1 -0
  374. package/dist/store/facts.mjs +58 -0
  375. package/dist/store/facts.mjs.map +1 -0
  376. package/dist/store/index.cjs +31 -0
  377. package/dist/store/index.cjs.map +1 -0
  378. package/dist/store/index.d.cts +291 -0
  379. package/dist/store/index.d.cts.map +1 -0
  380. package/dist/store/index.d.mts +291 -0
  381. package/dist/store/index.d.mts.map +1 -0
  382. package/dist/store/index.mjs +22 -0
  383. package/dist/store/index.mjs.map +1 -0
  384. package/dist/store/postgres-reporting.cjs +213 -0
  385. package/dist/store/postgres-reporting.cjs.map +1 -0
  386. package/dist/store/postgres-reporting.d.cts +63 -0
  387. package/dist/store/postgres-reporting.d.cts.map +1 -0
  388. package/dist/store/postgres-reporting.d.mts +63 -0
  389. package/dist/store/postgres-reporting.d.mts.map +1 -0
  390. package/dist/store/postgres-reporting.mjs +212 -0
  391. package/dist/store/postgres-reporting.mjs.map +1 -0
  392. package/dist/store/postgres.cjs +309 -0
  393. package/dist/store/postgres.cjs.map +1 -0
  394. package/dist/store/postgres.d.cts +77 -0
  395. package/dist/store/postgres.d.cts.map +1 -0
  396. package/dist/store/postgres.d.mts +77 -0
  397. package/dist/store/postgres.d.mts.map +1 -0
  398. package/dist/store/postgres.mjs +306 -0
  399. package/dist/store/postgres.mjs.map +1 -0
  400. package/dist/store/sql.cjs +24 -0
  401. package/dist/store/sql.cjs.map +1 -0
  402. package/dist/store/sql.d.cts +25 -0
  403. package/dist/store/sql.d.cts.map +1 -0
  404. package/dist/store/sql.d.mts +25 -0
  405. package/dist/store/sql.d.mts.map +1 -0
  406. package/dist/store/sql.mjs +23 -0
  407. package/dist/store/sql.mjs.map +1 -0
  408. package/dist/store/tables.cjs +404 -0
  409. package/dist/store/tables.cjs.map +1 -0
  410. package/dist/store/tables.d.cts +81 -0
  411. package/dist/store/tables.d.cts.map +1 -0
  412. package/dist/store/tables.d.mts +81 -0
  413. package/dist/store/tables.d.mts.map +1 -0
  414. package/dist/store/tables.mjs +399 -0
  415. package/dist/store/tables.mjs.map +1 -0
  416. package/dist/templates.cjs +247 -0
  417. package/dist/templates.cjs.map +1 -0
  418. package/dist/templates.d.cts +187 -0
  419. package/dist/templates.d.cts.map +1 -0
  420. package/dist/templates.d.mts +187 -0
  421. package/dist/templates.d.mts.map +1 -0
  422. package/dist/templates.mjs +230 -0
  423. package/dist/templates.mjs.map +1 -0
  424. package/dist/webhooks.cjs +96 -0
  425. package/dist/webhooks.cjs.map +1 -0
  426. package/dist/webhooks.d.cts +25 -0
  427. package/dist/webhooks.d.cts.map +1 -0
  428. package/dist/webhooks.d.mts +25 -0
  429. package/dist/webhooks.d.mts.map +1 -0
  430. package/dist/webhooks.mjs +94 -0
  431. package/dist/webhooks.mjs.map +1 -0
  432. package/dist/webpush.cjs +180 -0
  433. package/dist/webpush.cjs.map +1 -0
  434. package/dist/webpush.d.cts +53 -0
  435. package/dist/webpush.d.cts.map +1 -0
  436. package/dist/webpush.d.mts +53 -0
  437. package/dist/webpush.d.mts.map +1 -0
  438. package/dist/webpush.mjs +175 -0
  439. package/dist/webpush.mjs.map +1 -0
  440. package/package.json +189 -3
  441. package/src/cloudflare/schema.sql +127 -0
  442. package/src/cloudflare/workers.d.ts +44 -0
@@ -0,0 +1,212 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
3
+ const require_dsl_refs = require("./dsl/refs.cjs");
4
+ require("./dsl/index.cjs");
5
+ let zod_mini = require("zod/mini");
6
+ zod_mini = require_runtime.__toESM(zod_mini, 1);
7
+ //#region src/contract.ts
8
+ function defineContract(definition) {
9
+ for (const [name, schema] of Object.entries(definition.events)) {
10
+ if (name.startsWith("$")) throw new TypeError(`contract event '${name}': names starting with $ are reserved`);
11
+ assertJsonSchema(schema, `event '${name}'`, true);
12
+ }
13
+ assertJsonSchema(definition.profile, "profile", true);
14
+ const profileShape = definition.profile._zod.def.shape;
15
+ for (const [field, schema] of Object.entries(profileShape)) assertFlatScalar(schema, `profile.${field}`);
16
+ const strictProfile = definition.profile._zod.def.catchall?._zod.def.type === "never";
17
+ const names = Object.keys(definition.events);
18
+ return {
19
+ kind: "journey-contract",
20
+ events: require_dsl_refs.event(),
21
+ user: require_dsl_refs.user(),
22
+ schemas: {
23
+ events: definition.events,
24
+ profile: definition.profile
25
+ },
26
+ eventNames: names,
27
+ isEvent: (name) => Object.hasOwn(definition.events, name),
28
+ parseEvent(name, payload) {
29
+ if (!Object.hasOwn(definition.events, name)) return {
30
+ ok: false,
31
+ issues: [{
32
+ path: "",
33
+ message: `unknown event '${name}'`
34
+ }]
35
+ };
36
+ return toResult(zod_mini.safeParse(definition.events[name], payload));
37
+ },
38
+ parseProfilePatch(patch) {
39
+ if (typeof patch !== "object" || patch === null || Array.isArray(patch)) return {
40
+ ok: false,
41
+ issues: [{
42
+ path: "",
43
+ message: "props must be an object"
44
+ }]
45
+ };
46
+ const issues = [];
47
+ const data = {};
48
+ for (const [field, value] of Object.entries(patch)) {
49
+ if (!Object.hasOwn(profileShape, field)) {
50
+ if (strictProfile || field === "userId") issues.push({
51
+ path: field,
52
+ message: "not a declared profile field"
53
+ });
54
+ else data[field] = value;
55
+ continue;
56
+ }
57
+ if (value === null) {
58
+ data[field] = null;
59
+ continue;
60
+ }
61
+ const result = zod_mini.safeParse(profileShape[field], value);
62
+ if (result.success) data[field] = result.data;
63
+ else issues.push(...prefixed(field, result.error));
64
+ }
65
+ return issues.length > 0 ? {
66
+ ok: false,
67
+ issues
68
+ } : {
69
+ ok: true,
70
+ data
71
+ };
72
+ }
73
+ };
74
+ }
75
+ /**
76
+ * An event the contract refuses — raised for events a journey emits itself
77
+ * (`.sendEvent()`), which never pass the HTTP ingest: they go through the same
78
+ * check, and a refusal is deterministic, so it is not retried.
79
+ */
80
+ var ContractValidationError = class extends Error {
81
+ event;
82
+ issues;
83
+ name = "ContractValidationError";
84
+ constructor(event, issues) {
85
+ super(`event '${event}' refused by the contract: ${issues.map((i) => `${i.path || "(root)"} ${i.message}`).join("; ")}`);
86
+ this.event = event;
87
+ this.issues = issues;
88
+ }
89
+ };
90
+ /** The one check every event passes, from HTTP or from a journey: declared, and its payload parses. */
91
+ function checkEvent(contract, name, payload) {
92
+ if (!contract.isEvent(name)) return {
93
+ ok: false,
94
+ issues: [{
95
+ path: "",
96
+ message: `'${String(name)}' is not in the contract`
97
+ }]
98
+ };
99
+ return contract.parseEvent(name, payload);
100
+ }
101
+ function isContract(value) {
102
+ return typeof value === "object" && value !== null && value.kind === "journey-contract";
103
+ }
104
+ function toResult(result) {
105
+ return result.success ? {
106
+ ok: true,
107
+ data: result.data
108
+ } : {
109
+ ok: false,
110
+ issues: prefixed("", result.error)
111
+ };
112
+ }
113
+ function prefixed(prefix, error) {
114
+ return error.issues.map((issue) => ({
115
+ path: [prefix, ...issue.path.map(String)].filter((p) => p !== "").join("."),
116
+ message: issue.message
117
+ }));
118
+ }
119
+ /**
120
+ * The schema types a contract may use — JSON shapes that parse synchronously
121
+ * and mean the same before and after parsing. Anything not listed (default,
122
+ * transform, pipe, lazy, promise, custom, date, bigint, …) is refused, and
123
+ * every container is walked so nothing unsupported hides inside one.
124
+ */
125
+ const ALLOWED = /* @__PURE__ */ new Set([
126
+ "object",
127
+ "array",
128
+ "tuple",
129
+ "union",
130
+ "intersection",
131
+ "record",
132
+ "optional",
133
+ "nullable",
134
+ "readonly",
135
+ "nonoptional",
136
+ "string",
137
+ "number",
138
+ "boolean",
139
+ "null",
140
+ "enum",
141
+ "literal",
142
+ "unknown",
143
+ "any",
144
+ "never"
145
+ ]);
146
+ /** Checks that change the value (`overwrite`: `.trim()`, `.toLowerCase()`, …) or run arbitrary code (`custom`: `.refine()`, async or not). */
147
+ const REFUSED_CHECKS = /* @__PURE__ */ new Set(["custom", "overwrite"]);
148
+ function assertJsonSchema(schema, where, top = false) {
149
+ const def = schema?._zod?.def;
150
+ if (def === void 0) throw new TypeError(`contract ${where}: not a Zod schema`);
151
+ if (top && def.type !== "object") throw new TypeError(`contract ${where}: must be an object schema (z.looseObject / z.strictObject)`);
152
+ if (!ALLOWED.has(def.type)) throw new TypeError(`contract ${where}: ${def.type} schemas are not supported (input and output must mean the same JSON, parsed synchronously)`);
153
+ if (def.coerce === true) throw new TypeError(`contract ${where}: coercion (z.coerce) is not supported`);
154
+ for (const check of def.checks ?? []) if (REFUSED_CHECKS.has(check._zod.def.check)) throw new TypeError(`contract ${where}: ${check._zod.def.check === "overwrite" ? "value-changing checks (.overwrite, .trim, …)" : "custom refinements"} are not supported`);
155
+ const children = [];
156
+ switch (def.type) {
157
+ case "object": {
158
+ const object = def;
159
+ for (const [k, v] of Object.entries(object.shape)) children.push([`${where}.${k}`, v]);
160
+ if (object.catchall !== void 0) children.push([`${where}.*`, object.catchall]);
161
+ break;
162
+ }
163
+ case "optional":
164
+ case "nullable":
165
+ case "readonly":
166
+ case "nonoptional":
167
+ children.push([where, def.innerType]);
168
+ break;
169
+ case "array":
170
+ children.push([`${where}[]`, def.element]);
171
+ break;
172
+ case "tuple": {
173
+ const tuple = def;
174
+ tuple.items.forEach((item, index) => children.push([`${where}[${index}]`, item]));
175
+ if (tuple.rest !== null) children.push([`${where}[…]`, tuple.rest]);
176
+ break;
177
+ }
178
+ case "union":
179
+ for (const option of def.options) children.push([where, option]);
180
+ break;
181
+ case "intersection": {
182
+ const intersection = def;
183
+ children.push([where, intersection.left], [where, intersection.right]);
184
+ break;
185
+ }
186
+ case "record": {
187
+ const record = def;
188
+ children.push([`${where}{key}`, record.keyType], [`${where}{}`, record.valueType]);
189
+ break;
190
+ }
191
+ }
192
+ for (const [path, child] of children) assertJsonSchema(child, path);
193
+ }
194
+ const SCALARS = /* @__PURE__ */ new Set([
195
+ "string",
196
+ "number",
197
+ "boolean",
198
+ "enum",
199
+ "literal"
200
+ ]);
201
+ function assertFlatScalar(schema, where) {
202
+ let def = schema._zod.def;
203
+ if (def.type === "optional") def = def.innerType._zod.def;
204
+ if (!SCALARS.has(def.type)) throw new TypeError(`contract ${where}: profile fields must be flat scalars (string, number, boolean, enum, literal), got ${def.type}`);
205
+ }
206
+ //#endregion
207
+ exports.ContractValidationError = ContractValidationError;
208
+ exports.checkEvent = checkEvent;
209
+ exports.defineContract = defineContract;
210
+ exports.isContract = isContract;
211
+
212
+ //# sourceMappingURL=contract.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.cjs","names":["event","user","z"],"sources":["../src/contract.ts"],"sourcesContent":["import * as z from 'zod/mini';\nimport type * as core from 'zod/v4/core';\nimport { type EventRefs, type UserRefs, event, user } from './dsl';\n\n/**\n * `defineContract({ events, profile })` — the producer/engine contract as Zod\n * schemas, written once in a package both sides import. From it:\n *\n * - `contract.events` / `contract.user` are the DSL's typed reference tables\n * (what `event<E>()` / `user<U>()` used to be, now derived from the schemas);\n * - `JourneyClient({ contract })` types `track` / `identify` by event name and\n * checks payloads before sending;\n * - `journeyWorker({ contract })` re-validates every inbound `/events` and\n * `/identify` — never trusting the caller used the SDK — and refuses a bad\n * one with a 4xx before anything is stored, woken or started.\n *\n * Supported schemas (v1), synchronous and JSON-shaped: event payloads are\n * object schemas (`z.looseObject` keeps a producer's extra analytics fields,\n * `z.strictObject` refuses them) and may nest objects and arrays; the profile\n * is a flat object of string / number / boolean / enum / literal fields. Input\n * and output must mean the same thing, so defaults, transforms, coercion,\n * custom refinements and async checks are refused when the contract is\n * defined. The Zod instances stay in the host; nothing here changes the IR.\n */\n\ntype ObjectSchema = core.$ZodObject;\n\n/** The declared fields of an object schema — without a loose object's `[key: string]: unknown`, so the DSL only offers fields that were written down. */\nexport type DeclaredOutput<S> =\n S extends core.$ZodObject<infer Shape>\n ? core.$InferObjectOutput<Shape, Record<never, never>>\n : never;\n\nexport interface ContractDefinition<\n E extends Record<string, ObjectSchema>,\n P extends ObjectSchema,\n> {\n events: E;\n profile: P;\n}\n\n/** One rejected field, with the dotted path the producer can fix. */\nexport interface ContractIssue {\n path: string;\n message: string;\n}\n\nexport type ContractResult<T> = { ok: true; data: T } | { ok: false; issues: ContractIssue[] };\n\nexport interface Contract<\n E extends Record<string, ObjectSchema> = Record<string, ObjectSchema>,\n P extends ObjectSchema = ObjectSchema,\n> {\n readonly kind: 'journey-contract';\n /** The DSL's event reference table: `e.purchase` — payload refs from the declared fields only. */\n readonly events: EventRefs<{ [K in keyof E]: DeclaredOutput<E[K]> }>;\n /** The DSL's user-property reference table: `u.name`, plus the system `u.userId`. */\n readonly user: UserRefs<DeclaredOutput<P> & { userId: string }>;\n /** The raw schemas, for hosts that need them (validation, docs). */\n readonly schemas: { readonly events: E; readonly profile: P };\n /** Every event name the contract declares — what a producer forwards. */\n readonly eventNames: readonly (keyof E & string)[];\n isEvent(name: string): name is keyof E & string;\n /** Validate one event's payload; the parsed value is what may be stored. */\n parseEvent<K extends keyof E & string>(\n name: K,\n payload: unknown\n ): ContractResult<core.output<E[K]>>;\n /**\n * Validate an `/identify` merge patch: omitted fields stay as they are,\n * `null` removes a field, every provided value is checked against its field\n * schema, and an undeclared field is refused — a patch, never a full parse\n * that would fill defaults over fields the caller did not send.\n */\n parseProfilePatch(patch: unknown): ContractResult<ProfilePatch<P>>;\n}\n\n/** An `/identify` patch over the profile: any subset of fields, `null` to remove one. */\nexport type ProfilePatch<P> = { [K in keyof DeclaredOutput<P>]?: DeclaredOutput<P>[K] | null };\n\n/** Payload type of one event, for producers: `EventPayload<typeof contract, 'purchase'>`. */\nexport type EventPayload<C, K extends string> =\n C extends Contract<infer E> ? (K extends keyof E ? core.input<E[K]> : never) : never;\n\nexport function defineContract<E extends Record<string, ObjectSchema>, P extends ObjectSchema>(\n definition: ContractDefinition<E, P>\n): Contract<E, P> {\n for (const [name, schema] of Object.entries(definition.events)) {\n if (name.startsWith('$')) {\n throw new TypeError(`contract event '${name}': names starting with $ are reserved`);\n }\n assertJsonSchema(schema, `event '${name}'`, true);\n }\n assertJsonSchema(definition.profile, 'profile', true);\n const profileShape = (definition.profile._zod.def as core.$ZodObjectDef).shape;\n for (const [field, schema] of Object.entries(profileShape)) {\n assertFlatScalar(schema, `profile.${field}`);\n }\n const strictProfile = definition.profile._zod.def.catchall?._zod.def.type === 'never';\n\n const names = Object.keys(definition.events) as (keyof E & string)[];\n return {\n kind: 'journey-contract',\n events: event() as never,\n user: user() as never,\n schemas: { events: definition.events, profile: definition.profile },\n eventNames: names,\n isEvent: (name): name is keyof E & string => Object.hasOwn(definition.events, name),\n parseEvent(name, payload) {\n if (!Object.hasOwn(definition.events, name)) {\n return { ok: false, issues: [{ path: '', message: `unknown event '${name}'` }] };\n }\n return toResult(z.safeParse(definition.events[name], payload));\n },\n parseProfilePatch(patch) {\n if (typeof patch !== 'object' || patch === null || Array.isArray(patch)) {\n return { ok: false, issues: [{ path: '', message: 'props must be an object' }] };\n }\n const issues: ContractIssue[] = [];\n const data: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(patch)) {\n if (!Object.hasOwn(profileShape, field)) {\n // userId is the request's identity, not a profile field\n if (strictProfile || field === 'userId') {\n issues.push({ path: field, message: 'not a declared profile field' });\n } else {\n data[field] = value;\n }\n continue;\n }\n if (value === null) {\n data[field] = null;\n continue;\n }\n const result = z.safeParse(profileShape[field], value);\n if (result.success) data[field] = result.data;\n else issues.push(...prefixed(field, result.error));\n }\n return issues.length > 0 ? { ok: false, issues } : { ok: true, data: data as never };\n },\n };\n}\n\n/**\n * An event the contract refuses — raised for events a journey emits itself\n * (`.sendEvent()`), which never pass the HTTP ingest: they go through the same\n * check, and a refusal is deterministic, so it is not retried.\n */\nexport class ContractValidationError extends Error {\n override readonly name = 'ContractValidationError';\n constructor(\n readonly event: string,\n readonly issues: ContractIssue[]\n ) {\n super(\n `event '${event}' refused by the contract: ${issues\n .map((i) => `${i.path || '(root)'} ${i.message}`)\n .join('; ')}`\n );\n }\n}\n\n/** The one check every event passes, from HTTP or from a journey: declared, and its payload parses. */\nexport function checkEvent(\n contract: Contract,\n name: string,\n payload: unknown\n): ContractResult<Record<string, unknown>> {\n if (!contract.isEvent(name)) {\n return {\n ok: false,\n issues: [{ path: '', message: `'${String(name)}' is not in the contract` }],\n };\n }\n return contract.parseEvent(name, payload);\n}\n\nexport function isContract(value: unknown): value is Contract {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'journey-contract'\n );\n}\n\nfunction toResult<T>(result: core.util.SafeParseResult<T>): ContractResult<T> {\n return result.success\n ? { ok: true, data: result.data }\n : { ok: false, issues: prefixed('', result.error) };\n}\n\nfunction prefixed(prefix: string, error: core.$ZodError): ContractIssue[] {\n return error.issues.map((issue) => ({\n path: [prefix, ...issue.path.map(String)].filter((p) => p !== '').join('.'),\n message: issue.message,\n }));\n}\n\n/* ---------------------------- supported schemas ---------------------------- */\n\n/**\n * The schema types a contract may use — JSON shapes that parse synchronously\n * and mean the same before and after parsing. Anything not listed (default,\n * transform, pipe, lazy, promise, custom, date, bigint, …) is refused, and\n * every container is walked so nothing unsupported hides inside one.\n */\nconst ALLOWED = new Set([\n 'object',\n 'array',\n 'tuple',\n 'union',\n 'intersection',\n 'record',\n 'optional',\n 'nullable',\n 'readonly',\n 'nonoptional',\n 'string',\n 'number',\n 'boolean',\n 'null',\n 'enum',\n 'literal',\n 'unknown',\n 'any',\n 'never',\n]);\n\n/** Checks that change the value (`overwrite`: `.trim()`, `.toLowerCase()`, …) or run arbitrary code (`custom`: `.refine()`, async or not). */\nconst REFUSED_CHECKS = new Set(['custom', 'overwrite']);\n\nfunction assertJsonSchema(schema: unknown, where: string, top = false): void {\n const def = (schema as core.$ZodType | undefined)?._zod?.def;\n if (def === undefined) throw new TypeError(`contract ${where}: not a Zod schema`);\n if (top && def.type !== 'object') {\n throw new TypeError(\n `contract ${where}: must be an object schema (z.looseObject / z.strictObject)`\n );\n }\n if (!ALLOWED.has(def.type)) {\n throw new TypeError(\n `contract ${where}: ${def.type} schemas are not supported (input and output must mean the same JSON, parsed synchronously)`\n );\n }\n if ((def as { coerce?: boolean }).coerce === true) {\n throw new TypeError(`contract ${where}: coercion (z.coerce) is not supported`);\n }\n for (const check of def.checks ?? []) {\n if (REFUSED_CHECKS.has(check._zod.def.check)) {\n throw new TypeError(\n `contract ${where}: ${check._zod.def.check === 'overwrite' ? 'value-changing checks (.overwrite, .trim, …)' : 'custom refinements'} are not supported`\n );\n }\n }\n const children: [string, unknown][] = [];\n switch (def.type) {\n case 'object': {\n const object = def as core.$ZodObjectDef;\n for (const [k, v] of Object.entries(object.shape)) children.push([`${where}.${k}`, v]);\n if (object.catchall !== undefined) children.push([`${where}.*`, object.catchall]);\n break;\n }\n case 'optional':\n case 'nullable':\n case 'readonly':\n case 'nonoptional':\n children.push([where, (def as unknown as { innerType: unknown }).innerType]);\n break;\n case 'array':\n children.push([`${where}[]`, (def as core.$ZodArrayDef).element]);\n break;\n case 'tuple': {\n const tuple = def as core.$ZodTupleDef;\n tuple.items.forEach((item, index) => children.push([`${where}[${index}]`, item]));\n if (tuple.rest !== null) children.push([`${where}[…]`, tuple.rest]);\n break;\n }\n case 'union':\n for (const option of (def as core.$ZodUnionDef).options) children.push([where, option]);\n break;\n case 'intersection': {\n const intersection = def as core.$ZodIntersectionDef;\n children.push([where, intersection.left], [where, intersection.right]);\n break;\n }\n case 'record': {\n const record = def as core.$ZodRecordDef;\n children.push([`${where}{key}`, record.keyType], [`${where}{}`, record.valueType]);\n break;\n }\n default:\n break;\n }\n for (const [path, child] of children) assertJsonSchema(child, path);\n}\n\nconst SCALARS = new Set(['string', 'number', 'boolean', 'enum', 'literal']);\n\nfunction assertFlatScalar(schema: unknown, where: string): void {\n let def = (schema as core.$ZodType)._zod.def;\n if (def.type === 'optional') def = (def as core.$ZodOptionalDef).innerType._zod.def;\n if (!SCALARS.has(def.type)) {\n throw new TypeError(\n `contract ${where}: profile fields must be flat scalars (string, number, boolean, enum, literal), got ${def.type}`\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { EventRefs, UserRefs } from "./dsl/refs.cjs";
2
+ import "./dsl/index.cjs";
3
+ import * as core from "zod/v4/core";
4
+ //#region src/contract.d.ts
5
+ /**
6
+ * `defineContract({ events, profile })` — the producer/engine contract as Zod
7
+ * schemas, written once in a package both sides import. From it:
8
+ *
9
+ * - `contract.events` / `contract.user` are the DSL's typed reference tables
10
+ * (what `event<E>()` / `user<U>()` used to be, now derived from the schemas);
11
+ * - `JourneyClient({ contract })` types `track` / `identify` by event name and
12
+ * checks payloads before sending;
13
+ * - `journeyWorker({ contract })` re-validates every inbound `/events` and
14
+ * `/identify` — never trusting the caller used the SDK — and refuses a bad
15
+ * one with a 4xx before anything is stored, woken or started.
16
+ *
17
+ * Supported schemas (v1), synchronous and JSON-shaped: event payloads are
18
+ * object schemas (`z.looseObject` keeps a producer's extra analytics fields,
19
+ * `z.strictObject` refuses them) and may nest objects and arrays; the profile
20
+ * is a flat object of string / number / boolean / enum / literal fields. Input
21
+ * and output must mean the same thing, so defaults, transforms, coercion,
22
+ * custom refinements and async checks are refused when the contract is
23
+ * defined. The Zod instances stay in the host; nothing here changes the IR.
24
+ */
25
+ type ObjectSchema = core.$ZodObject;
26
+ /** The declared fields of an object schema — without a loose object's `[key: string]: unknown`, so the DSL only offers fields that were written down. */
27
+ export type DeclaredOutput<S> = S extends core.$ZodObject<infer Shape> ? core.$InferObjectOutput<Shape, Record<never, never>> : never;
28
+ export interface ContractDefinition<E extends Record<string, ObjectSchema>, P extends ObjectSchema> {
29
+ events: E;
30
+ profile: P;
31
+ }
32
+ /** One rejected field, with the dotted path the producer can fix. */
33
+ export interface ContractIssue {
34
+ path: string;
35
+ message: string;
36
+ }
37
+ export type ContractResult<T> = {
38
+ ok: true;
39
+ data: T;
40
+ } | {
41
+ ok: false;
42
+ issues: ContractIssue[];
43
+ };
44
+ export interface Contract<E extends Record<string, ObjectSchema> = Record<string, ObjectSchema>, P extends ObjectSchema = ObjectSchema> {
45
+ readonly kind: 'journey-contract';
46
+ /** The DSL's event reference table: `e.purchase` — payload refs from the declared fields only. */
47
+ readonly events: EventRefs<{ [K in keyof E]: DeclaredOutput<E[K]>; }>;
48
+ /** The DSL's user-property reference table: `u.name`, plus the system `u.userId`. */
49
+ readonly user: UserRefs<DeclaredOutput<P> & {
50
+ userId: string;
51
+ }>;
52
+ /** The raw schemas, for hosts that need them (validation, docs). */
53
+ readonly schemas: {
54
+ readonly events: E;
55
+ readonly profile: P;
56
+ };
57
+ /** Every event name the contract declares — what a producer forwards. */
58
+ readonly eventNames: readonly (keyof E & string)[];
59
+ isEvent(name: string): name is keyof E & string;
60
+ /** Validate one event's payload; the parsed value is what may be stored. */
61
+ parseEvent<K extends keyof E & string>(name: K, payload: unknown): ContractResult<core.output<E[K]>>;
62
+ /**
63
+ * Validate an `/identify` merge patch: omitted fields stay as they are,
64
+ * `null` removes a field, every provided value is checked against its field
65
+ * schema, and an undeclared field is refused — a patch, never a full parse
66
+ * that would fill defaults over fields the caller did not send.
67
+ */
68
+ parseProfilePatch(patch: unknown): ContractResult<ProfilePatch<P>>;
69
+ }
70
+ /** An `/identify` patch over the profile: any subset of fields, `null` to remove one. */
71
+ export type ProfilePatch<P> = { [K in keyof DeclaredOutput<P>]?: DeclaredOutput<P>[K] | null; };
72
+ /** Payload type of one event, for producers: `EventPayload<typeof contract, 'purchase'>`. */
73
+ export type EventPayload<C, K extends string> = C extends Contract<infer E> ? (K extends keyof E ? core.input<E[K]> : never) : never;
74
+ export declare function defineContract<E extends Record<string, ObjectSchema>, P extends ObjectSchema>(definition: ContractDefinition<E, P>): Contract<E, P>;
75
+ /**
76
+ * An event the contract refuses — raised for events a journey emits itself
77
+ * (`.sendEvent()`), which never pass the HTTP ingest: they go through the same
78
+ * check, and a refusal is deterministic, so it is not retried.
79
+ */
80
+ export declare class ContractValidationError extends Error {
81
+ readonly event: string;
82
+ readonly issues: ContractIssue[];
83
+ readonly name = "ContractValidationError";
84
+ constructor(event: string, issues: ContractIssue[]);
85
+ }
86
+ /** The one check every event passes, from HTTP or from a journey: declared, and its payload parses. */
87
+ export declare function checkEvent(contract: Contract, name: string, payload: unknown): ContractResult<Record<string, unknown>>;
88
+ export declare function isContract(value: unknown): value is Contract;
89
+ //#endregion
90
+ //# sourceMappingURL=contract.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.cts","names":[],"sources":["../src/contract.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAyBK,eAAe,KAAK;;YAGb,eAAe,KACzB,UAAU,KAAK,iBAAiB,SAC5B,KAAK,mBAAmB,OAAO;iBAGpB,mBACf,UAAU,eAAe,eACzB,UAAU;EAEV,QAAQ;EACR,SAAS;;;iBAIM;EACf;EACA;;YAGU,eAAe;EAAO;EAAU,MAAM;;EAAQ;EAAW,QAAQ;;iBAE5D,SACf,UAAU,eAAe,gBAAgB,eAAe,eACxD,UAAU,eAAe;WAEhB;;WAEA,QAAQ,aAAa,WAAW,IAAI,eAAe,EAAE;;WAErD,MAAM,SAAS,eAAe;IAAO;;;WAErC;aAAoB,QAAQ;aAAY,SAAS;;;WAEjD,4BAA4B;EACrC,QAAQ,eAAe,cAAc;;EAErC,WAAW,gBAAgB,YACzB,MAAM,GACN,mBACC,eAAe,KAAK,OAAO,EAAE;;;;;;;EAOhC,kBAAkB,iBAAiB,eAAe,aAAa;;;YAIrD,aAAa,QAAQ,WAAW,eAAe,MAAM,eAAe,GAAG;;YAGvE,aAAa,GAAG,oBAC1B,UAAU,eAAe,MAAM,gBAAgB,IAAI,KAAK,MAAM,EAAE;wBAElD,eAAe,UAAU,eAAe,eAAe,UAAU,cAC/E,YAAY,mBAAmB,GAAG,KACjC,SAAS,GAAG;;;;;;qBA8DF,gCAAgC;WAGhC;WACA,QAAQ;WAHD;EAClB,YACW,eACA,QAAQ;;;wBAWL,WACd,UAAU,UACV,cACA,mBACC,eAAe;wBAUF,WAAW,iBAAiB,SAAS"}
@@ -0,0 +1,90 @@
1
+ import { EventRefs, UserRefs } from "./dsl/refs.mjs";
2
+ import "./dsl/index.mjs";
3
+ import * as core from "zod/v4/core";
4
+ //#region src/contract.d.ts
5
+ /**
6
+ * `defineContract({ events, profile })` — the producer/engine contract as Zod
7
+ * schemas, written once in a package both sides import. From it:
8
+ *
9
+ * - `contract.events` / `contract.user` are the DSL's typed reference tables
10
+ * (what `event<E>()` / `user<U>()` used to be, now derived from the schemas);
11
+ * - `JourneyClient({ contract })` types `track` / `identify` by event name and
12
+ * checks payloads before sending;
13
+ * - `journeyWorker({ contract })` re-validates every inbound `/events` and
14
+ * `/identify` — never trusting the caller used the SDK — and refuses a bad
15
+ * one with a 4xx before anything is stored, woken or started.
16
+ *
17
+ * Supported schemas (v1), synchronous and JSON-shaped: event payloads are
18
+ * object schemas (`z.looseObject` keeps a producer's extra analytics fields,
19
+ * `z.strictObject` refuses them) and may nest objects and arrays; the profile
20
+ * is a flat object of string / number / boolean / enum / literal fields. Input
21
+ * and output must mean the same thing, so defaults, transforms, coercion,
22
+ * custom refinements and async checks are refused when the contract is
23
+ * defined. The Zod instances stay in the host; nothing here changes the IR.
24
+ */
25
+ type ObjectSchema = core.$ZodObject;
26
+ /** The declared fields of an object schema — without a loose object's `[key: string]: unknown`, so the DSL only offers fields that were written down. */
27
+ export type DeclaredOutput<S> = S extends core.$ZodObject<infer Shape> ? core.$InferObjectOutput<Shape, Record<never, never>> : never;
28
+ export interface ContractDefinition<E extends Record<string, ObjectSchema>, P extends ObjectSchema> {
29
+ events: E;
30
+ profile: P;
31
+ }
32
+ /** One rejected field, with the dotted path the producer can fix. */
33
+ export interface ContractIssue {
34
+ path: string;
35
+ message: string;
36
+ }
37
+ export type ContractResult<T> = {
38
+ ok: true;
39
+ data: T;
40
+ } | {
41
+ ok: false;
42
+ issues: ContractIssue[];
43
+ };
44
+ export interface Contract<E extends Record<string, ObjectSchema> = Record<string, ObjectSchema>, P extends ObjectSchema = ObjectSchema> {
45
+ readonly kind: 'journey-contract';
46
+ /** The DSL's event reference table: `e.purchase` — payload refs from the declared fields only. */
47
+ readonly events: EventRefs<{ [K in keyof E]: DeclaredOutput<E[K]>; }>;
48
+ /** The DSL's user-property reference table: `u.name`, plus the system `u.userId`. */
49
+ readonly user: UserRefs<DeclaredOutput<P> & {
50
+ userId: string;
51
+ }>;
52
+ /** The raw schemas, for hosts that need them (validation, docs). */
53
+ readonly schemas: {
54
+ readonly events: E;
55
+ readonly profile: P;
56
+ };
57
+ /** Every event name the contract declares — what a producer forwards. */
58
+ readonly eventNames: readonly (keyof E & string)[];
59
+ isEvent(name: string): name is keyof E & string;
60
+ /** Validate one event's payload; the parsed value is what may be stored. */
61
+ parseEvent<K extends keyof E & string>(name: K, payload: unknown): ContractResult<core.output<E[K]>>;
62
+ /**
63
+ * Validate an `/identify` merge patch: omitted fields stay as they are,
64
+ * `null` removes a field, every provided value is checked against its field
65
+ * schema, and an undeclared field is refused — a patch, never a full parse
66
+ * that would fill defaults over fields the caller did not send.
67
+ */
68
+ parseProfilePatch(patch: unknown): ContractResult<ProfilePatch<P>>;
69
+ }
70
+ /** An `/identify` patch over the profile: any subset of fields, `null` to remove one. */
71
+ export type ProfilePatch<P> = { [K in keyof DeclaredOutput<P>]?: DeclaredOutput<P>[K] | null; };
72
+ /** Payload type of one event, for producers: `EventPayload<typeof contract, 'purchase'>`. */
73
+ export type EventPayload<C, K extends string> = C extends Contract<infer E> ? (K extends keyof E ? core.input<E[K]> : never) : never;
74
+ export declare function defineContract<E extends Record<string, ObjectSchema>, P extends ObjectSchema>(definition: ContractDefinition<E, P>): Contract<E, P>;
75
+ /**
76
+ * An event the contract refuses — raised for events a journey emits itself
77
+ * (`.sendEvent()`), which never pass the HTTP ingest: they go through the same
78
+ * check, and a refusal is deterministic, so it is not retried.
79
+ */
80
+ export declare class ContractValidationError extends Error {
81
+ readonly event: string;
82
+ readonly issues: ContractIssue[];
83
+ readonly name = "ContractValidationError";
84
+ constructor(event: string, issues: ContractIssue[]);
85
+ }
86
+ /** The one check every event passes, from HTTP or from a journey: declared, and its payload parses. */
87
+ export declare function checkEvent(contract: Contract, name: string, payload: unknown): ContractResult<Record<string, unknown>>;
88
+ export declare function isContract(value: unknown): value is Contract;
89
+ //#endregion
90
+ //# sourceMappingURL=contract.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.mts","names":[],"sources":["../src/contract.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAyBK,eAAe,KAAK;;YAGb,eAAe,KACzB,UAAU,KAAK,iBAAiB,SAC5B,KAAK,mBAAmB,OAAO;iBAGpB,mBACf,UAAU,eAAe,eACzB,UAAU;EAEV,QAAQ;EACR,SAAS;;;iBAIM;EACf;EACA;;YAGU,eAAe;EAAO;EAAU,MAAM;;EAAQ;EAAW,QAAQ;;iBAE5D,SACf,UAAU,eAAe,gBAAgB,eAAe,eACxD,UAAU,eAAe;WAEhB;;WAEA,QAAQ,aAAa,WAAW,IAAI,eAAe,EAAE;;WAErD,MAAM,SAAS,eAAe;IAAO;;;WAErC;aAAoB,QAAQ;aAAY,SAAS;;;WAEjD,4BAA4B;EACrC,QAAQ,eAAe,cAAc;;EAErC,WAAW,gBAAgB,YACzB,MAAM,GACN,mBACC,eAAe,KAAK,OAAO,EAAE;;;;;;;EAOhC,kBAAkB,iBAAiB,eAAe,aAAa;;;YAIrD,aAAa,QAAQ,WAAW,eAAe,MAAM,eAAe,GAAG;;YAGvE,aAAa,GAAG,oBAC1B,UAAU,eAAe,MAAM,gBAAgB,IAAI,KAAK,MAAM,EAAE;wBAElD,eAAe,UAAU,eAAe,eAAe,UAAU,cAC/E,YAAY,mBAAmB,GAAG,KACjC,SAAS,GAAG;;;;;;qBA8DF,gCAAgC;WAGhC;WACA,QAAQ;WAHD;EAClB,YACW,eACA,QAAQ;;;wBAWL,WACd,UAAU,UACV,cACA,mBACC,eAAe;wBAUF,WAAW,iBAAiB,SAAS"}
@@ -0,0 +1,206 @@
1
+ import { event, user } from "./dsl/refs.mjs";
2
+ import "./dsl/index.mjs";
3
+ import * as z from "zod/mini";
4
+ //#region src/contract.ts
5
+ function defineContract(definition) {
6
+ for (const [name, schema] of Object.entries(definition.events)) {
7
+ if (name.startsWith("$")) throw new TypeError(`contract event '${name}': names starting with $ are reserved`);
8
+ assertJsonSchema(schema, `event '${name}'`, true);
9
+ }
10
+ assertJsonSchema(definition.profile, "profile", true);
11
+ const profileShape = definition.profile._zod.def.shape;
12
+ for (const [field, schema] of Object.entries(profileShape)) assertFlatScalar(schema, `profile.${field}`);
13
+ const strictProfile = definition.profile._zod.def.catchall?._zod.def.type === "never";
14
+ const names = Object.keys(definition.events);
15
+ return {
16
+ kind: "journey-contract",
17
+ events: event(),
18
+ user: user(),
19
+ schemas: {
20
+ events: definition.events,
21
+ profile: definition.profile
22
+ },
23
+ eventNames: names,
24
+ isEvent: (name) => Object.hasOwn(definition.events, name),
25
+ parseEvent(name, payload) {
26
+ if (!Object.hasOwn(definition.events, name)) return {
27
+ ok: false,
28
+ issues: [{
29
+ path: "",
30
+ message: `unknown event '${name}'`
31
+ }]
32
+ };
33
+ return toResult(z.safeParse(definition.events[name], payload));
34
+ },
35
+ parseProfilePatch(patch) {
36
+ if (typeof patch !== "object" || patch === null || Array.isArray(patch)) return {
37
+ ok: false,
38
+ issues: [{
39
+ path: "",
40
+ message: "props must be an object"
41
+ }]
42
+ };
43
+ const issues = [];
44
+ const data = {};
45
+ for (const [field, value] of Object.entries(patch)) {
46
+ if (!Object.hasOwn(profileShape, field)) {
47
+ if (strictProfile || field === "userId") issues.push({
48
+ path: field,
49
+ message: "not a declared profile field"
50
+ });
51
+ else data[field] = value;
52
+ continue;
53
+ }
54
+ if (value === null) {
55
+ data[field] = null;
56
+ continue;
57
+ }
58
+ const result = z.safeParse(profileShape[field], value);
59
+ if (result.success) data[field] = result.data;
60
+ else issues.push(...prefixed(field, result.error));
61
+ }
62
+ return issues.length > 0 ? {
63
+ ok: false,
64
+ issues
65
+ } : {
66
+ ok: true,
67
+ data
68
+ };
69
+ }
70
+ };
71
+ }
72
+ /**
73
+ * An event the contract refuses — raised for events a journey emits itself
74
+ * (`.sendEvent()`), which never pass the HTTP ingest: they go through the same
75
+ * check, and a refusal is deterministic, so it is not retried.
76
+ */
77
+ var ContractValidationError = class extends Error {
78
+ event;
79
+ issues;
80
+ name = "ContractValidationError";
81
+ constructor(event, issues) {
82
+ super(`event '${event}' refused by the contract: ${issues.map((i) => `${i.path || "(root)"} ${i.message}`).join("; ")}`);
83
+ this.event = event;
84
+ this.issues = issues;
85
+ }
86
+ };
87
+ /** The one check every event passes, from HTTP or from a journey: declared, and its payload parses. */
88
+ function checkEvent(contract, name, payload) {
89
+ if (!contract.isEvent(name)) return {
90
+ ok: false,
91
+ issues: [{
92
+ path: "",
93
+ message: `'${String(name)}' is not in the contract`
94
+ }]
95
+ };
96
+ return contract.parseEvent(name, payload);
97
+ }
98
+ function isContract(value) {
99
+ return typeof value === "object" && value !== null && value.kind === "journey-contract";
100
+ }
101
+ function toResult(result) {
102
+ return result.success ? {
103
+ ok: true,
104
+ data: result.data
105
+ } : {
106
+ ok: false,
107
+ issues: prefixed("", result.error)
108
+ };
109
+ }
110
+ function prefixed(prefix, error) {
111
+ return error.issues.map((issue) => ({
112
+ path: [prefix, ...issue.path.map(String)].filter((p) => p !== "").join("."),
113
+ message: issue.message
114
+ }));
115
+ }
116
+ /**
117
+ * The schema types a contract may use — JSON shapes that parse synchronously
118
+ * and mean the same before and after parsing. Anything not listed (default,
119
+ * transform, pipe, lazy, promise, custom, date, bigint, …) is refused, and
120
+ * every container is walked so nothing unsupported hides inside one.
121
+ */
122
+ const ALLOWED = /* @__PURE__ */ new Set([
123
+ "object",
124
+ "array",
125
+ "tuple",
126
+ "union",
127
+ "intersection",
128
+ "record",
129
+ "optional",
130
+ "nullable",
131
+ "readonly",
132
+ "nonoptional",
133
+ "string",
134
+ "number",
135
+ "boolean",
136
+ "null",
137
+ "enum",
138
+ "literal",
139
+ "unknown",
140
+ "any",
141
+ "never"
142
+ ]);
143
+ /** Checks that change the value (`overwrite`: `.trim()`, `.toLowerCase()`, …) or run arbitrary code (`custom`: `.refine()`, async or not). */
144
+ const REFUSED_CHECKS = /* @__PURE__ */ new Set(["custom", "overwrite"]);
145
+ function assertJsonSchema(schema, where, top = false) {
146
+ const def = schema?._zod?.def;
147
+ if (def === void 0) throw new TypeError(`contract ${where}: not a Zod schema`);
148
+ if (top && def.type !== "object") throw new TypeError(`contract ${where}: must be an object schema (z.looseObject / z.strictObject)`);
149
+ if (!ALLOWED.has(def.type)) throw new TypeError(`contract ${where}: ${def.type} schemas are not supported (input and output must mean the same JSON, parsed synchronously)`);
150
+ if (def.coerce === true) throw new TypeError(`contract ${where}: coercion (z.coerce) is not supported`);
151
+ for (const check of def.checks ?? []) if (REFUSED_CHECKS.has(check._zod.def.check)) throw new TypeError(`contract ${where}: ${check._zod.def.check === "overwrite" ? "value-changing checks (.overwrite, .trim, …)" : "custom refinements"} are not supported`);
152
+ const children = [];
153
+ switch (def.type) {
154
+ case "object": {
155
+ const object = def;
156
+ for (const [k, v] of Object.entries(object.shape)) children.push([`${where}.${k}`, v]);
157
+ if (object.catchall !== void 0) children.push([`${where}.*`, object.catchall]);
158
+ break;
159
+ }
160
+ case "optional":
161
+ case "nullable":
162
+ case "readonly":
163
+ case "nonoptional":
164
+ children.push([where, def.innerType]);
165
+ break;
166
+ case "array":
167
+ children.push([`${where}[]`, def.element]);
168
+ break;
169
+ case "tuple": {
170
+ const tuple = def;
171
+ tuple.items.forEach((item, index) => children.push([`${where}[${index}]`, item]));
172
+ if (tuple.rest !== null) children.push([`${where}[…]`, tuple.rest]);
173
+ break;
174
+ }
175
+ case "union":
176
+ for (const option of def.options) children.push([where, option]);
177
+ break;
178
+ case "intersection": {
179
+ const intersection = def;
180
+ children.push([where, intersection.left], [where, intersection.right]);
181
+ break;
182
+ }
183
+ case "record": {
184
+ const record = def;
185
+ children.push([`${where}{key}`, record.keyType], [`${where}{}`, record.valueType]);
186
+ break;
187
+ }
188
+ }
189
+ for (const [path, child] of children) assertJsonSchema(child, path);
190
+ }
191
+ const SCALARS = /* @__PURE__ */ new Set([
192
+ "string",
193
+ "number",
194
+ "boolean",
195
+ "enum",
196
+ "literal"
197
+ ]);
198
+ function assertFlatScalar(schema, where) {
199
+ let def = schema._zod.def;
200
+ if (def.type === "optional") def = def.innerType._zod.def;
201
+ if (!SCALARS.has(def.type)) throw new TypeError(`contract ${where}: profile fields must be flat scalars (string, number, boolean, enum, literal), got ${def.type}`);
202
+ }
203
+ //#endregion
204
+ export { ContractValidationError, checkEvent, defineContract, isContract };
205
+
206
+ //# sourceMappingURL=contract.mjs.map