@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,119 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import * as schemaFields from "../../schema-fields";
3
+ import { yupMixed, yupObject } from "../../schema-fields";
4
+ import { WebhookEvent } from "../webhooks";
5
+
6
+ // =============== Team permissions =================
7
+
8
+ export const teamPermissionsCrudClientReadSchema = yupObject({
9
+ id: schemaFields.permissionDefinitionIdSchema.defined(),
10
+ user_id: schemaFields.userIdSchema.defined(),
11
+ team_id: schemaFields.teamIdSchema.defined(),
12
+ }).defined();
13
+
14
+ export const teamPermissionsCrudServerCreateSchema = yupObject({
15
+ }).defined();
16
+
17
+ export const teamPermissionsCrudServerDeleteSchema = yupMixed();
18
+
19
+ export const teamPermissionsCrud = createCrud({
20
+ clientReadSchema: teamPermissionsCrudClientReadSchema,
21
+ serverCreateSchema: teamPermissionsCrudServerCreateSchema,
22
+ serverDeleteSchema: teamPermissionsCrudServerDeleteSchema,
23
+ docs: {
24
+ clientList: {
25
+ summary: "List team permissions",
26
+ description: "List team permissions of the current user. `user_id=me` must be set for client requests. Note that this might contain the permissions with the same permission ID across different teams. `(team_id, user_id, permission_id)` together uniquely identify a permission.",
27
+ tags: ["Permissions"],
28
+ },
29
+ serverList: {
30
+ summary: "List team permissions of a user",
31
+ description: "Query and filter the permission with `team_id`, `user_id`, and `permission_id`. Note that this might contain the permissions with the same permission ID across different teams and users. `(team_id, user_id, permission_id)` together uniquely identify a permission.",
32
+ tags: ["Permissions"],
33
+ },
34
+ serverCreate: {
35
+ summary: "Grant a team permission to a user",
36
+ description: "Grant a team permission to a user (the team permission must be created first on the Hexclave dashboard)",
37
+ tags: ["Permissions"],
38
+ },
39
+ serverDelete: {
40
+ summary: "Revoke a team permission from a user",
41
+ description: "Revoke a team permission from a user",
42
+ tags: ["Permissions"],
43
+ },
44
+ },
45
+ });
46
+ export type TeamPermissionsCrud = CrudTypeOf<typeof teamPermissionsCrud>;
47
+
48
+ export const teamPermissionCreatedWebhookEvent = {
49
+ type: "team_permission.created",
50
+ schema: teamPermissionsCrud.server.readSchema,
51
+ metadata: {
52
+ summary: "Team Permission Created",
53
+ description: "This event is triggered when a team permission is created.",
54
+ tags: ["Teams"],
55
+ },
56
+ } satisfies WebhookEvent<typeof teamPermissionsCrud.server.readSchema>;
57
+
58
+ export const teamPermissionDeletedWebhookEvent = {
59
+ type: "team_permission.deleted",
60
+ schema: teamPermissionsCrud.server.readSchema,
61
+ metadata: {
62
+ summary: "Team Permission Deleted",
63
+ description: "This event is triggered when a team permission is deleted.",
64
+ tags: ["Teams"],
65
+ },
66
+ } satisfies WebhookEvent<typeof teamPermissionsCrud.server.readSchema>;
67
+
68
+ // =============== Team permission definitions =================
69
+
70
+ export const teamPermissionDefinitionsCrudAdminReadSchema = yupObject({
71
+ id: schemaFields.permissionDefinitionIdSchema.defined(),
72
+ description: schemaFields.teamPermissionDescriptionSchema.optional(),
73
+ contained_permission_ids: schemaFields.containedPermissionIdsSchema.defined(),
74
+ }).defined();
75
+
76
+ export const teamPermissionDefinitionsCrudAdminCreateSchema = yupObject({
77
+ id: schemaFields.customPermissionDefinitionIdSchema.defined(),
78
+ description: schemaFields.teamPermissionDescriptionSchema.optional(),
79
+ contained_permission_ids: schemaFields.containedPermissionIdsSchema.optional(),
80
+ }).defined();
81
+
82
+ export const teamPermissionDefinitionsCrudAdminUpdateSchema = yupObject({
83
+ id: schemaFields.customPermissionDefinitionIdSchema.optional(),
84
+ description: schemaFields.teamPermissionDescriptionSchema.optional(),
85
+ contained_permission_ids: schemaFields.containedPermissionIdsSchema.optional(),
86
+ }).defined();
87
+
88
+ export const teamPermissionDefinitionsCrudAdminDeleteSchema = yupMixed();
89
+
90
+ export const teamPermissionDefinitionsCrud = createCrud({
91
+ adminReadSchema: teamPermissionDefinitionsCrudAdminReadSchema,
92
+ adminCreateSchema: teamPermissionDefinitionsCrudAdminCreateSchema,
93
+ adminUpdateSchema: teamPermissionDefinitionsCrudAdminUpdateSchema,
94
+ adminDeleteSchema: teamPermissionDefinitionsCrudAdminDeleteSchema,
95
+ docs: {
96
+ adminList: {
97
+ summary: "List team permission definitions",
98
+ description: "Query and filter the permission with team_id, user_id, and permission_id (the equivalent of listing permissions on the Hexclave dashboard)",
99
+ tags: ["Permissions"],
100
+ },
101
+ adminCreate: {
102
+ summary: "Create a new team permission definition",
103
+ description: "Create a new permission definition (the equivalent of creating a new permission on the Hexclave dashboard)",
104
+ tags: ["Permissions"],
105
+ },
106
+ adminUpdate: {
107
+ summary: "Update a team permission definition",
108
+ description: "Update a permission definition (the equivalent of updating a permission on the Hexclave dashboard)",
109
+ tags: ["Permissions"],
110
+ },
111
+ adminDelete: {
112
+ summary: "Delete a team permission definition",
113
+ description: "Delete a permission definition (the equivalent of deleting a permission on the Hexclave dashboard)",
114
+ tags: ["Permissions"],
115
+ },
116
+ },
117
+ });
118
+
119
+ export type TeamPermissionDefinitionsCrud = CrudTypeOf<typeof teamPermissionDefinitionsCrud>;
@@ -0,0 +1,142 @@
1
+ import { CrudTypeOf, createCrud } from "../../crud";
2
+ import * as fieldSchema from "../../schema-fields";
3
+ import { yupObject } from "../../schema-fields";
4
+ import { WebhookEvent } from "../webhooks";
5
+
6
+ // Read
7
+ export const teamsCrudClientReadSchema = yupObject({
8
+ id: fieldSchema.teamIdSchema.defined(),
9
+ display_name: fieldSchema.teamDisplayNameSchema.defined(),
10
+ profile_image_url: fieldSchema.teamProfileImageUrlSchema.nullable().defined(),
11
+ client_metadata: fieldSchema.teamClientMetadataSchema.optional(),
12
+ client_read_only_metadata: fieldSchema.teamClientReadOnlyMetadataSchema.optional(),
13
+ }).defined();
14
+ export const teamsCrudServerReadSchema = teamsCrudClientReadSchema.concat(yupObject({
15
+ created_at_millis: fieldSchema.teamCreatedAtMillisSchema.defined(),
16
+ server_metadata: fieldSchema.teamServerMetadataSchema.optional(),
17
+ }).defined());
18
+
19
+ // Update
20
+ export const teamsCrudClientUpdateSchema = yupObject({
21
+ display_name: fieldSchema.teamDisplayNameSchema.optional(),
22
+ profile_image_url: fieldSchema.teamProfileImageUrlSchema.nullable().optional(),
23
+ client_metadata: fieldSchema.teamClientMetadataSchema.optional(),
24
+ }).defined();
25
+ export const teamsCrudServerUpdateSchema = teamsCrudClientUpdateSchema.concat(yupObject({
26
+ client_read_only_metadata: fieldSchema.teamClientReadOnlyMetadataSchema.optional(),
27
+ server_metadata: fieldSchema.teamServerMetadataSchema.optional(),
28
+ }).defined());
29
+
30
+ // Create
31
+ export const teamsCrudClientCreateSchema = teamsCrudClientUpdateSchema.concat(yupObject({
32
+ display_name: fieldSchema.teamDisplayNameSchema.defined(),
33
+ creator_user_id: fieldSchema.teamCreatorUserIdSchema.optional(),
34
+ }).defined());
35
+ export const teamsCrudServerCreateSchema = teamsCrudServerUpdateSchema.concat(yupObject({
36
+ display_name: fieldSchema.teamDisplayNameSchema.defined(),
37
+ creator_user_id: fieldSchema.teamCreatorUserIdSchema.optional(),
38
+ }).defined());
39
+
40
+ // Delete
41
+ export const teamsCrudClientDeleteSchema = fieldSchema.yupMixed();
42
+ export const teamsCrudServerDeleteSchema = teamsCrudClientDeleteSchema;
43
+
44
+ export const teamsCrud = createCrud({
45
+ // Client
46
+ clientReadSchema: teamsCrudClientReadSchema,
47
+ clientUpdateSchema: teamsCrudClientUpdateSchema,
48
+ clientCreateSchema: teamsCrudClientCreateSchema,
49
+ clientDeleteSchema: teamsCrudClientDeleteSchema,
50
+ // Server
51
+ serverReadSchema: teamsCrudServerReadSchema,
52
+ serverUpdateSchema: teamsCrudServerUpdateSchema,
53
+ serverCreateSchema: teamsCrudServerCreateSchema,
54
+ serverDeleteSchema: teamsCrudServerDeleteSchema,
55
+ docs: {
56
+ clientList: {
57
+ summary: "List teams",
58
+ description: "List all the teams that the current user is a member of. `user_id=me` must be passed in the query parameters.",
59
+ tags: ["Teams"],
60
+ },
61
+ clientCreate: {
62
+ summary: "Create a team",
63
+ description: "Create a new team and optionally add the current user as a member.",
64
+ tags: ["Teams"],
65
+ },
66
+ clientRead: {
67
+ summary: "Get a team",
68
+ description: "Get a team that the current user is a member of.",
69
+ tags: ["Teams"],
70
+ },
71
+ clientUpdate: {
72
+ summary: "Update a team",
73
+ description: "Update the team information. Only allowed if the current user is a member of the team and has the `$update_team` permission.",
74
+ tags: ["Teams"],
75
+ },
76
+ clientDelete: {
77
+ summary: "Delete a team",
78
+ description: "Delete a team. Only allowed if the current user is a member of the team and has the `$delete_team` permission.",
79
+ tags: ["Teams"],
80
+ },
81
+ serverCreate: {
82
+ summary: "Create a team",
83
+ description: "Create a new team and optionally add the current user as a member.",
84
+ tags: ["Teams"],
85
+ },
86
+ serverList: {
87
+ summary: "List teams",
88
+ description: "List all the teams in the project.",
89
+ tags: ["Teams"],
90
+ },
91
+ serverRead: {
92
+ summary: "Get a team",
93
+ description: "Get a team by ID.",
94
+ tags: ["Teams"],
95
+ },
96
+ serverUpdate: {
97
+ summary: "Update a team",
98
+ description: "Update the team information by ID.",
99
+ tags: ["Teams"],
100
+ },
101
+ serverDelete: {
102
+ summary: "Delete a team",
103
+ description: "Delete a team by ID.",
104
+ tags: ["Teams"],
105
+ },
106
+ },
107
+ });
108
+ export type TeamsCrud = CrudTypeOf<typeof teamsCrud>;
109
+
110
+ export const teamCreatedWebhookEvent = {
111
+ type: "team.created",
112
+ schema: teamsCrud.server.readSchema,
113
+ metadata: {
114
+ summary: "Team Created",
115
+ description: "This event is triggered when a team is created.",
116
+ tags: ["Teams"],
117
+ },
118
+ } satisfies WebhookEvent<typeof teamsCrud.server.readSchema>;
119
+
120
+ export const teamUpdatedWebhookEvent = {
121
+ type: "team.updated",
122
+ schema: teamsCrud.server.readSchema,
123
+ metadata: {
124
+ summary: "Team Updated",
125
+ description: "This event is triggered when a team is updated.",
126
+ tags: ["Teams"],
127
+ },
128
+ } satisfies WebhookEvent<typeof teamsCrud.server.readSchema>;
129
+
130
+ const webhookTeamDeletedSchema = fieldSchema.yupObject({
131
+ id: fieldSchema.userIdSchema.defined(),
132
+ }).defined();
133
+
134
+ export const teamDeletedWebhookEvent = {
135
+ type: "team.deleted",
136
+ schema: webhookTeamDeletedSchema,
137
+ metadata: {
138
+ summary: "Team Deleted",
139
+ description: "This event is triggered when a team is deleted.",
140
+ tags: ["Teams"],
141
+ },
142
+ } satisfies WebhookEvent<typeof webhookTeamDeletedSchema>;
@@ -0,0 +1,131 @@
1
+ import type { InferType } from "yup";
2
+ import {
3
+ customerTypeSchema,
4
+ inlineProductSchema,
5
+ moneyAmountSchema,
6
+ yupArray,
7
+ yupBoolean,
8
+ yupNumber,
9
+ yupObject,
10
+ yupString,
11
+ yupUnion,
12
+ } from "../../schema-fields";
13
+ import { SUPPORTED_CURRENCIES } from "../../utils/currency-constants";
14
+ import { typedFromEntries } from "../../utils/objects";
15
+ import { throwErr } from "../../utils/errors";
16
+
17
+
18
+ const USD_CURRENCY = SUPPORTED_CURRENCIES.find((currency) => currency.code === "USD") ?? throwErr("USD currency configuration missing in SUPPORTED_CURRENCIES");
19
+
20
+ const chargedAmountSchema = yupObject({
21
+ ...typedFromEntries(SUPPORTED_CURRENCIES.map((currency) => [currency.code, moneyAmountSchema(currency).optional()])),
22
+ }).noUnknown(true).test("at-least-one-currency", "charged_amount must include at least one currency amount", (value) => {
23
+ return Object.values(value).some((amount) => typeof amount === "string");
24
+ }).defined();
25
+
26
+ const netAmountSchema = yupObject({
27
+ USD: moneyAmountSchema(USD_CURRENCY).defined(),
28
+ }).noUnknown(true).defined();
29
+
30
+ const transactionEntryMoneyTransferSchema = yupObject({
31
+ type: yupString().oneOf(["money_transfer"]).defined(),
32
+ adjusted_transaction_id: yupString().nullable().defined(),
33
+ adjusted_entry_index: yupNumber().integer().min(0).nullable().defined(),
34
+ customer_type: customerTypeSchema.defined(),
35
+ customer_id: yupString().defined(),
36
+ charged_amount: chargedAmountSchema,
37
+ net_amount: netAmountSchema,
38
+ }).defined();
39
+
40
+ const transactionEntryItemQuantityChangeSchema = yupObject({
41
+ type: yupString().oneOf(["item_quantity_change"]).defined(),
42
+ adjusted_transaction_id: yupString().nullable().defined(),
43
+ adjusted_entry_index: yupNumber().integer().min(0).nullable().defined(),
44
+ customer_type: customerTypeSchema.defined(),
45
+ customer_id: yupString().defined(),
46
+ item_id: yupString().defined(),
47
+ quantity: yupNumber().defined(),
48
+ }).defined();
49
+
50
+ const transactionEntryProductGrantSchema = yupObject({
51
+ type: yupString().oneOf(["product_grant"]).defined(),
52
+ adjusted_transaction_id: yupString().nullable().defined(),
53
+ adjusted_entry_index: yupNumber().integer().min(0).nullable().defined(),
54
+ customer_type: customerTypeSchema.defined(),
55
+ customer_id: yupString().defined(),
56
+ product_id: yupString().nullable().defined(),
57
+ product: inlineProductSchema.defined(),
58
+ price_id: yupString().nullable().defined(),
59
+ quantity: yupNumber().defined(),
60
+ subscription_id: yupString().optional(),
61
+ one_time_purchase_id: yupString().optional(),
62
+ }).test(
63
+ "exclusive-reference",
64
+ "subscription_id and one_time_purchase_id cannot both be set",
65
+ (value, context) => {
66
+ if (value.subscription_id != null && value.one_time_purchase_id != null) {
67
+ return context.createError({
68
+ message: "subscription_id and one_time_purchase_id cannot both be set",
69
+ });
70
+ }
71
+ return true;
72
+ },
73
+ ).defined();
74
+
75
+ const transactionEntryProductRevocationSchema = yupObject({
76
+ type: yupString().oneOf(["product_revocation"]).defined(),
77
+ adjusted_transaction_id: yupString().defined(),
78
+ adjusted_entry_index: yupNumber().integer().min(0).defined(),
79
+ quantity: yupNumber().defined(),
80
+ }).defined();
81
+
82
+ const transactionEntryProductRevocationReversalSchema = yupObject({
83
+ type: yupString().oneOf(["product_revocation_reversal"]).defined(),
84
+ adjusted_transaction_id: yupString().defined(),
85
+ adjusted_entry_index: yupNumber().integer().min(0).defined(),
86
+ quantity: yupNumber().defined(),
87
+ }).defined();
88
+
89
+ export const transactionEntrySchema = yupUnion(
90
+ transactionEntryMoneyTransferSchema,
91
+ transactionEntryItemQuantityChangeSchema,
92
+ transactionEntryProductGrantSchema,
93
+ transactionEntryProductRevocationSchema,
94
+ transactionEntryProductRevocationReversalSchema,
95
+ ).defined();
96
+
97
+ export type TransactionEntry = InferType<typeof transactionEntrySchema>;
98
+
99
+ export const TRANSACTION_TYPES = [
100
+ "purchase",
101
+ "subscription-cancellation",
102
+ "subscription-renewal",
103
+ "manual-item-quantity-change",
104
+ "refund",
105
+ "chargeback", // todo
106
+ "product-change", // todo
107
+ ] as const;
108
+
109
+ export type TransactionType = (typeof TRANSACTION_TYPES)[number];
110
+
111
+ export const transactionSchema = yupObject({
112
+ id: yupString().defined(),
113
+ created_at_millis: yupNumber().defined(),
114
+ effective_at_millis: yupNumber().defined(),
115
+ type: yupString().oneOf(TRANSACTION_TYPES).nullable().defined(),
116
+ // Customer is exposed at the transaction level (not only per-entry) so
117
+ // consumers can attribute every row — including refund rows whose surviving
118
+ // entries (`product_revocation`, or none at all) carry no customer fields.
119
+ customer_type: customerTypeSchema.defined(),
120
+ customer_id: yupString().defined(),
121
+ entries: yupArray(transactionEntrySchema).defined(),
122
+ adjusted_by: yupArray(
123
+ yupObject({
124
+ transaction_id: yupString().defined(),
125
+ entry_index: yupNumber().integer().min(0).defined(),
126
+ }).defined(),
127
+ ).defined(),
128
+ test_mode: yupBoolean().defined(),
129
+ }).defined();
130
+
131
+ export type Transaction = InferType<typeof transactionSchema>;
@@ -0,0 +1,185 @@
1
+ import type { InferType } from "yup";
2
+ import * as yup from "yup";
3
+ import { CrudTypeOf, createCrud } from "../../crud";
4
+ import * as fieldSchema from "../../schema-fields";
5
+ import { WebhookEvent } from "../webhooks";
6
+ import { teamsCrudServerReadSchema } from "./teams";
7
+
8
+ const restrictedByAdminMeta = {
9
+ restricted_by_admin: { openapiField: { description: 'Whether the user is restricted by an administrator. Can be set manually or by sign-up rules.', exampleValue: false } },
10
+ restricted_by_admin_reason: { openapiField: { description: 'Public reason shown to the user explaining why they are restricted. Optional.', exampleValue: null } },
11
+ restricted_by_admin_private_details: { openapiField: { description: 'Private details about the restriction (e.g., which sign-up rule triggered). Only visible to server access and above.', exampleValue: null } },
12
+ } as const;
13
+
14
+ const countryCodeMeta = { openapiField: { description: 'Best-effort ISO country code captured at sign-up time from request geo headers.', exampleValue: "US" } } as const;
15
+
16
+ export const riskScoreFieldSchema = fieldSchema.yupNumber().integer().min(0).max(100).defined();
17
+ export const signUpRiskScoresSchema = fieldSchema.yupObject({
18
+ sign_up: fieldSchema.yupObject({
19
+ bot: riskScoreFieldSchema,
20
+ free_trial_abuse: riskScoreFieldSchema,
21
+ }).defined(),
22
+ });
23
+ export type SignUpRiskScoresCrud = InferType<typeof signUpRiskScoresSchema>["sign_up"];
24
+
25
+ const oauthProviderBaseFields = {
26
+ id: fieldSchema.yupString().defined(),
27
+ account_id: fieldSchema.yupString().defined(),
28
+ };
29
+ const hiddenFieldMeta = { openapiField: { hidden: true } } as const;
30
+
31
+ function restrictedByAdminConsistencyTest(this: yup.TestContext<any>, value: any) {
32
+ if (value == null) return true;
33
+ if (value.restricted_by_admin !== true) {
34
+ if (value.restricted_by_admin_reason != null) {
35
+ return this.createError({ message: "restricted_by_admin_reason must be null when restricted_by_admin is not true" });
36
+ }
37
+ if (value.restricted_by_admin_private_details != null) {
38
+ return this.createError({ message: "restricted_by_admin_private_details must be null when restricted_by_admin is not true" });
39
+ }
40
+ }
41
+ return true;
42
+ }
43
+
44
+ export const usersCrudServerUpdateSchema = fieldSchema.yupObject({
45
+ display_name: fieldSchema.userDisplayNameSchema.optional(),
46
+ profile_image_url: fieldSchema.profileImageUrlSchema.nullable().optional(),
47
+ client_metadata: fieldSchema.userClientMetadataSchema.optional(),
48
+ client_read_only_metadata: fieldSchema.userClientReadOnlyMetadataSchema.optional(),
49
+ server_metadata: fieldSchema.userServerMetadataSchema.optional(),
50
+ primary_email: fieldSchema.primaryEmailSchema.nullable().optional().nonEmpty(),
51
+ primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.optional(),
52
+ primary_email_auth_enabled: fieldSchema.primaryEmailAuthEnabledSchema.optional(),
53
+ passkey_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.optional(),
54
+ password: fieldSchema.userPasswordMutationSchema.optional(),
55
+ password_hash: fieldSchema.userPasswordHashMutationSchema.optional(),
56
+ otp_auth_enabled: fieldSchema.userOtpAuthEnabledMutationSchema.optional(),
57
+ totp_secret_base64: fieldSchema.userTotpSecretMutationSchema.optional(),
58
+ selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().optional(),
59
+ is_anonymous: fieldSchema.yupBoolean().oneOf([false]).optional(),
60
+ restricted_by_admin: fieldSchema.yupBoolean().optional().meta(restrictedByAdminMeta.restricted_by_admin),
61
+ restricted_by_admin_reason: fieldSchema.yupString().nullable().optional().meta(restrictedByAdminMeta.restricted_by_admin_reason),
62
+ restricted_by_admin_private_details: fieldSchema.yupString().nullable().optional().meta(restrictedByAdminMeta.restricted_by_admin_private_details),
63
+ country_code: fieldSchema.countryCodeSchema.nullable().optional().meta(countryCodeMeta),
64
+ risk_scores: signUpRiskScoresSchema.optional(),
65
+ }).defined().test(
66
+ "restricted_by_admin_consistency",
67
+ "When restricted_by_admin is not true, reason and private_details must be null",
68
+ restrictedByAdminConsistencyTest,
69
+ );
70
+
71
+ export const usersCrudServerReadSchema = fieldSchema.yupObject({
72
+ id: fieldSchema.userIdSchema.defined(),
73
+ primary_email: fieldSchema.primaryEmailSchema.nullable().defined(),
74
+ primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.defined(),
75
+ primary_email_auth_enabled: fieldSchema.primaryEmailAuthEnabledSchema.defined(),
76
+ display_name: fieldSchema.userDisplayNameSchema.nullable().defined(),
77
+ selected_team: teamsCrudServerReadSchema.nullable().defined(),
78
+ selected_team_id: fieldSchema.selectedTeamIdSchema.nullable().defined(),
79
+ profile_image_url: fieldSchema.profileImageUrlSchema.nullable().defined(),
80
+ signed_up_at_millis: fieldSchema.signedUpAtMillisSchema.defined(),
81
+ has_password: fieldSchema.userHasPasswordSchema.defined(),
82
+ otp_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.defined(),
83
+ passkey_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.defined(),
84
+ client_metadata: fieldSchema.userClientMetadataSchema,
85
+ client_read_only_metadata: fieldSchema.userClientReadOnlyMetadataSchema,
86
+ server_metadata: fieldSchema.userServerMetadataSchema,
87
+ last_active_at_millis: fieldSchema.userLastActiveAtMillisSchema.nonNullable().defined(),
88
+ is_anonymous: fieldSchema.yupBoolean().defined(),
89
+ is_restricted: fieldSchema.yupBoolean().defined().meta({ openapiField: { description: 'Whether the user is in restricted state (has signed up but not completed onboarding requirements)', exampleValue: false } }),
90
+ restricted_reason: fieldSchema.restrictedReasonSchema.nullable().defined().meta({ openapiField: { description: 'The reason why the user is restricted (e.g., type: "email_not_verified", "anonymous", or "restricted_by_administrator"), null if not restricted', exampleValue: null } }),
91
+ restricted_by_admin: fieldSchema.yupBoolean().defined().meta(restrictedByAdminMeta.restricted_by_admin),
92
+ restricted_by_admin_reason: fieldSchema.yupString().nullable().defined().meta(restrictedByAdminMeta.restricted_by_admin_reason),
93
+ restricted_by_admin_private_details: fieldSchema.yupString().nullable().defined().meta(restrictedByAdminMeta.restricted_by_admin_private_details),
94
+ country_code: fieldSchema.countryCodeSchema.nullable().defined().meta(countryCodeMeta),
95
+ risk_scores: signUpRiskScoresSchema.defined().meta({ openapiField: { description: 'User risk scores used for sign-up risk evaluation.', exampleValue: { sign_up: { bot: 0, free_trial_abuse: 0 } } } }),
96
+
97
+ oauth_providers: fieldSchema.yupArray(fieldSchema.yupObject({
98
+ ...oauthProviderBaseFields,
99
+ email: fieldSchema.yupString().nullable(),
100
+ }).defined()).defined().meta(hiddenFieldMeta),
101
+
102
+ /**
103
+ * @deprecated
104
+ */
105
+ auth_with_email: fieldSchema.yupBoolean().defined().meta({ openapiField: { hidden: true, description: 'Whether the user can authenticate with their primary e-mail. If set to true, the user can log-in with credentials and/or magic link, if enabled in the project settings.', exampleValue: true } }),
106
+ /**
107
+ * @deprecated
108
+ */
109
+ requires_totp_mfa: fieldSchema.yupBoolean().defined().meta({ openapiField: { hidden: true, description: 'Whether the user is required to use TOTP MFA to sign in', exampleValue: false } }),
110
+ }).defined().test("restricted_reason_iff_restricted", "restricted_reason must be present if and only if is_restricted is true", function(this: yup.TestContext<any>, value: any) {
111
+ if (value == null) return true;
112
+ return value.is_restricted === !!value.restricted_reason;
113
+ }).test(
114
+ "restricted_by_admin_consistency",
115
+ "When restricted_by_admin is not true, reason and private_details must be null",
116
+ restrictedByAdminConsistencyTest,
117
+ );
118
+
119
+ export const usersCrudServerCreateSchema = usersCrudServerUpdateSchema.omit(['selected_team_id']).concat(fieldSchema.yupObject({
120
+ oauth_providers: fieldSchema.yupArray(fieldSchema.yupObject({
121
+ ...oauthProviderBaseFields,
122
+ email: fieldSchema.yupString().nullable().defined().default(null),
123
+ }).defined()).optional().meta(hiddenFieldMeta),
124
+ is_anonymous: fieldSchema.yupBoolean().optional(),
125
+ }).defined());
126
+
127
+ export const usersCrudServerDeleteSchema = fieldSchema.yupMixed();
128
+
129
+ export const usersCrud = createCrud({
130
+ serverReadSchema: usersCrudServerReadSchema,
131
+ serverUpdateSchema: usersCrudServerUpdateSchema,
132
+ serverCreateSchema: usersCrudServerCreateSchema,
133
+ serverDeleteSchema: usersCrudServerDeleteSchema,
134
+ docs: {
135
+ serverCreate: {
136
+ tags: ["Users"],
137
+ summary: 'Create user',
138
+ description: 'Creates a new user. E-mail authentication is always enabled, and no password is set, meaning the only way to authenticate the newly created user is through magic link.',
139
+ },
140
+ serverRead: {
141
+ tags: ["Users"],
142
+ summary: 'Get user',
143
+ description: 'Gets a user by user ID.',
144
+ },
145
+ serverUpdate: {
146
+ tags: ["Users"],
147
+ summary: 'Update user',
148
+ description: 'Updates a user. Only the values provided will be updated.',
149
+ },
150
+ serverDelete: {
151
+ tags: ["Users"],
152
+ summary: 'Delete user',
153
+ description: 'Deletes a user. Use this with caution.',
154
+ },
155
+ serverList: {
156
+ tags: ["Users"],
157
+ summary: 'List users',
158
+ description: 'Lists all the users in the project. By default, only fully onboarded users are returned. Restricted users (those who haven\'t completed onboarding requirements like email verification) are included if `include_restricted` is set to `true`. Anonymous users are included if `include_anonymous` is set to `true` (which also includes restricted users).',
159
+ },
160
+ },
161
+ });
162
+ export type UsersCrud = CrudTypeOf<typeof usersCrud>;
163
+
164
+ function userWebhookEvent<S extends yup.Schema>(action: string, schema: S): WebhookEvent<S> {
165
+ return {
166
+ type: `user.${action}`,
167
+ schema,
168
+ metadata: {
169
+ summary: `User ${action[0].toUpperCase()}${action.slice(1)}`,
170
+ description: `This event is triggered when a user is ${action}.`,
171
+ tags: ["Users"],
172
+ },
173
+ };
174
+ }
175
+
176
+ export const userCreatedWebhookEvent = userWebhookEvent("created", usersCrud.server.readSchema);
177
+ export const userUpdatedWebhookEvent = userWebhookEvent("updated", usersCrud.server.readSchema);
178
+
179
+ const webhookUserDeletedSchema = fieldSchema.yupObject({
180
+ id: fieldSchema.userIdSchema.defined(),
181
+ teams: fieldSchema.yupArray(fieldSchema.yupObject({
182
+ id: fieldSchema.yupString().defined(),
183
+ })).defined(),
184
+ }).defined();
185
+ export const userDeletedWebhookEvent = userWebhookEvent("deleted", webhookUserDeletedSchema);
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @deprecated Plain string URLs are deprecated. Use `{ type: "custom", url: "...", version: 0 }` instead.
3
+ */
4
+ type DeprecatedStringUrl = string;
5
+
6
+ export type HandlerPageUrls = Record<
7
+ | "handler"
8
+ | "signIn"
9
+ | "signUp"
10
+ | "signOut"
11
+ | "emailVerification"
12
+ | "passwordReset"
13
+ | "forgotPassword"
14
+ | "oauthCallback"
15
+ | "magicLinkCallback"
16
+ | "accountSettings"
17
+ | "teamInvitation"
18
+ | "cliAuthConfirm"
19
+ | "mfa"
20
+ | "error"
21
+ | "onboarding",
22
+ DeprecatedStringUrl | { type: "custom", url: string, version: number } | { type: "hosted" | "handler-component" }
23
+ >;
24
+
25
+ export type HandlerRedirectUrls = Record<
26
+ | "afterSignIn"
27
+ | "afterSignUp"
28
+ | "afterSignOut"
29
+ | "home",
30
+ string
31
+ >;
32
+
33
+ export type HandlerUrls = HandlerPageUrls & HandlerRedirectUrls;
34
+ export type HandlerUrlTarget = HandlerUrls[keyof HandlerUrls];
35
+
36
+ /**
37
+ * The default handler URL target, applied to any key not explicitly set.
38
+ *
39
+ * - `{ type: "handler-component" }` — render the page inside the local `StackHandler` component (current default, may change in the next breaking version).
40
+ * - `{ type: "hosted" }` — redirect to Stack's hosted auth pages.
41
+ */
42
+ export type DefaultHandlerUrlTarget = { type: "hosted" | "handler-component" };
43
+
44
+ /**
45
+ * Configuration for where each auth page/redirect lives.
46
+ *
47
+ * **`default`** — fallback target for every key not set individually:
48
+ * - `{ type: "handler-component" }` — use the local `StackHandler` (current default, may change in the next breaking version).
49
+ * - `{ type: "hosted" }` — use Stack's hosted auth pages.
50
+ *
51
+ * **Page keys** (`signIn`, `signUp`, `signOut`, `emailVerification`, `passwordReset`,
52
+ * `forgotPassword`, `oauthCallback`, `magicLinkCallback`, `accountSettings`,
53
+ * `teamInvitation`, `cliAuthConfirm`, `mfa`, `error`, `onboarding`, `handler`):
54
+ * - A URL string (e.g. `"/my-sign-in"`) — custom path.
55
+ * - `{ type: "custom", url: "...", version: 0 }` — custom URL with version tracking.
56
+ * - `{ type: "hosted" }` — Stack's hosted page.
57
+ * - `{ type: "handler-component" }` — local `StackHandler`.
58
+ *
59
+ * **Redirect keys** (`afterSignIn`, `afterSignUp`, `afterSignOut`, `home`):
60
+ * - A URL string (e.g. `"/dashboard"`) — where to redirect after the action.
61
+ */
62
+ export type HandlerUrlOptions = Partial<HandlerUrls> & { default?: DefaultHandlerUrlTarget };
63
+ export type ResolvedHandlerUrls = {
64
+ [K in keyof HandlerUrls]: string;
65
+ };
66
+
67
+ export {
68
+ getCustomPagePrompts,
69
+ getLatestPageVersions,
70
+ type CustomPagePrompt,
71
+ type PageComponentKey,
72
+ type PageVersionEntry,
73
+ type PageVersions
74
+ } from "./page-component-versions";