@elevasis/core 0.7.0 → 0.8.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 (473) hide show
  1. package/package.json +3 -3
  2. package/src/README.md +41 -41
  3. package/src/__tests__/publish.test.ts +18 -18
  4. package/src/__tests__/{template-foundations-compatibility.test.ts → template-core-compatibility.test.ts} +99 -99
  5. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1135 -1131
  6. package/src/_gen/__tests__/scaffold-contracts.test.ts +53 -53
  7. package/src/_gen/scaffold-contracts.ts +45 -45
  8. package/src/auth/multi-tenancy/credentials/README.md +38 -38
  9. package/src/auth/multi-tenancy/credentials/index.ts +6 -6
  10. package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -39
  11. package/src/auth/multi-tenancy/credentials/server/service.ts +60 -60
  12. package/src/auth/multi-tenancy/index.ts +17 -17
  13. package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -107
  14. package/src/auth/multi-tenancy/invitations/index.ts +37 -37
  15. package/src/auth/multi-tenancy/invitations/invitation.ts +86 -86
  16. package/src/auth/multi-tenancy/invitations/server/index.ts +25 -25
  17. package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -24
  18. package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -24
  19. package/src/auth/multi-tenancy/invitations/supabase.ts +50 -50
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -126
  21. package/src/auth/multi-tenancy/memberships/index.ts +21 -21
  22. package/src/auth/multi-tenancy/memberships/membership.ts +138 -138
  23. package/src/auth/multi-tenancy/memberships/server/index.ts +15 -15
  24. package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -32
  25. package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -21
  26. package/src/auth/multi-tenancy/memberships/supabase.ts +46 -46
  27. package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -128
  28. package/src/auth/multi-tenancy/organizations/index.ts +23 -23
  29. package/src/auth/multi-tenancy/organizations/organization.ts +24 -24
  30. package/src/auth/multi-tenancy/organizations/server/index.ts +10 -10
  31. package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -35
  32. package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -20
  33. package/src/auth/multi-tenancy/types.ts +83 -83
  34. package/src/auth/multi-tenancy/users/api-schemas.ts +194 -194
  35. package/src/auth/multi-tenancy/users/index.ts +27 -27
  36. package/src/auth/multi-tenancy/users/server/index.ts +19 -19
  37. package/src/auth/multi-tenancy/users/server/transforms.ts +21 -21
  38. package/src/auth/multi-tenancy/users/server/workos.ts +16 -16
  39. package/src/auth/multi-tenancy/users/user.ts +65 -65
  40. package/src/business/README.md +52 -52
  41. package/src/business/__tests__/entities-published.test.ts +33 -33
  42. package/src/business/acquisition/api-schemas.ts +759 -759
  43. package/src/business/acquisition/index.ts +109 -109
  44. package/src/business/acquisition/types.ts +402 -402
  45. package/src/business/base-entities.test.ts +481 -481
  46. package/src/business/base-entities.ts +241 -241
  47. package/src/business/entities-published.ts +24 -24
  48. package/src/business/index.ts +15 -15
  49. package/src/business/pdf/browser/pdfmake-browser.ts +229 -229
  50. package/src/business/pdf/index.ts +10 -10
  51. package/src/business/pdf/server/index.ts +21 -21
  52. package/src/business/pdf/server/themes/default.ts +8 -8
  53. package/src/business/pdf/server/themes/index.ts +9 -9
  54. package/src/business/pdf/server/themes/types.ts +8 -8
  55. package/src/business/pdf/types.ts +272 -272
  56. package/src/business/projects/index.ts +2 -1
  57. package/src/business/projects/sse-events.ts +21 -0
  58. package/src/business/projects/types.ts +89 -89
  59. package/src/business/sales/api-schemas.ts +75 -75
  60. package/src/business/seo/__tests__/linking.test.ts +549 -549
  61. package/src/business/seo/__tests__/types.test.ts +404 -404
  62. package/src/business/seo/index.ts +2 -2
  63. package/src/business/seo/linking.ts +281 -281
  64. package/src/business/seo/types.ts +199 -199
  65. package/src/commands/queue/index.ts +3 -3
  66. package/src/commands/queue/schemas.test.ts +593 -593
  67. package/src/commands/queue/schemas.ts +125 -125
  68. package/src/commands/queue/sse-events.ts +61 -61
  69. package/src/commands/queue/types/action.ts +52 -52
  70. package/src/commands/queue/types/checkpoint.ts +44 -44
  71. package/src/commands/queue/types/index.ts +7 -7
  72. package/src/commands/queue/types/task.ts +116 -116
  73. package/src/commands/queue/types.ts +14 -14
  74. package/src/content/distribution-metadata.ts +61 -61
  75. package/src/content/index.ts +10 -10
  76. package/src/deployments/index.ts +22 -22
  77. package/src/execution/core/__tests__/archived-logs.test.ts +72 -72
  78. package/src/execution/core/index.ts +11 -11
  79. package/src/execution/core/runner-types.ts +80 -80
  80. package/src/execution/core/server/environment.ts +31 -31
  81. package/src/execution/core/sse-executions.ts +119 -119
  82. package/src/execution/core/types.ts +29 -29
  83. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  84. package/src/execution/engine/__tests__/timeout.test.ts +565 -565
  85. package/src/execution/engine/agent/__tests__/errors.test.ts +508 -508
  86. package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -531
  87. package/src/execution/engine/agent/actions/executor.ts +205 -205
  88. package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -230
  89. package/src/execution/engine/agent/actions/processor.ts +116 -116
  90. package/src/execution/engine/agent/actions/types.ts +70 -70
  91. package/src/execution/engine/agent/core/agent.ts +810 -810
  92. package/src/execution/engine/agent/core/types.ts +155 -155
  93. package/src/execution/engine/agent/errors.ts +251 -251
  94. package/src/execution/engine/agent/index.ts +78 -78
  95. package/src/execution/engine/agent/knowledge-map/types.ts +106 -106
  96. package/src/execution/engine/agent/knowledge-map/utils.ts +101 -101
  97. package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -754
  98. package/src/execution/engine/agent/memory/domains.ts +99 -99
  99. package/src/execution/engine/agent/memory/manager.ts +365 -365
  100. package/src/execution/engine/agent/memory/processor.ts +66 -66
  101. package/src/execution/engine/agent/memory/types.ts +90 -90
  102. package/src/execution/engine/agent/memory/utils.ts +134 -134
  103. package/src/execution/engine/agent/observability/logging.ts +467 -467
  104. package/src/execution/engine/agent/observability/types.ts +64 -64
  105. package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -349
  106. package/src/execution/engine/agent/reasoning/processor.ts +92 -92
  107. package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -134
  108. package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -49
  109. package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -93
  110. package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -65
  111. package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -44
  112. package/src/execution/engine/agent/reasoning/request-builder.ts +169 -169
  113. package/src/execution/engine/agent/reasoning/types.ts +18 -18
  114. package/src/execution/engine/base/errors.ts +118 -118
  115. package/src/execution/engine/base/index.ts +2 -2
  116. package/src/execution/engine/base/logging.ts +31 -31
  117. package/src/execution/engine/base/serialization.ts +324 -324
  118. package/src/execution/engine/base/types.ts +126 -126
  119. package/src/execution/engine/base/utils.ts +41 -41
  120. package/src/execution/engine/index.ts +434 -434
  121. package/src/execution/engine/interface/index.ts +1 -1
  122. package/src/execution/engine/interface/types.ts +62 -62
  123. package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -50
  124. package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -321
  125. package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -115
  126. package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -375
  127. package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -463
  128. package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -177
  129. package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -722
  130. package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -376
  131. package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -551
  132. package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -563
  133. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -105
  134. package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -537
  135. package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -147
  136. package/src/execution/engine/llm/adapters/index.ts +17 -17
  137. package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -116
  138. package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -130
  139. package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -137
  140. package/src/execution/engine/llm/adapters/server/google.ts +283 -283
  141. package/src/execution/engine/llm/adapters/server/index.ts +12 -12
  142. package/src/execution/engine/llm/adapters/server/openai.ts +206 -206
  143. package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -235
  144. package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -230
  145. package/src/execution/engine/llm/errors.ts +186 -186
  146. package/src/execution/engine/llm/model-info.ts +332 -332
  147. package/src/execution/engine/llm/response-schema-validator.ts +113 -113
  148. package/src/execution/engine/llm/types.ts +86 -86
  149. package/src/execution/engine/test-utils/index.ts +6 -6
  150. package/src/execution/engine/test-utils/mocks.ts +56 -56
  151. package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -50
  152. package/src/execution/engine/tools/integration/index.ts +53 -53
  153. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -73
  154. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -209
  155. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -82
  156. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -122
  157. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -89
  158. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -84
  159. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -16
  160. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -293
  161. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -100
  162. package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -217
  163. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -92
  164. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -218
  165. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -87
  166. package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -11
  167. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +361 -361
  168. package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -162
  169. package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -594
  170. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -214
  171. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -152
  172. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -141
  173. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -86
  174. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -105
  175. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -118
  176. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -165
  177. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -96
  178. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -104
  179. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -156
  180. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -220
  181. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -140
  182. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +146 -146
  183. package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -31
  184. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -210
  185. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -104
  186. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  187. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -1189
  188. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -641
  189. package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -18
  190. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -86
  191. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -289
  192. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -154
  193. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -325
  194. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -153
  195. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -84
  196. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -125
  197. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -107
  198. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -85
  199. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -91
  200. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -92
  201. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -195
  202. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -113
  203. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -104
  204. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -155
  205. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -196
  206. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -102
  207. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -189
  208. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -87
  209. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -112
  210. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -76
  211. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -86
  212. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -98
  213. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -126
  214. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -193
  215. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -99
  216. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -621
  217. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -125
  218. package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -29
  219. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -178
  220. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -1473
  221. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -59
  222. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -102
  223. package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -17
  224. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -80
  225. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -102
  226. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -102
  227. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -134
  228. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -75
  229. package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -27
  230. package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -108
  231. package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -132
  232. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -274
  233. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -230
  234. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -133
  235. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -90
  236. package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -210
  237. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -517
  238. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -309
  239. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -133
  240. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -122
  241. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -111
  242. package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -11
  243. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -78
  244. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -222
  245. package/src/execution/engine/tools/integration/server/index.ts +61 -61
  246. package/src/execution/engine/tools/integration/service.ts +161 -161
  247. package/src/execution/engine/tools/integration/tool.ts +253 -253
  248. package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -74
  249. package/src/execution/engine/tools/integration/types/apify.ts +92 -92
  250. package/src/execution/engine/tools/integration/types/index.ts +19 -19
  251. package/src/execution/engine/tools/integration/types/instantly.ts +557 -557
  252. package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -56
  253. package/src/execution/engine/tools/integration/types/stripe.ts +162 -162
  254. package/src/execution/engine/tools/integration/types/tomba.ts +94 -94
  255. package/src/execution/engine/tools/lead-service-types.ts +884 -884
  256. package/src/execution/engine/tools/llm/index.ts +11 -11
  257. package/src/execution/engine/tools/llm/server/index.ts +8 -8
  258. package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -118
  259. package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -441
  260. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -248
  261. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -319
  262. package/src/execution/engine/tools/platform/acquisition/index.ts +43 -43
  263. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -148
  264. package/src/execution/engine/tools/platform/acquisition/types.ts +260 -260
  265. package/src/execution/engine/tools/platform/email/index.ts +122 -122
  266. package/src/execution/engine/tools/platform/email/types.ts +96 -96
  267. package/src/execution/engine/tools/platform/index.ts +157 -157
  268. package/src/execution/engine/tools/platform/notification.ts +81 -81
  269. package/src/execution/engine/tools/platform/pdf/index.ts +110 -110
  270. package/src/execution/engine/tools/platform/pdf/types.ts +77 -77
  271. package/src/execution/engine/tools/platform/scheduler.ts +87 -87
  272. package/src/execution/engine/tools/platform/storage/index.ts +370 -370
  273. package/src/execution/engine/tools/platform/types.ts +148 -148
  274. package/src/execution/engine/tools/registry.ts +700 -699
  275. package/src/execution/engine/tools/tool-maps.ts +786 -786
  276. package/src/execution/engine/tools/types.ts +233 -233
  277. package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -139
  278. package/src/execution/engine/workflow/errors.ts +63 -63
  279. package/src/execution/engine/workflow/helpers/index.ts +11 -11
  280. package/src/execution/engine/workflow/helpers/server/index.ts +8 -8
  281. package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -93
  282. package/src/execution/engine/workflow/index.ts +19 -19
  283. package/src/execution/engine/workflow/log-truncate.ts +26 -26
  284. package/src/execution/engine/workflow/logging.ts +191 -191
  285. package/src/execution/engine/workflow/types.ts +182 -182
  286. package/src/execution/engine/workflow/utils.ts +280 -280
  287. package/src/execution/engine/workflow/workflow.ts +168 -168
  288. package/src/execution/index.ts +3 -3
  289. package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -733
  290. package/src/execution/scheduler/__tests__/utils.test.ts +1009 -1009
  291. package/src/execution/scheduler/api-schemas.ts +296 -296
  292. package/src/execution/scheduler/index.ts +50 -50
  293. package/src/execution/scheduler/schemas.ts +264 -264
  294. package/src/execution/scheduler/types.ts +111 -111
  295. package/src/execution/scheduler/utils.ts +364 -364
  296. package/src/forms/index.ts +7 -7
  297. package/src/forms/schemas.ts +69 -69
  298. package/src/forms/types.ts +70 -70
  299. package/src/index.ts +71 -60
  300. package/src/integrations/credentials/__tests__/schemas.test.ts +82 -82
  301. package/src/integrations/credentials/__tests__/utils.test.ts +144 -144
  302. package/src/integrations/credentials/api-schemas.ts +143 -143
  303. package/src/integrations/credentials/index.ts +32 -32
  304. package/src/integrations/credentials/schemas.ts +164 -164
  305. package/src/integrations/credentials/utils.ts +59 -59
  306. package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -59
  307. package/src/integrations/oauth/api-schemas.ts +92 -92
  308. package/src/integrations/oauth/index.ts +19 -19
  309. package/src/integrations/oauth/provider-registry.ts +61 -61
  310. package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -183
  311. package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -577
  312. package/src/integrations/oauth/server/credentials.ts +39 -39
  313. package/src/integrations/oauth/server/refresh.ts +214 -214
  314. package/src/integrations/oauth/types.ts +34 -34
  315. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -318
  316. package/src/integrations/webhook-endpoints/api-schemas.ts +102 -102
  317. package/src/integrations/webhook-endpoints/index.ts +28 -28
  318. package/src/integrations/webhook-endpoints/types.ts +51 -51
  319. package/src/operations/activities/api-schemas.ts +79 -79
  320. package/src/operations/activities/index.ts +9 -9
  321. package/src/operations/activities/sse-events.ts +30 -30
  322. package/src/operations/activities/types.ts +63 -63
  323. package/src/operations/debug-logs/client.ts +60 -60
  324. package/src/operations/debug-logs/debug-logger.ts +83 -83
  325. package/src/operations/debug-logs/index.ts +8 -8
  326. package/src/operations/debug-logs/server.ts +19 -19
  327. package/src/operations/debug-logs/types.ts +33 -33
  328. package/src/operations/index.ts +50 -50
  329. package/src/operations/notifications/api-schemas.ts +91 -91
  330. package/src/operations/notifications/index.ts +3 -3
  331. package/src/operations/notifications/sse-events.ts +21 -21
  332. package/src/operations/notifications/types.ts +47 -47
  333. package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -297
  334. package/src/operations/observability/__tests__/utils.test.ts +54 -54
  335. package/src/operations/observability/ai-usage-collector.ts +64 -64
  336. package/src/operations/observability/index.ts +13 -13
  337. package/src/operations/observability/metrics-collector.ts +49 -49
  338. package/src/operations/observability/schemas.ts +39 -39
  339. package/src/operations/observability/types.ts +463 -463
  340. package/src/operations/observability/utils.ts +77 -77
  341. package/src/operations/sessions/__tests__/manager.test.ts +821 -821
  342. package/src/operations/sessions/index.ts +26 -26
  343. package/src/operations/sessions/server/manager.ts +90 -90
  344. package/src/operations/sessions/server/session.ts +180 -180
  345. package/src/operations/sessions/types.ts +98 -98
  346. package/src/operations/triggers/index.ts +12 -12
  347. package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -44
  348. package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -51
  349. package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -45
  350. package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -49
  351. package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -45
  352. package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -54
  353. package/src/operations/triggers/webhook/index.ts +35 -35
  354. package/src/operations/triggers/webhook/types.ts +74 -74
  355. package/src/organization-model/README.md +97 -97
  356. package/src/organization-model/__tests__/defaults.test.ts +175 -175
  357. package/src/organization-model/__tests__/domains/customers.test.ts +295 -295
  358. package/src/organization-model/__tests__/domains/goals.test.ts +479 -479
  359. package/src/organization-model/__tests__/domains/identity.test.ts +279 -279
  360. package/src/organization-model/__tests__/domains/navigation.test.ts +212 -212
  361. package/src/organization-model/__tests__/domains/offerings.test.ts +419 -419
  362. package/src/organization-model/__tests__/domains/operations.test.ts +203 -203
  363. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -362
  364. package/src/organization-model/__tests__/domains/roles.test.ts +347 -347
  365. package/src/organization-model/__tests__/domains/statuses.test.ts +243 -243
  366. package/src/organization-model/__tests__/foundation.test.ts +105 -105
  367. package/src/organization-model/__tests__/graph.test.ts +894 -894
  368. package/src/organization-model/__tests__/resolve.test.ts +690 -690
  369. package/src/organization-model/__tests__/schema.test.ts +407 -407
  370. package/src/organization-model/contracts.ts +14 -14
  371. package/src/organization-model/defaults.ts +148 -148
  372. package/src/organization-model/domains/branding.ts +22 -22
  373. package/src/organization-model/domains/customers.ts +75 -75
  374. package/src/organization-model/domains/features.ts +22 -22
  375. package/src/organization-model/domains/goals.ts +80 -80
  376. package/src/organization-model/domains/identity.ts +94 -94
  377. package/src/organization-model/domains/navigation.ts +391 -391
  378. package/src/organization-model/domains/offerings.ts +66 -66
  379. package/src/organization-model/domains/operations.ts +85 -85
  380. package/src/organization-model/domains/projects.ts +48 -48
  381. package/src/organization-model/domains/prospecting.ts +33 -33
  382. package/src/organization-model/domains/roles.ts +55 -55
  383. package/src/organization-model/domains/sales.ts +94 -94
  384. package/src/organization-model/domains/shared.ts +62 -62
  385. package/src/organization-model/domains/statuses.ts +130 -130
  386. package/src/organization-model/foundation.ts +97 -97
  387. package/src/organization-model/graph/build.ts +399 -399
  388. package/src/organization-model/graph/index.ts +4 -4
  389. package/src/organization-model/graph/schema.ts +48 -48
  390. package/src/organization-model/graph/types.ts +40 -40
  391. package/src/organization-model/index.ts +13 -13
  392. package/src/organization-model/organization-graph.mdx +272 -272
  393. package/src/organization-model/organization-model.mdx +320 -320
  394. package/src/organization-model/published.ts +85 -85
  395. package/src/organization-model/resolve.ts +66 -66
  396. package/src/organization-model/schema.ts +287 -287
  397. package/src/organization-model/types.ts +46 -46
  398. package/src/platform/api/index.ts +1 -1
  399. package/src/platform/api/types.ts +35 -35
  400. package/src/platform/constants/http.ts +37 -37
  401. package/src/platform/constants/index.ts +5 -5
  402. package/src/platform/constants/limits.ts +32 -32
  403. package/src/platform/constants/resilience.ts +51 -51
  404. package/src/platform/constants/timeouts.ts +20 -20
  405. package/src/platform/constants/versions.ts +3 -3
  406. package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -347
  407. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1028 -1028
  408. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -393
  409. package/src/platform/registry/__tests__/resource-registry.test.ts +2005 -2005
  410. package/src/platform/registry/__tests__/serialization.test.ts +1127 -1127
  411. package/src/platform/registry/command-view.ts +180 -180
  412. package/src/platform/registry/domains.ts +165 -165
  413. package/src/platform/registry/index.ts +93 -93
  414. package/src/platform/registry/reserved.ts +24 -24
  415. package/src/platform/registry/resource-metadata.ts +59 -59
  416. package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -129
  417. package/src/platform/registry/resource-registry.ts +876 -876
  418. package/src/platform/registry/serialization.ts +273 -273
  419. package/src/platform/registry/serialized-types.ts +231 -231
  420. package/src/platform/registry/stats-types.ts +66 -66
  421. package/src/platform/registry/types.ts +404 -404
  422. package/src/platform/registry/validation.ts +513 -513
  423. package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -471
  424. package/src/platform/resilience/circuit-breaker.ts +164 -164
  425. package/src/platform/resilience/errors.ts +68 -68
  426. package/src/platform/resilience/http-error-mapper.ts +129 -129
  427. package/src/platform/resilience/index.ts +93 -93
  428. package/src/platform/resilience/rate-limiter-types.ts +46 -46
  429. package/src/platform/resilience/rate-limiter.ts +140 -140
  430. package/src/platform/resilience/retry.ts +89 -89
  431. package/src/platform/resilience/timeout.ts +63 -63
  432. package/src/platform/sse/events.ts +37 -34
  433. package/src/platform/sse/index.ts +7 -7
  434. package/src/platform/utils/__tests__/validation.test.ts +1083 -1083
  435. package/src/platform/utils/currency.ts +96 -96
  436. package/src/platform/utils/debounce.ts +52 -52
  437. package/src/platform/utils/error.ts +41 -41
  438. package/src/platform/utils/hmac.test.ts +97 -97
  439. package/src/platform/utils/index.ts +32 -32
  440. package/src/platform/utils/server/betterstack-logger.ts +210 -210
  441. package/src/platform/utils/server/hmac.ts +44 -44
  442. package/src/platform/utils/server/unsubscribe.ts +111 -111
  443. package/src/platform/utils/token-counter.ts +96 -96
  444. package/src/platform/utils/validation.ts +425 -425
  445. package/src/projects/api-schemas.ts +268 -268
  446. package/src/published.ts +1 -1
  447. package/src/reference/_generated/contracts.md +611 -607
  448. package/src/reference/glossary.md +105 -105
  449. package/src/requests/__tests__/api-schemas.test.ts +277 -277
  450. package/src/requests/api-schemas.ts +83 -83
  451. package/src/requests/index.ts +1 -1
  452. package/src/scaffold-registry/__tests__/index.test.ts +17 -0
  453. package/src/scaffold-registry/__tests__/schema.test.ts +329 -230
  454. package/src/scaffold-registry/index.ts +205 -189
  455. package/src/scaffold-registry/schema.ts +196 -128
  456. package/src/server.ts +272 -272
  457. package/src/supabase/database.types.ts +2719 -2719
  458. package/src/supabase/helpers.ts +20 -20
  459. package/src/supabase/index.ts +52 -52
  460. package/src/supabase/server/client.ts +58 -58
  461. package/src/test-utils/README.md +38 -38
  462. package/src/test-utils/browser-mocks.ts +54 -54
  463. package/src/test-utils/fixtures/api-keys.ts +52 -52
  464. package/src/test-utils/fixtures/index.ts +4 -4
  465. package/src/test-utils/fixtures/memberships.ts +80 -80
  466. package/src/test-utils/fixtures/organizations.ts +69 -69
  467. package/src/test-utils/fixtures/users.ts +79 -79
  468. package/src/test-utils/index.ts +11 -11
  469. package/src/test-utils/mocks/index.ts +2 -2
  470. package/src/test-utils/mocks/supabase.ts +142 -142
  471. package/src/test-utils/mocks/workos.ts +108 -108
  472. package/src/test-utils/rls/RLSTestContext.ts +556 -556
  473. package/src/test-utils/rls/index.ts +1 -1
