@robelest/convex-auth 0.0.4-preview.18 → 0.0.4-preview.19

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 (541) hide show
  1. package/README.md +6 -3
  2. package/dist/authorization/index.d.ts +46 -0
  3. package/dist/authorization/index.d.ts.map +1 -1
  4. package/dist/authorization/index.js +46 -0
  5. package/dist/authorization/index.js.map +1 -1
  6. package/dist/bin.cjs +21 -13
  7. package/dist/client/core/types.d.ts +20 -0
  8. package/dist/client/core/types.d.ts.map +1 -0
  9. package/dist/client/index.d.ts +2 -16
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +67 -565
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/component/_generated/api.d.ts +40 -12
  14. package/dist/component/_generated/api.d.ts.map +1 -1
  15. package/dist/component/_generated/api.js.map +1 -1
  16. package/dist/component/_generated/component.d.ts +1306 -1344
  17. package/dist/component/_generated/component.d.ts.map +1 -1
  18. package/dist/component/client/core/types.d.ts +2 -0
  19. package/dist/component/client/index.d.ts +2 -2
  20. package/dist/component/model.d.ts +80 -80
  21. package/dist/component/model.d.ts.map +1 -1
  22. package/dist/component/model.js +5 -1
  23. package/dist/component/model.js.map +1 -1
  24. package/dist/component/providers/credentials.d.ts +3 -2
  25. package/dist/component/providers/credentials.d.ts.map +1 -1
  26. package/dist/component/providers/email.d.ts +30 -0
  27. package/dist/component/providers/email.d.ts.map +1 -1
  28. package/dist/component/providers/phone.d.ts +28 -0
  29. package/dist/component/providers/phone.d.ts.map +1 -1
  30. package/dist/component/public/enterprise/audit.d.ts +73 -0
  31. package/dist/component/public/enterprise/audit.d.ts.map +1 -0
  32. package/dist/component/public/enterprise/audit.js +108 -0
  33. package/dist/component/public/enterprise/audit.js.map +1 -0
  34. package/dist/component/public/enterprise/core.d.ts +176 -0
  35. package/dist/component/public/enterprise/core.d.ts.map +1 -0
  36. package/dist/component/public/enterprise/core.js +292 -0
  37. package/dist/component/public/enterprise/core.js.map +1 -0
  38. package/dist/component/public/enterprise/domains.d.ts +174 -0
  39. package/dist/component/public/enterprise/domains.d.ts.map +1 -0
  40. package/dist/component/public/enterprise/domains.js +271 -0
  41. package/dist/component/public/enterprise/domains.js.map +1 -0
  42. package/dist/component/public/enterprise/scim.d.ts +245 -0
  43. package/dist/component/public/enterprise/scim.d.ts.map +1 -0
  44. package/dist/component/public/enterprise/scim.js +344 -0
  45. package/dist/component/public/enterprise/scim.js.map +1 -0
  46. package/dist/component/public/enterprise/secrets.d.ts +78 -0
  47. package/dist/component/public/enterprise/secrets.d.ts.map +1 -0
  48. package/dist/component/public/enterprise/secrets.js +118 -0
  49. package/dist/component/public/enterprise/secrets.js.map +1 -0
  50. package/dist/component/public/enterprise/webhooks.d.ts +211 -0
  51. package/dist/component/public/enterprise/webhooks.d.ts.map +1 -0
  52. package/dist/component/public/enterprise/webhooks.js +300 -0
  53. package/dist/component/public/enterprise/webhooks.js.map +1 -0
  54. package/dist/component/public/factors/devices.d.ts +157 -0
  55. package/dist/component/public/factors/devices.d.ts.map +1 -0
  56. package/dist/component/public/factors/devices.js +216 -0
  57. package/dist/component/public/factors/devices.js.map +1 -0
  58. package/dist/component/public/factors/passkeys.d.ts +175 -0
  59. package/dist/component/public/factors/passkeys.d.ts.map +1 -0
  60. package/dist/component/public/factors/passkeys.js +238 -0
  61. package/dist/component/public/factors/passkeys.js.map +1 -0
  62. package/dist/component/public/factors/totp.d.ts +189 -0
  63. package/dist/component/public/factors/totp.d.ts.map +1 -0
  64. package/dist/component/public/factors/totp.js +254 -0
  65. package/dist/component/public/factors/totp.js.map +1 -0
  66. package/dist/component/public/groups/core.d.ts +137 -0
  67. package/dist/component/public/groups/core.d.ts.map +1 -0
  68. package/dist/component/public/groups/core.js +321 -0
  69. package/dist/component/public/groups/core.js.map +1 -0
  70. package/dist/component/public/groups/invites.d.ts +217 -0
  71. package/dist/component/public/groups/invites.d.ts.map +1 -0
  72. package/dist/component/public/groups/invites.js +457 -0
  73. package/dist/component/public/groups/invites.js.map +1 -0
  74. package/dist/component/public/groups/members.d.ts +204 -0
  75. package/dist/component/public/groups/members.d.ts.map +1 -0
  76. package/dist/component/public/groups/members.js +355 -0
  77. package/dist/component/public/groups/members.js.map +1 -0
  78. package/dist/component/public/identity/accounts.d.ts +147 -0
  79. package/dist/component/public/identity/accounts.d.ts.map +1 -0
  80. package/dist/component/public/identity/accounts.js +200 -0
  81. package/dist/component/public/identity/accounts.js.map +1 -0
  82. package/dist/component/public/identity/codes.d.ts +104 -0
  83. package/dist/component/public/identity/codes.d.ts.map +1 -0
  84. package/dist/component/public/identity/codes.js +140 -0
  85. package/dist/component/public/identity/codes.js.map +1 -0
  86. package/dist/component/public/identity/sessions.d.ts +128 -0
  87. package/dist/component/public/identity/sessions.d.ts.map +1 -0
  88. package/dist/component/public/identity/sessions.js +192 -0
  89. package/dist/component/public/identity/sessions.js.map +1 -0
  90. package/dist/component/public/identity/tokens.d.ts +169 -0
  91. package/dist/component/public/identity/tokens.d.ts.map +1 -0
  92. package/dist/component/public/identity/tokens.js +227 -0
  93. package/dist/component/public/identity/tokens.js.map +1 -0
  94. package/dist/component/public/identity/users.d.ts +212 -0
  95. package/dist/component/public/identity/users.d.ts.map +1 -0
  96. package/dist/component/public/identity/users.js +311 -0
  97. package/dist/component/public/identity/users.js.map +1 -0
  98. package/dist/component/public/identity/verifiers.d.ts +116 -0
  99. package/dist/component/public/identity/verifiers.d.ts.map +1 -0
  100. package/dist/component/public/identity/verifiers.js +154 -0
  101. package/dist/component/public/identity/verifiers.js.map +1 -0
  102. package/dist/component/public/security/keys.d.ts +209 -0
  103. package/dist/component/public/security/keys.d.ts.map +1 -0
  104. package/dist/component/public/security/keys.js +319 -0
  105. package/dist/component/public/security/keys.js.map +1 -0
  106. package/dist/component/public/security/limits.d.ts +114 -0
  107. package/dist/component/public/security/limits.d.ts.map +1 -0
  108. package/dist/component/public/security/limits.js +169 -0
  109. package/dist/component/public/security/limits.js.map +1 -0
  110. package/dist/component/public.d.ts +22 -7
  111. package/dist/component/public.js +21 -6
  112. package/dist/component/schema.d.ts +288 -288
  113. package/dist/component/server/auth.d.ts +212 -25
  114. package/dist/component/server/auth.d.ts.map +1 -1
  115. package/dist/component/server/auth.js +68 -4
  116. package/dist/component/server/auth.js.map +1 -1
  117. package/dist/component/server/authError.js +34 -0
  118. package/dist/component/server/authError.js.map +1 -0
  119. package/dist/component/server/{providers.js → config.js} +2 -2
  120. package/dist/component/server/config.js.map +1 -0
  121. package/dist/component/server/{domains/core.js → core.js} +107 -88
  122. package/dist/component/server/core.js.map +1 -0
  123. package/dist/component/server/{provider.js → crypto.js} +3 -3
  124. package/dist/component/server/crypto.js.map +1 -0
  125. package/dist/component/server/device.js +1 -1
  126. package/dist/component/server/device.js.map +1 -1
  127. package/dist/component/server/enterprise/config.js +46 -0
  128. package/dist/component/server/enterprise/config.js.map +1 -0
  129. package/dist/component/server/{domains/sso.js → enterprise/domain.js} +6 -5
  130. package/dist/component/server/enterprise/domain.js.map +1 -0
  131. package/dist/component/server/enterprise/http.js +766 -0
  132. package/dist/component/server/enterprise/http.js.map +1 -0
  133. package/dist/component/server/enterprise/oidc.js +248 -0
  134. package/dist/component/server/enterprise/oidc.js.map +1 -0
  135. package/dist/component/server/enterprise/policy.js +85 -0
  136. package/dist/component/server/enterprise/policy.js.map +1 -0
  137. package/dist/component/server/enterprise/saml.js +338 -0
  138. package/dist/component/server/enterprise/saml.js.map +1 -0
  139. package/dist/component/server/enterprise/scim.js +97 -0
  140. package/dist/component/server/enterprise/scim.js.map +1 -0
  141. package/dist/component/server/enterprise/shared.js +51 -0
  142. package/dist/component/server/enterprise/shared.js.map +1 -0
  143. package/dist/component/server/errors.js.map +1 -1
  144. package/dist/component/server/http.js +2 -1
  145. package/dist/component/server/http.js.map +1 -1
  146. package/dist/component/server/identity.js +1 -1
  147. package/dist/component/server/identity.js.map +1 -1
  148. package/dist/component/server/{ratelimit.js → limits.js} +3 -3
  149. package/dist/component/server/limits.js.map +1 -0
  150. package/dist/component/server/mutations/account.js +3 -3
  151. package/dist/component/server/mutations/account.js.map +1 -1
  152. package/dist/component/server/mutations/code.js +2 -2
  153. package/dist/component/server/mutations/code.js.map +1 -1
  154. package/dist/component/server/mutations/invalidate.js +1 -1
  155. package/dist/component/server/mutations/invalidate.js.map +1 -1
  156. package/dist/component/server/mutations/oauth.js +5 -3
  157. package/dist/component/server/mutations/oauth.js.map +1 -1
  158. package/dist/component/server/mutations/refresh.js +1 -1
  159. package/dist/component/server/mutations/refresh.js.map +1 -1
  160. package/dist/component/server/mutations/register.js +3 -3
  161. package/dist/component/server/mutations/register.js.map +1 -1
  162. package/dist/component/server/mutations/retrieve.js +4 -4
  163. package/dist/component/server/mutations/retrieve.js.map +1 -1
  164. package/dist/component/server/mutations/signature.js +2 -2
  165. package/dist/component/server/mutations/signature.js.map +1 -1
  166. package/dist/component/server/mutations/signin.js +1 -1
  167. package/dist/component/server/mutations/signin.js.map +1 -1
  168. package/dist/component/server/mutations/signout.js +1 -1
  169. package/dist/component/server/mutations/signout.js.map +1 -1
  170. package/dist/component/server/mutations/store/refs.js +15 -0
  171. package/dist/component/server/mutations/store/refs.js.map +1 -0
  172. package/dist/component/server/mutations/store.js +80 -10
  173. package/dist/component/server/mutations/store.js.map +1 -1
  174. package/dist/component/server/mutations/verifier.js +1 -1
  175. package/dist/component/server/mutations/verifier.js.map +1 -1
  176. package/dist/component/server/mutations/verify.js +4 -3
  177. package/dist/component/server/mutations/verify.js.map +1 -1
  178. package/dist/component/server/oauth.js +1 -1
  179. package/dist/component/server/oauth.js.map +1 -1
  180. package/dist/component/server/passkey.js +2 -1
  181. package/dist/component/server/passkey.js.map +1 -1
  182. package/dist/component/server/redirects.js +1 -1
  183. package/dist/component/server/redirects.js.map +1 -1
  184. package/dist/component/server/refresh.js +1 -1
  185. package/dist/component/server/refresh.js.map +1 -1
  186. package/dist/component/server/{factory.d.ts → runtime.d.ts} +2 -2
  187. package/dist/component/server/runtime.d.ts.map +1 -0
  188. package/dist/component/server/runtime.js +413 -0
  189. package/dist/component/server/runtime.js.map +1 -0
  190. package/dist/component/server/signin.js +2 -1
  191. package/dist/component/server/signin.js.map +1 -1
  192. package/dist/component/server/totp.js +2 -1
  193. package/dist/component/server/totp.js.map +1 -1
  194. package/dist/component/server/types.d.ts +225 -41
  195. package/dist/component/server/types.d.ts.map +1 -1
  196. package/dist/component/server/types.js.map +1 -1
  197. package/dist/component/server/users.js +1 -1
  198. package/dist/component/server/users.js.map +1 -1
  199. package/dist/component/server/utils.js +1 -1
  200. package/dist/component/server/utils.js.map +1 -1
  201. package/dist/core/types.d.ts +369 -0
  202. package/dist/core/types.d.ts.map +1 -0
  203. package/dist/factors/device.js +105 -0
  204. package/dist/factors/device.js.map +1 -0
  205. package/dist/factors/passkey.js +181 -0
  206. package/dist/factors/passkey.js.map +1 -0
  207. package/dist/factors/totp.js +122 -0
  208. package/dist/factors/totp.js.map +1 -0
  209. package/dist/providers/credentials.d.ts +5 -2
  210. package/dist/providers/credentials.d.ts.map +1 -1
  211. package/dist/providers/credentials.js +2 -0
  212. package/dist/providers/credentials.js.map +1 -1
  213. package/dist/providers/email.d.ts +30 -0
  214. package/dist/providers/email.d.ts.map +1 -1
  215. package/dist/providers/email.js +24 -0
  216. package/dist/providers/email.js.map +1 -1
  217. package/dist/providers/phone.d.ts +28 -0
  218. package/dist/providers/phone.d.ts.map +1 -1
  219. package/dist/providers/phone.js +22 -0
  220. package/dist/providers/phone.js.map +1 -1
  221. package/dist/runtime/browser.js +68 -0
  222. package/dist/runtime/browser.js.map +1 -0
  223. package/dist/runtime/invite.js +51 -0
  224. package/dist/runtime/invite.js.map +1 -0
  225. package/dist/runtime/proxy.js +70 -0
  226. package/dist/runtime/proxy.js.map +1 -0
  227. package/dist/runtime/storage.js +37 -0
  228. package/dist/runtime/storage.js.map +1 -0
  229. package/dist/server/auth.d.ts +218 -28
  230. package/dist/server/auth.d.ts.map +1 -1
  231. package/dist/server/auth.js +68 -4
  232. package/dist/server/auth.js.map +1 -1
  233. package/dist/server/{fx.d.ts → authError.d.ts} +25 -15
  234. package/dist/server/authError.d.ts.map +1 -0
  235. package/dist/server/authError.js +34 -0
  236. package/dist/server/authError.js.map +1 -0
  237. package/dist/server/{providers.js → config.js} +2 -2
  238. package/dist/server/config.js.map +1 -0
  239. package/dist/server/core.d.ts +1436 -0
  240. package/dist/server/core.d.ts.map +1 -0
  241. package/dist/server/{domains/core.js → core.js} +107 -88
  242. package/dist/server/core.js.map +1 -0
  243. package/dist/server/{provider.d.ts → crypto.d.ts} +2 -2
  244. package/dist/server/crypto.d.ts.map +1 -0
  245. package/dist/server/{provider.js → crypto.js} +3 -3
  246. package/dist/{component/server/provider.js.map → server/crypto.js.map} +1 -1
  247. package/dist/server/device.js +1 -1
  248. package/dist/server/device.js.map +1 -1
  249. package/dist/server/enterprise/config.js +46 -0
  250. package/dist/server/enterprise/config.js.map +1 -0
  251. package/dist/server/{domains/sso.d.ts → enterprise/domain.d.ts} +4 -4
  252. package/dist/server/enterprise/domain.d.ts.map +1 -0
  253. package/dist/server/{domains/sso.js → enterprise/domain.js} +6 -5
  254. package/dist/server/enterprise/domain.js.map +1 -0
  255. package/dist/server/enterprise/http.d.ts +26 -0
  256. package/dist/server/enterprise/http.d.ts.map +1 -0
  257. package/dist/server/enterprise/http.js +766 -0
  258. package/dist/server/enterprise/http.js.map +1 -0
  259. package/dist/server/enterprise/oidc.js +248 -0
  260. package/dist/server/enterprise/oidc.js.map +1 -0
  261. package/dist/server/enterprise/policy.js +85 -0
  262. package/dist/server/enterprise/policy.js.map +1 -0
  263. package/dist/server/enterprise/saml.d.ts +1 -0
  264. package/dist/server/enterprise/saml.js +338 -0
  265. package/dist/server/enterprise/saml.js.map +1 -0
  266. package/dist/server/enterprise/scim.d.ts +1 -0
  267. package/dist/server/enterprise/scim.js +97 -0
  268. package/dist/server/enterprise/scim.js.map +1 -0
  269. package/dist/server/enterprise/shared.d.ts +5 -0
  270. package/dist/server/enterprise/shared.d.ts.map +1 -0
  271. package/dist/server/enterprise/shared.js +51 -0
  272. package/dist/server/enterprise/shared.js.map +1 -0
  273. package/dist/server/enterprise/validators.d.ts +1 -0
  274. package/dist/server/{enterpriseValidators.js → enterprise/validators.js} +2 -2
  275. package/dist/server/enterprise/validators.js.map +1 -0
  276. package/dist/server/errors.d.ts +2 -0
  277. package/dist/server/errors.d.ts.map +1 -1
  278. package/dist/server/errors.js +2 -0
  279. package/dist/server/errors.js.map +1 -1
  280. package/dist/server/http.d.ts +2 -2
  281. package/dist/server/http.d.ts.map +1 -1
  282. package/dist/server/http.js +2 -1
  283. package/dist/server/http.js.map +1 -1
  284. package/dist/server/identity.js +1 -1
  285. package/dist/server/identity.js.map +1 -1
  286. package/dist/server/index.d.ts +4 -705
  287. package/dist/server/index.js +4 -1367
  288. package/dist/server/limits.d.ts +1 -0
  289. package/dist/server/{ratelimit.js → limits.js} +3 -3
  290. package/dist/server/limits.js.map +1 -0
  291. package/dist/server/mounts.d.ts +647 -0
  292. package/dist/server/mounts.d.ts.map +1 -0
  293. package/dist/server/mounts.js +643 -0
  294. package/dist/server/mounts.js.map +1 -0
  295. package/dist/server/mutations/account.d.ts +8 -8
  296. package/dist/server/mutations/account.js +3 -3
  297. package/dist/server/mutations/account.js.map +1 -1
  298. package/dist/server/mutations/code.d.ts +13 -13
  299. package/dist/server/mutations/code.js +2 -2
  300. package/dist/server/mutations/code.js.map +1 -1
  301. package/dist/server/mutations/index.d.ts +8 -312
  302. package/dist/server/mutations/index.js +14 -84
  303. package/dist/server/mutations/invalidate.d.ts +5 -5
  304. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  305. package/dist/server/mutations/invalidate.js +1 -1
  306. package/dist/server/mutations/invalidate.js.map +1 -1
  307. package/dist/server/mutations/oauth.d.ts +9 -9
  308. package/dist/server/mutations/oauth.d.ts.map +1 -1
  309. package/dist/server/mutations/oauth.js +5 -3
  310. package/dist/server/mutations/oauth.js.map +1 -1
  311. package/dist/server/mutations/refresh.d.ts +4 -4
  312. package/dist/server/mutations/refresh.js +1 -1
  313. package/dist/server/mutations/refresh.js.map +1 -1
  314. package/dist/server/mutations/register.d.ts +10 -10
  315. package/dist/server/mutations/register.d.ts.map +1 -1
  316. package/dist/server/mutations/register.js +3 -3
  317. package/dist/server/mutations/register.js.map +1 -1
  318. package/dist/server/mutations/retrieve.d.ts +8 -10
  319. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  320. package/dist/server/mutations/retrieve.js +5 -7
  321. package/dist/server/mutations/retrieve.js.map +1 -1
  322. package/dist/server/mutations/signature.d.ts +6 -6
  323. package/dist/server/mutations/signature.d.ts.map +1 -1
  324. package/dist/server/mutations/signature.js +2 -2
  325. package/dist/server/mutations/signature.js.map +1 -1
  326. package/dist/server/mutations/signin.d.ts +1 -1
  327. package/dist/server/mutations/signin.js +1 -1
  328. package/dist/server/mutations/signin.js.map +1 -1
  329. package/dist/server/mutations/signout.d.ts +1 -1
  330. package/dist/server/mutations/signout.js +1 -1
  331. package/dist/server/mutations/signout.js.map +1 -1
  332. package/dist/server/mutations/store/refs.d.ts +12 -0
  333. package/dist/server/mutations/store/refs.d.ts.map +1 -0
  334. package/dist/server/mutations/store/refs.js +15 -0
  335. package/dist/server/mutations/store/refs.js.map +1 -0
  336. package/dist/server/mutations/store.d.ts +303 -9
  337. package/dist/server/mutations/store.d.ts.map +1 -1
  338. package/dist/server/mutations/store.js +80 -10
  339. package/dist/server/mutations/store.js.map +1 -1
  340. package/dist/server/mutations/verifier.d.ts +1 -1
  341. package/dist/server/mutations/verifier.js +1 -1
  342. package/dist/server/mutations/verifier.js.map +1 -1
  343. package/dist/server/mutations/verify.d.ts +8 -8
  344. package/dist/server/mutations/verify.d.ts.map +1 -1
  345. package/dist/server/mutations/verify.js +4 -3
  346. package/dist/server/mutations/verify.js.map +1 -1
  347. package/dist/server/oauth.js +1 -1
  348. package/dist/server/oauth.js.map +1 -1
  349. package/dist/server/passkey.d.ts +2 -2
  350. package/dist/server/passkey.d.ts.map +1 -1
  351. package/dist/server/passkey.js +3 -2
  352. package/dist/server/passkey.js.map +1 -1
  353. package/dist/server/redirects.js +1 -1
  354. package/dist/server/redirects.js.map +1 -1
  355. package/dist/server/refresh.js +1 -1
  356. package/dist/server/refresh.js.map +1 -1
  357. package/dist/server/{factory.d.ts → runtime.d.ts} +16 -16
  358. package/dist/server/runtime.d.ts.map +1 -0
  359. package/dist/server/runtime.js +413 -0
  360. package/dist/server/runtime.js.map +1 -0
  361. package/dist/server/signin.js +3 -2
  362. package/dist/server/signin.js.map +1 -1
  363. package/dist/server/ssr.d.ts +226 -0
  364. package/dist/server/ssr.d.ts.map +1 -0
  365. package/dist/server/ssr.js +786 -0
  366. package/dist/server/ssr.js.map +1 -0
  367. package/dist/server/totp.js +2 -1
  368. package/dist/server/totp.js.map +1 -1
  369. package/dist/server/types.d.ts +242 -42
  370. package/dist/server/types.d.ts.map +1 -1
  371. package/dist/server/types.js +12 -1
  372. package/dist/server/types.js.map +1 -1
  373. package/dist/server/users.js +1 -1
  374. package/dist/server/users.js.map +1 -1
  375. package/dist/server/utils.js +1 -1
  376. package/dist/server/utils.js.map +1 -1
  377. package/package.json +3 -4
  378. package/src/authorization/index.ts +46 -0
  379. package/src/cli/index.ts +38 -20
  380. package/src/client/core/types.ts +437 -0
  381. package/src/client/factors/device.ts +160 -0
  382. package/src/client/factors/passkey.ts +282 -0
  383. package/src/client/factors/totp.ts +150 -0
  384. package/src/client/index.ts +133 -1267
  385. package/src/client/runtime/browser.ts +112 -0
  386. package/src/client/runtime/invite.ts +65 -0
  387. package/src/client/runtime/proxy.ts +111 -0
  388. package/src/client/runtime/storage.ts +79 -0
  389. package/src/component/_generated/api.ts +40 -12
  390. package/src/component/_generated/component.ts +1772 -1798
  391. package/src/component/model.ts +6 -0
  392. package/src/component/public/enterprise/audit.ts +120 -0
  393. package/src/component/public/enterprise/core.ts +354 -0
  394. package/src/component/public/enterprise/domains.ts +323 -0
  395. package/src/component/public/enterprise/scim.ts +396 -0
  396. package/src/component/public/enterprise/secrets.ts +132 -0
  397. package/src/component/public/enterprise/webhooks.ts +306 -0
  398. package/src/component/public/factors/devices.ts +223 -0
  399. package/src/component/public/factors/passkeys.ts +242 -0
  400. package/src/component/public/factors/totp.ts +258 -0
  401. package/src/component/public/groups/core.ts +481 -0
  402. package/src/component/public/groups/invites.ts +602 -0
  403. package/src/component/public/groups/members.ts +409 -0
  404. package/src/component/public/identity/accounts.ts +206 -0
  405. package/src/component/public/identity/codes.ts +148 -0
  406. package/src/component/public/identity/sessions.ts +209 -0
  407. package/src/component/public/identity/tokens.ts +250 -0
  408. package/src/component/public/identity/users.ts +354 -0
  409. package/src/component/public/identity/verifiers.ts +157 -0
  410. package/src/component/public/security/keys.ts +365 -0
  411. package/src/component/public/security/limits.ts +173 -0
  412. package/src/component/public.ts +27 -5
  413. package/src/providers/credentials.ts +4 -5
  414. package/src/providers/email.ts +30 -0
  415. package/src/providers/phone.ts +28 -0
  416. package/src/server/auth.ts +282 -28
  417. package/src/server/authError.ts +44 -0
  418. package/src/server/core.ts +2095 -0
  419. package/src/server/{provider.ts → crypto.ts} +1 -1
  420. package/src/server/device.ts +1 -1
  421. package/src/server/enterprise/config.ts +51 -0
  422. package/src/server/{domains/sso.ts → enterprise/domain.ts} +4 -2
  423. package/src/server/enterprise/http.ts +1324 -0
  424. package/src/server/enterprise/oidc.ts +500 -0
  425. package/src/server/enterprise/policy.ts +128 -0
  426. package/src/server/enterprise/saml.ts +578 -0
  427. package/src/server/enterprise/scim.ts +135 -0
  428. package/src/server/enterprise/shared.ts +134 -0
  429. package/src/server/errors.ts +2 -0
  430. package/src/server/http.ts +3 -1
  431. package/src/server/identity.ts +1 -1
  432. package/src/server/index.ts +32 -2605
  433. package/src/server/{ratelimit.ts → limits.ts} +1 -1
  434. package/src/server/mounts.ts +948 -0
  435. package/src/server/mutations/account.ts +4 -4
  436. package/src/server/mutations/code.ts +3 -3
  437. package/src/server/mutations/index.ts +8 -148
  438. package/src/server/mutations/invalidate.ts +2 -2
  439. package/src/server/mutations/oauth.ts +8 -6
  440. package/src/server/mutations/refresh.ts +3 -3
  441. package/src/server/mutations/register.ts +3 -3
  442. package/src/server/mutations/retrieve.ts +4 -8
  443. package/src/server/mutations/signature.ts +3 -3
  444. package/src/server/mutations/signin.ts +2 -2
  445. package/src/server/mutations/signout.ts +2 -2
  446. package/src/server/mutations/store/refs.ts +10 -0
  447. package/src/server/mutations/store.ts +137 -9
  448. package/src/server/mutations/verifier.ts +2 -2
  449. package/src/server/mutations/verify.ts +5 -5
  450. package/src/server/oauth.ts +1 -1
  451. package/src/server/passkey.ts +3 -4
  452. package/src/server/redirects.ts +1 -1
  453. package/src/server/refresh.ts +1 -1
  454. package/src/server/runtime.ts +880 -0
  455. package/src/server/signin.ts +3 -1
  456. package/src/server/ssr.ts +1764 -0
  457. package/src/server/totp.ts +3 -1
  458. package/src/server/types.ts +254 -43
  459. package/src/server/users.ts +1 -1
  460. package/src/server/utils.ts +1 -1
  461. package/src/test.ts +25 -0
  462. package/dist/component/public/enterprise.d.ts +0 -54
  463. package/dist/component/public/enterprise.d.ts.map +0 -1
  464. package/dist/component/public/enterprise.js +0 -515
  465. package/dist/component/public/enterprise.js.map +0 -1
  466. package/dist/component/public/factors.d.ts +0 -52
  467. package/dist/component/public/factors.d.ts.map +0 -1
  468. package/dist/component/public/factors.js +0 -285
  469. package/dist/component/public/factors.js.map +0 -1
  470. package/dist/component/public/groups.d.ts +0 -124
  471. package/dist/component/public/groups.d.ts.map +0 -1
  472. package/dist/component/public/groups.js +0 -680
  473. package/dist/component/public/groups.js.map +0 -1
  474. package/dist/component/public/identity.d.ts +0 -93
  475. package/dist/component/public/identity.d.ts.map +0 -1
  476. package/dist/component/public/identity.js +0 -426
  477. package/dist/component/public/identity.js.map +0 -1
  478. package/dist/component/public/keys.d.ts +0 -41
  479. package/dist/component/public/keys.d.ts.map +0 -1
  480. package/dist/component/public/keys.js +0 -157
  481. package/dist/component/public/keys.js.map +0 -1
  482. package/dist/component/public/shared.d.ts +0 -26
  483. package/dist/component/public/shared.d.ts.map +0 -1
  484. package/dist/component/public/shared.js +0 -32
  485. package/dist/component/public/shared.js.map +0 -1
  486. package/dist/component/server/domains/core.js.map +0 -1
  487. package/dist/component/server/domains/sso.js.map +0 -1
  488. package/dist/component/server/factory.d.ts.map +0 -1
  489. package/dist/component/server/factory.js +0 -1134
  490. package/dist/component/server/factory.js.map +0 -1
  491. package/dist/component/server/fx.js +0 -66
  492. package/dist/component/server/fx.js.map +0 -1
  493. package/dist/component/server/mutations/index.js +0 -85
  494. package/dist/component/server/mutations/index.js.map +0 -1
  495. package/dist/component/server/providers.js.map +0 -1
  496. package/dist/component/server/ratelimit.js.map +0 -1
  497. package/dist/component/server/sso.js +0 -830
  498. package/dist/component/server/sso.js.map +0 -1
  499. package/dist/server/domains/core.d.ts +0 -449
  500. package/dist/server/domains/core.d.ts.map +0 -1
  501. package/dist/server/domains/core.js.map +0 -1
  502. package/dist/server/domains/sso.d.ts.map +0 -1
  503. package/dist/server/domains/sso.js.map +0 -1
  504. package/dist/server/enterpriseValidators.js.map +0 -1
  505. package/dist/server/factory.d.ts.map +0 -1
  506. package/dist/server/factory.js +0 -1134
  507. package/dist/server/factory.js.map +0 -1
  508. package/dist/server/fx.d.ts.map +0 -1
  509. package/dist/server/fx.js +0 -66
  510. package/dist/server/fx.js.map +0 -1
  511. package/dist/server/index.d.ts.map +0 -1
  512. package/dist/server/index.js.map +0 -1
  513. package/dist/server/mutations/index.d.ts.map +0 -1
  514. package/dist/server/mutations/index.js.map +0 -1
  515. package/dist/server/provider.d.ts.map +0 -1
  516. package/dist/server/provider.js.map +0 -1
  517. package/dist/server/providers.js.map +0 -1
  518. package/dist/server/ratelimit.js.map +0 -1
  519. package/dist/server/sso.js +0 -830
  520. package/dist/server/sso.js.map +0 -1
  521. package/dist/server/version.d.ts +0 -5
  522. package/dist/server/version.d.ts.map +0 -1
  523. package/dist/server/version.js +0 -6
  524. package/dist/server/version.js.map +0 -1
  525. package/src/component/public/enterprise.ts +0 -753
  526. package/src/component/public/factors.ts +0 -333
  527. package/src/component/public/groups.ts +0 -1066
  528. package/src/component/public/identity.ts +0 -569
  529. package/src/component/public/keys.ts +0 -209
  530. package/src/component/public/shared.ts +0 -119
  531. package/src/server/domains/core.ts +0 -1096
  532. package/src/server/factory.ts +0 -2181
  533. package/src/server/fx.ts +0 -152
  534. package/src/server/sso.ts +0 -1516
  535. package/src/server/version.ts +0 -2
  536. /package/dist/server/{enterpriseValidators.d.ts → config.d.ts} +0 -0
  537. /package/dist/server/{providers.d.ts → enterprise/config.d.ts} +0 -0
  538. /package/dist/server/{ratelimit.d.ts → enterprise/oidc.d.ts} +0 -0
  539. /package/dist/server/{sso.d.ts → enterprise/policy.d.ts} +0 -0
  540. /package/src/server/{providers.ts → config.ts} +0 -0
  541. /package/src/server/{enterpriseValidators.ts → enterprise/validators.ts} +0 -0
