@hexclave/shared 1.0.3 → 1.0.5

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 (343) hide show
  1. package/dist/ai/unified-prompts/reminders.js +4 -3
  2. package/dist/ai/unified-prompts/reminders.js.map +1 -1
  3. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  4. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  5. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +216 -29
  6. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  7. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  8. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  9. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  10. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  11. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  12. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  13. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  14. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  15. package/dist/config/schema.d.ts +71 -71
  16. package/dist/config/schema.d.ts.map +1 -1
  17. package/dist/config/schema.js +5 -5
  18. package/dist/config/schema.js.map +1 -1
  19. package/dist/config-authoring.d.ts +4 -4
  20. package/dist/config-authoring.d.ts.map +1 -1
  21. package/dist/config-authoring.js +2 -2
  22. package/dist/config-authoring.js.map +1 -1
  23. package/dist/config-rendering.d.ts +4 -4
  24. package/dist/config-rendering.d.ts.map +1 -1
  25. package/dist/config-rendering.js +19 -18
  26. package/dist/config-rendering.js.map +1 -1
  27. package/dist/esm/ai/unified-prompts/reminders.js +4 -3
  28. package/dist/esm/ai/unified-prompts/reminders.js.map +1 -1
  29. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  30. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  31. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +215 -30
  32. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  33. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  34. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  35. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  36. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  37. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  38. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  39. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  40. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  41. package/dist/esm/config/schema.d.ts +71 -71
  42. package/dist/esm/config/schema.d.ts.map +1 -1
  43. package/dist/esm/config/schema.js +5 -5
  44. package/dist/esm/config/schema.js.map +1 -1
  45. package/dist/esm/config-authoring.d.ts +4 -4
  46. package/dist/esm/config-authoring.d.ts.map +1 -1
  47. package/dist/esm/config-authoring.js +2 -2
  48. package/dist/esm/config-authoring.js.map +1 -1
  49. package/dist/esm/config-rendering.d.ts +4 -4
  50. package/dist/esm/config-rendering.d.ts.map +1 -1
  51. package/dist/esm/config-rendering.js +15 -14
  52. package/dist/esm/config-rendering.js.map +1 -1
  53. package/dist/esm/helpers/vault/client-side.d.ts.map +1 -1
  54. package/dist/esm/helpers/vault/client-side.js.map +1 -1
  55. package/dist/esm/helpers/vault/server-side.d.ts.map +1 -1
  56. package/dist/esm/helpers/vault/server-side.js.map +1 -1
  57. package/dist/esm/hexclave-config-file.d.ts +15 -0
  58. package/dist/esm/hexclave-config-file.d.ts.map +1 -0
  59. package/dist/esm/{stack-config-file.js → hexclave-config-file.js} +7 -7
  60. package/dist/esm/hexclave-config-file.js.map +1 -0
  61. package/dist/esm/hooks/use-async-callback.js +1 -1
  62. package/dist/esm/hooks/use-async-external-store.js +1 -1
  63. package/dist/esm/hooks/use-strict-memo.js +1 -1
  64. package/dist/esm/interface/admin-metrics.d.ts +4 -4
  65. package/dist/esm/interface/admin-metrics.js.map +1 -1
  66. package/dist/esm/interface/client-interface.js +2 -2
  67. package/dist/esm/interface/client-interface.js.map +1 -1
  68. package/dist/esm/interface/conversations.d.ts +13 -13
  69. package/dist/esm/interface/crud/current-user.d.ts +9 -9
  70. package/dist/esm/interface/crud/email-outbox.d.ts +112 -112
  71. package/dist/esm/interface/crud/products.d.ts +1 -1
  72. package/dist/esm/interface/crud/project-api-keys.d.ts +2 -2
  73. package/dist/esm/interface/crud/project-permissions.js +5 -5
  74. package/dist/esm/interface/crud/project-permissions.js.map +1 -1
  75. package/dist/esm/interface/crud/projects.d.ts +28 -28
  76. package/dist/esm/interface/crud/team-member-profiles.d.ts +22 -22
  77. package/dist/esm/interface/crud/team-permissions.js +5 -5
  78. package/dist/esm/interface/crud/team-permissions.js.map +1 -1
  79. package/dist/esm/interface/crud/users.d.ts +14 -14
  80. package/dist/esm/interface/page-component-versions.js +107 -107
  81. package/dist/esm/interface/page-component-versions.js.map +1 -1
  82. package/dist/esm/interface/webhooks.d.ts +4 -4
  83. package/dist/esm/known-errors.js +4 -4
  84. package/dist/esm/known-errors.js.map +1 -1
  85. package/dist/esm/schema-fields.d.ts +15 -5
  86. package/dist/esm/schema-fields.d.ts.map +1 -1
  87. package/dist/esm/schema-fields.js +26 -16
  88. package/dist/esm/schema-fields.js.map +1 -1
  89. package/dist/esm/utils/crypto.d.ts.map +1 -1
  90. package/dist/esm/utils/crypto.js.map +1 -1
  91. package/dist/esm/utils/currency-constants.d.ts +6 -0
  92. package/dist/esm/utils/currency-constants.d.ts.map +1 -1
  93. package/dist/esm/utils/currency-constants.js.map +1 -1
  94. package/dist/esm/utils/dev-env-state-path.d.ts +3 -3
  95. package/dist/esm/utils/dev-env-state-path.d.ts.map +1 -1
  96. package/dist/esm/utils/dev-env-state-path.js +4 -4
  97. package/dist/esm/utils/dev-env-state-path.js.map +1 -1
  98. package/dist/esm/utils/errors.js +2 -2
  99. package/dist/esm/utils/errors.js.map +1 -1
  100. package/dist/esm/utils/esbuild.d.ts.map +1 -1
  101. package/dist/esm/utils/esbuild.js +0 -1
  102. package/dist/esm/utils/esbuild.js.map +1 -1
  103. package/dist/esm/utils/featurebase.d.ts +3 -3
  104. package/dist/esm/utils/featurebase.d.ts.map +1 -1
  105. package/dist/esm/utils/featurebase.js +15 -15
  106. package/dist/esm/utils/featurebase.js.map +1 -1
  107. package/dist/esm/utils/fs.js +6 -6
  108. package/dist/esm/utils/fs.js.map +1 -1
  109. package/dist/esm/utils/globals.d.ts.map +1 -1
  110. package/dist/esm/utils/globals.js +10 -10
  111. package/dist/esm/utils/globals.js.map +1 -1
  112. package/dist/esm/utils/jwt.d.ts.map +1 -1
  113. package/dist/esm/utils/jwt.js +3 -3
  114. package/dist/esm/utils/jwt.js.map +1 -1
  115. package/dist/esm/utils/redirect-urls.d.ts +3 -3
  116. package/dist/esm/utils/redirect-urls.d.ts.map +1 -1
  117. package/dist/esm/utils/redirect-urls.js +5 -5
  118. package/dist/esm/utils/redirect-urls.js.map +1 -1
  119. package/dist/esm/utils/urls.js.map +1 -1
  120. package/dist/helpers/vault/client-side.d.ts.map +1 -1
  121. package/dist/helpers/vault/client-side.js.map +1 -1
  122. package/dist/helpers/vault/server-side.d.ts.map +1 -1
  123. package/dist/helpers/vault/server-side.js.map +1 -1
  124. package/dist/hexclave-config-file.d.ts +15 -0
  125. package/dist/hexclave-config-file.d.ts.map +1 -0
  126. package/dist/{stack-config-file.js → hexclave-config-file.js} +8 -8
  127. package/dist/hexclave-config-file.js.map +1 -0
  128. package/dist/hooks/use-async-callback.js +1 -1
  129. package/dist/hooks/use-async-external-store.js +1 -1
  130. package/dist/hooks/use-strict-memo.js +1 -1
  131. package/dist/interface/admin-metrics.d.ts +4 -4
  132. package/dist/interface/admin-metrics.js.map +1 -1
  133. package/dist/interface/client-interface.js +2 -2
  134. package/dist/interface/client-interface.js.map +1 -1
  135. package/dist/interface/conversations.d.ts +13 -13
  136. package/dist/interface/crud/current-user.d.ts +9 -9
  137. package/dist/interface/crud/email-outbox.d.ts +112 -112
  138. package/dist/interface/crud/products.d.ts +1 -1
  139. package/dist/interface/crud/project-api-keys.d.ts +2 -2
  140. package/dist/interface/crud/project-permissions.js +5 -5
  141. package/dist/interface/crud/project-permissions.js.map +1 -1
  142. package/dist/interface/crud/projects.d.ts +28 -28
  143. package/dist/interface/crud/team-member-profiles.d.ts +22 -22
  144. package/dist/interface/crud/team-permissions.js +5 -5
  145. package/dist/interface/crud/team-permissions.js.map +1 -1
  146. package/dist/interface/crud/users.d.ts +14 -14
  147. package/dist/interface/page-component-versions.js +107 -107
  148. package/dist/interface/page-component-versions.js.map +1 -1
  149. package/dist/interface/webhooks.d.ts +4 -4
  150. package/dist/known-errors.js +4 -4
  151. package/dist/known-errors.js.map +1 -1
  152. package/dist/schema-fields.d.ts +15 -5
  153. package/dist/schema-fields.d.ts.map +1 -1
  154. package/dist/schema-fields.js +26 -16
  155. package/dist/schema-fields.js.map +1 -1
  156. package/dist/utils/crypto.d.ts.map +1 -1
  157. package/dist/utils/crypto.js.map +1 -1
  158. package/dist/utils/currency-constants.d.ts +6 -0
  159. package/dist/utils/currency-constants.d.ts.map +1 -1
  160. package/dist/utils/currency-constants.js.map +1 -1
  161. package/dist/utils/dev-env-state-path.d.ts +3 -3
  162. package/dist/utils/dev-env-state-path.d.ts.map +1 -1
  163. package/dist/utils/dev-env-state-path.js +5 -5
  164. package/dist/utils/dev-env-state-path.js.map +1 -1
  165. package/dist/utils/errors.js +2 -2
  166. package/dist/utils/errors.js.map +1 -1
  167. package/dist/utils/esbuild.d.ts.map +1 -1
  168. package/dist/utils/esbuild.js +0 -1
  169. package/dist/utils/esbuild.js.map +1 -1
  170. package/dist/utils/featurebase.d.ts +3 -3
  171. package/dist/utils/featurebase.d.ts.map +1 -1
  172. package/dist/utils/featurebase.js +15 -15
  173. package/dist/utils/featurebase.js.map +1 -1
  174. package/dist/utils/fs.js.map +1 -1
  175. package/dist/utils/globals.d.ts.map +1 -1
  176. package/dist/utils/globals.js +10 -10
  177. package/dist/utils/globals.js.map +1 -1
  178. package/dist/utils/jwt.d.ts.map +1 -1
  179. package/dist/utils/jwt.js +3 -3
  180. package/dist/utils/jwt.js.map +1 -1
  181. package/dist/utils/redirect-urls.d.ts +3 -3
  182. package/dist/utils/redirect-urls.d.ts.map +1 -1
  183. package/dist/utils/redirect-urls.js +5 -5
  184. package/dist/utils/redirect-urls.js.map +1 -1
  185. package/dist/utils/urls.js.map +1 -1
  186. package/package.json +2 -1
  187. package/src/ai/image-limits.ts +62 -0
  188. package/src/ai/llms/llms.ts +36 -0
  189. package/src/ai/unified-prompts/reminders.ts +27 -0
  190. package/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts +1047 -0
  191. package/src/ai/unified-prompts/skill-site-prompt-parts/brain.ts +5 -0
  192. package/src/ai/unified-prompts/skill-site-prompt-parts/cli-help.ts +5 -0
  193. package/src/ai/unified-prompts/skill-site-prompt-parts/config-docs.ts +5 -0
  194. package/src/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.ts +5 -0
  195. package/src/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.ts +5 -0
  196. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-index.ts +80 -0
  197. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.ts +322 -0
  198. package/src/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.ts +5 -0
  199. package/src/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.ts +5 -0
  200. package/src/ai/unified-prompts/skill-site-prompt.ts +72 -0
  201. package/src/apps/apps-config.ts +177 -0
  202. package/src/apps/apps-ui.tsx +112 -0
  203. package/src/config/README.md +154 -0
  204. package/src/config/db-sync-mappings.ts +2293 -0
  205. package/src/config/format.ts +388 -0
  206. package/src/config/migrate-catalogs-to-product-lines.ts +475 -0
  207. package/src/config/schema-fuzzer.test.ts +377 -0
  208. package/src/config/schema.ts +1507 -0
  209. package/src/config-authoring.test.ts +52 -0
  210. package/src/config-authoring.ts +37 -0
  211. package/src/config-rendering.ts +142 -0
  212. package/src/crud.tsx +275 -0
  213. package/src/global.d.ts +1 -0
  214. package/src/helpers/emails.ts +250 -0
  215. package/src/helpers/init-prompt.ts +39 -0
  216. package/src/helpers/password.ts +16 -0
  217. package/src/helpers/production-mode.ts +58 -0
  218. package/src/helpers/support-sla.test.ts +124 -0
  219. package/src/helpers/support-sla.ts +93 -0
  220. package/src/helpers/vault/client-side.ts +92 -0
  221. package/src/helpers/vault/server-side.ts +153 -0
  222. package/src/hexclave-config-file.ts +120 -0
  223. package/src/hooks/use-async-callback.tsx +43 -0
  224. package/src/hooks/use-async-external-store.tsx +24 -0
  225. package/src/hooks/use-hash.tsx +14 -0
  226. package/src/hooks/use-hover.tsx +88 -0
  227. package/src/hooks/use-strict-memo.tsx +157 -0
  228. package/src/index.ts +17 -0
  229. package/src/interface/admin-interface.ts +1043 -0
  230. package/src/interface/admin-metrics.ts +214 -0
  231. package/src/interface/client-interface.test.ts +765 -0
  232. package/src/interface/client-interface.ts +2586 -0
  233. package/src/interface/conversations.ts +109 -0
  234. package/src/interface/crud/analytics.ts +11 -0
  235. package/src/interface/crud/connected-accounts.ts +52 -0
  236. package/src/interface/crud/contact-channels.ts +74 -0
  237. package/src/interface/crud/current-user.ts +72 -0
  238. package/src/interface/crud/email-outbox.ts +263 -0
  239. package/src/interface/crud/email-templates.ts +50 -0
  240. package/src/interface/crud/emails.ts +22 -0
  241. package/src/interface/crud/internal-api-keys.ts +69 -0
  242. package/src/interface/crud/invoices.ts +36 -0
  243. package/src/interface/crud/items.ts +24 -0
  244. package/src/interface/crud/notification-preferences.ts +33 -0
  245. package/src/interface/crud/oauth-providers.ts +91 -0
  246. package/src/interface/crud/products.ts +42 -0
  247. package/src/interface/crud/project-api-keys.ts +100 -0
  248. package/src/interface/crud/project-permissions.ts +118 -0
  249. package/src/interface/crud/projects.ts +229 -0
  250. package/src/interface/crud/session-replays.ts +85 -0
  251. package/src/interface/crud/sessions.ts +66 -0
  252. package/src/interface/crud/sign-up-rules.ts +12 -0
  253. package/src/interface/crud/svix-token.ts +20 -0
  254. package/src/interface/crud/team-invitation-details.ts +22 -0
  255. package/src/interface/crud/team-invitation.ts +35 -0
  256. package/src/interface/crud/team-member-profiles.ts +61 -0
  257. package/src/interface/crud/team-memberships.ts +56 -0
  258. package/src/interface/crud/team-permissions.ts +119 -0
  259. package/src/interface/crud/teams.ts +142 -0
  260. package/src/interface/crud/transactions.ts +131 -0
  261. package/src/interface/crud/users.ts +185 -0
  262. package/src/interface/handler-urls.ts +74 -0
  263. package/src/interface/page-component-versions.ts +1702 -0
  264. package/src/interface/server-interface.ts +1146 -0
  265. package/src/interface/webhooks.ts +28 -0
  266. package/src/known-errors.tsx +2031 -0
  267. package/src/local-emulator.ts +5 -0
  268. package/src/payments/payment-methods.ts +167 -0
  269. package/src/payments/stripe-limits.ts +18 -0
  270. package/src/plans.ts +107 -0
  271. package/src/schema-fields.ts +944 -0
  272. package/src/sessions.ts +310 -0
  273. package/src/utils/api-keys.tsx +122 -0
  274. package/src/utils/arrays.tsx +248 -0
  275. package/src/utils/auth-methods.ts +8 -0
  276. package/src/utils/base64.tsx +24 -0
  277. package/src/utils/booleans.tsx +34 -0
  278. package/src/utils/browser-compat.tsx +17 -0
  279. package/src/utils/bytes.tsx +280 -0
  280. package/src/utils/caches.tsx +280 -0
  281. package/src/utils/cel-fields.ts +92 -0
  282. package/src/utils/cloud-hosts.tsx +92 -0
  283. package/src/utils/compile-time.tsx +11 -0
  284. package/src/utils/country-codes.ts +39 -0
  285. package/src/utils/crypto.tsx +174 -0
  286. package/src/utils/currencies.tsx +53 -0
  287. package/src/utils/currency-constants.tsx +51 -0
  288. package/src/utils/dates.tsx +246 -0
  289. package/src/utils/dev-env-state-path.ts +14 -0
  290. package/src/utils/dom.tsx +7 -0
  291. package/src/utils/env.tsx +117 -0
  292. package/src/utils/errors.tsx +284 -0
  293. package/src/utils/esbuild.tsx +235 -0
  294. package/src/utils/featurebase.tsx +247 -0
  295. package/src/utils/fs.tsx +33 -0
  296. package/src/utils/functions.tsx +22 -0
  297. package/src/utils/geo.tsx +16 -0
  298. package/src/utils/globals.tsx +48 -0
  299. package/src/utils/hashes.tsx +52 -0
  300. package/src/utils/html.tsx +60 -0
  301. package/src/utils/http.tsx +91 -0
  302. package/src/utils/ips.tsx +47 -0
  303. package/src/utils/json.tsx +200 -0
  304. package/src/utils/jsx-editable-transpiler.test.ts +156 -0
  305. package/src/utils/jsx-editable-transpiler.tsx +401 -0
  306. package/src/utils/jwt.tsx +170 -0
  307. package/src/utils/locks.tsx +71 -0
  308. package/src/utils/maps.tsx +407 -0
  309. package/src/utils/math.tsx +18 -0
  310. package/src/utils/monkey-patch.tsx +29 -0
  311. package/src/utils/node-http.tsx +47 -0
  312. package/src/utils/numbers.tsx +82 -0
  313. package/src/utils/oauth.tsx +9 -0
  314. package/src/utils/objects.tsx +581 -0
  315. package/src/utils/paginated-lists.test.ts +1039 -0
  316. package/src/utils/paginated-lists.tsx +479 -0
  317. package/src/utils/passkey.tsx +1 -0
  318. package/src/utils/promises.tsx +540 -0
  319. package/src/utils/proxies.tsx +212 -0
  320. package/src/utils/react.tsx +308 -0
  321. package/src/utils/redirect-urls.tsx +299 -0
  322. package/src/utils/regex.tsx +10 -0
  323. package/src/utils/results.tsx +411 -0
  324. package/src/utils/sentry.tsx +20 -0
  325. package/src/utils/stores.tsx +238 -0
  326. package/src/utils/strings.nicify.test.ts +253 -0
  327. package/src/utils/strings.tsx +723 -0
  328. package/src/utils/telemetry.tsx +37 -0
  329. package/src/utils/turnstile-browser.ts +106 -0
  330. package/src/utils/turnstile-flow.test.ts +101 -0
  331. package/src/utils/turnstile-flow.ts +266 -0
  332. package/src/utils/turnstile.ts +34 -0
  333. package/src/utils/typed-arrays.tsx +17 -0
  334. package/src/utils/types.tsx +208 -0
  335. package/src/utils/unicode.tsx +24 -0
  336. package/src/utils/urls.tsx +411 -0
  337. package/src/utils/uuids.tsx +47 -0
  338. package/dist/esm/stack-config-file.d.ts +0 -15
  339. package/dist/esm/stack-config-file.d.ts.map +0 -1
  340. package/dist/esm/stack-config-file.js.map +0 -1
  341. package/dist/stack-config-file.d.ts +0 -15
  342. package/dist/stack-config-file.d.ts.map +0 -1
  343. package/dist/stack-config-file.js.map +0 -1