@@ -1,425 +1,425 @@
1
- /**
2
- * Common validation utilities
3
- *
4
- * Reusable Zod schema primitives for input validation across all domains.
5
- * These validators are composed by domain-specific api-schemas.ts files.
6
- *
7
- * Design Principles:
8
- * - KISS: Pure functions, no classes, no state
9
- * - DRY: Common patterns extracted once, reused everywhere
10
- * - Type Safety: Full TypeScript inference, no any types
11
- * - Composability: Small validators easily combined using Zod methods
12
- *
13
- * Security Benefits:
14
- * - SQL Injection Prevention: Strict format validation (UUID, Email)
15
- * - DoS Protection: Max length constraints on strings/arrays, pagination limits
16
- * - Mass Assignment Prevention: Use .strict() mode on all request schemas
17
- * - XSS Prevention: Input sanitization and format validation
18
- *
19
- * @module validation
20
- */
21
-
22
- import { z } from 'zod'
23
-
24
- /**
25
- * UUID validation schema
26
- * Ensures string is a valid UUID (v4 format)
27
- */
28
- export const UuidSchema = z.string().uuid()
29
-
30
- /**
31
- * Non-empty string validation schema
32
- * Trims whitespace and enforces minimum 1 character, maximum 1000 characters
33
- */
34
- export const NonEmptyStringSchema = z.string().trim().min(1).max(1000)
35
-
36
- /**
37
- * Resource type validation
38
- * Used across execution systems for workflow and agent resources
39
- */
40
- export const ResourceTypeSchema = z.enum(['agent', 'workflow'])
41
-
42
- /**
43
- * Origin resource type validation
44
- * Includes all possible execution origins for audit trails
45
- */
46
- export const OriginResourceTypeSchema = z.enum(['agent', 'workflow', 'scheduler', 'api'])
47
-
48
- /**
49
- * Creates a payload size validator with configurable max size
50
- * Validates that JSON serialization of payload does not exceed size limit
51
- *
52
- * @param maxSizeBytes - Maximum allowed size in bytes (e.g., 500_000 for 500KB)
53
- * @param options - Configuration options
54
- * @param options.optional - If false, undefined values are rejected (default: false)
55
- * @returns Zod schema that validates payload size
56
- *
57
- * @example
58
- * ```typescript
59
- * const PayloadSchema = createPayloadSizeValidator(500_000) // Required, 500KB limit
60
- * const OptionalPayloadSchema = createPayloadSizeValidator(500_000, { optional: true })
61
- * PayloadSchema.parse({ data: 'test' }) // OK
62
- * PayloadSchema.parse({ data: 'x'.repeat(600_000) }) // Fails - too large
63
- * PayloadSchema.parse(undefined) // Fails - required
64
- * OptionalPayloadSchema.parse(undefined) // OK - optional
65
- * ```
66
- */
67
- export function createPayloadSizeValidator(maxSizeBytes: number, options?: { optional?: boolean }) {
68
- const allowUndefined = options?.optional === true
69
-
70
- return z.unknown().superRefine((val, ctx) => {
71
- // Check if value is undefined
72
- if (val === undefined) {
73
- if (!allowUndefined) {
74
- ctx.addIssue({
75
- code: 'custom',
76
- message: 'Payload is required'
77
- })
78
- }
79
- return // Stop validation if undefined
80
- }
81
-
82
- // Null is treated as valid empty payload
83
- if (val === null) {
84
- return
85
- }
86
-
87
- // Check size
88
- const size = JSON.stringify(val).length
89
- if (size > maxSizeBytes) {
90
- ctx.addIssue({
91
- code: 'custom',
92
- message: `Payload exceeds maximum size of ${Math.round(maxSizeBytes / 1000)}KB`
93
- })
94
- }
95
- })
96
- }
97
-
98
- /**
99
- * Credential name validation
100
- * - Lowercase letters, numbers, and hyphens only
101
- * - Must contain at least one hyphen (enforces {service}-{env} convention)
102
- * - No sequential hyphens, no leading/trailing hyphens
103
- * - 1-100 characters
104
- * - Input is auto-lowercased and trimmed
105
- *
106
- * SECURITY: Prevents path traversal attacks on /decrypt endpoint
107
- * Rejects: '../admin-cred', 'test@prod', 'gmail prod', 'Gmail_Prod'
108
- *
109
- * Valid: 'gmail-prod', 'attio-dev', 'stripe-api-key'
110
- * Invalid: 'GmailProd', 'gmail_prod', 'gmail--prod', 'gmail', '-gmail-prod'
111
- */
112
- export const CredentialNameSchema = z
113
- .string()
114
- .trim()
115
- .toLowerCase()
116
- .min(1, 'Credential name required')
117
- .max(100, 'Credential name too long (max 100 chars)')
118
- .regex(
119
- /^[a-z0-9]+(-[a-z0-9]+)+$/,
120
- 'Credential name must be lowercase letters, numbers, and hyphens in format: service-environment (e.g., gmail-prod, attio-dev)'
121
- )
122
-
123
- /**
124
- * Organization ID validation (UUID format)
125
- */
126
- export const OrganizationIdSchema = UuidSchema
127
-
128
- /**
129
- * OAuth provider validation
130
- * Must match providers in provider-registry.ts
131
- */
132
- export const OAuthProviderSchema = z.enum(['google-sheets', 'dropbox'])
133
-
134
- /**
135
- * OAuth authorization code validation
136
- * Typical OAuth codes are 20-500 characters
137
- */
138
- export const OAuthCodeSchema = z
139
- .string()
140
- .min(10, 'Authorization code too short')
141
- .max(1000, 'Authorization code too long')
142
-
143
- /**
144
- * OAuth state parameter validation
145
- * Base64-encoded JSON state object, max 2KB
146
- */
147
- export const OAuthStateParamSchema = z
148
- .string()
149
- .min(10, 'State parameter too short')
150
- .max(2048, 'State parameter too long')
151
-
152
- /**
153
- * Sanitized string (removes dangerous characters)
154
- */
155
- export const SanitizedStringSchema = z
156
- .string()
157
- .trim()
158
- .transform((str) => str.replace(/[<>'"]/g, ''))
159
-
160
- /**
161
- * Validates email format (RFC 5322)
162
- *
163
- * Security: Prevents email header injection, validates format before sending
164
- *
165
- * @example
166
- * EmailSchema.parse('user@example.com') // OK
167
- * EmailSchema.parse('invalid') // Error: Invalid email
168
- */
169
- export const EmailSchema = z.string().email()
170
-
171
- /**
172
- * Validates URL format (HTTP/HTTPS)
173
- *
174
- * Security: Prevents open redirect attacks, validates callback/webhook URLs
175
- *
176
- * @example
177
- * UrlSchema.parse('https://example.com') // OK
178
- * UrlSchema.parse('not-a-url') // Error: Invalid URL
179
- *
180
- * @example
181
- * // HTTPS only
182
- * const SecureUrlSchema = UrlSchema.refine(
183
- * (url) => url.startsWith('https://'),
184
- * { message: 'HTTPS required' }
185
- * )
186
- */
187
- export const UrlSchema = z.string().url()
188
-
189
- /**
190
- * Standard pagination parameters
191
- *
192
- * Constraints:
193
- * - limit: 1-100 items (default: 20)
194
- * - offset: 0+ items (default: 0)
195
- *
196
- * Uses z.coerce to handle string query parameters from URLs
197
- *
198
- * Security: DoS protection (max 100 items), prevents type coercion exploits
199
- *
200
- * @example
201
- * // Query string: ?limit=50&offset=100
202
- * PaginationSchema.parse({ limit: '50', offset: '100' })
203
- * // Result: { limit: 50, offset: 100 }
204
- *
205
- * @example
206
- * // Extend with filters
207
- * const FilteredListSchema = PaginationSchema.extend({
208
- * status: z.enum(['active', 'inactive']),
209
- * search: z.string().optional()
210
- * })
211
- */
212
- export const PaginationSchema = z.object({
213
- limit: z.coerce.number().int().min(1).max(100).default(20),
214
- offset: z.coerce.number().int().min(0).default(0)
215
- })
216
-
217
- /**
218
- * Validates ISO 8601 datetime format
219
- *
220
- * Security: Prevents date parsing exploits, ensures consistent timezone handling
221
- *
222
- * @example
223
- * TimestampSchema.parse('2025-11-13T10:30:00Z') // OK
224
- * TimestampSchema.parse('invalid-date') // Error: Invalid datetime
225
- */
226
- export const TimestampSchema = z.string().datetime()
227
-
228
- /**
229
- * Date range with start and end timestamps
230
- *
231
- * Note: Does not validate that end > start by default.
232
- * Use .refine() for logical validation.
233
- *
234
- * Security: Prevents time-based attacks, validates report ranges
235
- *
236
- * @example
237
- * const schema = DateRangeSchema.refine(
238
- * (data) => new Date(data.endDate) > new Date(data.startDate),
239
- * { message: 'End date must be after start date' }
240
- * )
241
- */
242
- export const DateRangeSchema = z.object({
243
- startDate: z.string().datetime(),
244
- endDate: z.string().datetime()
245
- })
246
-
247
- /**
248
- * Creates an enum schema with custom error message
249
- *
250
- * @param values - Array of valid enum values
251
- * @param errorMessage - Optional custom error message
252
- *
253
- * @example
254
- * const StatusSchema = createEnumSchema(
255
- * ['active', 'inactive', 'pending'],
256
- * 'Status must be active, inactive, or pending'
257
- * )
258
- *
259
- * const taskSchema = z.object({
260
- * status: StatusSchema
261
- * })
262
- */
263
- export function createEnumSchema<T extends [string, ...string[]]>(values: T, errorMessage?: string) {
264
- const schema = z.enum(values)
265
- return errorMessage ? schema.describe(errorMessage) : schema
266
- }
267
-
268
- /**
269
- * Creates a string schema with custom length constraints
270
- *
271
- * @param minLength - Minimum string length
272
- * @param maxLength - Maximum string length
273
- * @param fieldName - Optional field name for error messages
274
- *
275
- * @example
276
- * const UsernameSchema = createStringSchema(3, 20, 'Username')
277
- * const BioSchema = createStringSchema(0, 500, 'Bio')
278
- *
279
- * const userSchema = z.object({
280
- * username: UsernameSchema,
281
- * bio: BioSchema.optional()
282
- * })
283
- */
284
- export function createStringSchema(minLength: number, maxLength: number, fieldName?: string): z.ZodString {
285
- const schema = z.string().trim().min(minLength).max(maxLength)
286
- return fieldName ? schema.describe(`${fieldName} (${minLength}-${maxLength} characters)`) : schema
287
- }
288
-
289
- /**
290
- * Creates an array schema with size constraints
291
- *
292
- * @param itemSchema - Zod schema for array items
293
- * @param minItems - Minimum array size
294
- * @param maxItems - Maximum array size
295
- * @param fieldName - Optional field name for error messages
296
- *
297
- * @example
298
- * const TagsSchema = createArraySchema(
299
- * z.string(),
300
- * 1,
301
- * 10,
302
- * 'Tags'
303
- * )
304
- *
305
- * const EmailListSchema = createArraySchema(
306
- * EmailSchema,
307
- * 1,
308
- * 5,
309
- * 'Email addresses'
310
- * )
311
- *
312
- * const articleSchema = z.object({
313
- * tags: TagsSchema,
314
- * notifyEmails: EmailListSchema
315
- * })
316
- */
317
- export function createArraySchema<T extends z.ZodTypeAny>(
318
- itemSchema: T,
319
- minItems: number,
320
- maxItems: number,
321
- fieldName?: string
322
- ): z.ZodArray<T> {
323
- const schema = z.array(itemSchema).min(minItems).max(maxItems)
324
- return fieldName ? schema.describe(`${fieldName} (${minItems}-${maxItems} items)`) : schema
325
- }
326
-
327
- /**
328
- * Formatted validation error response
329
- * Used by API error handler to return structured validation errors
330
- */
331
- export interface ValidationErrorResponse {
332
- message: string
333
- fields: Record<string, string[]>
334
- }
335
-
336
- /**
337
- * Format Zod validation errors into structured, user-friendly messages
338
- *
339
- * Transforms Zod's nested error structure into a flat field-to-errors mapping
340
- * for better API consumer experience. Shows ALL validation errors at once.
341
- *
342
- * Security: Sanitizes internal schema details while preserving actionable feedback
343
- *
344
- * @param error - ZodError from failed validation
345
- * @returns Structured error response with message and field-level errors
346
- *
347
- * @example
348
- * ```typescript
349
- * const schema = z.object({
350
- * email: EmailSchema,
351
- * age: z.number().min(18)
352
- * })
353
- *
354
- * try {
355
- * schema.parse({ email: 'invalid', age: 15 })
356
- * } catch (error) {
357
- * const formatted = formatZodValidationError(error as ZodError)
358
- * // {
359
- * // message: 'Validation failed',
360
- * // fields: {
361
- * // email: ['Invalid email'],
362
- * // age: ['Number must be greater than or equal to 18']
363
- * // }
364
- * // }
365
- * }
366
- * ```
367
- *
368
- * @example
369
- * ```typescript
370
- * // Nested object validation
371
- * const schema = z.object({
372
- * user: z.object({
373
- * profile: z.object({
374
- * email: EmailSchema
375
- * })
376
- * })
377
- * })
378
- *
379
- * // Error path: user.profile.email
380
- * // Output: { 'user.profile.email': ['Invalid email'] }
381
- * ```
382
- */
383
- export function formatZodValidationError(error: z.ZodError): ValidationErrorResponse {
384
- const fieldErrors: Record<string, string[]> = {}
385
-
386
- for (const issue of error.issues) {
387
- // Build field path (e.g., 'user.email' or 'items[0].name')
388
- const path = issue.path.length > 0 ? issue.path.join('.') : '_root'
389
-
390
- // Initialize field error array if not exists
391
- if (!fieldErrors[path]) {
392
- fieldErrors[path] = []
393
- }
394
-
395
- // Add error message (Zod provides good messages by default)
396
- fieldErrors[path].push(issue.message)
397
- }
398
-
399
- // Count total errors for summary message
400
- const errorCount = Object.keys(fieldErrors).length
401
- const fieldWord = errorCount === 1 ? 'field' : 'fields'
402
-
403
- return {
404
- message: `Validation failed on ${errorCount} ${fieldWord}`,
405
- fields: fieldErrors
406
- }
407
- }
408
-
409
- /**
410
- * Export type helpers for domain schemas
411
- */
412
- export type PaginationParams = z.infer<typeof PaginationSchema>
413
- export type DateRange = z.infer<typeof DateRangeSchema>
414
-
415
- /**
416
- * Standard paginated response envelope for collection endpoints.
417
- * Use this for all new paginated API responses.
418
- */
419
- export interface PaginatedResponse<T> {
420
- data: T[]
421
- total: number
422
- page: number
423
- limit: number
424
- hasMore: boolean
425
- }
1
+ /**
2
+ * Common validation utilities
3
+ *
4
+ * Reusable Zod schema primitives for input validation across all domains.
5
+ * These validators are composed by domain-specific api-schemas.ts files.
6
+ *
7
+ * Design Principles:
8
+ * - KISS: Pure functions, no classes, no state
9
+ * - DRY: Common patterns extracted once, reused everywhere
10
+ * - Type Safety: Full TypeScript inference, no any types
11
+ * - Composability: Small validators easily combined using Zod methods
12
+ *
13
+ * Security Benefits:
14
+ * - SQL Injection Prevention: Strict format validation (UUID, Email)
15
+ * - DoS Protection: Max length constraints on strings/arrays, pagination limits
16
+ * - Mass Assignment Prevention: Use .strict() mode on all request schemas
17
+ * - XSS Prevention: Input sanitization and format validation
18
+ *
19
+ * @module validation
20
+ */
21
+
22
+ import { z } from 'zod'
23
+
24
+ /**
25
+ * UUID validation schema
26
+ * Ensures string is a valid UUID (v4 format)
27
+ */
28
+ export const UuidSchema = z.string().uuid()
29
+
30
+ /**
31
+ * Non-empty string validation schema
32
+ * Trims whitespace and enforces minimum 1 character, maximum 1000 characters
33
+ */
34
+ export const NonEmptyStringSchema = z.string().trim().min(1).max(1000)
35
+
36
+ /**
37
+ * Resource type validation
38
+ * Used across execution systems for workflow and agent resources
39
+ */
40
+ export const ResourceTypeSchema = z.enum(['agent', 'workflow'])
41
+
42
+ /**
43
+ * Origin resource type validation
44
+ * Includes all possible execution origins for audit trails
45
+ */
46
+ export const OriginResourceTypeSchema = z.enum(['agent', 'workflow', 'scheduler', 'api'])
47
+
48
+ /**
49
+ * Creates a payload size validator with configurable max size
50
+ * Validates that JSON serialization of payload does not exceed size limit
51
+ *
52
+ * @param maxSizeBytes - Maximum allowed size in bytes (e.g., 500_000 for 500KB)
53
+ * @param options - Configuration options
54
+ * @param options.optional - If false, undefined values are rejected (default: false)
55
+ * @returns Zod schema that validates payload size
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const PayloadSchema = createPayloadSizeValidator(500_000) // Required, 500KB limit
60
+ * const OptionalPayloadSchema = createPayloadSizeValidator(500_000, { optional: true })
61
+ * PayloadSchema.parse({ data: 'test' }) // OK
62
+ * PayloadSchema.parse({ data: 'x'.repeat(600_000) }) // Fails - too large
63
+ * PayloadSchema.parse(undefined) // Fails - required
64
+ * OptionalPayloadSchema.parse(undefined) // OK - optional
65
+ * ```
66
+ */
67
+ export function createPayloadSizeValidator(maxSizeBytes: number, options?: { optional?: boolean }) {
68
+ const allowUndefined = options?.optional === true
69
+
70
+ return z.unknown().superRefine((val, ctx) => {
71
+ // Check if value is undefined
72
+ if (val === undefined) {
73
+ if (!allowUndefined) {
74
+ ctx.addIssue({
75
+ code: 'custom',
76
+ message: 'Payload is required'
77
+ })
78
+ }
79
+ return // Stop validation if undefined
80
+ }
81
+
82
+ // Null is treated as valid empty payload
83
+ if (val === null) {
84
+ return
85
+ }
86
+
87
+ // Check size
88
+ const size = JSON.stringify(val).length
89
+ if (size > maxSizeBytes) {
90
+ ctx.addIssue({
91
+ code: 'custom',
92
+ message: `Payload exceeds maximum size of ${Math.round(maxSizeBytes / 1000)}KB`
93
+ })
94
+ }
95
+ })
96
+ }
97
+
98
+ /**
99
+ * Credential name validation
100
+ * - Lowercase letters, numbers, and hyphens only
101
+ * - Must contain at least one hyphen (enforces {service}-{env} convention)
102
+ * - No sequential hyphens, no leading/trailing hyphens
103
+ * - 1-100 characters
104
+ * - Input is auto-lowercased and trimmed
105
+ *
106
+ * SECURITY: Prevents path traversal attacks on /decrypt endpoint
107
+ * Rejects: '../admin-cred', 'test@prod', 'gmail prod', 'Gmail_Prod'
108
+ *
109
+ * Valid: 'gmail-prod', 'attio-dev', 'stripe-api-key'
110
+ * Invalid: 'GmailProd', 'gmail_prod', 'gmail--prod', 'gmail', '-gmail-prod'
111
+ */
112
+ export const CredentialNameSchema = z
113
+ .string()
114
+ .trim()
115
+ .toLowerCase()
116
+ .min(1, 'Credential name required')
117
+ .max(100, 'Credential name too long (max 100 chars)')
118
+ .regex(
119
+ /^[a-z0-9]+(-[a-z0-9]+)+$/,
120
+ 'Credential name must be lowercase letters, numbers, and hyphens in format: service-environment (e.g., gmail-prod, attio-dev)'
121
+ )
122
+
123
+ /**
124
+ * Organization ID validation (UUID format)
125
+ */
126
+ export const OrganizationIdSchema = UuidSchema
127
+
128
+ /**
129
+ * OAuth provider validation
130
+ * Must match providers in provider-registry.ts
131
+ */
132
+ export const OAuthProviderSchema = z.enum(['google-sheets', 'dropbox'])
133
+
134
+ /**
135
+ * OAuth authorization code validation
136
+ * Typical OAuth codes are 20-500 characters
137
+ */
138
+ export const OAuthCodeSchema = z
139
+ .string()
140
+ .min(10, 'Authorization code too short')
141
+ .max(1000, 'Authorization code too long')
142
+
143
+ /**
144
+ * OAuth state parameter validation
145
+ * Base64-encoded JSON state object, max 2KB
146
+ */
147
+ export const OAuthStateParamSchema = z
148
+ .string()
149
+ .min(10, 'State parameter too short')
150
+ .max(2048, 'State parameter too long')
151
+
152
+ /**
153
+ * Sanitized string (removes dangerous characters)
154
+ */
155
+ export const SanitizedStringSchema = z
156
+ .string()
157
+ .trim()
158
+ .transform((str) => str.replace(/[<>'"]/g, ''))
159
+
160
+ /**
161
+ * Validates email format (RFC 5322)
162
+ *
163
+ * Security: Prevents email header injection, validates format before sending
164
+ *
165
+ * @example
166
+ * EmailSchema.parse('user@example.com') // OK
167
+ * EmailSchema.parse('invalid') // Error: Invalid email
168
+ */
169
+ export const EmailSchema = z.string().email()
170
+
171
+ /**
172
+ * Validates URL format (HTTP/HTTPS)
173
+ *
174
+ * Security: Prevents open redirect attacks, validates callback/webhook URLs
175
+ *
176
+ * @example
177
+ * UrlSchema.parse('https://example.com') // OK
178
+ * UrlSchema.parse('not-a-url') // Error: Invalid URL
179
+ *
180
+ * @example
181
+ * // HTTPS only
182
+ * const SecureUrlSchema = UrlSchema.refine(
183
+ * (url) => url.startsWith('https://'),
184
+ * { message: 'HTTPS required' }
185
+ * )
186
+ */
187
+ export const UrlSchema = z.string().url()
188
+
189
+ /**
190
+ * Standard pagination parameters
191
+ *
192
+ * Constraints:
193
+ * - limit: 1-100 items (default: 20)
194
+ * - offset: 0+ items (default: 0)
195
+ *
196
+ * Uses z.coerce to handle string query parameters from URLs
197
+ *
198
+ * Security: DoS protection (max 100 items), prevents type coercion exploits
199
+ *
200
+ * @example
201
+ * // Query string: ?limit=50&offset=100
202
+ * PaginationSchema.parse({ limit: '50', offset: '100' })
203
+ * // Result: { limit: 50, offset: 100 }
204
+ *
205
+ * @example
206
+ * // Extend with filters
207
+ * const FilteredListSchema = PaginationSchema.extend({
208
+ * status: z.enum(['active', 'inactive']),
209
+ * search: z.string().optional()
210
+ * })
211
+ */
212
+ export const PaginationSchema = z.object({
213
+ limit: z.coerce.number().int().min(1).max(100).default(20),
214
+ offset: z.coerce.number().int().min(0).default(0)
215
+ })
216
+
217
+ /**
218
+ * Validates ISO 8601 datetime format
219
+ *
220
+ * Security: Prevents date parsing exploits, ensures consistent timezone handling
221
+ *
222
+ * @example
223
+ * TimestampSchema.parse('2025-11-13T10:30:00Z') // OK
224
+ * TimestampSchema.parse('invalid-date') // Error: Invalid datetime
225
+ */
226
+ export const TimestampSchema = z.string().datetime()
227
+
228
+ /**
229
+ * Date range with start and end timestamps
230
+ *
231
+ * Note: Does not validate that end > start by default.
232
+ * Use .refine() for logical validation.
233
+ *
234
+ * Security: Prevents time-based attacks, validates report ranges
235
+ *
236
+ * @example
237
+ * const schema = DateRangeSchema.refine(
238
+ * (data) => new Date(data.endDate) > new Date(data.startDate),
239
+ * { message: 'End date must be after start date' }
240
+ * )
241
+ */
242
+ export const DateRangeSchema = z.object({
243
+ startDate: z.string().datetime(),
244
+ endDate: z.string().datetime()
245
+ })
246
+
247
+ /**
248
+ * Creates an enum schema with custom error message
249
+ *
250
+ * @param values - Array of valid enum values
251
+ * @param errorMessage - Optional custom error message
252
+ *
253
+ * @example
254
+ * const StatusSchema = createEnumSchema(
255
+ * ['active', 'inactive', 'pending'],
256
+ * 'Status must be active, inactive, or pending'
257
+ * )
258
+ *
259
+ * const taskSchema = z.object({
260
+ * status: StatusSchema
261
+ * })
262
+ */
263
+ export function createEnumSchema<T extends [string, ...string[]]>(values: T, errorMessage?: string) {
264
+ const schema = z.enum(values)
265
+ return errorMessage ? schema.describe(errorMessage) : schema
266
+ }
267
+
268
+ /**
269
+ * Creates a string schema with custom length constraints
270
+ *
271
+ * @param minLength - Minimum string length
272
+ * @param maxLength - Maximum string length
273
+ * @param fieldName - Optional field name for error messages
274
+ *
275
+ * @example
276
+ * const UsernameSchema = createStringSchema(3, 20, 'Username')
277
+ * const BioSchema = createStringSchema(0, 500, 'Bio')
278
+ *
279
+ * const userSchema = z.object({
280
+ * username: UsernameSchema,
281
+ * bio: BioSchema.optional()
282
+ * })
283
+ */
284
+ export function createStringSchema(minLength: number, maxLength: number, fieldName?: string): z.ZodString {
285
+ const schema = z.string().trim().min(minLength).max(maxLength)
286
+ return fieldName ? schema.describe(`${fieldName} (${minLength}-${maxLength} characters)`) : schema
287
+ }
288
+
289
+ /**
290
+ * Creates an array schema with size constraints
291
+ *
292
+ * @param itemSchema - Zod schema for array items
293
+ * @param minItems - Minimum array size
294
+ * @param maxItems - Maximum array size
295
+ * @param fieldName - Optional field name for error messages
296
+ *
297
+ * @example
298
+ * const TagsSchema = createArraySchema(
299
+ * z.string(),
300
+ * 1,
301
+ * 10,
302
+ * 'Tags'
303
+ * )
304
+ *
305
+ * const EmailListSchema = createArraySchema(
306
+ * EmailSchema,
307
+ * 1,
308
+ * 5,
309
+ * 'Email addresses'
310
+ * )
311
+ *
312
+ * const articleSchema = z.object({
313
+ * tags: TagsSchema,
314
+ * notifyEmails: EmailListSchema
315
+ * })
316
+ */
317
+ export function createArraySchema<T extends z.ZodTypeAny>(
318
+ itemSchema: T,
319
+ minItems: number,
320
+ maxItems: number,
321
+ fieldName?: string
322
+ ): z.ZodArray<T> {
323
+ const schema = z.array(itemSchema).min(minItems).max(maxItems)
324
+ return fieldName ? schema.describe(`${fieldName} (${minItems}-${maxItems} items)`) : schema
325
+ }
326
+
327
+ /**
328
+ * Formatted validation error response
329
+ * Used by API error handler to return structured validation errors
330
+ */
331
+ export interface ValidationErrorResponse {
332
+ message: string
333
+ fields: Record<string, string[]>
334
+ }
335
+
336
+ /**
337
+ * Format Zod validation errors into structured, user-friendly messages
338
+ *
339
+ * Transforms Zod's nested error structure into a flat field-to-errors mapping
340
+ * for better API consumer experience. Shows ALL validation errors at once.
341
+ *
342
+ * Security: Sanitizes internal schema details while preserving actionable feedback
343
+ *
344
+ * @param error - ZodError from failed validation
345
+ * @returns Structured error response with message and field-level errors
346
+ *
347
+ * @example
348
+ * ```typescript
349
+ * const schema = z.object({
350
+ * email: EmailSchema,
351
+ * age: z.number().min(18)
352
+ * })
353
+ *
354
+ * try {
355
+ * schema.parse({ email: 'invalid', age: 15 })
356
+ * } catch (error) {
357
+ * const formatted = formatZodValidationError(error as ZodError)
358
+ * // {
359
+ * // message: 'Validation failed',
360
+ * // fields: {
361
+ * // email: ['Invalid email'],
362
+ * // age: ['Number must be greater than or equal to 18']
363
+ * // }
364
+ * // }
365
+ * }
366
+ * ```
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * // Nested object validation
371
+ * const schema = z.object({
372
+ * user: z.object({
373
+ * profile: z.object({
374
+ * email: EmailSchema
375
+ * })
376
+ * })
377
+ * })
378
+ *
379
+ * // Error path: user.profile.email
380
+ * // Output: { 'user.profile.email': ['Invalid email'] }
381
+ * ```
382
+ */
383
+ export function formatZodValidationError(error: z.ZodError): ValidationErrorResponse {
384
+ const fieldErrors: Record<string, string[]> = {}
385
+
386
+ for (const issue of error.issues) {
387
+ // Build field path (e.g., 'user.email' or 'items[0].name')
388
+ const path = issue.path.length > 0 ? issue.path.join('.') : '_root'
389
+
390
+ // Initialize field error array if not exists
391
+ if (!fieldErrors[path]) {
392
+ fieldErrors[path] = []
393
+ }
394
+
395
+ // Add error message (Zod provides good messages by default)
396
+ fieldErrors[path].push(issue.message)
397
+ }
398
+
399
+ // Count total errors for summary message
400
+ const errorCount = Object.keys(fieldErrors).length
401
+ const fieldWord = errorCount === 1 ? 'field' : 'fields'
402
+
403
+ return {
404
+ message: `Validation failed on ${errorCount} ${fieldWord}`,
405
+ fields: fieldErrors
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Export type helpers for domain schemas
411
+ */
412
+ export type PaginationParams = z.infer<typeof PaginationSchema>
413
+ export type DateRange = z.infer<typeof DateRangeSchema>
414
+
415
+ /**
416
+ * Standard paginated response envelope for collection endpoints.
417
+ * Use this for all new paginated API responses.
418
+ */
419
+ export interface PaginatedResponse<T> {
420
+ data: T[]
421
+ total: number
422
+ page: number
423
+ limit: number
424
+ hasMore: boolean
425
+ }