@elevasis/core 0.7.1 → 0.8.2

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 (476) hide show
  1. package/dist/test-utils/index.d.ts +3122 -0
  2. package/dist/test-utils/index.js +386 -0
  3. package/package.json +6 -1
  4. package/src/README.md +39 -36
  5. package/src/__tests__/publish.test.ts +18 -13
  6. package/src/__tests__/{template-foundations-compatibility.test.ts → template-core-compatibility.test.ts} +99 -99
  7. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1135 -1131
  8. package/src/_gen/__tests__/scaffold-contracts.test.ts +47 -36
  9. package/src/_gen/scaffold-contracts.ts +45 -45
  10. package/src/auth/multi-tenancy/credentials/README.md +38 -38
  11. package/src/auth/multi-tenancy/credentials/index.ts +6 -6
  12. package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -39
  13. package/src/auth/multi-tenancy/credentials/server/service.ts +60 -60
  14. package/src/auth/multi-tenancy/index.ts +17 -17
  15. package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -107
  16. package/src/auth/multi-tenancy/invitations/index.ts +37 -37
  17. package/src/auth/multi-tenancy/invitations/invitation.ts +86 -86
  18. package/src/auth/multi-tenancy/invitations/server/index.ts +25 -25
  19. package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -24
  20. package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -24
  21. package/src/auth/multi-tenancy/invitations/supabase.ts +50 -50
  22. package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -126
  23. package/src/auth/multi-tenancy/memberships/index.ts +21 -21
  24. package/src/auth/multi-tenancy/memberships/membership.ts +138 -138
  25. package/src/auth/multi-tenancy/memberships/server/index.ts +15 -15
  26. package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -32
  27. package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -21
  28. package/src/auth/multi-tenancy/memberships/supabase.ts +46 -46
  29. package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -128
  30. package/src/auth/multi-tenancy/organizations/index.ts +23 -23
  31. package/src/auth/multi-tenancy/organizations/organization.ts +24 -24
  32. package/src/auth/multi-tenancy/organizations/server/index.ts +10 -10
  33. package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -35
  34. package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -20
  35. package/src/auth/multi-tenancy/types.ts +83 -83
  36. package/src/auth/multi-tenancy/users/api-schemas.ts +194 -194
  37. package/src/auth/multi-tenancy/users/index.ts +27 -27
  38. package/src/auth/multi-tenancy/users/server/index.ts +19 -19
  39. package/src/auth/multi-tenancy/users/server/transforms.ts +21 -21
  40. package/src/auth/multi-tenancy/users/server/workos.ts +16 -16
  41. package/src/auth/multi-tenancy/users/user.ts +65 -65
  42. package/src/business/README.md +52 -52
  43. package/src/business/__tests__/entities-published.test.ts +33 -33
  44. package/src/business/acquisition/api-schemas.ts +759 -759
  45. package/src/business/acquisition/index.ts +109 -109
  46. package/src/business/acquisition/types.ts +402 -402
  47. package/src/business/base-entities.test.ts +481 -481
  48. package/src/business/base-entities.ts +241 -241
  49. package/src/business/entities-published.ts +24 -24
  50. package/src/business/index.ts +15 -15
  51. package/src/business/pdf/browser/pdfmake-browser.ts +229 -229
  52. package/src/business/pdf/index.ts +10 -10
  53. package/src/business/pdf/server/index.ts +21 -21
  54. package/src/business/pdf/server/themes/default.ts +8 -8
  55. package/src/business/pdf/server/themes/index.ts +9 -9
  56. package/src/business/pdf/server/themes/types.ts +8 -8
  57. package/src/business/pdf/types.ts +272 -272
  58. package/src/business/projects/index.ts +2 -2
  59. package/src/business/projects/sse-events.ts +21 -21
  60. package/src/business/projects/types.ts +89 -89
  61. package/src/business/sales/api-schemas.ts +75 -75
  62. package/src/business/seo/__tests__/linking.test.ts +549 -549
  63. package/src/business/seo/__tests__/types.test.ts +404 -404
  64. package/src/business/seo/index.ts +2 -2
  65. package/src/business/seo/linking.ts +281 -281
  66. package/src/business/seo/types.ts +199 -199
  67. package/src/commands/queue/index.ts +3 -3
  68. package/src/commands/queue/schemas.test.ts +593 -593
  69. package/src/commands/queue/schemas.ts +125 -125
  70. package/src/commands/queue/sse-events.ts +61 -61
  71. package/src/commands/queue/types/action.ts +52 -52
  72. package/src/commands/queue/types/checkpoint.ts +44 -44
  73. package/src/commands/queue/types/index.ts +7 -7
  74. package/src/commands/queue/types/task.ts +116 -116
  75. package/src/commands/queue/types.ts +14 -14
  76. package/src/content/distribution-metadata.ts +61 -61
  77. package/src/content/index.ts +10 -10
  78. package/src/deployments/index.ts +22 -22
  79. package/src/execution/core/__tests__/archived-logs.test.ts +72 -72
  80. package/src/execution/core/index.ts +11 -11
  81. package/src/execution/core/runner-types.ts +80 -80
  82. package/src/execution/core/server/environment.ts +31 -31
  83. package/src/execution/core/sse-executions.ts +119 -119
  84. package/src/execution/core/types.ts +29 -29
  85. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  86. package/src/execution/engine/__tests__/timeout.test.ts +565 -565
  87. package/src/execution/engine/agent/__tests__/errors.test.ts +508 -508
  88. package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -531
  89. package/src/execution/engine/agent/actions/executor.ts +205 -205
  90. package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -230
  91. package/src/execution/engine/agent/actions/processor.ts +116 -116
  92. package/src/execution/engine/agent/actions/types.ts +70 -70
  93. package/src/execution/engine/agent/core/agent.ts +810 -810
  94. package/src/execution/engine/agent/core/types.ts +155 -155
  95. package/src/execution/engine/agent/errors.ts +251 -251
  96. package/src/execution/engine/agent/index.ts +78 -78
  97. package/src/execution/engine/agent/knowledge-map/types.ts +106 -106
  98. package/src/execution/engine/agent/knowledge-map/utils.ts +101 -101
  99. package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -754
  100. package/src/execution/engine/agent/memory/domains.ts +99 -99
  101. package/src/execution/engine/agent/memory/manager.ts +365 -365
  102. package/src/execution/engine/agent/memory/processor.ts +66 -66
  103. package/src/execution/engine/agent/memory/types.ts +90 -90
  104. package/src/execution/engine/agent/memory/utils.ts +134 -134
  105. package/src/execution/engine/agent/observability/logging.ts +467 -467
  106. package/src/execution/engine/agent/observability/types.ts +64 -64
  107. package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -349
  108. package/src/execution/engine/agent/reasoning/processor.ts +92 -92
  109. package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -134
  110. package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -49
  111. package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -93
  112. package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -65
  113. package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -44
  114. package/src/execution/engine/agent/reasoning/request-builder.ts +169 -169
  115. package/src/execution/engine/agent/reasoning/types.ts +18 -18
  116. package/src/execution/engine/base/errors.ts +118 -118
  117. package/src/execution/engine/base/index.ts +2 -2
  118. package/src/execution/engine/base/logging.ts +31 -31
  119. package/src/execution/engine/base/serialization.ts +324 -324
  120. package/src/execution/engine/base/types.ts +126 -126
  121. package/src/execution/engine/base/utils.ts +41 -41
  122. package/src/execution/engine/index.ts +434 -434
  123. package/src/execution/engine/interface/index.ts +1 -1
  124. package/src/execution/engine/interface/types.ts +62 -62
  125. package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -50
  126. package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -321
  127. package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -115
  128. package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -375
  129. package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -463
  130. package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -177
  131. package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -722
  132. package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -376
  133. package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -551
  134. package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -563
  135. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -105
  136. package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -537
  137. package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -147
  138. package/src/execution/engine/llm/adapters/index.ts +17 -17
  139. package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -116
  140. package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -130
  141. package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -137
  142. package/src/execution/engine/llm/adapters/server/google.ts +283 -283
  143. package/src/execution/engine/llm/adapters/server/index.ts +12 -12
  144. package/src/execution/engine/llm/adapters/server/openai.ts +206 -206
  145. package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -235
  146. package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -230
  147. package/src/execution/engine/llm/errors.ts +186 -186
  148. package/src/execution/engine/llm/model-info.ts +332 -332
  149. package/src/execution/engine/llm/response-schema-validator.ts +113 -113
  150. package/src/execution/engine/llm/types.ts +86 -86
  151. package/src/execution/engine/test-utils/index.ts +6 -6
  152. package/src/execution/engine/test-utils/mocks.ts +56 -56
  153. package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -50
  154. package/src/execution/engine/tools/integration/index.ts +53 -53
  155. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -73
  156. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -209
  157. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -82
  158. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -122
  159. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -89
  160. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -84
  161. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -16
  162. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -293
  163. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -100
  164. package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -217
  165. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -92
  166. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -218
  167. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -87
  168. package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -11
  169. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +361 -361
  170. package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -162
  171. package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -594
  172. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -214
  173. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -152
  174. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -141
  175. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -86
  176. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -105
  177. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -118
  178. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -165
  179. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -96
  180. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -104
  181. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -156
  182. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -220
  183. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -140
  184. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +146 -146
  185. package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -31
  186. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -210
  187. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -104
  188. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  189. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -1189
  190. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -641
  191. package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -18
  192. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -86
  193. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -289
  194. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -154
  195. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -325
  196. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -153
  197. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -84
  198. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -125
  199. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -107
  200. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -85
  201. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -91
  202. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -92
  203. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -195
  204. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -113
  205. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -104
  206. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -155
  207. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -196
  208. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -102
  209. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -189
  210. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -87
  211. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -112
  212. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -76
  213. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -86
  214. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -98
  215. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -126
  216. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -193
  217. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -99
  218. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -621
  219. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -125
  220. package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -29
  221. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -178
  222. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -1473
  223. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -59
  224. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -102
  225. package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -17
  226. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -80
  227. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -102
  228. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -102
  229. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -134
  230. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -75
  231. package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -27
  232. package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -108
  233. package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -132
  234. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -274
  235. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -230
  236. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -133
  237. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -90
  238. package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -210
  239. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -517
  240. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -309
  241. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -133
  242. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -122
  243. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -111
  244. package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -11
  245. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -78
  246. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -222
  247. package/src/execution/engine/tools/integration/server/index.ts +61 -61
  248. package/src/execution/engine/tools/integration/service.ts +161 -161
  249. package/src/execution/engine/tools/integration/tool.ts +253 -253
  250. package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -74
  251. package/src/execution/engine/tools/integration/types/apify.ts +92 -92
  252. package/src/execution/engine/tools/integration/types/index.ts +19 -19
  253. package/src/execution/engine/tools/integration/types/instantly.ts +557 -557
  254. package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -56
  255. package/src/execution/engine/tools/integration/types/stripe.ts +162 -162
  256. package/src/execution/engine/tools/integration/types/tomba.ts +94 -94
  257. package/src/execution/engine/tools/lead-service-types.ts +884 -884
  258. package/src/execution/engine/tools/llm/index.ts +11 -11
  259. package/src/execution/engine/tools/llm/server/index.ts +8 -8
  260. package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -118
  261. package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -441
  262. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -248
  263. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -319
  264. package/src/execution/engine/tools/platform/acquisition/index.ts +43 -43
  265. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -148
  266. package/src/execution/engine/tools/platform/acquisition/types.ts +260 -260
  267. package/src/execution/engine/tools/platform/email/index.ts +122 -122
  268. package/src/execution/engine/tools/platform/email/types.ts +96 -96
  269. package/src/execution/engine/tools/platform/index.ts +157 -157
  270. package/src/execution/engine/tools/platform/notification.ts +81 -81
  271. package/src/execution/engine/tools/platform/pdf/index.ts +110 -110
  272. package/src/execution/engine/tools/platform/pdf/types.ts +77 -77
  273. package/src/execution/engine/tools/platform/scheduler.ts +87 -87
  274. package/src/execution/engine/tools/platform/storage/index.ts +370 -370
  275. package/src/execution/engine/tools/platform/types.ts +148 -148
  276. package/src/execution/engine/tools/registry.ts +700 -700
  277. package/src/execution/engine/tools/tool-maps.ts +786 -786
  278. package/src/execution/engine/tools/types.ts +233 -233
  279. package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -139
  280. package/src/execution/engine/workflow/errors.ts +63 -63
  281. package/src/execution/engine/workflow/helpers/index.ts +11 -11
  282. package/src/execution/engine/workflow/helpers/server/index.ts +8 -8
  283. package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -93
  284. package/src/execution/engine/workflow/index.ts +19 -19
  285. package/src/execution/engine/workflow/log-truncate.ts +26 -26
  286. package/src/execution/engine/workflow/logging.ts +191 -191
  287. package/src/execution/engine/workflow/types.ts +182 -182
  288. package/src/execution/engine/workflow/utils.ts +280 -280
  289. package/src/execution/engine/workflow/workflow.ts +168 -168
  290. package/src/execution/index.ts +3 -3
  291. package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -733
  292. package/src/execution/scheduler/__tests__/utils.test.ts +1009 -1009
  293. package/src/execution/scheduler/api-schemas.ts +296 -296
  294. package/src/execution/scheduler/index.ts +50 -50
  295. package/src/execution/scheduler/schemas.ts +264 -264
  296. package/src/execution/scheduler/types.ts +111 -111
  297. package/src/execution/scheduler/utils.ts +364 -364
  298. package/src/forms/index.ts +7 -7
  299. package/src/forms/schemas.ts +69 -69
  300. package/src/forms/types.ts +70 -70
  301. package/src/index.ts +71 -60
  302. package/src/integrations/credentials/__tests__/schemas.test.ts +82 -82
  303. package/src/integrations/credentials/__tests__/utils.test.ts +144 -144
  304. package/src/integrations/credentials/api-schemas.ts +143 -143
  305. package/src/integrations/credentials/index.ts +32 -32
  306. package/src/integrations/credentials/schemas.ts +164 -164
  307. package/src/integrations/credentials/utils.ts +59 -59
  308. package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -59
  309. package/src/integrations/oauth/api-schemas.ts +92 -92
  310. package/src/integrations/oauth/index.ts +19 -19
  311. package/src/integrations/oauth/provider-registry.ts +61 -61
  312. package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -183
  313. package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -577
  314. package/src/integrations/oauth/server/credentials.ts +39 -39
  315. package/src/integrations/oauth/server/refresh.ts +214 -214
  316. package/src/integrations/oauth/types.ts +34 -34
  317. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -318
  318. package/src/integrations/webhook-endpoints/api-schemas.ts +102 -102
  319. package/src/integrations/webhook-endpoints/index.ts +28 -28
  320. package/src/integrations/webhook-endpoints/types.ts +51 -51
  321. package/src/operations/activities/api-schemas.ts +79 -79
  322. package/src/operations/activities/index.ts +9 -9
  323. package/src/operations/activities/sse-events.ts +30 -30
  324. package/src/operations/activities/types.ts +63 -63
  325. package/src/operations/debug-logs/client.ts +60 -60
  326. package/src/operations/debug-logs/debug-logger.ts +83 -83
  327. package/src/operations/debug-logs/index.ts +8 -8
  328. package/src/operations/debug-logs/server.ts +19 -19
  329. package/src/operations/debug-logs/types.ts +33 -33
  330. package/src/operations/index.ts +50 -50
  331. package/src/operations/notifications/api-schemas.ts +91 -91
  332. package/src/operations/notifications/index.ts +3 -3
  333. package/src/operations/notifications/sse-events.ts +21 -21
  334. package/src/operations/notifications/types.ts +47 -47
  335. package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -297
  336. package/src/operations/observability/__tests__/utils.test.ts +54 -54
  337. package/src/operations/observability/ai-usage-collector.ts +64 -64
  338. package/src/operations/observability/index.ts +13 -13
  339. package/src/operations/observability/metrics-collector.ts +49 -49
  340. package/src/operations/observability/schemas.ts +39 -39
  341. package/src/operations/observability/types.ts +463 -463
  342. package/src/operations/observability/utils.ts +77 -77
  343. package/src/operations/sessions/__tests__/manager.test.ts +821 -821
  344. package/src/operations/sessions/index.ts +26 -26
  345. package/src/operations/sessions/server/manager.ts +90 -90
  346. package/src/operations/sessions/server/session.ts +180 -180
  347. package/src/operations/sessions/types.ts +98 -98
  348. package/src/operations/triggers/index.ts +12 -12
  349. package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -44
  350. package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -51
  351. package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -45
  352. package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -49
  353. package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -45
  354. package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -54
  355. package/src/operations/triggers/webhook/index.ts +35 -35
  356. package/src/operations/triggers/webhook/types.ts +74 -74
  357. package/src/organization-model/README.md +97 -97
  358. package/src/organization-model/__tests__/defaults.test.ts +175 -175
  359. package/src/organization-model/__tests__/domains/customers.test.ts +295 -295
  360. package/src/organization-model/__tests__/domains/goals.test.ts +479 -479
  361. package/src/organization-model/__tests__/domains/identity.test.ts +279 -279
  362. package/src/organization-model/__tests__/domains/navigation.test.ts +212 -212
  363. package/src/organization-model/__tests__/domains/offerings.test.ts +419 -419
  364. package/src/organization-model/__tests__/domains/operations.test.ts +203 -203
  365. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -362
  366. package/src/organization-model/__tests__/domains/roles.test.ts +347 -347
  367. package/src/organization-model/__tests__/domains/statuses.test.ts +243 -243
  368. package/src/organization-model/__tests__/foundation.test.ts +105 -105
  369. package/src/organization-model/__tests__/graph.test.ts +894 -894
  370. package/src/organization-model/__tests__/resolve.test.ts +690 -690
  371. package/src/organization-model/__tests__/schema.test.ts +407 -407
  372. package/src/organization-model/contracts.ts +14 -14
  373. package/src/organization-model/defaults.ts +148 -148
  374. package/src/organization-model/domains/branding.ts +22 -22
  375. package/src/organization-model/domains/customers.ts +75 -75
  376. package/src/organization-model/domains/features.ts +22 -22
  377. package/src/organization-model/domains/goals.ts +80 -80
  378. package/src/organization-model/domains/identity.ts +94 -94
  379. package/src/organization-model/domains/navigation.ts +391 -391
  380. package/src/organization-model/domains/offerings.ts +66 -66
  381. package/src/organization-model/domains/operations.ts +85 -85
  382. package/src/organization-model/domains/projects.ts +48 -48
  383. package/src/organization-model/domains/prospecting.ts +33 -33
  384. package/src/organization-model/domains/roles.ts +55 -55
  385. package/src/organization-model/domains/sales.ts +94 -94
  386. package/src/organization-model/domains/shared.ts +62 -62
  387. package/src/organization-model/domains/statuses.ts +130 -130
  388. package/src/organization-model/foundation.ts +97 -97
  389. package/src/organization-model/graph/build.ts +399 -399
  390. package/src/organization-model/graph/index.ts +4 -4
  391. package/src/organization-model/graph/schema.ts +48 -48
  392. package/src/organization-model/graph/types.ts +40 -40
  393. package/src/organization-model/index.ts +13 -13
  394. package/src/organization-model/organization-graph.mdx +272 -272
  395. package/src/organization-model/organization-model.mdx +320 -320
  396. package/src/organization-model/published.ts +85 -85
  397. package/src/organization-model/resolve.ts +66 -66
  398. package/src/organization-model/schema.ts +287 -287
  399. package/src/organization-model/types.ts +46 -46
  400. package/src/platform/api/index.ts +1 -1
  401. package/src/platform/api/types.ts +35 -35
  402. package/src/platform/constants/http.ts +37 -37
  403. package/src/platform/constants/index.ts +5 -5
  404. package/src/platform/constants/limits.ts +32 -32
  405. package/src/platform/constants/resilience.ts +51 -51
  406. package/src/platform/constants/timeouts.ts +20 -20
  407. package/src/platform/constants/versions.ts +3 -3
  408. package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -347
  409. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1028 -1028
  410. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -393
  411. package/src/platform/registry/__tests__/resource-registry.test.ts +2005 -2005
  412. package/src/platform/registry/__tests__/serialization.test.ts +1127 -1127
  413. package/src/platform/registry/command-view.ts +180 -180
  414. package/src/platform/registry/domains.ts +165 -165
  415. package/src/platform/registry/index.ts +93 -93
  416. package/src/platform/registry/reserved.ts +24 -24
  417. package/src/platform/registry/resource-metadata.ts +59 -59
  418. package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -129
  419. package/src/platform/registry/resource-registry.ts +876 -876
  420. package/src/platform/registry/serialization.ts +273 -273
  421. package/src/platform/registry/serialized-types.ts +231 -231
  422. package/src/platform/registry/stats-types.ts +66 -66
  423. package/src/platform/registry/types.ts +404 -404
  424. package/src/platform/registry/validation.ts +513 -513
  425. package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -471
  426. package/src/platform/resilience/circuit-breaker.ts +164 -164
  427. package/src/platform/resilience/errors.ts +68 -68
  428. package/src/platform/resilience/http-error-mapper.ts +129 -129
  429. package/src/platform/resilience/index.ts +93 -93
  430. package/src/platform/resilience/rate-limiter-types.ts +46 -46
  431. package/src/platform/resilience/rate-limiter.ts +140 -140
  432. package/src/platform/resilience/retry.ts +89 -89
  433. package/src/platform/resilience/timeout.ts +63 -63
  434. package/src/platform/sse/events.ts +37 -37
  435. package/src/platform/sse/index.ts +7 -7
  436. package/src/platform/utils/__tests__/validation.test.ts +1083 -1083
  437. package/src/platform/utils/currency.ts +96 -96
  438. package/src/platform/utils/debounce.ts +52 -52
  439. package/src/platform/utils/error.ts +41 -41
  440. package/src/platform/utils/hmac.test.ts +97 -97
  441. package/src/platform/utils/index.ts +32 -32
  442. package/src/platform/utils/server/betterstack-logger.ts +210 -210
  443. package/src/platform/utils/server/hmac.ts +44 -44
  444. package/src/platform/utils/server/unsubscribe.ts +111 -111
  445. package/src/platform/utils/token-counter.ts +96 -96
  446. package/src/platform/utils/validation.ts +425 -425
  447. package/src/projects/api-schemas.ts +268 -268
  448. package/src/published.ts +1 -1
  449. package/src/reference/_generated/contracts.md +607 -607
  450. package/src/reference/glossary.md +105 -105
  451. package/src/requests/__tests__/api-schemas.test.ts +277 -277
  452. package/src/requests/api-schemas.ts +83 -83
  453. package/src/requests/index.ts +1 -1
  454. package/src/scaffold-registry/__tests__/index.test.ts +17 -0
  455. package/src/scaffold-registry/__tests__/schema.test.ts +329 -230
  456. package/src/scaffold-registry/index.ts +205 -189
  457. package/src/scaffold-registry/schema.ts +196 -128
  458. package/src/server.ts +272 -272
  459. package/src/supabase/database.types.ts +2719 -2719
  460. package/src/supabase/helpers.ts +20 -20
  461. package/src/supabase/index.ts +52 -52
  462. package/src/supabase/server/client.ts +58 -58
  463. package/src/test-utils/README.md +30 -138
  464. package/src/test-utils/browser-mocks.ts +54 -54
  465. package/src/test-utils/fixtures/api-keys.ts +52 -52
  466. package/src/test-utils/fixtures/index.ts +4 -4
  467. package/src/test-utils/fixtures/memberships.ts +80 -80
  468. package/src/test-utils/fixtures/organizations.ts +69 -69
  469. package/src/test-utils/fixtures/users.ts +79 -79
  470. package/src/test-utils/index.ts +7 -8
  471. package/src/test-utils/mocks/index.ts +2 -2
  472. package/src/test-utils/mocks/supabase.ts +142 -142
  473. package/src/test-utils/mocks/workos.ts +108 -108
  474. package/src/test-utils/published.ts +4 -0
  475. package/src/test-utils/rls/RLSTestContext.ts +554 -554
  476. 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
+ }