@@ -0,0 +1,204 @@
1
+ declare namespace members_d_exports {
2
+ export { memberAdd, memberGet, memberGetByGroupAndUser, memberList, memberRemove, memberResolve, memberUpdate };
3
+ }
4
+ /**
5
+ * Add a user as a member of a group.
6
+ *
7
+ * The `roleIds` field stores application-defined role identifiers. The auth
8
+ * component stores assignments but does not enforce access control — your
9
+ * application defines what each role means.
10
+ *
11
+ * Throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` when the user is
12
+ * already a member of the target group. The duplicate check uses the
13
+ * `group_id_user_id` compound index for an exact match.
14
+ *
15
+ * @param args.groupId - The `Id<"Group">` of the group to add the user to.
16
+ * @param args.userId - The `Id<"User">` of the user to add as a member.
17
+ * @param args.roleIds - Optional array of application-defined role identifiers (e.g. `["admin", "editor"]`).
18
+ * @param args.status - Optional membership status string (e.g. `"active"`, `"suspended"`). Defaults to whatever your application convention is.
19
+ * @param args.extend - Optional arbitrary payload for application-specific metadata on the membership.
20
+ * @returns The `Id<"GroupMember">` of the newly created member document.
21
+ * @throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` if the user is already a member of this group.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const memberId = await ctx.runMutation(
26
+ * components.auth.groups.memberAdd,
27
+ * {
28
+ * groupId: teamGroupId,
29
+ * userId: newUserId,
30
+ * roleIds: ["viewer"],
31
+ * status: "active",
32
+ * },
33
+ * );
34
+ * ```
35
+ */
36
+ declare const memberAdd: any;
37
+ /**
38
+ * Retrieve a member record by its document ID.
39
+ *
40
+ * Performs a direct lookup in the `GroupMember` table and returns the full
41
+ * member document, or `null` if no member exists with the given ID.
42
+ *
43
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to retrieve.
44
+ * @returns The member document (including `groupId`, `userId`, `roleIds`, `status`, etc.) or `null` if not found.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const member = await ctx.runQuery(components.auth.groups.memberGet, {
49
+ * memberId: existingMemberId,
50
+ * });
51
+ * if (member !== null) {
52
+ * console.log(member.userId, member.roleIds);
53
+ * }
54
+ * ```
55
+ */
56
+ declare const memberGet: any;
57
+ /**
58
+ * List members with optional filtering, sorting, and pagination.
59
+ *
60
+ * Returns `{ items, nextCursor }`. Supports filtering by `groupId`,
61
+ * `userId`, `roleId`, and `status`. The query engine automatically selects
62
+ * the best compound index based on the combination of filter fields
63
+ * provided. The `roleId` filter is applied in-memory after the index scan
64
+ * because role IDs are stored as an array.
65
+ *
66
+ * @param args.where - Optional filter criteria for narrowing results.
67
+ * @param args.where.groupId - Match members belonging to this group.
68
+ * @param args.where.userId - Match members for this specific user.
69
+ * @param args.where.roleId - Match members whose `roleIds` array includes this role identifier.
70
+ * @param args.where.status - Match members with this exact status string (e.g. `"active"`).
71
+ * @param args.limit - Maximum number of items per page (clamped to 1..100, defaults to 50).
72
+ * @param args.cursor - An opaque cursor string from a previous response's `nextCursor` to fetch the next page, or `null` to start from the beginning.
73
+ * @param args.orderBy - The field to sort by: `"_creationTime"` or `"status"`.
74
+ * @param args.order - Sort direction: `"asc"` or `"desc"` (defaults to `"desc"`).
75
+ * @returns An object `{ items, nextCursor }` where `items` is an array of member documents and `nextCursor` is `null` when there are no more pages.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const { items, nextCursor } = await ctx.runQuery(
80
+ * components.auth.groups.memberList,
81
+ * {
82
+ * where: { groupId: teamGroupId, status: "active" },
83
+ * limit: 30,
84
+ * order: "asc",
85
+ * },
86
+ * );
87
+ * ```
88
+ */
89
+ declare const memberList: any;
90
+ /**
91
+ * Look up a specific user's membership in a specific group.
92
+ *
93
+ * Uses the `group_id_user_id` compound index for an efficient exact-match
94
+ * lookup. Returns `null` if the user is not a member of the group. Unlike
95
+ * {@link memberResolve}, this does **not** walk the group hierarchy — it
96
+ * checks only the specified group.
97
+ *
98
+ * @param args.groupId - The `Id<"Group">` of the group to check.
99
+ * @param args.userId - The `Id<"User">` of the user whose membership to look up.
100
+ * @returns The member document or `null` if the user is not a direct member of the group.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const member = await ctx.runQuery(
105
+ * components.auth.groups.memberGetByGroupAndUser,
106
+ * { groupId: teamGroupId, userId: currentUserId },
107
+ * );
108
+ * if (member !== null) {
109
+ * console.log("User has roles:", member.roleIds);
110
+ * }
111
+ * ```
112
+ */
113
+ declare const memberGetByGroupAndUser: any;
114
+ /**
115
+ * Resolve a user's membership by walking the group hierarchy from the
116
+ * requested group up to the root. Returns the first matching membership
117
+ * found, enabling inherited (ancestor-level) access checks.
118
+ *
119
+ * The traversal walks from `groupId` to its `parentGroupId`, then to the
120
+ * parent's parent, and so on, up to `maxDepth` levels (default 32). It
121
+ * stops at the first group where the user has a membership record. Cycle
122
+ * detection prevents infinite loops if the hierarchy is malformed.
123
+ *
124
+ * When `ancestry` is `true`, the response includes a `traversedGroupIds`
125
+ * array showing the full path that was walked (useful for debugging or
126
+ * audit trails).
127
+ *
128
+ * This runs entirely inside the component (no cross-component RPCs per level).
129
+ *
130
+ * @param args.userId - The `Id<"User">` of the user whose membership to resolve.
131
+ * @param args.groupId - The `Id<"Group">` to start the upward traversal from.
132
+ * @param args.maxDepth - Optional maximum number of parent levels to traverse (defaults to 32). Set to `0` to check only the exact group.
133
+ * @param args.ancestry - When `true`, the response includes the `traversedGroupIds` array showing all group IDs visited during the walk.
134
+ * @returns An object with:
135
+ * - `membership` — the member document at the matched group, or `null` if none was found.
136
+ * - `matchedGroupId` — the ID of the group where membership was found, or `null`.
137
+ * - `depth` — how many levels above `groupId` the match was found (0 = direct), or `null` if not found.
138
+ * - `isDirect` — `true` when `depth === 0`.
139
+ * - `isInherited` — `true` when `depth > 0`.
140
+ * - `traversedGroupIds` — (only when `ancestry` is `true`) array of group IDs visited.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * const result = await ctx.runQuery(
145
+ * components.auth.groups.memberResolve,
146
+ * {
147
+ * userId: currentUserId,
148
+ * groupId: subTeamGroupId,
149
+ * maxDepth: 5,
150
+ * ancestry: true,
151
+ * },
152
+ * );
153
+ * if (result.membership !== null) {
154
+ * console.log(
155
+ * result.isDirect ? "Direct member" : `Inherited from depth ${result.depth}`,
156
+ * );
157
+ * }
158
+ * ```
159
+ */
160
+ declare const memberResolve: any;
161
+ /**
162
+ * Remove a member from a group by permanently deleting the member record.
163
+ *
164
+ * This is a hard delete — the `GroupMember` document is removed from the
165
+ * database entirely. If you need soft-delete semantics, use
166
+ * {@link memberUpdate} to set the `status` field instead.
167
+ *
168
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to delete.
169
+ * @returns `null` on success.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * await ctx.runMutation(components.auth.groups.memberRemove, {
174
+ * memberId: memberToRemoveId,
175
+ * });
176
+ * ```
177
+ */
178
+ declare const memberRemove: any;
179
+ /**
180
+ * Update a member record's mutable fields such as `roleIds`, `status`, and
181
+ * `extend`.
182
+ *
183
+ * Uses `db.patch` under the hood, so only the fields present in `data` are
184
+ * modified — all other fields on the member document are left unchanged.
185
+ *
186
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to update.
187
+ * @param args.data - A partial object of fields to patch. Supported keys include `roleIds`, `status`, and `extend`.
188
+ * @returns `null` on success.
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * await ctx.runMutation(components.auth.groups.memberUpdate, {
193
+ * memberId: existingMemberId,
194
+ * data: {
195
+ * roleIds: ["admin", "editor"],
196
+ * status: "active",
197
+ * },
198
+ * });
199
+ * ```
200
+ */
201
+ declare const memberUpdate: any;
202
+ //#endregion
203
+ export { memberAdd, memberGet, memberGetByGroupAndUser, memberList, memberRemove, memberResolve, memberUpdate, members_d_exports };
204
+ //# sourceMappingURL=members.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"members.d.ts","names":[],"sources":["../../../../src/component/public/groups/members.ts"],"mappings":";;;;;;;;;;;;;;;AAqCA;;;;;AAgDA;;;;;AAwCA;;;;;AAqGA;;;;;cA7La,SAAA;;;;;AAyUb;;;;;AA+BA;;;;;;;;;;cAxTa,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwCA,UAAA;;;;;;;;;;;;;;;;;;;;;;;;cAqGA,uBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2DA,aAAA;;;;;;;;;;;;;;;;;;cAiFA,YAAA;;;;;;;;;;;;;;;;;;;;;;;cA+BA,YAAA"}
@@ -0,0 +1,355 @@
1
+ import { mutation, query } from "../../functions.js";
2
+ import { vGroupMemberDoc, vPaginated } from "../../model.js";
3
+ import { ConvexError, v } from "convex/values";
4
+
5
+ //#region src/component/public/groups/members.ts
6
+ /**
7
+ * Add a user as a member of a group.
8
+ *
9
+ * The `roleIds` field stores application-defined role identifiers. The auth
10
+ * component stores assignments but does not enforce access control — your
11
+ * application defines what each role means.
12
+ *
13
+ * Throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` when the user is
14
+ * already a member of the target group. The duplicate check uses the
15
+ * `group_id_user_id` compound index for an exact match.
16
+ *
17
+ * @param args.groupId - The `Id<"Group">` of the group to add the user to.
18
+ * @param args.userId - The `Id<"User">` of the user to add as a member.
19
+ * @param args.roleIds - Optional array of application-defined role identifiers (e.g. `["admin", "editor"]`).
20
+ * @param args.status - Optional membership status string (e.g. `"active"`, `"suspended"`). Defaults to whatever your application convention is.
21
+ * @param args.extend - Optional arbitrary payload for application-specific metadata on the membership.
22
+ * @returns The `Id<"GroupMember">` of the newly created member document.
23
+ * @throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` if the user is already a member of this group.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const memberId = await ctx.runMutation(
28
+ * components.auth.groups.memberAdd,
29
+ * {
30
+ * groupId: teamGroupId,
31
+ * userId: newUserId,
32
+ * roleIds: ["viewer"],
33
+ * status: "active",
34
+ * },
35
+ * );
36
+ * ```
37
+ */
38
+ const memberAdd = mutation({
39
+ args: {
40
+ groupId: v.id("Group"),
41
+ userId: v.id("User"),
42
+ roleIds: v.optional(v.array(v.string())),
43
+ status: v.optional(v.string()),
44
+ extend: v.optional(v.any())
45
+ },
46
+ returns: v.id("GroupMember"),
47
+ handler: async (ctx, args) => {
48
+ const existingMembership = await ctx.db.query("GroupMember").withIndex("group_id_user_id", (q) => q.eq("groupId", args.groupId).eq("userId", args.userId)).unique();
49
+ if (existingMembership !== null) throw new ConvexError({
50
+ code: "DUPLICATE_MEMBERSHIP",
51
+ message: "User is already a member of this group",
52
+ groupId: args.groupId,
53
+ userId: args.userId,
54
+ existingMemberId: existingMembership._id
55
+ });
56
+ return await ctx.db.insert("GroupMember", args);
57
+ }
58
+ });
59
+ /**
60
+ * Retrieve a member record by its document ID.
61
+ *
62
+ * Performs a direct lookup in the `GroupMember` table and returns the full
63
+ * member document, or `null` if no member exists with the given ID.
64
+ *
65
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to retrieve.
66
+ * @returns The member document (including `groupId`, `userId`, `roleIds`, `status`, etc.) or `null` if not found.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * const member = await ctx.runQuery(components.auth.groups.memberGet, {
71
+ * memberId: existingMemberId,
72
+ * });
73
+ * if (member !== null) {
74
+ * console.log(member.userId, member.roleIds);
75
+ * }
76
+ * ```
77
+ */
78
+ const memberGet = query({
79
+ args: { memberId: v.id("GroupMember") },
80
+ returns: v.union(vGroupMemberDoc, v.null()),
81
+ handler: async (ctx, { memberId }) => {
82
+ return await ctx.db.get("GroupMember", memberId);
83
+ }
84
+ });
85
+ /**
86
+ * List members with optional filtering, sorting, and pagination.
87
+ *
88
+ * Returns `{ items, nextCursor }`. Supports filtering by `groupId`,
89
+ * `userId`, `roleId`, and `status`. The query engine automatically selects
90
+ * the best compound index based on the combination of filter fields
91
+ * provided. The `roleId` filter is applied in-memory after the index scan
92
+ * because role IDs are stored as an array.
93
+ *
94
+ * @param args.where - Optional filter criteria for narrowing results.
95
+ * @param args.where.groupId - Match members belonging to this group.
96
+ * @param args.where.userId - Match members for this specific user.
97
+ * @param args.where.roleId - Match members whose `roleIds` array includes this role identifier.
98
+ * @param args.where.status - Match members with this exact status string (e.g. `"active"`).
99
+ * @param args.limit - Maximum number of items per page (clamped to 1..100, defaults to 50).
100
+ * @param args.cursor - An opaque cursor string from a previous response's `nextCursor` to fetch the next page, or `null` to start from the beginning.
101
+ * @param args.orderBy - The field to sort by: `"_creationTime"` or `"status"`.
102
+ * @param args.order - Sort direction: `"asc"` or `"desc"` (defaults to `"desc"`).
103
+ * @returns An object `{ items, nextCursor }` where `items` is an array of member documents and `nextCursor` is `null` when there are no more pages.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const { items, nextCursor } = await ctx.runQuery(
108
+ * components.auth.groups.memberList,
109
+ * {
110
+ * where: { groupId: teamGroupId, status: "active" },
111
+ * limit: 30,
112
+ * order: "asc",
113
+ * },
114
+ * );
115
+ * ```
116
+ */
117
+ const memberList = query({
118
+ args: {
119
+ where: v.optional(v.object({
120
+ groupId: v.optional(v.id("Group")),
121
+ userId: v.optional(v.id("User")),
122
+ roleId: v.optional(v.string()),
123
+ status: v.optional(v.string())
124
+ })),
125
+ limit: v.optional(v.number()),
126
+ cursor: v.optional(v.union(v.string(), v.null())),
127
+ orderBy: v.optional(v.union(v.literal("_creationTime"), v.literal("status"))),
128
+ order: v.optional(v.union(v.literal("asc"), v.literal("desc")))
129
+ },
130
+ returns: vPaginated(vGroupMemberDoc),
131
+ handler: async (ctx, args) => {
132
+ const where = args.where ?? {};
133
+ const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);
134
+ const order = args.order ?? "desc";
135
+ let q;
136
+ if (where.groupId !== void 0 && where.userId !== void 0) {
137
+ q = ctx.db.query("GroupMember").withIndex("group_id_user_id", (idx) => idx.eq("groupId", where.groupId).eq("userId", where.userId));
138
+ if (where.status !== void 0) q = q.filter((f) => f.eq(f.field("status"), where.status));
139
+ } else if (where.groupId !== void 0 && where.status !== void 0) q = ctx.db.query("GroupMember").withIndex("group_id_status", (idx) => idx.eq("groupId", where.groupId).eq("status", where.status));
140
+ else if (where.groupId !== void 0) q = ctx.db.query("GroupMember").withIndex("group_id", (idx) => idx.eq("groupId", where.groupId));
141
+ else if (where.userId !== void 0) {
142
+ q = ctx.db.query("GroupMember").withIndex("user_id", (idx) => idx.eq("userId", where.userId));
143
+ if (where.status !== void 0) q = q.filter((f) => f.eq(f.field("status"), where.status));
144
+ } else {
145
+ q = ctx.db.query("GroupMember");
146
+ if (where.status !== void 0) q = q.filter((f) => f.eq(f.field("status"), where.status));
147
+ }
148
+ q = q.order(order);
149
+ let all = await q.collect();
150
+ if (where.roleId !== void 0) all = all.filter((doc) => (doc.roleIds ?? []).includes(where.roleId));
151
+ let startIdx = 0;
152
+ if (args.cursor) {
153
+ const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);
154
+ if (cursorIdx !== -1) startIdx = cursorIdx + 1;
155
+ }
156
+ const page = all.slice(startIdx, startIdx + limit + 1);
157
+ const hasMore = page.length > limit;
158
+ const items = hasMore ? page.slice(0, limit) : page;
159
+ return {
160
+ items,
161
+ nextCursor: hasMore ? items[items.length - 1]._id : null
162
+ };
163
+ }
164
+ });
165
+ /**
166
+ * Look up a specific user's membership in a specific group.
167
+ *
168
+ * Uses the `group_id_user_id` compound index for an efficient exact-match
169
+ * lookup. Returns `null` if the user is not a member of the group. Unlike
170
+ * {@link memberResolve}, this does **not** walk the group hierarchy — it
171
+ * checks only the specified group.
172
+ *
173
+ * @param args.groupId - The `Id<"Group">` of the group to check.
174
+ * @param args.userId - The `Id<"User">` of the user whose membership to look up.
175
+ * @returns The member document or `null` if the user is not a direct member of the group.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * const member = await ctx.runQuery(
180
+ * components.auth.groups.memberGetByGroupAndUser,
181
+ * { groupId: teamGroupId, userId: currentUserId },
182
+ * );
183
+ * if (member !== null) {
184
+ * console.log("User has roles:", member.roleIds);
185
+ * }
186
+ * ```
187
+ */
188
+ const memberGetByGroupAndUser = query({
189
+ args: {
190
+ groupId: v.id("Group"),
191
+ userId: v.id("User")
192
+ },
193
+ returns: v.union(vGroupMemberDoc, v.null()),
194
+ handler: async (ctx, { groupId, userId }) => {
195
+ return await ctx.db.query("GroupMember").withIndex("group_id_user_id", (q) => q.eq("groupId", groupId).eq("userId", userId)).unique();
196
+ }
197
+ });
198
+ /**
199
+ * Resolve a user's membership by walking the group hierarchy from the
200
+ * requested group up to the root. Returns the first matching membership
201
+ * found, enabling inherited (ancestor-level) access checks.
202
+ *
203
+ * The traversal walks from `groupId` to its `parentGroupId`, then to the
204
+ * parent's parent, and so on, up to `maxDepth` levels (default 32). It
205
+ * stops at the first group where the user has a membership record. Cycle
206
+ * detection prevents infinite loops if the hierarchy is malformed.
207
+ *
208
+ * When `ancestry` is `true`, the response includes a `traversedGroupIds`
209
+ * array showing the full path that was walked (useful for debugging or
210
+ * audit trails).
211
+ *
212
+ * This runs entirely inside the component (no cross-component RPCs per level).
213
+ *
214
+ * @param args.userId - The `Id<"User">` of the user whose membership to resolve.
215
+ * @param args.groupId - The `Id<"Group">` to start the upward traversal from.
216
+ * @param args.maxDepth - Optional maximum number of parent levels to traverse (defaults to 32). Set to `0` to check only the exact group.
217
+ * @param args.ancestry - When `true`, the response includes the `traversedGroupIds` array showing all group IDs visited during the walk.
218
+ * @returns An object with:
219
+ * - `membership` — the member document at the matched group, or `null` if none was found.
220
+ * - `matchedGroupId` — the ID of the group where membership was found, or `null`.
221
+ * - `depth` — how many levels above `groupId` the match was found (0 = direct), or `null` if not found.
222
+ * - `isDirect` — `true` when `depth === 0`.
223
+ * - `isInherited` — `true` when `depth > 0`.
224
+ * - `traversedGroupIds` — (only when `ancestry` is `true`) array of group IDs visited.
225
+ *
226
+ * @example
227
+ * ```ts
228
+ * const result = await ctx.runQuery(
229
+ * components.auth.groups.memberResolve,
230
+ * {
231
+ * userId: currentUserId,
232
+ * groupId: subTeamGroupId,
233
+ * maxDepth: 5,
234
+ * ancestry: true,
235
+ * },
236
+ * );
237
+ * if (result.membership !== null) {
238
+ * console.log(
239
+ * result.isDirect ? "Direct member" : `Inherited from depth ${result.depth}`,
240
+ * );
241
+ * }
242
+ * ```
243
+ */
244
+ const memberResolve = query({
245
+ args: {
246
+ userId: v.id("User"),
247
+ groupId: v.id("Group"),
248
+ maxDepth: v.optional(v.number()),
249
+ ancestry: v.optional(v.boolean())
250
+ },
251
+ returns: v.object({
252
+ membership: v.union(vGroupMemberDoc, v.null()),
253
+ matchedGroupId: v.union(v.id("Group"), v.null()),
254
+ depth: v.union(v.number(), v.null()),
255
+ isDirect: v.boolean(),
256
+ isInherited: v.boolean(),
257
+ traversedGroupIds: v.optional(v.array(v.id("Group")))
258
+ }),
259
+ handler: async (ctx, args) => {
260
+ const maxDepth = Math.max(0, Math.floor(args.maxDepth ?? 32));
261
+ const includeAncestry = args.ancestry ?? false;
262
+ const visited = /* @__PURE__ */ new Set();
263
+ const traversedGroupIds = [];
264
+ let currentGroupId = args.groupId;
265
+ let depth = 0;
266
+ while (currentGroupId !== void 0 && depth <= maxDepth) {
267
+ if (visited.has(currentGroupId)) break;
268
+ visited.add(currentGroupId);
269
+ if (includeAncestry) traversedGroupIds.push(currentGroupId);
270
+ const membership = await ctx.db.query("GroupMember").withIndex("group_id_user_id", (q) => q.eq("groupId", currentGroupId).eq("userId", args.userId)).unique();
271
+ if (membership !== null) return {
272
+ membership,
273
+ matchedGroupId: currentGroupId,
274
+ depth,
275
+ isDirect: depth === 0,
276
+ isInherited: depth > 0,
277
+ ...includeAncestry ? { traversedGroupIds } : {}
278
+ };
279
+ const groupDoc = await ctx.db.get(currentGroupId);
280
+ if (!groupDoc?.parentGroupId) break;
281
+ currentGroupId = groupDoc.parentGroupId;
282
+ depth++;
283
+ }
284
+ return {
285
+ membership: null,
286
+ matchedGroupId: null,
287
+ depth: null,
288
+ isDirect: false,
289
+ isInherited: false,
290
+ ...includeAncestry ? { traversedGroupIds } : {}
291
+ };
292
+ }
293
+ });
294
+ /**
295
+ * Remove a member from a group by permanently deleting the member record.
296
+ *
297
+ * This is a hard delete — the `GroupMember` document is removed from the
298
+ * database entirely. If you need soft-delete semantics, use
299
+ * {@link memberUpdate} to set the `status` field instead.
300
+ *
301
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to delete.
302
+ * @returns `null` on success.
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * await ctx.runMutation(components.auth.groups.memberRemove, {
307
+ * memberId: memberToRemoveId,
308
+ * });
309
+ * ```
310
+ */
311
+ const memberRemove = mutation({
312
+ args: { memberId: v.id("GroupMember") },
313
+ returns: v.null(),
314
+ handler: async (ctx, { memberId }) => {
315
+ await ctx.db.delete("GroupMember", memberId);
316
+ return null;
317
+ }
318
+ });
319
+ /**
320
+ * Update a member record's mutable fields such as `roleIds`, `status`, and
321
+ * `extend`.
322
+ *
323
+ * Uses `db.patch` under the hood, so only the fields present in `data` are
324
+ * modified — all other fields on the member document are left unchanged.
325
+ *
326
+ * @param args.memberId - The `Id<"GroupMember">` of the member record to update.
327
+ * @param args.data - A partial object of fields to patch. Supported keys include `roleIds`, `status`, and `extend`.
328
+ * @returns `null` on success.
329
+ *
330
+ * @example
331
+ * ```ts
332
+ * await ctx.runMutation(components.auth.groups.memberUpdate, {
333
+ * memberId: existingMemberId,
334
+ * data: {
335
+ * roleIds: ["admin", "editor"],
336
+ * status: "active",
337
+ * },
338
+ * });
339
+ * ```
340
+ */
341
+ const memberUpdate = mutation({
342
+ args: {
343
+ memberId: v.id("GroupMember"),
344
+ data: v.any()
345
+ },
346
+ returns: v.null(),
347
+ handler: async (ctx, { memberId, data }) => {
348
+ await ctx.db.patch("GroupMember", memberId, data);
349
+ return null;
350
+ }
351
+ });
352
+
353
+ //#endregion
354
+ export { memberAdd, memberGet, memberGetByGroupAndUser, memberList, memberRemove, memberResolve, memberUpdate };
355
+ //# sourceMappingURL=members.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"members.js","names":[],"sources":["../../../../src/component/public/groups/members.ts"],"sourcesContent":["import { ConvexError, v } from \"convex/values\";\nimport type { Id } from \"../../_generated/dataModel\";\nimport { mutation, query } from \"../../functions\";\nimport { vGroupMemberDoc, vPaginated } from \"../../model\";\n\n/**\n * Add a user as a member of a group.\n *\n * The `roleIds` field stores application-defined role identifiers. The auth\n * component stores assignments but does not enforce access control — your\n * application defines what each role means.\n *\n * Throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` when the user is\n * already a member of the target group. The duplicate check uses the\n * `group_id_user_id` compound index for an exact match.\n *\n * @param args.groupId - The `Id<\"Group\">` of the group to add the user to.\n * @param args.userId - The `Id<\"User\">` of the user to add as a member.\n * @param args.roleIds - Optional array of application-defined role identifiers (e.g. `[\"admin\", \"editor\"]`).\n * @param args.status - Optional membership status string (e.g. `\"active\"`, `\"suspended\"`). Defaults to whatever your application convention is.\n * @param args.extend - Optional arbitrary payload for application-specific metadata on the membership.\n * @returns The `Id<\"GroupMember\">` of the newly created member document.\n * @throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` if the user is already a member of this group.\n *\n * @example\n * ```ts\n * const memberId = await ctx.runMutation(\n * components.auth.groups.memberAdd,\n * {\n * groupId: teamGroupId,\n * userId: newUserId,\n * roleIds: [\"viewer\"],\n * status: \"active\",\n * },\n * );\n * ```\n */\nexport const memberAdd = mutation({\n args: {\n groupId: v.id(\"Group\"),\n userId: v.id(\"User\"),\n roleIds: v.optional(v.array(v.string())),\n status: v.optional(v.string()),\n extend: v.optional(v.any()),\n },\n returns: v.id(\"GroupMember\"),\n handler: async (ctx, args) => {\n const existingMembership = await ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id_user_id\", (q) =>\n q.eq(\"groupId\", args.groupId).eq(\"userId\", args.userId),\n )\n .unique();\n if (existingMembership !== null) {\n throw new ConvexError({\n code: \"DUPLICATE_MEMBERSHIP\",\n message: \"User is already a member of this group\",\n groupId: args.groupId,\n userId: args.userId,\n existingMemberId: existingMembership._id,\n });\n }\n return await ctx.db.insert(\"GroupMember\", args);\n },\n});\n\n/**\n * Retrieve a member record by its document ID.\n *\n * Performs a direct lookup in the `GroupMember` table and returns the full\n * member document, or `null` if no member exists with the given ID.\n *\n * @param args.memberId - The `Id<\"GroupMember\">` of the member record to retrieve.\n * @returns The member document (including `groupId`, `userId`, `roleIds`, `status`, etc.) or `null` if not found.\n *\n * @example\n * ```ts\n * const member = await ctx.runQuery(components.auth.groups.memberGet, {\n * memberId: existingMemberId,\n * });\n * if (member !== null) {\n * console.log(member.userId, member.roleIds);\n * }\n * ```\n */\nexport const memberGet = query({\n args: { memberId: v.id(\"GroupMember\") },\n returns: v.union(vGroupMemberDoc, v.null()),\n handler: async (ctx, { memberId }) => {\n return await ctx.db.get(\"GroupMember\", memberId);\n },\n});\n\n/**\n * List members with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }`. Supports filtering by `groupId`,\n * `userId`, `roleId`, and `status`. The query engine automatically selects\n * the best compound index based on the combination of filter fields\n * provided. The `roleId` filter is applied in-memory after the index scan\n * because role IDs are stored as an array.\n *\n * @param args.where - Optional filter criteria for narrowing results.\n * @param args.where.groupId - Match members belonging to this group.\n * @param args.where.userId - Match members for this specific user.\n * @param args.where.roleId - Match members whose `roleIds` array includes this role identifier.\n * @param args.where.status - Match members with this exact status string (e.g. `\"active\"`).\n * @param args.limit - Maximum number of items per page (clamped to 1..100, defaults to 50).\n * @param args.cursor - An opaque cursor string from a previous response's `nextCursor` to fetch the next page, or `null` to start from the beginning.\n * @param args.orderBy - The field to sort by: `\"_creationTime\"` or `\"status\"`.\n * @param args.order - Sort direction: `\"asc\"` or `\"desc\"` (defaults to `\"desc\"`).\n * @returns An object `{ items, nextCursor }` where `items` is an array of member documents and `nextCursor` is `null` when there are no more pages.\n *\n * @example\n * ```ts\n * const { items, nextCursor } = await ctx.runQuery(\n * components.auth.groups.memberList,\n * {\n * where: { groupId: teamGroupId, status: \"active\" },\n * limit: 30,\n * order: \"asc\",\n * },\n * );\n * ```\n */\nexport const memberList = query({\n args: {\n where: v.optional(\n v.object({\n groupId: v.optional(v.id(\"Group\")),\n userId: v.optional(v.id(\"User\")),\n roleId: v.optional(v.string()),\n status: v.optional(v.string()),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(v.literal(\"_creationTime\"), v.literal(\"status\")),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n returns: vPaginated(vGroupMemberDoc),\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.groupId !== undefined && where.userId !== undefined) {\n q = ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id_user_id\", (idx) =>\n idx.eq(\"groupId\", where.groupId!).eq(\"userId\", where.userId!),\n );\n if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n } else if (where.groupId !== undefined && where.status !== undefined) {\n q = ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id_status\", (idx) =>\n idx.eq(\"groupId\", where.groupId!).eq(\"status\", where.status!),\n );\n } else if (where.groupId !== undefined) {\n q = ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", where.groupId!));\n } else if (where.userId !== undefined) {\n q = ctx.db\n .query(\"GroupMember\")\n .withIndex(\"user_id\", (idx) => idx.eq(\"userId\", where.userId!));\n if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n } else {\n q = ctx.db.query(\"GroupMember\");\n if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n }\n\n q = q.order(order);\n\n let all = await q.collect();\n if (where.roleId !== undefined) {\n all = all.filter((doc) => (doc.roleIds ?? []).includes(where.roleId!));\n }\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/**\n * Look up a specific user's membership in a specific group.\n *\n * Uses the `group_id_user_id` compound index for an efficient exact-match\n * lookup. Returns `null` if the user is not a member of the group. Unlike\n * {@link memberResolve}, this does **not** walk the group hierarchy — it\n * checks only the specified group.\n *\n * @param args.groupId - The `Id<\"Group\">` of the group to check.\n * @param args.userId - The `Id<\"User\">` of the user whose membership to look up.\n * @returns The member document or `null` if the user is not a direct member of the group.\n *\n * @example\n * ```ts\n * const member = await ctx.runQuery(\n * components.auth.groups.memberGetByGroupAndUser,\n * { groupId: teamGroupId, userId: currentUserId },\n * );\n * if (member !== null) {\n * console.log(\"User has roles:\", member.roleIds);\n * }\n * ```\n */\nexport const memberGetByGroupAndUser = query({\n args: { groupId: v.id(\"Group\"), userId: v.id(\"User\") },\n returns: v.union(vGroupMemberDoc, v.null()),\n handler: async (ctx, { groupId, userId }) => {\n return await ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id_user_id\", (q) =>\n q.eq(\"groupId\", groupId).eq(\"userId\", userId),\n )\n .unique();\n },\n});\n\n/**\n * Resolve a user's membership by walking the group hierarchy from the\n * requested group up to the root. Returns the first matching membership\n * found, enabling inherited (ancestor-level) access checks.\n *\n * The traversal walks from `groupId` to its `parentGroupId`, then to the\n * parent's parent, and so on, up to `maxDepth` levels (default 32). It\n * stops at the first group where the user has a membership record. Cycle\n * detection prevents infinite loops if the hierarchy is malformed.\n *\n * When `ancestry` is `true`, the response includes a `traversedGroupIds`\n * array showing the full path that was walked (useful for debugging or\n * audit trails).\n *\n * This runs entirely inside the component (no cross-component RPCs per level).\n *\n * @param args.userId - The `Id<\"User\">` of the user whose membership to resolve.\n * @param args.groupId - The `Id<\"Group\">` to start the upward traversal from.\n * @param args.maxDepth - Optional maximum number of parent levels to traverse (defaults to 32). Set to `0` to check only the exact group.\n * @param args.ancestry - When `true`, the response includes the `traversedGroupIds` array showing all group IDs visited during the walk.\n * @returns An object with:\n * - `membership` — the member document at the matched group, or `null` if none was found.\n * - `matchedGroupId` — the ID of the group where membership was found, or `null`.\n * - `depth` — how many levels above `groupId` the match was found (0 = direct), or `null` if not found.\n * - `isDirect` — `true` when `depth === 0`.\n * - `isInherited` — `true` when `depth > 0`.\n * - `traversedGroupIds` — (only when `ancestry` is `true`) array of group IDs visited.\n *\n * @example\n * ```ts\n * const result = await ctx.runQuery(\n * components.auth.groups.memberResolve,\n * {\n * userId: currentUserId,\n * groupId: subTeamGroupId,\n * maxDepth: 5,\n * ancestry: true,\n * },\n * );\n * if (result.membership !== null) {\n * console.log(\n * result.isDirect ? \"Direct member\" : `Inherited from depth ${result.depth}`,\n * );\n * }\n * ```\n */\nexport const memberResolve = query({\n args: {\n userId: v.id(\"User\"),\n groupId: v.id(\"Group\"),\n maxDepth: v.optional(v.number()),\n ancestry: v.optional(v.boolean()),\n },\n returns: v.object({\n membership: v.union(vGroupMemberDoc, v.null()),\n matchedGroupId: v.union(v.id(\"Group\"), v.null()),\n depth: v.union(v.number(), v.null()),\n isDirect: v.boolean(),\n isInherited: v.boolean(),\n traversedGroupIds: v.optional(v.array(v.id(\"Group\"))),\n }),\n handler: async (ctx, args) => {\n const maxDepth = Math.max(0, Math.floor(args.maxDepth ?? 32));\n const includeAncestry = args.ancestry ?? false;\n const visited = new Set<string>();\n const traversedGroupIds: Id<\"Group\">[] = [];\n let currentGroupId: Id<\"Group\"> | undefined = args.groupId;\n let depth = 0;\n\n while (currentGroupId !== undefined && depth <= maxDepth) {\n if (visited.has(currentGroupId)) break;\n visited.add(currentGroupId);\n if (includeAncestry) traversedGroupIds.push(currentGroupId);\n\n const membership = await ctx.db\n .query(\"GroupMember\")\n .withIndex(\"group_id_user_id\", (q) =>\n q.eq(\"groupId\", currentGroupId!).eq(\"userId\", args.userId),\n )\n .unique();\n\n if (membership !== null) {\n return {\n membership,\n matchedGroupId: currentGroupId,\n depth,\n isDirect: depth === 0,\n isInherited: depth > 0,\n ...(includeAncestry ? { traversedGroupIds } : {}),\n };\n }\n\n const groupDoc: { parentGroupId?: Id<\"Group\"> } | null =\n await ctx.db.get(currentGroupId);\n if (!groupDoc?.parentGroupId) break;\n currentGroupId = groupDoc.parentGroupId;\n depth++;\n }\n\n return {\n membership: null,\n matchedGroupId: null,\n depth: null,\n isDirect: false,\n isInherited: false,\n ...(includeAncestry ? { traversedGroupIds } : {}),\n };\n },\n});\n\n/**\n * Remove a member from a group by permanently deleting the member record.\n *\n * This is a hard delete — the `GroupMember` document is removed from the\n * database entirely. If you need soft-delete semantics, use\n * {@link memberUpdate} to set the `status` field instead.\n *\n * @param args.memberId - The `Id<\"GroupMember\">` of the member record to delete.\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(components.auth.groups.memberRemove, {\n * memberId: memberToRemoveId,\n * });\n * ```\n */\nexport const memberRemove = mutation({\n args: { memberId: v.id(\"GroupMember\") },\n returns: v.null(),\n handler: async (ctx, { memberId }) => {\n await ctx.db.delete(\"GroupMember\", memberId);\n return null;\n },\n});\n\n/**\n * Update a member record's mutable fields such as `roleIds`, `status`, and\n * `extend`.\n *\n * Uses `db.patch` under the hood, so only the fields present in `data` are\n * modified — all other fields on the member document are left unchanged.\n *\n * @param args.memberId - The `Id<\"GroupMember\">` of the member record to update.\n * @param args.data - A partial object of fields to patch. Supported keys include `roleIds`, `status`, and `extend`.\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(components.auth.groups.memberUpdate, {\n * memberId: existingMemberId,\n * data: {\n * roleIds: [\"admin\", \"editor\"],\n * status: \"active\",\n * },\n * });\n * ```\n */\nexport const memberUpdate = mutation({\n args: { memberId: v.id(\"GroupMember\"), data: v.any() },\n returns: v.null(),\n handler: async (ctx, { memberId, data }) => {\n await ctx.db.patch(\"GroupMember\", memberId, data);\n return null;\n },\n});\n\n// ============================================================================\n// Invites\n// ============================================================================\n"],"mappings":"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"}