@convex-dev/better-auth 0.8.0-alpha.8 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/commonjs/auth.d.ts +4 -0
  2. package/dist/commonjs/auth.d.ts.map +1 -0
  3. package/dist/commonjs/auth.js +44 -0
  4. package/dist/commonjs/auth.js.map +1 -0
  5. package/dist/commonjs/client/adapter.d.ts +8 -10
  6. package/dist/commonjs/client/adapter.d.ts.map +1 -1
  7. package/dist/commonjs/client/adapter.js +48 -32
  8. package/dist/commonjs/client/adapter.js.map +1 -1
  9. package/dist/commonjs/client/adapterUtils.d.ts +66 -0
  10. package/dist/commonjs/client/adapterUtils.d.ts.map +1 -0
  11. package/dist/commonjs/client/adapterUtils.js +429 -0
  12. package/dist/commonjs/client/adapterUtils.js.map +1 -0
  13. package/dist/commonjs/client/createSchema.d.ts +24 -0
  14. package/dist/commonjs/client/createSchema.d.ts.map +1 -0
  15. package/dist/commonjs/client/createSchema.js +101 -0
  16. package/dist/commonjs/client/createSchema.js.map +1 -0
  17. package/dist/commonjs/client/index.d.ts +449 -599
  18. package/dist/commonjs/client/index.d.ts.map +1 -1
  19. package/dist/commonjs/client/index.js +339 -212
  20. package/dist/commonjs/client/index.js.map +1 -1
  21. package/dist/commonjs/component/adapter.d.ts +128 -0
  22. package/dist/commonjs/component/adapter.d.ts.map +1 -0
  23. package/dist/commonjs/component/adapter.js +5 -0
  24. package/dist/commonjs/component/adapter.js.map +1 -0
  25. package/dist/commonjs/component/adapterTest.d.ts +3 -5
  26. package/dist/commonjs/component/adapterTest.d.ts.map +1 -1
  27. package/dist/commonjs/component/adapterTest.js +3 -17
  28. package/dist/commonjs/component/adapterTest.js.map +1 -1
  29. package/dist/commonjs/component/lib.d.ts +4 -2
  30. package/dist/commonjs/component/lib.d.ts.map +1 -1
  31. package/dist/commonjs/component/schema.d.ts +464 -175
  32. package/dist/commonjs/component/schema.d.ts.map +1 -1
  33. package/dist/commonjs/component/schema.js +74 -158
  34. package/dist/commonjs/component/schema.js.map +1 -1
  35. package/dist/commonjs/component/util.d.ts +31 -11
  36. package/dist/commonjs/component/util.d.ts.map +1 -1
  37. package/dist/commonjs/nextjs/index.d.ts +1 -2
  38. package/dist/commonjs/nextjs/index.d.ts.map +1 -1
  39. package/dist/commonjs/nextjs/index.js +3 -2
  40. package/dist/commonjs/nextjs/index.js.map +1 -1
  41. package/dist/commonjs/plugins/convex/client.d.ts +2 -5
  42. package/dist/commonjs/plugins/convex/client.d.ts.map +1 -1
  43. package/dist/commonjs/plugins/convex/client.js.map +1 -1
  44. package/dist/commonjs/plugins/convex/index.d.ts +13 -144
  45. package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
  46. package/dist/commonjs/plugins/convex/index.js +11 -125
  47. package/dist/commonjs/plugins/convex/index.js.map +1 -1
  48. package/dist/commonjs/plugins/cross-domain/index.js +2 -2
  49. package/dist/commonjs/plugins/cross-domain/index.js.map +1 -1
  50. package/dist/commonjs/react-start/index.d.ts +17 -36
  51. package/dist/commonjs/react-start/index.d.ts.map +1 -1
  52. package/dist/commonjs/react-start/index.js +43 -31
  53. package/dist/commonjs/react-start/index.js.map +1 -1
  54. package/dist/commonjs/src/auth.d.ts +3085 -0
  55. package/dist/commonjs/src/auth.d.ts.map +1 -0
  56. package/dist/commonjs/src/auth.js +72 -0
  57. package/dist/commonjs/src/auth.js.map +1 -0
  58. package/dist/commonjs/src/client/adapter.d.ts +18 -0
  59. package/dist/commonjs/src/client/adapter.d.ts.map +1 -0
  60. package/dist/commonjs/src/client/adapter.js +211 -0
  61. package/dist/commonjs/src/client/adapter.js.map +1 -0
  62. package/dist/commonjs/src/client/createSchema.d.ts +25 -0
  63. package/dist/commonjs/src/client/createSchema.d.ts.map +1 -0
  64. package/dist/commonjs/src/client/createSchema.js +103 -0
  65. package/dist/commonjs/src/client/createSchema.js.map +1 -0
  66. package/dist/commonjs/src/client/index.d.ts +3310 -0
  67. package/dist/commonjs/src/client/index.d.ts.map +1 -0
  68. package/dist/commonjs/src/client/index.js +377 -0
  69. package/dist/commonjs/src/client/index.js.map +1 -0
  70. package/dist/commonjs/src/client/plugins/index.d.ts +3 -0
  71. package/dist/commonjs/src/client/plugins/index.d.ts.map +1 -0
  72. package/dist/commonjs/src/client/plugins/index.js +3 -0
  73. package/dist/commonjs/src/client/plugins/index.js.map +1 -0
  74. package/dist/commonjs/src/component/_generated/api.d.ts +12 -0
  75. package/dist/commonjs/src/component/_generated/api.d.ts.map +1 -0
  76. package/dist/commonjs/src/component/_generated/api.js +22 -0
  77. package/dist/commonjs/src/component/_generated/api.js.map +1 -0
  78. package/dist/commonjs/src/component/_generated/server.d.ts +64 -0
  79. package/dist/commonjs/src/component/_generated/server.d.ts.map +1 -0
  80. package/dist/commonjs/src/component/_generated/server.js +74 -0
  81. package/dist/commonjs/src/component/_generated/server.js.map +1 -0
  82. package/dist/commonjs/src/component/adapter.d.ts +355 -0
  83. package/dist/commonjs/src/component/adapter.d.ts.map +1 -0
  84. package/dist/commonjs/src/component/adapter.js +573 -0
  85. package/dist/commonjs/src/component/adapter.js.map +1 -0
  86. package/dist/commonjs/src/component/adapterTest.d.ts +18 -0
  87. package/dist/commonjs/src/component/adapterTest.d.ts.map +1 -0
  88. package/dist/commonjs/src/component/adapterTest.js +75 -0
  89. package/dist/commonjs/src/component/adapterTest.js.map +1 -0
  90. package/dist/commonjs/src/component/convex.config.d.ts +3 -0
  91. package/dist/commonjs/src/component/convex.config.d.ts.map +1 -0
  92. package/dist/commonjs/src/component/convex.config.js +4 -0
  93. package/dist/commonjs/src/component/convex.config.js.map +1 -0
  94. package/dist/commonjs/src/component/schema.d.ts +562 -0
  95. package/dist/commonjs/src/component/schema.d.ts.map +1 -0
  96. package/dist/commonjs/src/component/schema.js +217 -0
  97. package/dist/commonjs/src/component/schema.js.map +1 -0
  98. package/dist/commonjs/src/nextjs/index.d.ts +10 -0
  99. package/dist/commonjs/src/nextjs/index.d.ts.map +1 -0
  100. package/dist/commonjs/src/nextjs/index.js +43 -0
  101. package/dist/commonjs/src/nextjs/index.js.map +1 -0
  102. package/dist/commonjs/src/plugins/convex/client.d.ts +9 -0
  103. package/dist/commonjs/src/plugins/convex/client.d.ts.map +1 -0
  104. package/dist/commonjs/src/plugins/convex/client.js +7 -0
  105. package/dist/commonjs/src/plugins/convex/client.js.map +1 -0
  106. package/dist/commonjs/src/plugins/convex/index.d.ts +415 -0
  107. package/dist/commonjs/src/plugins/convex/index.d.ts.map +1 -0
  108. package/dist/commonjs/src/plugins/convex/index.js +354 -0
  109. package/dist/commonjs/src/plugins/convex/index.js.map +1 -0
  110. package/dist/commonjs/src/plugins/cross-domain/client.d.ts +132 -0
  111. package/dist/commonjs/src/plugins/cross-domain/client.d.ts.map +1 -0
  112. package/dist/commonjs/src/plugins/cross-domain/client.js +176 -0
  113. package/dist/commonjs/src/plugins/cross-domain/client.js.map +1 -0
  114. package/dist/commonjs/src/plugins/cross-domain/index.d.ts +83 -0
  115. package/dist/commonjs/src/plugins/cross-domain/index.d.ts.map +1 -0
  116. package/dist/commonjs/src/plugins/cross-domain/index.js +153 -0
  117. package/dist/commonjs/src/plugins/cross-domain/index.js.map +1 -0
  118. package/dist/commonjs/src/plugins/index.d.ts +3 -0
  119. package/dist/commonjs/src/plugins/index.d.ts.map +1 -0
  120. package/dist/commonjs/src/plugins/index.js +3 -0
  121. package/dist/commonjs/src/plugins/index.js.map +1 -0
  122. package/dist/commonjs/src/react/client.d.ts +31 -0
  123. package/dist/commonjs/src/react/client.d.ts.map +1 -0
  124. package/dist/commonjs/src/react/client.js +96 -0
  125. package/dist/commonjs/src/react/client.js.map +1 -0
  126. package/dist/commonjs/src/react/index.d.ts +9 -0
  127. package/dist/commonjs/src/react/index.d.ts.map +1 -0
  128. package/dist/commonjs/src/react/index.js +15 -0
  129. package/dist/commonjs/src/react/index.js.map +1 -0
  130. package/dist/commonjs/src/react-start/index.d.ts +45 -0
  131. package/dist/commonjs/src/react-start/index.d.ts.map +1 -0
  132. package/dist/commonjs/src/react-start/index.js +60 -0
  133. package/dist/commonjs/src/react-start/index.js.map +1 -0
  134. package/dist/commonjs/src/utils/index.d.ts +9 -0
  135. package/dist/commonjs/src/utils/index.d.ts.map +1 -0
  136. package/dist/commonjs/src/utils/index.js +35 -0
  137. package/dist/commonjs/src/utils/index.js.map +1 -0
  138. package/dist/esm/auth.d.ts +4 -0
  139. package/dist/esm/auth.d.ts.map +1 -0
  140. package/dist/esm/auth.js +44 -0
  141. package/dist/esm/auth.js.map +1 -0
  142. package/dist/esm/client/adapter.d.ts +8 -10
  143. package/dist/esm/client/adapter.d.ts.map +1 -1
  144. package/dist/esm/client/adapter.js +48 -32
  145. package/dist/esm/client/adapter.js.map +1 -1
  146. package/dist/esm/client/adapterUtils.d.ts +66 -0
  147. package/dist/esm/client/adapterUtils.d.ts.map +1 -0
  148. package/dist/esm/client/adapterUtils.js +429 -0
  149. package/dist/esm/client/adapterUtils.js.map +1 -0
  150. package/dist/esm/client/createSchema.d.ts +24 -0
  151. package/dist/esm/client/createSchema.d.ts.map +1 -0
  152. package/dist/esm/client/createSchema.js +101 -0
  153. package/dist/esm/client/createSchema.js.map +1 -0
  154. package/dist/esm/client/index.d.ts +449 -599
  155. package/dist/esm/client/index.d.ts.map +1 -1
  156. package/dist/esm/client/index.js +339 -212
  157. package/dist/esm/client/index.js.map +1 -1
  158. package/dist/esm/component/adapter.d.ts +128 -0
  159. package/dist/esm/component/adapter.d.ts.map +1 -0
  160. package/dist/esm/component/adapter.js +5 -0
  161. package/dist/esm/component/adapter.js.map +1 -0
  162. package/dist/esm/component/adapterTest.d.ts +3 -5
  163. package/dist/esm/component/adapterTest.d.ts.map +1 -1
  164. package/dist/esm/component/adapterTest.js +3 -17
  165. package/dist/esm/component/adapterTest.js.map +1 -1
  166. package/dist/esm/component/lib.d.ts +4 -2
  167. package/dist/esm/component/lib.d.ts.map +1 -1
  168. package/dist/esm/component/schema.d.ts +464 -175
  169. package/dist/esm/component/schema.d.ts.map +1 -1
  170. package/dist/esm/component/schema.js +74 -158
  171. package/dist/esm/component/schema.js.map +1 -1
  172. package/dist/esm/component/util.d.ts +31 -11
  173. package/dist/esm/component/util.d.ts.map +1 -1
  174. package/dist/esm/nextjs/index.d.ts +1 -2
  175. package/dist/esm/nextjs/index.d.ts.map +1 -1
  176. package/dist/esm/nextjs/index.js +3 -2
  177. package/dist/esm/nextjs/index.js.map +1 -1
  178. package/dist/esm/plugins/convex/client.d.ts +2 -5
  179. package/dist/esm/plugins/convex/client.d.ts.map +1 -1
  180. package/dist/esm/plugins/convex/client.js.map +1 -1
  181. package/dist/esm/plugins/convex/index.d.ts +13 -144
  182. package/dist/esm/plugins/convex/index.d.ts.map +1 -1
  183. package/dist/esm/plugins/convex/index.js +11 -125
  184. package/dist/esm/plugins/convex/index.js.map +1 -1
  185. package/dist/esm/plugins/cross-domain/index.js +2 -2
  186. package/dist/esm/plugins/cross-domain/index.js.map +1 -1
  187. package/dist/esm/react-start/index.d.ts +17 -36
  188. package/dist/esm/react-start/index.d.ts.map +1 -1
  189. package/dist/esm/react-start/index.js +43 -31
  190. package/dist/esm/react-start/index.js.map +1 -1
  191. package/dist/esm/src/auth.d.ts +3085 -0
  192. package/dist/esm/src/auth.d.ts.map +1 -0
  193. package/dist/esm/src/auth.js +72 -0
  194. package/dist/esm/src/auth.js.map +1 -0
  195. package/dist/esm/src/client/adapter.d.ts +18 -0
  196. package/dist/esm/src/client/adapter.d.ts.map +1 -0
  197. package/dist/esm/src/client/adapter.js +211 -0
  198. package/dist/esm/src/client/adapter.js.map +1 -0
  199. package/dist/esm/src/client/createSchema.d.ts +25 -0
  200. package/dist/esm/src/client/createSchema.d.ts.map +1 -0
  201. package/dist/esm/src/client/createSchema.js +103 -0
  202. package/dist/esm/src/client/createSchema.js.map +1 -0
  203. package/dist/esm/src/client/index.d.ts +3310 -0
  204. package/dist/esm/src/client/index.d.ts.map +1 -0
  205. package/dist/esm/src/client/index.js +377 -0
  206. package/dist/esm/src/client/index.js.map +1 -0
  207. package/dist/esm/src/client/plugins/index.d.ts +3 -0
  208. package/dist/esm/src/client/plugins/index.d.ts.map +1 -0
  209. package/dist/esm/src/client/plugins/index.js +3 -0
  210. package/dist/esm/src/client/plugins/index.js.map +1 -0
  211. package/dist/esm/src/component/_generated/api.d.ts +12 -0
  212. package/dist/esm/src/component/_generated/api.d.ts.map +1 -0
  213. package/dist/esm/src/component/_generated/api.js +22 -0
  214. package/dist/esm/src/component/_generated/api.js.map +1 -0
  215. package/dist/esm/src/component/_generated/server.d.ts +64 -0
  216. package/dist/esm/src/component/_generated/server.d.ts.map +1 -0
  217. package/dist/esm/src/component/_generated/server.js +74 -0
  218. package/dist/esm/src/component/_generated/server.js.map +1 -0
  219. package/dist/esm/src/component/adapter.d.ts +355 -0
  220. package/dist/esm/src/component/adapter.d.ts.map +1 -0
  221. package/dist/esm/src/component/adapter.js +573 -0
  222. package/dist/esm/src/component/adapter.js.map +1 -0
  223. package/dist/esm/src/component/adapterTest.d.ts +18 -0
  224. package/dist/esm/src/component/adapterTest.d.ts.map +1 -0
  225. package/dist/esm/src/component/adapterTest.js +75 -0
  226. package/dist/esm/src/component/adapterTest.js.map +1 -0
  227. package/dist/esm/src/component/convex.config.d.ts +3 -0
  228. package/dist/esm/src/component/convex.config.d.ts.map +1 -0
  229. package/dist/esm/src/component/convex.config.js +4 -0
  230. package/dist/esm/src/component/convex.config.js.map +1 -0
  231. package/dist/esm/src/component/schema.d.ts +562 -0
  232. package/dist/esm/src/component/schema.d.ts.map +1 -0
  233. package/dist/esm/src/component/schema.js +217 -0
  234. package/dist/esm/src/component/schema.js.map +1 -0
  235. package/dist/esm/src/nextjs/index.d.ts +10 -0
  236. package/dist/esm/src/nextjs/index.d.ts.map +1 -0
  237. package/dist/esm/src/nextjs/index.js +43 -0
  238. package/dist/esm/src/nextjs/index.js.map +1 -0
  239. package/dist/esm/src/plugins/convex/client.d.ts +9 -0
  240. package/dist/esm/src/plugins/convex/client.d.ts.map +1 -0
  241. package/dist/esm/src/plugins/convex/client.js +7 -0
  242. package/dist/esm/src/plugins/convex/client.js.map +1 -0
  243. package/dist/esm/src/plugins/convex/index.d.ts +415 -0
  244. package/dist/esm/src/plugins/convex/index.d.ts.map +1 -0
  245. package/dist/esm/src/plugins/convex/index.js +354 -0
  246. package/dist/esm/src/plugins/convex/index.js.map +1 -0
  247. package/dist/esm/src/plugins/cross-domain/client.d.ts +132 -0
  248. package/dist/esm/src/plugins/cross-domain/client.d.ts.map +1 -0
  249. package/dist/esm/src/plugins/cross-domain/client.js +176 -0
  250. package/dist/esm/src/plugins/cross-domain/client.js.map +1 -0
  251. package/dist/esm/src/plugins/cross-domain/index.d.ts +83 -0
  252. package/dist/esm/src/plugins/cross-domain/index.d.ts.map +1 -0
  253. package/dist/esm/src/plugins/cross-domain/index.js +153 -0
  254. package/dist/esm/src/plugins/cross-domain/index.js.map +1 -0
  255. package/dist/esm/src/plugins/index.d.ts +3 -0
  256. package/dist/esm/src/plugins/index.d.ts.map +1 -0
  257. package/dist/esm/src/plugins/index.js +3 -0
  258. package/dist/esm/src/plugins/index.js.map +1 -0
  259. package/dist/esm/src/react/client.d.ts +31 -0
  260. package/dist/esm/src/react/client.d.ts.map +1 -0
  261. package/dist/esm/src/react/client.js +96 -0
  262. package/dist/esm/src/react/client.js.map +1 -0
  263. package/dist/esm/src/react/index.d.ts +9 -0
  264. package/dist/esm/src/react/index.d.ts.map +1 -0
  265. package/dist/esm/src/react/index.js +15 -0
  266. package/dist/esm/src/react/index.js.map +1 -0
  267. package/dist/esm/src/react-start/index.d.ts +45 -0
  268. package/dist/esm/src/react-start/index.d.ts.map +1 -0
  269. package/dist/esm/src/react-start/index.js +60 -0
  270. package/dist/esm/src/react-start/index.js.map +1 -0
  271. package/dist/esm/src/utils/index.d.ts +9 -0
  272. package/dist/esm/src/utils/index.d.ts.map +1 -0
  273. package/dist/esm/src/utils/index.js +35 -0
  274. package/dist/esm/src/utils/index.js.map +1 -0
  275. package/package.json +30 -7
  276. package/src/auth.ts +57 -0
  277. package/src/client/adapter.test.ts +15 -0
  278. package/src/client/adapter.ts +83 -58
  279. package/src/{component/lib.ts → client/adapterUtils.ts} +106 -256
  280. package/src/client/createSchema.ts +149 -0
  281. package/src/client/index.ts +561 -317
  282. package/src/component/_generated/api.d.ts +1744 -787
  283. package/src/component/adapter.ts +13 -0
  284. package/src/component/adapterTest.ts +8 -34
  285. package/src/component/schema.ts +81 -172
  286. package/src/nextjs/index.ts +5 -5
  287. package/src/plugins/convex/client.ts +2 -3
  288. package/src/plugins/convex/index.ts +16 -147
  289. package/src/plugins/cross-domain/index.ts +2 -2
  290. package/src/react-start/index.ts +76 -44
  291. package/src/component/util.ts +0 -4