@@ -0,0 +1,109 @@
1
+ import * as yup from "yup";
2
+ import { yupArray, yupBoolean, yupMixed, yupObject, yupString } from "../schema-fields";
3
+
4
+ export const conversationStatusValues = ["open", "pending", "closed"] as const;
5
+ export type ConversationStatus = (typeof conversationStatusValues)[number];
6
+
7
+ export const conversationPriorityValues = ["low", "normal", "high", "urgent"] as const;
8
+ export type ConversationPriority = (typeof conversationPriorityValues)[number];
9
+
10
+ export const conversationSourceValues = ["manual", "chat", "email", "api"] as const;
11
+ export type ConversationSource = (typeof conversationSourceValues)[number];
12
+
13
+ export const conversationSenderTypeValues = ["user", "agent", "system"] as const;
14
+ export type ConversationSenderType = (typeof conversationSenderTypeValues)[number];
15
+
16
+ export const conversationMessageTypeValues = ["message", "internal-note", "status-change"] as const;
17
+ export type ConversationMessageType = (typeof conversationMessageTypeValues)[number];
18
+
19
+ export const conversationMetadataSchema = yupObject({
20
+ assignedToUserId: yupString().nullable().defined(),
21
+ assignedToDisplayName: yupString().nullable().defined(),
22
+ tags: yupArray(yupString().defined()).defined(),
23
+ firstResponseDueAt: yupString().nullable().defined(),
24
+ firstResponseAt: yupString().nullable().defined(),
25
+ nextResponseDueAt: yupString().nullable().defined(),
26
+ lastCustomerReplyAt: yupString().nullable().defined(),
27
+ lastAgentReplyAt: yupString().nullable().defined(),
28
+ });
29
+
30
+ export const conversationSenderSchema = yupObject({
31
+ type: yupString().oneOf(conversationSenderTypeValues).defined(),
32
+ id: yupString().nullable().defined(),
33
+ displayName: yupString().nullable().defined(),
34
+ primaryEmail: yupString().nullable().defined(),
35
+ });
36
+
37
+ export const conversationSummarySchema = yupObject({
38
+ conversationId: yupString().uuid().defined(),
39
+ userId: yupString().uuid().nullable().defined(),
40
+ teamId: yupString().uuid().nullable().defined(),
41
+ userDisplayName: yupString().nullable().defined(),
42
+ userPrimaryEmail: yupString().nullable().defined(),
43
+ userProfileImageUrl: yupString().nullable().defined(),
44
+ subject: yupString().defined(),
45
+ status: yupString().oneOf(conversationStatusValues).defined(),
46
+ priority: yupString().oneOf(conversationPriorityValues).defined(),
47
+ source: yupString().oneOf(conversationSourceValues).defined(),
48
+ lastMessageType: yupString().oneOf(conversationMessageTypeValues).defined(),
49
+ preview: yupString().nullable().defined(),
50
+ lastActivityAt: yupString().defined(),
51
+ metadata: conversationMetadataSchema.defined(),
52
+ createdAt: yupString().optional(),
53
+ updatedAt: yupString().optional(),
54
+ lastMessageAt: yupString().optional(),
55
+ lastInboundAt: yupString().nullable().optional(),
56
+ lastOutboundAt: yupString().nullable().optional(),
57
+ closedAt: yupString().nullable().optional(),
58
+ recordMetadata: yupMixed().nullable().optional(),
59
+ });
60
+
61
+ export const conversationEntryPointSchema = yupObject({
62
+ id: yupString().uuid().defined(),
63
+ channelType: yupString().defined(),
64
+ adapterKey: yupString().defined(),
65
+ externalChannelId: yupString().nullable().defined(),
66
+ isEntryPoint: yupBoolean().defined(),
67
+ metadata: yupMixed().nullable().defined(),
68
+ createdAt: yupString().defined(),
69
+ updatedAt: yupString().defined(),
70
+ });
71
+
72
+ // Message detail responses include parent conversation context for clients.
73
+ // `subject`, `status`, `priority`, and `source` are populated from the parent
74
+ // Conversation by the backend mapper; they are not stored on ConversationMessage.
75
+ export const conversationMessageSchema = yupObject({
76
+ id: yupString().uuid().defined(),
77
+ conversationId: yupString().uuid().defined(),
78
+ userId: yupString().uuid().nullable().defined(),
79
+ teamId: yupString().uuid().nullable().defined(),
80
+ subject: yupString().defined(),
81
+ status: yupString().oneOf(conversationStatusValues).defined(),
82
+ priority: yupString().oneOf(conversationPriorityValues).defined(),
83
+ source: yupString().oneOf(conversationSourceValues).defined(),
84
+ messageType: yupString().oneOf(conversationMessageTypeValues).defined(),
85
+ body: yupString().nullable().defined(),
86
+ attachments: yupArray(yupMixed().defined()).defined(),
87
+ metadata: yupMixed().nullable().defined(),
88
+ createdAt: yupString().defined(),
89
+ sender: conversationSenderSchema.defined(),
90
+ });
91
+
92
+ export const conversationListResponseSchema = yupObject({
93
+ conversations: yupArray(conversationSummarySchema.defined()).defined(),
94
+ hasMore: yupBoolean().defined(),
95
+ });
96
+
97
+ export const conversationDetailResponseSchema = yupObject({
98
+ conversation: conversationSummarySchema.defined(),
99
+ messages: yupArray(conversationMessageSchema.defined()).defined(),
100
+ entryPoints: yupArray(conversationEntryPointSchema.defined()).defined(),
101
+ });
102
+
103
+ export type ConversationMetadata = yup.InferType<typeof conversationMetadataSchema>;
104
+ export type ConversationSender = yup.InferType<typeof conversationSenderSchema>;
105
+ export type ConversationSummary = yup.InferType<typeof conversationSummarySchema>;
106
+ export type ConversationMessage = yup.InferType<typeof conversationMessageSchema>;
107
+ export type ConversationListResponse = yup.InferType<typeof conversationListResponseSchema>;
108
+ export type ConversationEntryPoint = yup.InferType<typeof conversationEntryPointSchema>;
109
+ export type ConversationDetailResponse = yup.InferType<typeof conversationDetailResponseSchema>;
@@ -0,0 +1,11 @@
1
+ export type AnalyticsQueryOptions = {
2
+ query: string,
3
+ params?: Record<string, unknown>,
4
+ timeout_ms?: number,
5
+ include_all_branches?: boolean,
6
+ };
7
+
8
+ export type AnalyticsQueryResponse = {
9
+ result: Record<string, unknown>[],
10
+ query_id: string,
11
+ };
@@ -0,0 +1,52 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import {
3
+ oauthProviderAccountIdSchema,
4
+ oauthProviderProviderConfigIdSchema,
5
+ userIdOrMeSchema,
6
+ yupObject,
7
+ yupString
8
+ } from "../../schema-fields";
9
+
10
+ // Connected Account CRUD (for listing/reading connected accounts)
11
+ export const connectedAccountClientReadSchema = yupObject({
12
+ user_id: userIdOrMeSchema.defined(),
13
+ provider: oauthProviderProviderConfigIdSchema.defined(),
14
+ provider_account_id: oauthProviderAccountIdSchema.defined(),
15
+ }).defined();
16
+
17
+ export const connectedAccountCrud = createCrud({
18
+ clientReadSchema: connectedAccountClientReadSchema,
19
+ docs: {
20
+ clientRead: {
21
+ summary: "Get a connected account",
22
+ description: "Retrieves a specific connected account by the user ID and provider account ID.",
23
+ tags: ["Connected Accounts"],
24
+ },
25
+ clientList: {
26
+ summary: "List connected accounts",
27
+ description: "Retrieves a list of all connected accounts for a user.",
28
+ tags: ["Connected Accounts"],
29
+ },
30
+ },
31
+ });
32
+ export type ConnectedAccountCrud = CrudTypeOf<typeof connectedAccountCrud>;
33
+
34
+ // Connected Account Access Token CRUD (for getting access tokens)
35
+ export const connectedAccountAccessTokenReadSchema = yupObject({
36
+ access_token: yupString().defined(),
37
+ }).defined();
38
+
39
+ export const connectedAccountAccessTokenCreateSchema = yupObject({
40
+ scope: yupString().optional(),
41
+ }).defined();
42
+
43
+ export const connectedAccountAccessTokenCrud = createCrud({
44
+ clientReadSchema: connectedAccountAccessTokenReadSchema,
45
+ clientCreateSchema: connectedAccountAccessTokenCreateSchema,
46
+ docs: {
47
+ clientCreate: {
48
+ hidden: true,
49
+ }
50
+ },
51
+ });
52
+ export type ConnectedAccountAccessTokenCrud = CrudTypeOf<typeof connectedAccountAccessTokenCrud>;
@@ -0,0 +1,74 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import { contactChannelIdSchema, contactChannelIsPrimarySchema, contactChannelIsVerifiedSchema, contactChannelTypeSchema, contactChannelUsedForAuthSchema, contactChannelValueSchema, userIdOrMeSchema, userIdSchema, yupMixed, yupObject } from "../../schema-fields";
3
+
4
+ export const contactChannelsClientReadSchema = yupObject({
5
+ user_id: userIdSchema.defined(),
6
+ id: contactChannelIdSchema.defined(),
7
+ value: contactChannelValueSchema.defined(),
8
+ type: contactChannelTypeSchema.defined(),
9
+ used_for_auth: contactChannelUsedForAuthSchema.defined(),
10
+ is_verified: contactChannelIsVerifiedSchema.defined(),
11
+ is_primary: contactChannelIsPrimarySchema.defined(),
12
+ }).defined();
13
+
14
+ export const contactChannelsCrudClientUpdateSchema = yupObject({
15
+ value: contactChannelValueSchema.optional(),
16
+ type: contactChannelTypeSchema.optional(),
17
+ used_for_auth: contactChannelUsedForAuthSchema.optional(),
18
+ is_primary: contactChannelIsPrimarySchema.optional(),
19
+ }).defined();
20
+
21
+ export const contactChannelsCrudServerUpdateSchema = contactChannelsCrudClientUpdateSchema.concat(yupObject({
22
+ is_verified: contactChannelIsVerifiedSchema.optional(),
23
+ }));
24
+
25
+ export const contactChannelsCrudClientCreateSchema = yupObject({
26
+ user_id: userIdOrMeSchema.defined(),
27
+ value: contactChannelValueSchema.defined(),
28
+ type: contactChannelTypeSchema.defined(),
29
+ used_for_auth: contactChannelUsedForAuthSchema.defined(),
30
+ is_primary: contactChannelIsPrimarySchema.optional(),
31
+ }).defined();
32
+
33
+ export const contactChannelsCrudServerCreateSchema = contactChannelsCrudClientCreateSchema.concat(yupObject({
34
+ is_verified: contactChannelIsVerifiedSchema.optional(),
35
+ }));
36
+
37
+ export const contactChannelsCrudClientDeleteSchema = yupMixed();
38
+
39
+ export const contactChannelsCrud = createCrud({
40
+ clientReadSchema: contactChannelsClientReadSchema,
41
+ clientUpdateSchema: contactChannelsCrudClientUpdateSchema,
42
+ clientCreateSchema: contactChannelsCrudClientCreateSchema,
43
+ clientDeleteSchema: contactChannelsCrudClientDeleteSchema,
44
+ serverUpdateSchema: contactChannelsCrudServerUpdateSchema,
45
+ serverCreateSchema: contactChannelsCrudServerCreateSchema,
46
+ docs: {
47
+ clientRead: {
48
+ summary: "Get a contact channel",
49
+ description: "Retrieves a specific contact channel by the user ID and the contact channel ID.",
50
+ tags: ["Contact Channels"],
51
+ },
52
+ clientCreate: {
53
+ summary: "Create a contact channel",
54
+ description: "Add a new contact channel for a user.",
55
+ tags: ["Contact Channels"],
56
+ },
57
+ clientUpdate: {
58
+ summary: "Update a contact channel",
59
+ description: "Updates an existing contact channel. Only the values provided will be updated.",
60
+ tags: ["Contact Channels"],
61
+ },
62
+ clientDelete: {
63
+ summary: "Delete a contact channel",
64
+ description: "Removes a contact channel for a given user.",
65
+ tags: ["Contact Channels"],
66
+ },
67
+ clientList: {
68
+ summary: "List contact channels",
69
+ description: "Retrieves a list of all contact channels for a user.",
70
+ tags: ["Contact Channels"],
71
+ }
72
+ }
73
+ });
74
+ export type ContactChannelsCrud = CrudTypeOf<typeof contactChannelsCrud>;
@@ -0,0 +1,72 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import { yupObject } from "../../schema-fields";
3
+ import { teamsCrudClientReadSchema } from "./teams";
4
+ import { usersCrudServerDeleteSchema, usersCrudServerReadSchema, usersCrudServerUpdateSchema } from "./users";
5
+
6
+ const clientUpdateSchema = usersCrudServerUpdateSchema.pick([
7
+ "display_name",
8
+ "profile_image_url",
9
+ "client_metadata",
10
+ "selected_team_id",
11
+ "totp_secret_base64",
12
+ "otp_auth_enabled",
13
+ "passkey_auth_enabled",
14
+ "primary_email",
15
+ ]).defined();
16
+
17
+ const serverUpdateSchema = usersCrudServerUpdateSchema;
18
+
19
+ const clientReadSchema = usersCrudServerReadSchema.pick([
20
+ "id",
21
+ "primary_email",
22
+ "primary_email_verified",
23
+ "display_name",
24
+ "client_metadata",
25
+ "client_read_only_metadata",
26
+ "profile_image_url",
27
+ "signed_up_at_millis",
28
+ "has_password",
29
+ "auth_with_email",
30
+ "oauth_providers",
31
+ "selected_team_id",
32
+ "requires_totp_mfa",
33
+ "otp_auth_enabled",
34
+ "passkey_auth_enabled",
35
+ "is_anonymous",
36
+ "is_restricted",
37
+ "restricted_reason",
38
+ "restricted_by_admin",
39
+ "restricted_by_admin_reason",
40
+ ]).concat(yupObject({
41
+ selected_team: teamsCrudClientReadSchema.nullable().defined(),
42
+ })).defined();
43
+
44
+ const serverReadSchema = usersCrudServerReadSchema.defined();
45
+
46
+ const clientDeleteSchema = usersCrudServerDeleteSchema;
47
+
48
+ export const currentUserCrud = createCrud({
49
+ clientReadSchema,
50
+ serverReadSchema,
51
+ clientUpdateSchema,
52
+ serverUpdateSchema,
53
+ clientDeleteSchema,
54
+ docs: {
55
+ clientRead: {
56
+ summary: 'Get current user',
57
+ description: 'Gets the currently authenticated user.',
58
+ tags: ['Users'],
59
+ },
60
+ clientUpdate: {
61
+ summary: 'Update current user',
62
+ description: 'Updates the currently authenticated user. Only the values provided will be updated.',
63
+ tags: ['Users'],
64
+ },
65
+ clientDelete: {
66
+ summary: 'Delete current user',
67
+ description: 'Deletes the currently authenticated user. Use this with caution.',
68
+ tags: ['Users'],
69
+ },
70
+ },
71
+ });
72
+ export type CurrentUserCrud = CrudTypeOf<typeof currentUserCrud>;
@@ -0,0 +1,263 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import * as fieldSchema from "../../schema-fields";
3
+
4
+
5
+ // Recipient types
6
+ const recipientUserPrimaryEmailSchema = fieldSchema.yupObject({
7
+ type: fieldSchema.yupString().oneOf(["user-primary-email"]).defined(),
8
+ user_id: fieldSchema.yupString().defined(),
9
+ }).defined();
10
+
11
+ const recipientUserCustomEmailsSchema = fieldSchema.yupObject({
12
+ type: fieldSchema.yupString().oneOf(["user-custom-emails"]).defined(),
13
+ user_id: fieldSchema.yupString().defined(),
14
+ emails: fieldSchema.yupArray(fieldSchema.yupString().defined()).defined(),
15
+ }).defined();
16
+
17
+ const recipientCustomEmailsSchema = fieldSchema.yupObject({
18
+ type: fieldSchema.yupString().oneOf(["custom-emails"]).defined(),
19
+ emails: fieldSchema.yupArray(fieldSchema.yupString().defined()).defined(),
20
+ }).defined();
21
+
22
+ const recipientSchema = fieldSchema.yupUnion(
23
+ recipientUserPrimaryEmailSchema,
24
+ recipientUserCustomEmailsSchema,
25
+ recipientCustomEmailsSchema
26
+ );
27
+
28
+
29
+ // =============================== BASE FIELDS ===============================
30
+
31
+ // Base fields present on all emails
32
+ const emailOutboxBaseSchema = fieldSchema.yupObject({
33
+ id: fieldSchema.yupString().defined(),
34
+ created_at_millis: fieldSchema.yupNumber().defined(),
35
+ updated_at_millis: fieldSchema.yupNumber().defined(),
36
+ tsx_source: fieldSchema.yupString().defined(),
37
+ theme_id: fieldSchema.yupString().nullable().defined(),
38
+ to: recipientSchema.defined(),
39
+ variables: fieldSchema.yupRecord(fieldSchema.yupString(), fieldSchema.jsonSchema).defined(),
40
+ skip_deliverability_check: fieldSchema.yupBoolean().defined(),
41
+ scheduled_at_millis: fieldSchema.yupNumber().defined(),
42
+
43
+
44
+ // Source tracking for grouping emails by template/draft
45
+ created_with: fieldSchema.yupString().oneOf(["draft", "programmatic-call"]).defined(),
46
+ email_draft_id: fieldSchema.yupString().nullable().defined(),
47
+ email_programmatic_call_template_id: fieldSchema.yupString().nullable().defined(),
48
+
49
+ // Retry-related fields (for debugging/testing deferred retry logic)
50
+ send_retries: fieldSchema.yupNumber().defined(),
51
+ next_send_retry_at_millis: fieldSchema.yupNumber().nullable().defined(),
52
+ // Array of errors from each failed send attempt, each with internal/external messages
53
+ send_attempt_errors: fieldSchema.yupArray(fieldSchema.yupObject({
54
+ attempt_number: fieldSchema.yupNumber().defined(),
55
+ timestamp: fieldSchema.yupString().defined(),
56
+ external_message: fieldSchema.yupString().defined(),
57
+ external_details: fieldSchema.yupRecord(fieldSchema.yupString(), fieldSchema.jsonSchema).defined(),
58
+ internal_message: fieldSchema.yupString().defined(),
59
+ internal_details: fieldSchema.yupRecord(fieldSchema.yupString(), fieldSchema.jsonSchema).defined(),
60
+ }).defined()).nullable().defined(),
61
+
62
+ status: fieldSchema.yupString().defined(),
63
+ simple_status: fieldSchema.yupString().defined(),
64
+
65
+ // These fields are overridden because we use concat to build the final schema for each state
66
+ is_paused: fieldSchema.yupBoolean().oneOf([false]).defined(),
67
+ has_rendered: fieldSchema.yupBoolean().oneOf([false]).defined(),
68
+ has_delivered: fieldSchema.yupBoolean().oneOf([false]).defined(),
69
+ }).defined();
70
+
71
+ // Rendered output fields
72
+ const renderedFieldsSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
73
+ started_rendering_at_millis: fieldSchema.yupNumber().defined(),
74
+ rendered_at_millis: fieldSchema.yupNumber().defined(),
75
+ subject: fieldSchema.yupString().defined(),
76
+ html: fieldSchema.yupString().nullable().defined(),
77
+ text: fieldSchema.yupString().nullable().defined(),
78
+ is_transactional: fieldSchema.yupBoolean().defined(),
79
+ is_high_priority: fieldSchema.yupBoolean().defined(),
80
+ notification_category_id: fieldSchema.yupString().nullable().defined(),
81
+ has_rendered: fieldSchema.yupBoolean().oneOf([true]).defined(),
82
+ }).defined());
83
+
84
+ const startedSendingFieldsSchema = renderedFieldsSchema.concat(fieldSchema.yupObject({
85
+ started_sending_at_millis: fieldSchema.yupNumber().defined(),
86
+ }).defined());
87
+
88
+ // Finished delivering tracking fields
89
+ const finishedDeliveringFieldsSchema = startedSendingFieldsSchema.concat(fieldSchema.yupObject({
90
+ delivered_at_millis: fieldSchema.yupNumber().defined(),
91
+ has_delivered: fieldSchema.yupBoolean().oneOf([true]).defined(),
92
+ }).defined());
93
+
94
+
95
+ // =============================== STATUS-SPECIFIC SCHEMAS ===============================
96
+
97
+ const pausedStatusSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
98
+ status: fieldSchema.yupString().oneOf(["paused"]).defined(),
99
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
100
+ is_paused: fieldSchema.yupBoolean().oneOf([true]).defined(),
101
+ }).defined());
102
+
103
+ const preparingStatusSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
104
+ status: fieldSchema.yupString().oneOf(["preparing"]).defined(),
105
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
106
+ }).defined());
107
+
108
+ const renderingStatusSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
109
+ status: fieldSchema.yupString().oneOf(["rendering"]).defined(),
110
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
111
+ started_rendering_at_millis: fieldSchema.yupNumber().defined(),
112
+ }).defined());
113
+
114
+ const renderErrorStatusSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
115
+ status: fieldSchema.yupString().oneOf(["render-error"]).defined(),
116
+ simple_status: fieldSchema.yupString().oneOf(["error"]).defined(),
117
+ started_rendering_at_millis: fieldSchema.yupNumber().defined(),
118
+ rendered_at_millis: fieldSchema.yupNumber().defined(),
119
+ render_error: fieldSchema.yupString().defined(),
120
+ }).defined());
121
+
122
+ const scheduledStatusSchema = renderedFieldsSchema.concat(fieldSchema.yupObject({
123
+ status: fieldSchema.yupString().oneOf(["scheduled"]).defined(),
124
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
125
+ has_rendered: fieldSchema.yupBoolean().oneOf([true]).defined(),
126
+ }).defined());
127
+
128
+ const queuedStatusSchema = renderedFieldsSchema.concat(fieldSchema.yupObject({
129
+ status: fieldSchema.yupString().oneOf(["queued"]).defined(),
130
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
131
+ has_rendered: fieldSchema.yupBoolean().oneOf([true]).defined(),
132
+ }).defined());
133
+
134
+ const sendingStatusSchema = startedSendingFieldsSchema.concat(fieldSchema.yupObject({
135
+ status: fieldSchema.yupString().oneOf(["sending"]).defined(),
136
+ simple_status: fieldSchema.yupString().oneOf(["in-progress"]).defined(),
137
+ }).defined());
138
+
139
+ const serverErrorStatusSchema = startedSendingFieldsSchema.concat(fieldSchema.yupObject({
140
+ status: fieldSchema.yupString().oneOf(["server-error"]).defined(),
141
+ simple_status: fieldSchema.yupString().oneOf(["error"]).defined(),
142
+ error_at_millis: fieldSchema.yupNumber().defined(),
143
+ server_error: fieldSchema.yupString().defined(),
144
+ }).defined());
145
+
146
+ // SKIPPED can happen at any time in the lifecycle (like PAUSED)
147
+ // An email can be skipped before rendering (has_rendered: false) or after rendering (has_rendered: true)
148
+ // e.g., user deleted after the email was rendered but before it was sent
149
+ const skippedStatusSchema = emailOutboxBaseSchema.concat(fieldSchema.yupObject({
150
+ status: fieldSchema.yupString().oneOf(["skipped"]).defined(),
151
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
152
+ skipped_at_millis: fieldSchema.yupNumber().defined(),
153
+ skipped_reason: fieldSchema.yupString().defined(),
154
+ skipped_details: fieldSchema.yupRecord(fieldSchema.yupString(), fieldSchema.jsonSchema).defined(),
155
+ // Override has_rendered to allow both true and false since email can be skipped at any time
156
+ has_rendered: fieldSchema.yupBoolean().defined(),
157
+ // These fields may or may not be present depending on when the email was skipped
158
+ started_rendering_at_millis: fieldSchema.yupNumber().optional(),
159
+ rendered_at_millis: fieldSchema.yupNumber().optional(),
160
+ subject: fieldSchema.yupString().optional(),
161
+ html: fieldSchema.yupString().nullable().optional(),
162
+ text: fieldSchema.yupString().nullable().optional(),
163
+ is_transactional: fieldSchema.yupBoolean().optional(),
164
+ is_high_priority: fieldSchema.yupBoolean().optional(),
165
+ notification_category_id: fieldSchema.yupString().nullable().optional(),
166
+ started_sending_at_millis: fieldSchema.yupNumber().optional(),
167
+ }).defined());
168
+
169
+ const bouncedStatusSchema = startedSendingFieldsSchema.concat(fieldSchema.yupObject({
170
+ status: fieldSchema.yupString().oneOf(["bounced"]).defined(),
171
+ simple_status: fieldSchema.yupString().oneOf(["error"]).defined(),
172
+ bounced_at_millis: fieldSchema.yupNumber().defined(),
173
+ }).defined());
174
+
175
+ const deliveryDelayedStatusSchema = startedSendingFieldsSchema.concat(fieldSchema.yupObject({
176
+ status: fieldSchema.yupString().oneOf(["delivery-delayed"]).defined(),
177
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
178
+ delivery_delayed_at_millis: fieldSchema.yupNumber().defined(),
179
+ }).defined());
180
+
181
+ const sentStatusSchema = finishedDeliveringFieldsSchema.concat(fieldSchema.yupObject({
182
+ status: fieldSchema.yupString().oneOf(["sent"]).defined(),
183
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
184
+ // Whether this email's provider supports delivery tracking (opens, clicks, etc.)
185
+ can_have_delivery_info: fieldSchema.yupBoolean().defined(),
186
+ }).defined());
187
+
188
+ const openedStatusSchema = finishedDeliveringFieldsSchema.concat(fieldSchema.yupObject({
189
+ status: fieldSchema.yupString().oneOf(["opened"]).defined(),
190
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
191
+ opened_at_millis: fieldSchema.yupNumber().defined(),
192
+ can_have_delivery_info: fieldSchema.yupBoolean().oneOf([true]).defined(),
193
+ }).defined());
194
+
195
+ const clickedStatusSchema = finishedDeliveringFieldsSchema.concat(fieldSchema.yupObject({
196
+ status: fieldSchema.yupString().oneOf(["clicked"]).defined(),
197
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
198
+ clicked_at_millis: fieldSchema.yupNumber().defined(),
199
+ can_have_delivery_info: fieldSchema.yupBoolean().oneOf([true]).defined(),
200
+ }).defined());
201
+
202
+ const markedAsSpamStatusSchema = finishedDeliveringFieldsSchema.concat(fieldSchema.yupObject({
203
+ status: fieldSchema.yupString().oneOf(["marked-as-spam"]).defined(),
204
+ simple_status: fieldSchema.yupString().oneOf(["ok"]).defined(),
205
+ marked_as_spam_at_millis: fieldSchema.yupNumber().defined(),
206
+ can_have_delivery_info: fieldSchema.yupBoolean().oneOf([true]).defined(),
207
+ }).defined());
208
+
209
+ // Combined read schema using union
210
+ export const emailOutboxReadSchema = fieldSchema.yupUnion(
211
+ pausedStatusSchema,
212
+ preparingStatusSchema,
213
+ renderingStatusSchema,
214
+ renderErrorStatusSchema,
215
+ scheduledStatusSchema,
216
+ queuedStatusSchema,
217
+ sendingStatusSchema,
218
+ serverErrorStatusSchema,
219
+ skippedStatusSchema,
220
+ bouncedStatusSchema,
221
+ deliveryDelayedStatusSchema,
222
+ sentStatusSchema,
223
+ openedStatusSchema,
224
+ clickedStatusSchema,
225
+ markedAsSpamStatusSchema
226
+ );
227
+
228
+ // Update schema for PATCH endpoint
229
+ export const emailOutboxUpdateSchema = fieldSchema.yupObject({
230
+ tsx_source: fieldSchema.yupString().optional(),
231
+ theme_id: fieldSchema.yupString().nullable().optional(),
232
+ to: recipientSchema.optional(),
233
+ variables: fieldSchema.yupRecord(fieldSchema.yupString(), fieldSchema.jsonSchema).optional(),
234
+ skip_deliverability_check: fieldSchema.yupBoolean().optional(),
235
+ scheduled_at_millis: fieldSchema.yupNumber().optional(),
236
+ is_paused: fieldSchema.yupBoolean().optional(),
237
+ cancel: fieldSchema.yupBoolean().oneOf([true]).optional(),
238
+ }).defined();
239
+
240
+ export const emailOutboxCrud = createCrud({
241
+ serverReadSchema: emailOutboxReadSchema,
242
+ serverUpdateSchema: emailOutboxUpdateSchema,
243
+ docs: {
244
+ serverRead: {
245
+ tags: ["Emails"],
246
+ summary: "Get email outbox entry",
247
+ description: "Gets a single email from the outbox by ID.",
248
+ },
249
+ serverUpdate: {
250
+ tags: ["Emails"],
251
+ summary: "Update email outbox entry",
252
+ description: "Updates an email in the outbox. Can be used to edit email content, pause/resume, or cancel emails. Only emails in editable states (`paused`, `preparing`, `rendering`, `render-error`, `scheduled`, `queued`, `server-error`) can be modified.",
253
+ },
254
+ serverList: {
255
+ tags: ["Emails"],
256
+ summary: "List email outbox",
257
+ description: "Lists all emails in the outbox with optional filtering by status or simple_status.",
258
+ },
259
+ },
260
+ });
261
+
262
+ export type EmailOutboxCrud = CrudTypeOf<typeof emailOutboxCrud>;
263
+
@@ -0,0 +1,50 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import { jsonSchema, yupBoolean, yupMixed, yupObject, yupString } from "../../schema-fields";
3
+
4
+ export type EmailTemplateType = typeof emailTemplateTypes[number];
5
+ export const emailTemplateTypes = ['email_verification', 'password_reset', 'magic_link', 'team_invitation', 'sign_in_invitation', 'payment_receipt', 'payment_failed'] as const;
6
+
7
+ export const emailTemplateAdminReadSchema = yupObject({
8
+ type: yupString().oneOf(emailTemplateTypes).defined(),
9
+ subject: yupString().defined(),
10
+ content: jsonSchema.defined(),
11
+ is_default: yupBoolean().defined(),
12
+ }).defined();
13
+
14
+ export const emailTemplateCrudAdminUpdateSchema = yupObject({
15
+ content: jsonSchema.nonNullable().optional(),
16
+ subject: yupString().optional(),
17
+ }).defined();
18
+
19
+ export const emailTemplateCrudAdminDeleteSchema = yupMixed();
20
+
21
+ export const emailTemplateCrudAdminCreateSchema = yupObject({
22
+ type: yupString().oneOf(emailTemplateTypes).defined(),
23
+ content: jsonSchema.defined(),
24
+ subject: yupString().defined(),
25
+ }).defined();
26
+
27
+ export const emailTemplateCrud = createCrud({
28
+ adminReadSchema: emailTemplateAdminReadSchema,
29
+ adminUpdateSchema: emailTemplateCrudAdminUpdateSchema,
30
+ adminCreateSchema: emailTemplateCrudAdminCreateSchema,
31
+ adminDeleteSchema: emailTemplateCrudAdminDeleteSchema,
32
+ docs: {
33
+ adminRead: {
34
+ hidden: true,
35
+ },
36
+ adminCreate: {
37
+ hidden: true,
38
+ },
39
+ adminUpdate: {
40
+ hidden: true,
41
+ },
42
+ adminDelete: {
43
+ hidden: true,
44
+ },
45
+ adminList: {
46
+ hidden: true,
47
+ }
48
+ }
49
+ });
50
+ export type EmailTemplateCrud = CrudTypeOf<typeof emailTemplateCrud>;
@@ -0,0 +1,22 @@
1
+ import { createCrud, CrudTypeOf } from "../../crud";
2
+ import * as fieldSchema from "../../schema-fields";
3
+
4
+
5
+ export const sentEmailReadSchema = fieldSchema.yupObject({
6
+ id: fieldSchema.yupString().defined(),
7
+ subject: fieldSchema.yupString().defined(),
8
+ sent_at_millis: fieldSchema.yupNumber().defined(),
9
+ to: fieldSchema.yupArray(fieldSchema.yupString().defined()),
10
+ error: fieldSchema.yupMixed().nullable().optional(),
11
+ }).defined();
12
+
13
+ export const internalEmailsCrud = createCrud({
14
+ adminReadSchema: sentEmailReadSchema,
15
+ docs: {
16
+ adminList: {
17
+ hidden: true,
18
+ },
19
+ },
20
+ });
21
+
22
+ export type InternalEmailsCrud = CrudTypeOf<typeof internalEmailsCrud>;