@@ -1,76 +1,88 @@
1
1
  import {
2
2
  type Auth as ConvexAuth,
3
+ DataModelFromSchemaDefinition,
3
4
  type DefaultFunctionArgs,
4
5
  type Expand,
6
+ FunctionHandle,
5
7
  type FunctionReference,
6
8
  GenericActionCtx,
7
9
  type GenericDataModel,
10
+ GenericDocument,
8
11
  GenericMutationCtx,
9
12
  type GenericQueryCtx,
13
+ GenericSchema,
10
14
  type HttpRouter,
15
+ SchemaDefinition,
11
16
  httpActionGeneric,
12
17
  internalMutationGeneric,
18
+ mutationGeneric,
19
+ paginationOptsValidator,
13
20
  queryGeneric,
14
21
  } from "convex/server";
15
22
  import { type GenericId, Infer, v } from "convex/values";
16
- import type { api } from "../component/_generated/api";
17
- import schema from "../component/schema";
18
23
  import { convexAdapter } from "./adapter";
19
- import { betterAuth } from "better-auth";
20
- import { omit } from "convex-helpers";
21
- import { createCookieGetter } from "better-auth/cookies";
22
- import { fetchQuery } from "convex/nextjs";
23
- import { JWT_COOKIE_NAME } from "../plugins/convex";
24
+ import { AdapterInstance, betterAuth } from "better-auth";
25
+ import { asyncMap, omit } from "convex-helpers";
24
26
  import { requireEnv } from "../utils";
25
- import { parse, partial } from "convex-helpers/validators";
26
- import { adapterArgsValidator, adapterWhereValidator } from "../component/lib";
27
+ import { partial } from "convex-helpers/validators";
28
+ import {
29
+ adapterWhereValidator,
30
+ checkUniqueFields,
31
+ hasUniqueFields,
32
+ listOne,
33
+ paginate,
34
+ selectFields,
35
+ } from "./adapterUtils";
27
36
  import { corsRouter } from "convex-helpers/server/cors";
28
37
  import { version as convexVersion } from "convex";
29
38
  import semver from "semver";
39
+ import defaultSchema from "../component/schema";
40
+ import { getAuthTables } from "better-auth/db";
41
+ import { api } from "../component/_generated/api";
30
42
 
31
43
  export { convexAdapter };
32
44
 
45
+ export type CreateAdapter = <Ctx extends RunCtx>(ctx: Ctx) => AdapterInstance;
46
+
33
47
  if (semver.lt(convexVersion, "1.25.0")) {
34
48
  throw new Error("Convex version must be at least 1.25.0");
35
49
  }
36
50
 
37
- const createUserFields = omit(schema.tables.user.validator.fields, ["userId"]);
38
- const createUserValidator = v.object(createUserFields);
39
- const createPermissiveArgsValidator = v.object({
40
- input: v.object({
41
- model: v.literal("user"),
42
- data: v.record(
43
- v.string(),
51
+ const whereValidator = (
52
+ schema: SchemaDefinition<any, any>,
53
+ tableName: string
54
+ ) =>
55
+ v.object({
56
+ field: v.union(
57
+ ...Object.keys(schema.tables[tableName].validator.fields).map((field) =>
58
+ v.literal(field)
59
+ ),
60
+ v.literal("id")
61
+ ),
62
+ operator: v.optional(
44
63
  v.union(
45
- v.string(),
46
- v.number(),
47
- v.boolean(),
48
- v.array(v.string()),
49
- v.array(v.number()),
50
- v.null()
64
+ v.literal("lt"),
65
+ v.literal("lte"),
66
+ v.literal("gt"),
67
+ v.literal("gte"),
68
+ v.literal("eq"),
69
+ v.literal("in"),
70
+ v.literal("ne"),
71
+ v.literal("contains"),
72
+ v.literal("starts_with"),
73
+ v.literal("ends_with")
51
74
  )
52
75
  ),
53
- }),
54
- });
55
- const createUserArgsValidator = v.object({
56
- input: v.object({
57
- model: v.literal("user"),
58
- data: v.object(createUserFields),
59
- }),
60
- });
61
- const updateUserArgsValidator = v.object({
62
- input: v.object({
63
- model: v.literal("user"),
64
- where: v.optional(v.array(adapterWhereValidator)),
65
- update: v.object(partial(createUserFields)),
66
- }),
67
- });
68
- const createSessionArgsValidator = v.object({
69
- input: v.object({
70
- model: v.literal("session"),
71
- data: v.object(schema.tables.session.validator.fields),
72
- }),
73
- });
76
+ value: v.union(
77
+ v.string(),
78
+ v.number(),
79
+ v.boolean(),
80
+ v.array(v.string()),
81
+ v.array(v.number()),
82
+ v.null()
83
+ ),
84
+ connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
85
+ });
74
86
 
75
87
  export type EventFunction<T extends DefaultFunctionArgs> = FunctionReference<
76
88
  "mutation",
@@ -78,330 +90,562 @@ export type EventFunction<T extends DefaultFunctionArgs> = FunctionReference<
78
90
  T
79
91
  >;
80
92
 
93
+ export type GenericCtx<DataModel extends GenericDataModel = GenericDataModel> =
94
+ | GenericQueryCtx<DataModel>
95
+ | GenericMutationCtx<DataModel>
96
+ | GenericActionCtx<DataModel>;
97
+
81
98
  export type AuthFunctions = {
82
- createUser: FunctionReference<
83
- "mutation",
84
- "internal",
85
- Infer<typeof createPermissiveArgsValidator>
86
- >;
87
- deleteUser: FunctionReference<
88
- "mutation",
89
- "internal",
90
- Infer<typeof adapterArgsValidator>
91
- >;
92
- updateUser: FunctionReference<
93
- "mutation",
94
- "internal",
95
- Infer<typeof updateUserArgsValidator>
96
- >;
97
- createSession: FunctionReference<
98
- "mutation",
99
- "internal",
100
- Infer<typeof createSessionArgsValidator>
101
- >;
99
+ onCreate?: FunctionReference<"mutation", "internal", { [key: string]: any }>;
100
+ onUpdate?: FunctionReference<"mutation", "internal", { [key: string]: any }>;
101
+ onDelete?: FunctionReference<"mutation", "internal", { [key: string]: any }>;
102
102
  };
103
103
 
104
- export type PublicAuthFunctions = {
105
- isAuthenticated: FunctionReference<"query", "public">;
106
- };
104
+ export const createApi = <
105
+ DataModel extends GenericDataModel,
106
+ Schema extends SchemaDefinition<any, any>,
107
+ >(
108
+ schema: Schema,
109
+ createAuth: (ctx: GenericCtx<DataModel>) => ReturnType<typeof betterAuth>
110
+ ) => {
111
+ const betterAuthSchema = getAuthTables(createAuth({} as any)!.options);
112
+ return {
113
+ create: mutationGeneric({
114
+ args: {
115
+ input: v.union(
116
+ ...Object.entries(schema.tables).map(([model, table]) =>
117
+ v.object({
118
+ model: v.literal(model),
119
+ data: v.object((table as any).validator.fields),
120
+ })
121
+ )
122
+ ),
123
+ select: v.optional(v.array(v.string())),
124
+ onCreateHandle: v.optional(v.string()),
125
+ },
126
+ handler: async (ctx, args) => {
127
+ await checkUniqueFields(
128
+ ctx,
129
+ schema,
130
+ betterAuthSchema,
131
+ args.input.model,
132
+ args.input.data
133
+ );
134
+ const id = await ctx.db.insert(
135
+ args.input.model as any,
136
+ args.input.data
137
+ );
138
+ const doc = await ctx.db.get(id);
139
+ if (!doc) {
140
+ throw new Error(`Failed to create ${args.input.model}`);
141
+ }
142
+ const result = selectFields(doc, args.select);
143
+ if (args.onCreateHandle) {
144
+ await ctx.runMutation(
145
+ args.onCreateHandle as FunctionHandle<"mutation">,
146
+ {
147
+ model: args.input.model,
148
+ doc,
149
+ }
150
+ );
151
+ }
152
+ return result;
153
+ },
154
+ }),
155
+ findOne: queryGeneric({
156
+ args: {
157
+ model: v.union(
158
+ ...Object.keys(schema.tables).map((model) => v.literal(model))
159
+ ),
160
+ where: v.optional(v.array(adapterWhereValidator)),
161
+ select: v.optional(v.array(v.string())),
162
+ },
163
+ handler: async (ctx, args) => {
164
+ return await listOne(ctx, schema, betterAuthSchema, args);
165
+ },
166
+ }),
167
+ findMany: queryGeneric({
168
+ args: {
169
+ model: v.union(
170
+ ...Object.keys(schema.tables).map((model) => v.literal(model))
171
+ ),
172
+ where: v.optional(v.array(adapterWhereValidator)),
173
+ limit: v.optional(v.number()),
174
+ sortBy: v.optional(
175
+ v.object({
176
+ direction: v.union(v.literal("asc"), v.literal("desc")),
177
+ field: v.string(),
178
+ })
179
+ ),
180
+ offset: v.optional(v.number()),
181
+ paginationOpts: paginationOptsValidator,
182
+ },
183
+ handler: async (ctx, args) => {
184
+ return await paginate(ctx, schema, betterAuthSchema, args);
185
+ },
186
+ }),
187
+ updateOne: mutationGeneric({
188
+ args: {
189
+ input: v.union(
190
+ ...Object.entries(schema.tables).map(
191
+ ([tableName, table]: [string, Schema["tables"][string]]) => {
192
+ const fields = partial(table.validator.fields);
193
+ return v.object({
194
+ model: v.literal(tableName),
195
+ update: v.object(fields),
196
+ where: v.optional(v.array(whereValidator(schema, tableName))),
197
+ });
198
+ }
199
+ )
200
+ ),
201
+ onUpdateHandle: v.optional(v.string()),
202
+ },
203
+ handler: async (ctx, args) => {
204
+ const doc = await listOne(ctx, schema, betterAuthSchema, args.input);
205
+ if (!doc) {
206
+ throw new Error(`Failed to update ${args.input.model}`);
207
+ }
208
+ await checkUniqueFields(
209
+ ctx,
210
+ schema,
211
+ betterAuthSchema,
212
+ args.input.model,
213
+ args.input.update,
214
+ doc
215
+ );
216
+ await ctx.db.patch(
217
+ doc._id as GenericId<string>,
218
+ args.input.update as any
219
+ );
220
+ const updatedDoc = await ctx.db.get(doc._id as GenericId<string>);
221
+ if (!updatedDoc) {
222
+ throw new Error(`Failed to update ${args.input.model}`);
223
+ }
224
+ if (args.onUpdateHandle) {
225
+ await ctx.runMutation(
226
+ args.onUpdateHandle as FunctionHandle<"mutation">,
227
+ {
228
+ input: {
229
+ model: args.input.model,
230
+ oldDoc: doc,
231
+ newDoc: updatedDoc,
232
+ },
233
+ }
234
+ );
235
+ }
236
+ return updatedDoc;
237
+ },
238
+ }),
239
+ updateMany: mutationGeneric({
240
+ args: {
241
+ input: v.union(
242
+ ...Object.entries(schema.tables).map(
243
+ ([tableName, table]: [string, Schema["tables"][string]]) => {
244
+ const fields = partial(table.validator.fields);
245
+ return v.object({
246
+ model: v.literal(tableName),
247
+ update: v.object(fields),
248
+ where: v.optional(v.array(whereValidator(schema, tableName))),
249
+ });
250
+ }
251
+ )
252
+ ),
253
+ paginationOpts: paginationOptsValidator,
254
+ onUpdateHandle: v.optional(v.string()),
255
+ },
256
+ handler: async (ctx, args) => {
257
+ const { page, ...result } = await paginate(
258
+ ctx,
259
+ schema,
260
+ betterAuthSchema,
261
+ {
262
+ ...args.input,
263
+ paginationOpts: args.paginationOpts,
264
+ }
265
+ );
266
+ if (args.input.update) {
267
+ if (
268
+ hasUniqueFields(
269
+ betterAuthSchema,
270
+ args.input.model,
271
+ args.input.update ?? {}
272
+ ) &&
273
+ page.length > 1
274
+ ) {
275
+ throw new Error(
276
+ `Attempted to set unique fields in multiple documents in ${args.input.model} with the same value. Fields: ${Object.keys(args.input.update ?? {}).join(", ")}`
277
+ );
278
+ }
279
+ await asyncMap(page, async (doc) => {
280
+ await checkUniqueFields(
281
+ ctx,
282
+ schema,
283
+ betterAuthSchema,
284
+ args.input.model,
285
+ args.input.update ?? {},
286
+ doc
287
+ );
288
+ await ctx.db.patch(
289
+ doc._id as GenericId<string>,
290
+ args.input.update as any
291
+ );
107
292
 
108
- export class BetterAuth<UserId extends string = string> {
109
- constructor(
110
- public component: UseApi<typeof api>,
111
- public config: {
112
- authFunctions: AuthFunctions;
113
- publicAuthFunctions?: PublicAuthFunctions;
114
- verbose?: boolean;
115
- }
116
- ) {}
293
+ if (args.onUpdateHandle) {
294
+ await ctx.runMutation(
295
+ args.onUpdateHandle as FunctionHandle<"mutation">,
296
+ {
297
+ model: args.input.model,
298
+ oldDoc: doc,
299
+ newDoc: await ctx.db.get(doc._id as GenericId<string>),
300
+ }
301
+ );
302
+ }
303
+ });
304
+ }
305
+ return {
306
+ ...result,
307
+ count: page.length,
308
+ ids: page.map((doc) => doc._id),
309
+ };
310
+ },
311
+ }),
312
+ deleteOne: mutationGeneric({
313
+ args: {
314
+ input: v.union(
315
+ ...Object.keys(schema.tables).map((tableName: string) => {
316
+ return v.object({
317
+ model: v.literal(tableName),
318
+ where: v.optional(v.array(whereValidator(schema, tableName))),
319
+ });
320
+ })
321
+ ),
322
+ onDeleteHandle: v.optional(v.string()),
323
+ },
324
+ handler: async (ctx, args) => {
325
+ const doc = await listOne(ctx, schema, betterAuthSchema, args.input);
326
+ if (!doc) {
327
+ return;
328
+ }
329
+ await ctx.db.delete(doc._id as GenericId<string>);
330
+ if (args.onDeleteHandle) {
331
+ await ctx.runMutation(
332
+ args.onDeleteHandle as FunctionHandle<"mutation">,
333
+ { model: args.input.model, doc }
334
+ );
335
+ }
336
+ return doc;
337
+ },
338
+ }),
339
+ deleteMany: mutationGeneric({
340
+ args: {
341
+ input: v.union(
342
+ ...Object.keys(schema.tables).map((tableName: string) => {
343
+ return v.object({
344
+ model: v.literal(tableName),
345
+ where: v.optional(v.array(whereValidator(schema, tableName))),
346
+ });
347
+ })
348
+ ),
349
+ paginationOpts: paginationOptsValidator,
350
+ onDeleteHandle: v.optional(v.string()),
351
+ },
352
+ handler: async (ctx, args) => {
353
+ const { page, ...result } = await paginate(
354
+ ctx,
355
+ schema,
356
+ betterAuthSchema,
357
+ {
358
+ ...args.input,
359
+ paginationOpts: args.paginationOpts,
360
+ }
361
+ );
362
+ await asyncMap(page, async (doc) => {
363
+ if (args.onDeleteHandle) {
364
+ await ctx.runMutation(
365
+ args.onDeleteHandle as FunctionHandle<"mutation">,
366
+ {
367
+ model: args.input.model,
368
+ doc,
369
+ }
370
+ );
371
+ }
372
+ await ctx.db.delete(doc._id as GenericId<string>);
373
+ });
374
+ return {
375
+ ...result,
376
+ count: page.length,
377
+ ids: page.map((doc) => doc._id),
378
+ };
379
+ },
380
+ }),
381
+ };
382
+ };
117
383
 
118
- async isAuthenticated(token?: string | null) {
119
- if (!this.config.publicAuthFunctions?.isAuthenticated) {
120
- throw new Error(
121
- "isAuthenticated function not found. It must be a named export in convex/auth.ts"
122
- );
123
- }
124
- return fetchQuery(
125
- this.config.publicAuthFunctions.isAuthenticated,
126
- {},
127
- { token: token ?? undefined }
128
- );
129
- }
384
+ export type Triggers<
385
+ DataModel extends GenericDataModel,
386
+ Schema extends SchemaDefinition<any, any>,
387
+ > = {
388
+ [K in keyof Schema["tables"]]?: {
389
+ onCreate?: <Ctx extends GenericMutationCtx<DataModel>>(
390
+ ctx: Ctx,
391
+ doc: Infer<Schema["tables"][K]["validator"]> & {
392
+ _id: string;
393
+ _creationTime: number;
394
+ }
395
+ ) => Promise<void>;
396
+ onUpdate?: <Ctx extends GenericMutationCtx<DataModel>>(
397
+ ctx: Ctx,
398
+ oldDoc: Infer<Schema["tables"][K]["validator"]> & {
399
+ _id: string;
400
+ _creationTime: number;
401
+ },
402
+ newDoc: Infer<Schema["tables"][K]["validator"]> & {
403
+ _id: string;
404
+ _creationTime: number;
405
+ }
406
+ ) => Promise<void>;
407
+ onDelete?: <Ctx extends GenericMutationCtx<DataModel>>(
408
+ ctx: Ctx,
409
+ doc: Infer<Schema["tables"][K]["validator"]> & {
410
+ _id: string;
411
+ _creationTime: number;
412
+ }
413
+ ) => Promise<void>;
414
+ };
415
+ };
130
416
 
131
- async getHeaders(ctx: RunQueryCtx & { auth: ConvexAuth }) {
132
- const session = await ctx.runQuery(this.component.lib.getCurrentSession);
133
- return new Headers({
134
- ...(session?.token ? { authorization: `Bearer ${session.token}` } : {}),
135
- ...(session?.ipAddress ? { "x-forwarded-for": session.ipAddress } : {}),
136
- });
417
+ export const createClient = <
418
+ DataModel extends GenericDataModel,
419
+ Schema extends SchemaDefinition<GenericSchema, true> = typeof defaultSchema,
420
+ >(
421
+ component: UseApi<typeof api>,
422
+ config?: {
423
+ local?: {
424
+ schema?: Schema;
425
+ };
426
+ authFunctions?: AuthFunctions;
427
+ verbose?: boolean;
428
+ triggers?: Triggers<DataModel, Schema>;
137
429
  }
138
-
139
- // TODO: use the proper id type for auth functions
140
- async getAuthUserId(ctx: RunQueryCtx & { auth: ConvexAuth }) {
430
+ ) => {
431
+ const safeGetAuthUser = async (ctx: GenericQueryCtx<DataModel>) => {
141
432
  const identity = await ctx.auth.getUserIdentity();
142
433
  if (!identity) {
143
- return null;
434
+ return;
144
435
  }
145
- return identity.subject as UserId;
146
- }
147
436
 
148
- // Convenience function for getting the Better Auth user
149
- async getAuthUser(ctx: RunQueryCtx & { auth: ConvexAuth }) {
150
- const identity = await ctx.auth.getUserIdentity();
151
- if (!identity) {
152
- return null;
153
- }
154
- const doc:
155
- | null
156
- | (Infer<typeof schema.tables.user.validator> & {
157
- _id: string;
158
- _creationTime: number;
159
- }) = await ctx.runQuery(this.component.lib.findOne, {
437
+ type BetterAuthDataModel = DataModelFromSchemaDefinition<Schema>;
438
+
439
+ const doc = (await ctx.runQuery(component.adapter.findOne, {
160
440
  model: "user",
161
441
  where: [
162
442
  {
163
- field: "userId",
443
+ field: "id",
164
444
  value: identity.subject,
165
445
  },
166
446
  ],
167
- });
447
+ })) as BetterAuthDataModel["user"]["document"] | null;
168
448
  if (!doc) {
169
- return null;
170
- }
171
- // Type narrowing
172
- if (!("emailVerified" in doc)) {
173
- throw new Error("invalid user");
449
+ return;
174
450
  }
175
- return omit(doc, ["_id", "_creationTime"]);
176
- }
177
-
178
- async getIdTokenCookieName(
179
- createAuth: (ctx: GenericActionCtx<any>) => ReturnType<typeof betterAuth>
180
- ) {
181
- const auth = createAuth({} as any);
182
- const createCookie = createCookieGetter(auth.options);
183
- const cookie = createCookie(JWT_COOKIE_NAME);
184
- return cookie.name;
185
- }
451
+ return doc;
452
+ };
453
+ return {
454
+ component,
455
+ adapter: (ctx: GenericCtx<DataModel>) =>
456
+ convexAdapter<DataModel, typeof ctx, Schema>(ctx, component, config),
457
+ getHeaders: async (ctx: RunQueryCtx & { auth: ConvexAuth }) => {
458
+ const identity = await ctx.auth.getUserIdentity();
459
+ if (!identity) {
460
+ return;
461
+ }
462
+ const session = await ctx.runQuery(component.adapter.findOne, {
463
+ model: "session",
464
+ where: [
465
+ {
466
+ field: "userId",
467
+ value: identity.subject,
468
+ },
469
+ ],
470
+ });
471
+ return new Headers({
472
+ ...(session?.token ? { authorization: `Bearer ${session.token}` } : {}),
473
+ ...(session?.ipAddress
474
+ ? { "x-forwarded-for": session.ipAddress as string }
475
+ : {}),
476
+ });
477
+ },
186
478
 
187
- async updateUserMetadata(
188
- ctx: GenericMutationCtx<GenericDataModel>,
189
- userId: UserId,
190
- metadata: Omit<
191
- Partial<Infer<typeof schema.tables.user.validator>>,
192
- "userId"
193
- >
194
- ) {
195
- return ctx.runMutation(this.component.lib.updateOne, {
196
- input: {
197
- model: "user",
198
- where: [{ field: "userId", value: userId }],
199
- update: metadata,
200
- },
201
- });
202
- }
479
+ safeGetAuthUser,
203
480
 
204
- async getUserByUsername(
205
- ctx: GenericQueryCtx<GenericDataModel>,
206
- username: string
207
- ) {
208
- const user:
209
- | null
210
- | (Infer<typeof schema.tables.user.validator> & {
211
- _id: string;
212
- _creationTime: number;
213
- }) = await ctx.runQuery(this.component.lib.findOne, {
214
- model: "user",
215
- where: [{ field: "username", value: username }],
216
- });
217
- if (!user) {
218
- return null;
219
- }
220
- return omit(user, ["_id", "_creationTime"]);
221
- }
481
+ getAuthUser: async (ctx: GenericQueryCtx<DataModel>) => {
482
+ const user = await safeGetAuthUser(ctx);
483
+ if (!user) {
484
+ throw new Error("Unauthenticated");
485
+ }
486
+ return user;
487
+ },
222
488
 
223
- createAuthFunctions<DataModel extends GenericDataModel>(opts: {
224
- onCreateUser: (
225
- ctx: GenericMutationCtx<DataModel>,
226
- user: Infer<typeof createUserValidator>
227
- ) => Promise<UserId>;
228
- onDeleteUser?: (
229
- ctx: GenericMutationCtx<DataModel>,
230
- id: UserId
231
- ) => void | Promise<void>;
232
- onUpdateUser?: (
233
- ctx: GenericMutationCtx<DataModel>,
234
- user: Infer<typeof schema.tables.user.validator>
235
- ) => void | Promise<void>;
236
- onCreateSession?: (
489
+ // Replaces 0.7 behavior of returning a new user id from
490
+ // onCreateUser
491
+ setUserId: async (
237
492
  ctx: GenericMutationCtx<DataModel>,
238
- session: Infer<typeof schema.tables.session.validator>
239
- ) => void | Promise<void>;
240
- }) {
241
- return {
242
- isAuthenticated: queryGeneric({
243
- args: v.object({}),
244
- handler: async (ctx) => {
245
- const identity = await ctx.auth.getUserIdentity();
246
- return identity !== null;
493
+ authId: string,
494
+ userId: string
495
+ ) => {
496
+ await ctx.runMutation(component.adapter.updateOne, {
497
+ input: {
498
+ model: "user",
499
+ where: [{ field: "id", value: authId }],
500
+ update: { userId },
247
501
  },
248
- }),
249
- createUser: internalMutationGeneric({
250
- args: createPermissiveArgsValidator,
251
- handler: async (ctx, args) => {
252
- const userId = await opts.onCreateUser(ctx, args.input.data as any);
253
- const parsedArgs = parse(createUserArgsValidator, args);
254
- return ctx.runMutation(this.component.lib.create, {
255
- input: {
256
- ...parsedArgs.input,
257
- data: { ...parsedArgs.input.data, userId },
258
- },
259
- });
502
+ });
503
+ },
504
+
505
+ triggersApi: () => ({
506
+ onCreate: internalMutationGeneric({
507
+ args: {
508
+ doc: v.any(),
509
+ model: v.string(),
260
510
  },
261
- }),
262
- deleteUser: internalMutationGeneric({
263
- args: adapterArgsValidator,
264
511
  handler: async (ctx, args) => {
265
- const doc = await ctx.runMutation(this.component.lib.deleteOne, args);
266
- if (doc && opts.onDeleteUser) {
267
- await opts.onDeleteUser(ctx, doc.userId as UserId);
268
- }
269
- return doc;
512
+ await config?.triggers?.[args.model]?.onCreate?.(ctx, args.doc);
270
513
  },
271
514
  }),
272
- updateUser: internalMutationGeneric({
273
- args: updateUserArgsValidator,
515
+ onUpdate: internalMutationGeneric({
516
+ args: {
517
+ oldDoc: v.any(),
518
+ newDoc: v.any(),
519
+ model: v.string(),
520
+ },
274
521
  handler: async (ctx, args) => {
275
- const updatedUser = await ctx.runMutation(
276
- this.component.lib.updateOne,
277
- { input: args.input }
522
+ await config?.triggers?.[args.model]?.onUpdate?.(
523
+ ctx,
524
+ args.oldDoc,
525
+ args.newDoc
278
526
  );
279
- // Type narrowing
280
- if (!("emailVerified" in updatedUser)) {
281
- throw new Error("invalid user");
282
- }
283
- if (opts.onUpdateUser) {
284
- await opts.onUpdateUser(ctx, omit(updatedUser, ["_id"]));
285
- }
286
- return updatedUser;
287
527
  },
288
528
  }),
289
- createSession: internalMutationGeneric({
290
- args: createSessionArgsValidator,
529
+ onDelete: internalMutationGeneric({
530
+ args: {
531
+ doc: v.any(),
532
+ model: v.string(),
533
+ },
291
534
  handler: async (ctx, args) => {
292
- const session = await ctx.runMutation(this.component.lib.create, {
293
- input: args.input,
294
- });
295
- await opts.onCreateSession?.(ctx, session);
296
- return session;
535
+ await config?.triggers?.[args.model]?.onDelete?.(ctx, args.doc);
297
536
  },
298
537
  }),
299
- };
300
- }
538
+ }),
301
539
 
302
- registerRoutes(
303
- http: HttpRouter,
304
- createAuth: (ctx: GenericActionCtx<any>) => ReturnType<typeof betterAuth>,
305
- opts: {
306
- cors?:
307
- | boolean
308
- | {
309
- // These values are appended to the default values
310
- allowedOrigins?: string[];
311
- allowedHeaders?: string[];
312
- exposedHeaders?: string[];
313
- };
314
- } = {}
315
- ) {
316
- const betterAuthOptions = createAuth({} as any).options;
317
- const path = betterAuthOptions.basePath ?? "/api/auth";
318
- const authRequestHandler = httpActionGeneric(async (ctx, request) => {
319
- if (this.config.verbose) {
320
- console.log("options.baseURL", betterAuthOptions.baseURL);
321
- console.log("request headers", request.headers);
322
- }
323
- const auth = createAuth(ctx);
324
- const response = await auth.handler(request);
325
- if (this.config?.verbose) {
326
- console.log("response headers", response.headers);
540
+ registerRoutes: (
541
+ http: HttpRouter,
542
+ createAuth: (ctx: GenericCtx<DataModel>) => ReturnType<typeof betterAuth>,
543
+ opts: {
544
+ cors?:
545
+ | boolean
546
+ | {
547
+ // These values are appended to the default values
548
+ allowedOrigins?: string[];
549
+ allowedHeaders?: string[];
550
+ exposedHeaders?: string[];
551
+ };
552
+ } = {}
553
+ ) => {
554
+ const authDummy = createAuth({} as any);
555
+ const path = authDummy.options.basePath ?? "/api/auth";
556
+ const authRequestHandler = httpActionGeneric(async (ctx, request) => {
557
+ if (config?.verbose) {
558
+ console.log("options.baseURL", authDummy.options.baseURL);
559
+ console.log("request headers", request.headers);
560
+ }
561
+ const auth = createAuth(ctx as any);
562
+ const response = await auth.handler(request);
563
+ if (config?.verbose) {
564
+ console.log("response headers", response.headers);
565
+ }
566
+ return response;
567
+ });
568
+ const wellKnown = http.lookup("/.well-known/openid-configuration", "GET");
569
+
570
+ // If registerRoutes is used multiple times, this may already be defined
571
+ if (!wellKnown) {
572
+ // Redirect root well-known to api well-known
573
+ http.route({
574
+ path: "/.well-known/openid-configuration",
575
+ method: "GET",
576
+ handler: httpActionGeneric(async () => {
577
+ const url = `${requireEnv("CONVEX_SITE_URL")}${path}/convex/.well-known/openid-configuration`;
578
+ return Response.redirect(url);
579
+ }),
580
+ });
327
581
  }
328
- return response;
329
- });
330
582
 
331
- const wellKnown = http.lookup("/.well-known/openid-configuration", "GET");
583
+ if (!opts.cors) {
584
+ http.route({
585
+ pathPrefix: `${path}/`,
586
+ method: "GET",
587
+ handler: authRequestHandler,
588
+ });
332
589
 
333
- // If registerRoutes is used multiple times, this may already be defined
334
- if (!wellKnown) {
335
- // Redirect root well-known to api well-known
336
- http.route({
337
- path: "/.well-known/openid-configuration",
338
- method: "GET",
339
- handler: httpActionGeneric(async () => {
340
- const url = `${requireEnv("CONVEX_SITE_URL")}${path}/convex/.well-known/openid-configuration`;
341
- return Response.redirect(url);
342
- }),
590
+ http.route({
591
+ pathPrefix: `${path}/`,
592
+ method: "POST",
593
+ handler: authRequestHandler,
594
+ });
595
+
596
+ return;
597
+ }
598
+ const corsOpts =
599
+ typeof opts.cors === "boolean"
600
+ ? { allowedOrigins: [], allowedHeaders: [], exposedHeaders: [] }
601
+ : opts.cors;
602
+ let trustedOriginsOption:
603
+ | string[]
604
+ | ((request: Request) => string[] | Promise<string[]>)
605
+ | undefined;
606
+ const cors = corsRouter(http, {
607
+ allowedOrigins: async (request) => {
608
+ trustedOriginsOption =
609
+ trustedOriginsOption ??
610
+ (await authDummy.$context).options.trustedOrigins ??
611
+ [];
612
+ const trustedOrigins = Array.isArray(trustedOriginsOption)
613
+ ? trustedOriginsOption
614
+ : await trustedOriginsOption(request);
615
+ return trustedOrigins
616
+ .map((origin) =>
617
+ // Strip trailing wildcards, unsupported for allowedOrigins
618
+ origin.endsWith("*") && origin.length > 1
619
+ ? origin.slice(0, -1)
620
+ : origin
621
+ )
622
+ .concat(corsOpts.allowedOrigins ?? []);
623
+ },
624
+ allowCredentials: true,
625
+ allowedHeaders: ["Content-Type", "Better-Auth-Cookie"].concat(
626
+ corsOpts.allowedHeaders ?? []
627
+ ),
628
+ exposedHeaders: ["Set-Better-Auth-Cookie"].concat(
629
+ corsOpts.exposedHeaders ?? []
630
+ ),
631
+ debug: config?.verbose,
632
+ enforceAllowOrigins: false,
343
633
  });
344
- }
345
634
 
346
- if (!opts.cors) {
347
- http.route({
635
+ cors.route({
348
636
  pathPrefix: `${path}/`,
349
637
  method: "GET",
350
638
  handler: authRequestHandler,
351
639
  });
352
640
 
353
- http.route({
641
+ cors.route({
354
642
  pathPrefix: `${path}/`,
355
643
  method: "POST",
356
644
  handler: authRequestHandler,
357
645
  });
358
-
359
- return;
360
- }
361
- const corsOpts =
362
- typeof opts.cors === "boolean"
363
- ? { allowedOrigins: [], allowedHeaders: [], exposedHeaders: [] }
364
- : opts.cors;
365
- const cors = corsRouter(http, {
366
- allowedOrigins: async (request) => {
367
- const trustedOriginsOption =
368
- (await createAuth({} as any).$context).options.trustedOrigins ?? [];
369
- const trustedOrigins = Array.isArray(trustedOriginsOption)
370
- ? trustedOriginsOption
371
- : await trustedOriginsOption(request);
372
- return trustedOrigins
373
- .map((origin) =>
374
- // Strip trailing wildcards, unsupported for allowedOrigins
375
- origin.endsWith("*") && origin.length > 1
376
- ? origin.slice(0, -1)
377
- : origin
378
- )
379
- .concat(corsOpts.allowedOrigins ?? []);
380
- },
381
- allowCredentials: true,
382
- allowedHeaders: ["Content-Type", "Better-Auth-Cookie"].concat(
383
- corsOpts.allowedHeaders ?? []
384
- ),
385
- exposedHeaders: ["Set-Better-Auth-Cookie"].concat(
386
- corsOpts.exposedHeaders ?? []
387
- ),
388
- debug: this.config?.verbose,
389
- enforceAllowOrigins: false,
390
- });
391
-
392
- cors.route({
393
- pathPrefix: `${path}/`,
394
- method: "GET",
395
- handler: authRequestHandler,
396
- });
397
-
398
- cors.route({
399
- pathPrefix: `${path}/`,
400
- method: "POST",
401
- handler: authRequestHandler,
402
- });
403
- }
404
- }
646
+ },
647
+ };
648
+ };
405
649
 
406
650
  /* Type utils follow */
407
651