@hammadj/better-auth-core 1.5.0-beta.9

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 (353) hide show
  1. package/.turbo/turbo-build.log +266 -0
  2. package/.turbo/turbo-test.log +2 -0
  3. package/LICENSE.md +20 -0
  4. package/dist/api/index.d.mts +181 -0
  5. package/dist/api/index.mjs +34 -0
  6. package/dist/api/index.mjs.map +1 -0
  7. package/dist/async_hooks/index.d.mts +7 -0
  8. package/dist/async_hooks/index.mjs +22 -0
  9. package/dist/async_hooks/index.mjs.map +1 -0
  10. package/dist/async_hooks/pure.index.d.mts +7 -0
  11. package/dist/async_hooks/pure.index.mjs +35 -0
  12. package/dist/async_hooks/pure.index.mjs.map +1 -0
  13. package/dist/context/endpoint-context.d.mts +19 -0
  14. package/dist/context/endpoint-context.mjs +32 -0
  15. package/dist/context/endpoint-context.mjs.map +1 -0
  16. package/dist/context/global.d.mts +7 -0
  17. package/dist/context/global.mjs +38 -0
  18. package/dist/context/global.mjs.map +1 -0
  19. package/dist/context/index.d.mts +5 -0
  20. package/dist/context/index.mjs +6 -0
  21. package/dist/context/request-state.d.mts +26 -0
  22. package/dist/context/request-state.mjs +50 -0
  23. package/dist/context/request-state.mjs.map +1 -0
  24. package/dist/context/transaction.d.mts +25 -0
  25. package/dist/context/transaction.mjs +96 -0
  26. package/dist/context/transaction.mjs.map +1 -0
  27. package/dist/db/adapter/factory.d.mts +28 -0
  28. package/dist/db/adapter/factory.mjs +716 -0
  29. package/dist/db/adapter/factory.mjs.map +1 -0
  30. package/dist/db/adapter/get-default-field-name.d.mts +19 -0
  31. package/dist/db/adapter/get-default-field-name.mjs +39 -0
  32. package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
  33. package/dist/db/adapter/get-default-model-name.d.mts +13 -0
  34. package/dist/db/adapter/get-default-model-name.mjs +33 -0
  35. package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
  36. package/dist/db/adapter/get-field-attributes.d.mts +30 -0
  37. package/dist/db/adapter/get-field-attributes.mjs +40 -0
  38. package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
  39. package/dist/db/adapter/get-field-name.d.mts +19 -0
  40. package/dist/db/adapter/get-field-name.mjs +34 -0
  41. package/dist/db/adapter/get-field-name.mjs.map +1 -0
  42. package/dist/db/adapter/get-id-field.d.mts +40 -0
  43. package/dist/db/adapter/get-id-field.mjs +68 -0
  44. package/dist/db/adapter/get-id-field.mjs.map +1 -0
  45. package/dist/db/adapter/get-model-name.d.mts +13 -0
  46. package/dist/db/adapter/get-model-name.mjs +24 -0
  47. package/dist/db/adapter/get-model-name.mjs.map +1 -0
  48. package/dist/db/adapter/index.d.mts +515 -0
  49. package/dist/db/adapter/index.mjs +10 -0
  50. package/dist/db/adapter/types.d.mts +140 -0
  51. package/dist/db/adapter/utils.d.mts +8 -0
  52. package/dist/db/adapter/utils.mjs +39 -0
  53. package/dist/db/adapter/utils.mjs.map +1 -0
  54. package/dist/db/get-tables.d.mts +9 -0
  55. package/dist/db/get-tables.mjs +267 -0
  56. package/dist/db/get-tables.mjs.map +1 -0
  57. package/dist/db/index.d.mts +10 -0
  58. package/dist/db/index.mjs +9 -0
  59. package/dist/db/plugin.d.mts +13 -0
  60. package/dist/db/schema/account.d.mts +27 -0
  61. package/dist/db/schema/account.mjs +20 -0
  62. package/dist/db/schema/account.mjs.map +1 -0
  63. package/dist/db/schema/rate-limit.d.mts +15 -0
  64. package/dist/db/schema/rate-limit.mjs +12 -0
  65. package/dist/db/schema/rate-limit.mjs.map +1 -0
  66. package/dist/db/schema/session.d.mts +22 -0
  67. package/dist/db/schema/session.mjs +15 -0
  68. package/dist/db/schema/session.mjs.map +1 -0
  69. package/dist/db/schema/shared.d.mts +11 -0
  70. package/dist/db/schema/shared.mjs +12 -0
  71. package/dist/db/schema/shared.mjs.map +1 -0
  72. package/dist/db/schema/user.d.mts +21 -0
  73. package/dist/db/schema/user.mjs +14 -0
  74. package/dist/db/schema/user.mjs.map +1 -0
  75. package/dist/db/schema/verification.d.mts +20 -0
  76. package/dist/db/schema/verification.mjs +13 -0
  77. package/dist/db/schema/verification.mjs.map +1 -0
  78. package/dist/db/type.d.mts +147 -0
  79. package/dist/env/color-depth.d.mts +5 -0
  80. package/dist/env/color-depth.mjs +89 -0
  81. package/dist/env/color-depth.mjs.map +1 -0
  82. package/dist/env/env-impl.d.mts +33 -0
  83. package/dist/env/env-impl.mjs +83 -0
  84. package/dist/env/env-impl.mjs.map +1 -0
  85. package/dist/env/index.d.mts +4 -0
  86. package/dist/env/index.mjs +5 -0
  87. package/dist/env/logger.d.mts +49 -0
  88. package/dist/env/logger.mjs +82 -0
  89. package/dist/env/logger.mjs.map +1 -0
  90. package/dist/error/codes.d.mts +199 -0
  91. package/dist/error/codes.mjs +57 -0
  92. package/dist/error/codes.mjs.map +1 -0
  93. package/dist/error/index.d.mts +20 -0
  94. package/dist/error/index.mjs +30 -0
  95. package/dist/error/index.mjs.map +1 -0
  96. package/dist/index.d.mts +8 -0
  97. package/dist/index.mjs +1 -0
  98. package/dist/oauth2/client-credentials-token.d.mts +37 -0
  99. package/dist/oauth2/client-credentials-token.mjs +55 -0
  100. package/dist/oauth2/client-credentials-token.mjs.map +1 -0
  101. package/dist/oauth2/create-authorization-url.d.mts +46 -0
  102. package/dist/oauth2/create-authorization-url.mjs +43 -0
  103. package/dist/oauth2/create-authorization-url.mjs.map +1 -0
  104. package/dist/oauth2/index.d.mts +8 -0
  105. package/dist/oauth2/index.mjs +8 -0
  106. package/dist/oauth2/oauth-provider.d.mts +195 -0
  107. package/dist/oauth2/refresh-access-token.d.mts +36 -0
  108. package/dist/oauth2/refresh-access-token.mjs +59 -0
  109. package/dist/oauth2/refresh-access-token.mjs.map +1 -0
  110. package/dist/oauth2/utils.d.mts +8 -0
  111. package/dist/oauth2/utils.mjs +28 -0
  112. package/dist/oauth2/utils.mjs.map +1 -0
  113. package/dist/oauth2/validate-authorization-code.d.mts +56 -0
  114. package/dist/oauth2/validate-authorization-code.mjs +72 -0
  115. package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
  116. package/dist/oauth2/verify.d.mts +43 -0
  117. package/dist/oauth2/verify.mjs +96 -0
  118. package/dist/oauth2/verify.mjs.map +1 -0
  119. package/dist/social-providers/apple.d.mts +120 -0
  120. package/dist/social-providers/apple.mjs +105 -0
  121. package/dist/social-providers/apple.mjs.map +1 -0
  122. package/dist/social-providers/atlassian.d.mts +73 -0
  123. package/dist/social-providers/atlassian.mjs +84 -0
  124. package/dist/social-providers/atlassian.mjs.map +1 -0
  125. package/dist/social-providers/cognito.d.mts +88 -0
  126. package/dist/social-providers/cognito.mjs +166 -0
  127. package/dist/social-providers/cognito.mjs.map +1 -0
  128. package/dist/social-providers/discord.d.mts +127 -0
  129. package/dist/social-providers/discord.mjs +65 -0
  130. package/dist/social-providers/discord.mjs.map +1 -0
  131. package/dist/social-providers/dropbox.d.mts +72 -0
  132. package/dist/social-providers/dropbox.mjs +76 -0
  133. package/dist/social-providers/dropbox.mjs.map +1 -0
  134. package/dist/social-providers/facebook.d.mts +82 -0
  135. package/dist/social-providers/facebook.mjs +121 -0
  136. package/dist/social-providers/facebook.mjs.map +1 -0
  137. package/dist/social-providers/figma.d.mts +64 -0
  138. package/dist/social-providers/figma.mjs +87 -0
  139. package/dist/social-providers/figma.mjs.map +1 -0
  140. package/dist/social-providers/github.d.mts +105 -0
  141. package/dist/social-providers/github.mjs +97 -0
  142. package/dist/social-providers/github.mjs.map +1 -0
  143. package/dist/social-providers/gitlab.d.mts +126 -0
  144. package/dist/social-providers/gitlab.mjs +83 -0
  145. package/dist/social-providers/gitlab.mjs.map +1 -0
  146. package/dist/social-providers/google.d.mts +100 -0
  147. package/dist/social-providers/google.mjs +109 -0
  148. package/dist/social-providers/google.mjs.map +1 -0
  149. package/dist/social-providers/huggingface.d.mts +86 -0
  150. package/dist/social-providers/huggingface.mjs +76 -0
  151. package/dist/social-providers/huggingface.mjs.map +1 -0
  152. package/dist/social-providers/index.d.mts +1725 -0
  153. package/dist/social-providers/index.mjs +77 -0
  154. package/dist/social-providers/index.mjs.map +1 -0
  155. package/dist/social-providers/kakao.d.mts +164 -0
  156. package/dist/social-providers/kakao.mjs +73 -0
  157. package/dist/social-providers/kakao.mjs.map +1 -0
  158. package/dist/social-providers/kick.d.mts +76 -0
  159. package/dist/social-providers/kick.mjs +72 -0
  160. package/dist/social-providers/kick.mjs.map +1 -0
  161. package/dist/social-providers/line.d.mts +108 -0
  162. package/dist/social-providers/line.mjs +114 -0
  163. package/dist/social-providers/line.mjs.map +1 -0
  164. package/dist/social-providers/linear.d.mts +71 -0
  165. package/dist/social-providers/linear.mjs +89 -0
  166. package/dist/social-providers/linear.mjs.map +1 -0
  167. package/dist/social-providers/linkedin.d.mts +70 -0
  168. package/dist/social-providers/linkedin.mjs +77 -0
  169. package/dist/social-providers/linkedin.mjs.map +1 -0
  170. package/dist/social-providers/microsoft-entra-id.d.mts +175 -0
  171. package/dist/social-providers/microsoft-entra-id.mjs +107 -0
  172. package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
  173. package/dist/social-providers/naver.d.mts +95 -0
  174. package/dist/social-providers/naver.mjs +68 -0
  175. package/dist/social-providers/naver.mjs.map +1 -0
  176. package/dist/social-providers/notion.d.mts +67 -0
  177. package/dist/social-providers/notion.mjs +76 -0
  178. package/dist/social-providers/notion.mjs.map +1 -0
  179. package/dist/social-providers/paybin.d.mts +74 -0
  180. package/dist/social-providers/paybin.mjs +86 -0
  181. package/dist/social-providers/paybin.mjs.map +1 -0
  182. package/dist/social-providers/paypal.d.mts +132 -0
  183. package/dist/social-providers/paypal.mjs +145 -0
  184. package/dist/social-providers/paypal.mjs.map +1 -0
  185. package/dist/social-providers/polar.d.mts +77 -0
  186. package/dist/social-providers/polar.mjs +74 -0
  187. package/dist/social-providers/polar.mjs.map +1 -0
  188. package/dist/social-providers/reddit.d.mts +65 -0
  189. package/dist/social-providers/reddit.mjs +84 -0
  190. package/dist/social-providers/reddit.mjs.map +1 -0
  191. package/dist/social-providers/roblox.d.mts +73 -0
  192. package/dist/social-providers/roblox.mjs +60 -0
  193. package/dist/social-providers/roblox.mjs.map +1 -0
  194. package/dist/social-providers/salesforce.d.mts +82 -0
  195. package/dist/social-providers/salesforce.mjs +92 -0
  196. package/dist/social-providers/salesforce.mjs.map +1 -0
  197. package/dist/social-providers/slack.d.mts +86 -0
  198. package/dist/social-providers/slack.mjs +69 -0
  199. package/dist/social-providers/slack.mjs.map +1 -0
  200. package/dist/social-providers/spotify.d.mts +66 -0
  201. package/dist/social-providers/spotify.mjs +72 -0
  202. package/dist/social-providers/spotify.mjs.map +1 -0
  203. package/dist/social-providers/tiktok.d.mts +171 -0
  204. package/dist/social-providers/tiktok.mjs +63 -0
  205. package/dist/social-providers/tiktok.mjs.map +1 -0
  206. package/dist/social-providers/twitch.d.mts +82 -0
  207. package/dist/social-providers/twitch.mjs +79 -0
  208. package/dist/social-providers/twitch.mjs.map +1 -0
  209. package/dist/social-providers/twitter.d.mts +129 -0
  210. package/dist/social-providers/twitter.mjs +88 -0
  211. package/dist/social-providers/twitter.mjs.map +1 -0
  212. package/dist/social-providers/vercel.d.mts +65 -0
  213. package/dist/social-providers/vercel.mjs +62 -0
  214. package/dist/social-providers/vercel.mjs.map +1 -0
  215. package/dist/social-providers/vk.d.mts +73 -0
  216. package/dist/social-providers/vk.mjs +84 -0
  217. package/dist/social-providers/vk.mjs.map +1 -0
  218. package/dist/social-providers/zoom.d.mts +173 -0
  219. package/dist/social-providers/zoom.mjs +73 -0
  220. package/dist/social-providers/zoom.mjs.map +1 -0
  221. package/dist/types/context.d.mts +267 -0
  222. package/dist/types/cookie.d.mts +16 -0
  223. package/dist/types/helper.d.mts +10 -0
  224. package/dist/types/index.d.mts +8 -0
  225. package/dist/types/init-options.d.mts +1314 -0
  226. package/dist/types/plugin-client.d.mts +112 -0
  227. package/dist/types/plugin.d.mts +125 -0
  228. package/dist/utils/db.d.mts +12 -0
  229. package/dist/utils/db.mjs +17 -0
  230. package/dist/utils/db.mjs.map +1 -0
  231. package/dist/utils/deprecate.d.mts +10 -0
  232. package/dist/utils/deprecate.mjs +18 -0
  233. package/dist/utils/deprecate.mjs.map +1 -0
  234. package/dist/utils/error-codes.d.mts +13 -0
  235. package/dist/utils/error-codes.mjs +12 -0
  236. package/dist/utils/error-codes.mjs.map +1 -0
  237. package/dist/utils/id.d.mts +5 -0
  238. package/dist/utils/id.mjs +10 -0
  239. package/dist/utils/id.mjs.map +1 -0
  240. package/dist/utils/ip.d.mts +55 -0
  241. package/dist/utils/ip.mjs +119 -0
  242. package/dist/utils/ip.mjs.map +1 -0
  243. package/dist/utils/json.d.mts +5 -0
  244. package/dist/utils/json.mjs +26 -0
  245. package/dist/utils/json.mjs.map +1 -0
  246. package/dist/utils/string.d.mts +5 -0
  247. package/dist/utils/string.mjs +8 -0
  248. package/dist/utils/string.mjs.map +1 -0
  249. package/dist/utils/url.d.mts +21 -0
  250. package/dist/utils/url.mjs +33 -0
  251. package/dist/utils/url.mjs.map +1 -0
  252. package/package.json +147 -0
  253. package/src/api/index.ts +106 -0
  254. package/src/async_hooks/index.ts +40 -0
  255. package/src/async_hooks/pure.index.ts +46 -0
  256. package/src/context/endpoint-context.ts +50 -0
  257. package/src/context/global.ts +57 -0
  258. package/src/context/index.ts +23 -0
  259. package/src/context/request-state.test.ts +94 -0
  260. package/src/context/request-state.ts +91 -0
  261. package/src/context/transaction.ts +136 -0
  262. package/src/db/adapter/factory.ts +1362 -0
  263. package/src/db/adapter/get-default-field-name.ts +59 -0
  264. package/src/db/adapter/get-default-model-name.ts +51 -0
  265. package/src/db/adapter/get-field-attributes.ts +62 -0
  266. package/src/db/adapter/get-field-name.ts +43 -0
  267. package/src/db/adapter/get-id-field.ts +141 -0
  268. package/src/db/adapter/get-model-name.ts +36 -0
  269. package/src/db/adapter/index.ts +554 -0
  270. package/src/db/adapter/types.ts +171 -0
  271. package/src/db/adapter/utils.ts +61 -0
  272. package/src/db/get-tables.ts +296 -0
  273. package/src/db/index.ts +18 -0
  274. package/src/db/plugin.ts +11 -0
  275. package/src/db/schema/account.ts +34 -0
  276. package/src/db/schema/rate-limit.ts +21 -0
  277. package/src/db/schema/session.ts +17 -0
  278. package/src/db/schema/shared.ts +7 -0
  279. package/src/db/schema/user.ts +16 -0
  280. package/src/db/schema/verification.ts +15 -0
  281. package/src/db/test/get-tables.test.ts +116 -0
  282. package/src/db/type.ts +180 -0
  283. package/src/env/color-depth.ts +172 -0
  284. package/src/env/env-impl.ts +124 -0
  285. package/src/env/index.ts +23 -0
  286. package/src/env/logger.test.ts +34 -0
  287. package/src/env/logger.ts +145 -0
  288. package/src/error/codes.ts +58 -0
  289. package/src/error/index.ts +35 -0
  290. package/src/index.ts +1 -0
  291. package/src/oauth2/client-credentials-token.ts +102 -0
  292. package/src/oauth2/create-authorization-url.ts +87 -0
  293. package/src/oauth2/index.ts +26 -0
  294. package/src/oauth2/oauth-provider.ts +222 -0
  295. package/src/oauth2/refresh-access-token.ts +124 -0
  296. package/src/oauth2/utils.ts +38 -0
  297. package/src/oauth2/validate-authorization-code.ts +149 -0
  298. package/src/oauth2/validate-token.test.ts +174 -0
  299. package/src/oauth2/verify.ts +221 -0
  300. package/src/social-providers/apple.ts +223 -0
  301. package/src/social-providers/atlassian.ts +132 -0
  302. package/src/social-providers/cognito.ts +279 -0
  303. package/src/social-providers/discord.ts +169 -0
  304. package/src/social-providers/dropbox.ts +112 -0
  305. package/src/social-providers/facebook.ts +206 -0
  306. package/src/social-providers/figma.ts +117 -0
  307. package/src/social-providers/github.ts +184 -0
  308. package/src/social-providers/gitlab.ts +155 -0
  309. package/src/social-providers/google.ts +199 -0
  310. package/src/social-providers/huggingface.ts +118 -0
  311. package/src/social-providers/index.ts +127 -0
  312. package/src/social-providers/kakao.ts +178 -0
  313. package/src/social-providers/kick.ts +109 -0
  314. package/src/social-providers/line.ts +169 -0
  315. package/src/social-providers/linear.ts +121 -0
  316. package/src/social-providers/linkedin.ts +110 -0
  317. package/src/social-providers/microsoft-entra-id.ts +259 -0
  318. package/src/social-providers/naver.ts +112 -0
  319. package/src/social-providers/notion.ts +108 -0
  320. package/src/social-providers/paybin.ts +122 -0
  321. package/src/social-providers/paypal.ts +263 -0
  322. package/src/social-providers/polar.ts +110 -0
  323. package/src/social-providers/reddit.ts +122 -0
  324. package/src/social-providers/roblox.ts +111 -0
  325. package/src/social-providers/salesforce.ts +159 -0
  326. package/src/social-providers/slack.ts +111 -0
  327. package/src/social-providers/spotify.ts +93 -0
  328. package/src/social-providers/tiktok.ts +209 -0
  329. package/src/social-providers/twitch.ts +111 -0
  330. package/src/social-providers/twitter.ts +198 -0
  331. package/src/social-providers/vercel.ts +87 -0
  332. package/src/social-providers/vk.ts +124 -0
  333. package/src/social-providers/zoom.ts +238 -0
  334. package/src/types/context.ts +396 -0
  335. package/src/types/cookie.ts +10 -0
  336. package/src/types/helper.ts +26 -0
  337. package/src/types/index.ts +32 -0
  338. package/src/types/init-options.ts +1529 -0
  339. package/src/types/plugin-client.ts +127 -0
  340. package/src/types/plugin.ts +157 -0
  341. package/src/utils/db.ts +20 -0
  342. package/src/utils/deprecate.test.ts +72 -0
  343. package/src/utils/deprecate.ts +21 -0
  344. package/src/utils/error-codes.ts +65 -0
  345. package/src/utils/id.ts +5 -0
  346. package/src/utils/ip.test.ts +255 -0
  347. package/src/utils/ip.ts +211 -0
  348. package/src/utils/json.ts +25 -0
  349. package/src/utils/string.ts +3 -0
  350. package/src/utils/url.ts +43 -0
  351. package/tsconfig.json +7 -0
  352. package/tsdown.config.ts +35 -0
  353. package/vitest.config.ts +3 -0
@@ -0,0 +1,61 @@
1
+ import type { DBFieldAttribute } from "../type";
2
+
3
+ export function withApplyDefault(
4
+ value: any,
5
+ field: DBFieldAttribute,
6
+ action: "create" | "update" | "findOne" | "findMany",
7
+ ) {
8
+ if (action === "update") {
9
+ // Apply onUpdate if value is undefined
10
+ if (value === undefined && field.onUpdate !== undefined) {
11
+ if (typeof field.onUpdate === "function") {
12
+ return field.onUpdate();
13
+ }
14
+ return field.onUpdate;
15
+ }
16
+ return value;
17
+ }
18
+ if (action === "create") {
19
+ // we do not want to apply default values if the value is null & not required
20
+ if (value === undefined || (field.required === true && value === null)) {
21
+ if (field.defaultValue !== undefined) {
22
+ if (typeof field.defaultValue === "function") {
23
+ return field.defaultValue();
24
+ }
25
+ return field.defaultValue;
26
+ }
27
+ }
28
+ }
29
+ return value;
30
+ }
31
+
32
+ function isObject(item: unknown): item is Record<string, unknown> {
33
+ return item !== null && typeof item === "object" && !Array.isArray(item);
34
+ }
35
+
36
+ export function deepmerge<T>(target: T, source: Partial<T>): T {
37
+ if (Array.isArray(target) && Array.isArray(source)) {
38
+ // merge arrays by concatenation
39
+ return [...target, ...source] as T;
40
+ } else if (isObject(target) && isObject(source)) {
41
+ const result: Record<string, unknown> = { ...target };
42
+
43
+ for (const [key, value] of Object.entries(source)) {
44
+ if (value === undefined) continue; // skip undefined
45
+
46
+ if (key in target) {
47
+ result[key] = deepmerge(
48
+ (target as Record<string, unknown>)[key],
49
+ value as unknown as Partial<T>,
50
+ );
51
+ } else {
52
+ result[key] = value;
53
+ }
54
+ }
55
+
56
+ return result as T;
57
+ }
58
+
59
+ // primitives and fallback: source overrides target
60
+ return source as T;
61
+ }
@@ -0,0 +1,296 @@
1
+ import type { BetterAuthOptions } from "../types";
2
+ import type { BetterAuthDBSchema, DBFieldAttribute } from "./type";
3
+
4
+ export const getAuthTables = (
5
+ options: BetterAuthOptions,
6
+ ): BetterAuthDBSchema => {
7
+ const pluginSchema = (options.plugins ?? []).reduce(
8
+ (acc, plugin) => {
9
+ const schema = plugin.schema;
10
+ if (!schema) return acc;
11
+ for (const [key, value] of Object.entries(schema)) {
12
+ acc[key] = {
13
+ fields: {
14
+ ...acc[key]?.fields,
15
+ ...value.fields,
16
+ },
17
+ modelName: value.modelName || key,
18
+ };
19
+ }
20
+ return acc;
21
+ },
22
+ {} as Record<
23
+ string,
24
+ { fields: Record<string, DBFieldAttribute>; modelName: string }
25
+ >,
26
+ );
27
+
28
+ const shouldAddRateLimitTable = options.rateLimit?.storage === "database";
29
+ const rateLimitTable = {
30
+ rateLimit: {
31
+ modelName: options.rateLimit?.modelName || "rateLimit",
32
+ fields: {
33
+ key: {
34
+ type: "string",
35
+ unique: true,
36
+ required: true,
37
+ fieldName: options.rateLimit?.fields?.key || "key",
38
+ },
39
+ count: {
40
+ type: "number",
41
+ required: true,
42
+ fieldName: options.rateLimit?.fields?.count || "count",
43
+ },
44
+ lastRequest: {
45
+ type: "number",
46
+ bigint: true,
47
+ required: true,
48
+ fieldName: options.rateLimit?.fields?.lastRequest || "lastRequest",
49
+ defaultValue: () => Date.now(),
50
+ },
51
+ },
52
+ },
53
+ } satisfies BetterAuthDBSchema;
54
+
55
+ const { user, session, account, verification, ...pluginTables } =
56
+ pluginSchema;
57
+
58
+ const verificationTable = {
59
+ verification: {
60
+ modelName: options.verification?.modelName || "verification",
61
+ fields: {
62
+ identifier: {
63
+ type: "string",
64
+ required: true,
65
+ fieldName: options.verification?.fields?.identifier || "identifier",
66
+ index: true,
67
+ },
68
+ value: {
69
+ type: "string",
70
+ required: true,
71
+ fieldName: options.verification?.fields?.value || "value",
72
+ },
73
+ expiresAt: {
74
+ type: "date",
75
+ required: true,
76
+ fieldName: options.verification?.fields?.expiresAt || "expiresAt",
77
+ },
78
+ createdAt: {
79
+ type: "date",
80
+ required: true,
81
+ defaultValue: () => new Date(),
82
+ fieldName: options.verification?.fields?.createdAt || "createdAt",
83
+ },
84
+ updatedAt: {
85
+ type: "date",
86
+ required: true,
87
+ defaultValue: () => new Date(),
88
+ onUpdate: () => new Date(),
89
+ fieldName: options.verification?.fields?.updatedAt || "updatedAt",
90
+ },
91
+ ...verification?.fields,
92
+ ...options.verification?.additionalFields,
93
+ },
94
+ order: 4,
95
+ },
96
+ } satisfies BetterAuthDBSchema;
97
+
98
+ const sessionTable = {
99
+ session: {
100
+ modelName: options.session?.modelName || "session",
101
+ fields: {
102
+ expiresAt: {
103
+ type: "date",
104
+ required: true,
105
+ fieldName: options.session?.fields?.expiresAt || "expiresAt",
106
+ },
107
+ token: {
108
+ type: "string",
109
+ required: true,
110
+ fieldName: options.session?.fields?.token || "token",
111
+ unique: true,
112
+ },
113
+ createdAt: {
114
+ type: "date",
115
+ required: true,
116
+ fieldName: options.session?.fields?.createdAt || "createdAt",
117
+ defaultValue: () => new Date(),
118
+ },
119
+ updatedAt: {
120
+ type: "date",
121
+ required: true,
122
+ fieldName: options.session?.fields?.updatedAt || "updatedAt",
123
+ onUpdate: () => new Date(),
124
+ },
125
+ ipAddress: {
126
+ type: "string",
127
+ required: false,
128
+ fieldName: options.session?.fields?.ipAddress || "ipAddress",
129
+ },
130
+ userAgent: {
131
+ type: "string",
132
+ required: false,
133
+ fieldName: options.session?.fields?.userAgent || "userAgent",
134
+ },
135
+ userId: {
136
+ type: "string",
137
+ fieldName: options.session?.fields?.userId || "userId",
138
+ references: {
139
+ model: options.user?.modelName || "user",
140
+ field: "id",
141
+ onDelete: "cascade",
142
+ },
143
+ required: true,
144
+ index: true,
145
+ },
146
+ ...session?.fields,
147
+ ...options.session?.additionalFields,
148
+ },
149
+ order: 2,
150
+ },
151
+ } satisfies BetterAuthDBSchema;
152
+
153
+ return {
154
+ user: {
155
+ modelName: options.user?.modelName || "user",
156
+ fields: {
157
+ name: {
158
+ type: "string",
159
+ required: true,
160
+ fieldName: options.user?.fields?.name || "name",
161
+ sortable: true,
162
+ },
163
+ email: {
164
+ type: "string",
165
+ unique: true,
166
+ required: true,
167
+ fieldName: options.user?.fields?.email || "email",
168
+ sortable: true,
169
+ },
170
+ emailVerified: {
171
+ type: "boolean",
172
+ defaultValue: false,
173
+ required: true,
174
+ fieldName: options.user?.fields?.emailVerified || "emailVerified",
175
+ input: false,
176
+ },
177
+ image: {
178
+ type: "string",
179
+ required: false,
180
+ fieldName: options.user?.fields?.image || "image",
181
+ },
182
+ createdAt: {
183
+ type: "date",
184
+ defaultValue: () => new Date(),
185
+ required: true,
186
+ fieldName: options.user?.fields?.createdAt || "createdAt",
187
+ },
188
+ updatedAt: {
189
+ type: "date",
190
+ defaultValue: () => new Date(),
191
+ onUpdate: () => new Date(),
192
+ required: true,
193
+ fieldName: options.user?.fields?.updatedAt || "updatedAt",
194
+ },
195
+ ...user?.fields,
196
+ ...options.user?.additionalFields,
197
+ },
198
+ order: 1,
199
+ },
200
+ //only add session table if it's not stored in secondary storage
201
+ ...(!options.secondaryStorage || options.session?.storeSessionInDatabase
202
+ ? sessionTable
203
+ : {}),
204
+ account: {
205
+ modelName: options.account?.modelName || "account",
206
+ fields: {
207
+ accountId: {
208
+ type: "string",
209
+ required: true,
210
+ fieldName: options.account?.fields?.accountId || "accountId",
211
+ },
212
+ providerId: {
213
+ type: "string",
214
+ required: true,
215
+ fieldName: options.account?.fields?.providerId || "providerId",
216
+ },
217
+ userId: {
218
+ type: "string",
219
+ references: {
220
+ model: options.user?.modelName || "user",
221
+ field: "id",
222
+ onDelete: "cascade",
223
+ },
224
+ required: true,
225
+ fieldName: options.account?.fields?.userId || "userId",
226
+ index: true,
227
+ },
228
+ accessToken: {
229
+ type: "string",
230
+ required: false,
231
+ returned: false,
232
+ fieldName: options.account?.fields?.accessToken || "accessToken",
233
+ },
234
+ refreshToken: {
235
+ type: "string",
236
+ required: false,
237
+ returned: false,
238
+ fieldName: options.account?.fields?.refreshToken || "refreshToken",
239
+ },
240
+ idToken: {
241
+ type: "string",
242
+ required: false,
243
+ returned: false,
244
+ fieldName: options.account?.fields?.idToken || "idToken",
245
+ },
246
+ accessTokenExpiresAt: {
247
+ type: "date",
248
+ required: false,
249
+ returned: false,
250
+ fieldName:
251
+ options.account?.fields?.accessTokenExpiresAt ||
252
+ "accessTokenExpiresAt",
253
+ },
254
+ refreshTokenExpiresAt: {
255
+ type: "date",
256
+ required: false,
257
+ returned: false,
258
+ fieldName:
259
+ options.account?.fields?.refreshTokenExpiresAt ||
260
+ "refreshTokenExpiresAt",
261
+ },
262
+ scope: {
263
+ type: "string",
264
+ required: false,
265
+ fieldName: options.account?.fields?.scope || "scope",
266
+ },
267
+ password: {
268
+ type: "string",
269
+ required: false,
270
+ returned: false,
271
+ fieldName: options.account?.fields?.password || "password",
272
+ },
273
+ createdAt: {
274
+ type: "date",
275
+ required: true,
276
+ fieldName: options.account?.fields?.createdAt || "createdAt",
277
+ defaultValue: () => new Date(),
278
+ },
279
+ updatedAt: {
280
+ type: "date",
281
+ required: true,
282
+ fieldName: options.account?.fields?.updatedAt || "updatedAt",
283
+ onUpdate: () => new Date(),
284
+ },
285
+ ...account?.fields,
286
+ ...options.account?.additionalFields,
287
+ },
288
+ order: 3,
289
+ },
290
+ ...(!options.secondaryStorage || options.verification?.storeInDatabase
291
+ ? verificationTable
292
+ : {}),
293
+ ...pluginTables,
294
+ ...(shouldAddRateLimitTable ? rateLimitTable : {}),
295
+ } satisfies BetterAuthDBSchema;
296
+ };
@@ -0,0 +1,18 @@
1
+ export { getAuthTables } from "./get-tables";
2
+ export type { BetterAuthPluginDBSchema } from "./plugin";
3
+ export { type Account, accountSchema } from "./schema/account";
4
+ export { type RateLimit, rateLimitSchema } from "./schema/rate-limit";
5
+ export { type Session, sessionSchema } from "./schema/session";
6
+ export { coreSchema } from "./schema/shared";
7
+ export { type User, userSchema } from "./schema/user";
8
+ export { type Verification, verificationSchema } from "./schema/verification";
9
+ export type {
10
+ BaseModelNames,
11
+ BetterAuthDBSchema,
12
+ DBFieldAttribute,
13
+ DBFieldAttributeConfig,
14
+ DBFieldType,
15
+ DBPrimitive,
16
+ ModelNames,
17
+ SecondaryStorage,
18
+ } from "./type";
@@ -0,0 +1,11 @@
1
+ import type { DBFieldAttribute } from "./type";
2
+
3
+ export type BetterAuthPluginDBSchema = {
4
+ [table in string]: {
5
+ fields: {
6
+ [field: string]: DBFieldAttribute;
7
+ };
8
+ disableMigration?: boolean | undefined;
9
+ modelName?: string | undefined;
10
+ };
11
+ };
@@ -0,0 +1,34 @@
1
+ import * as z from "zod";
2
+ import { coreSchema } from "./shared";
3
+
4
+ export const accountSchema = coreSchema.extend({
5
+ providerId: z.string(),
6
+ accountId: z.string(),
7
+ userId: z.coerce.string(),
8
+ accessToken: z.string().nullish(),
9
+ refreshToken: z.string().nullish(),
10
+ idToken: z.string().nullish(),
11
+ /**
12
+ * Access token expires at
13
+ */
14
+ accessTokenExpiresAt: z.date().nullish(),
15
+ /**
16
+ * Refresh token expires at
17
+ */
18
+ refreshTokenExpiresAt: z.date().nullish(),
19
+ /**
20
+ * The scopes that the user has authorized
21
+ */
22
+ scope: z.string().nullish(),
23
+ /**
24
+ * Password is only stored in the credential provider
25
+ */
26
+ password: z.string().nullish(),
27
+ });
28
+
29
+ /**
30
+ * Account schema type used by better-auth, note that it's possible that account could have additional fields
31
+ *
32
+ * todo: we should use generics to extend this type with additional fields from plugins and options in the future
33
+ */
34
+ export type Account = z.infer<typeof accountSchema>;
@@ -0,0 +1,21 @@
1
+ import * as z from "zod";
2
+
3
+ export const rateLimitSchema = z.object({
4
+ /**
5
+ * The key to use for rate limiting
6
+ */
7
+ key: z.string(),
8
+ /**
9
+ * The number of requests made
10
+ */
11
+ count: z.number(),
12
+ /**
13
+ * The last request time in milliseconds
14
+ */
15
+ lastRequest: z.number(),
16
+ });
17
+
18
+ /**
19
+ * Rate limit schema type used by better-auth for rate limiting
20
+ */
21
+ export type RateLimit = z.infer<typeof rateLimitSchema>;
@@ -0,0 +1,17 @@
1
+ import * as z from "zod";
2
+ import { coreSchema } from "./shared";
3
+
4
+ export const sessionSchema = coreSchema.extend({
5
+ userId: z.coerce.string(),
6
+ expiresAt: z.date(),
7
+ token: z.string(),
8
+ ipAddress: z.string().nullish(),
9
+ userAgent: z.string().nullish(),
10
+ });
11
+
12
+ /**
13
+ * Session schema type used by better-auth, note that it's possible that session could have additional fields
14
+ *
15
+ * todo: we should use generics to extend this type with additional fields from plugins and options in the future
16
+ */
17
+ export type Session = z.infer<typeof sessionSchema>;
@@ -0,0 +1,7 @@
1
+ import * as z from "zod";
2
+
3
+ export const coreSchema = z.object({
4
+ id: z.string(),
5
+ createdAt: z.date().default(() => new Date()),
6
+ updatedAt: z.date().default(() => new Date()),
7
+ });
@@ -0,0 +1,16 @@
1
+ import * as z from "zod";
2
+ import { coreSchema } from "./shared";
3
+
4
+ export const userSchema = coreSchema.extend({
5
+ email: z.string().transform((val) => val.toLowerCase()),
6
+ emailVerified: z.boolean().default(false),
7
+ name: z.string(),
8
+ image: z.string().nullish(),
9
+ });
10
+
11
+ /**
12
+ * User schema type used by better-auth, note that it's possible that user could have additional fields
13
+ *
14
+ * todo: we should use generics to extend this type with additional fields from plugins and options in the future
15
+ */
16
+ export type User = z.infer<typeof userSchema>;
@@ -0,0 +1,15 @@
1
+ import * as z from "zod";
2
+ import { coreSchema } from "./shared";
3
+
4
+ export const verificationSchema = coreSchema.extend({
5
+ value: z.string(),
6
+ expiresAt: z.date(),
7
+ identifier: z.string(),
8
+ });
9
+
10
+ /**
11
+ * Verification schema type used by better-auth, note that it's possible that verification could have additional fields
12
+ *
13
+ * todo: we should use generics to extend this type with additional fields from plugins and options in the future
14
+ */
15
+ export type Verification = z.infer<typeof verificationSchema>;
@@ -0,0 +1,116 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getAuthTables } from "../get-tables";
3
+
4
+ describe("getAuthTables", () => {
5
+ it("should use correct field name for refreshTokenExpiresAt", () => {
6
+ const tables = getAuthTables({
7
+ account: {
8
+ fields: {
9
+ refreshTokenExpiresAt: "custom_refresh_token_expires_at",
10
+ },
11
+ },
12
+ });
13
+
14
+ const accountTable = tables.account;
15
+ const refreshTokenExpiresAtField =
16
+ accountTable!.fields.refreshTokenExpiresAt!;
17
+
18
+ expect(refreshTokenExpiresAtField.fieldName).toBe(
19
+ "custom_refresh_token_expires_at",
20
+ );
21
+ });
22
+
23
+ it("should not use accessTokenExpiresAt field name for refreshTokenExpiresAt", () => {
24
+ const tables = getAuthTables({
25
+ account: {
26
+ fields: {
27
+ accessTokenExpiresAt: "custom_access_token_expires_at",
28
+ refreshTokenExpiresAt: "custom_refresh_token_expires_at",
29
+ },
30
+ },
31
+ });
32
+
33
+ const accountTable = tables.account;
34
+ const refreshTokenExpiresAtField =
35
+ accountTable!.fields.refreshTokenExpiresAt!;
36
+ const accessTokenExpiresAtField =
37
+ accountTable!.fields.accessTokenExpiresAt!;
38
+
39
+ expect(refreshTokenExpiresAtField.fieldName).toBe(
40
+ "custom_refresh_token_expires_at",
41
+ );
42
+ expect(accessTokenExpiresAtField.fieldName).toBe(
43
+ "custom_access_token_expires_at",
44
+ );
45
+ expect(refreshTokenExpiresAtField.fieldName).not.toBe(
46
+ accessTokenExpiresAtField.fieldName,
47
+ );
48
+ });
49
+
50
+ it("should use default field names when no custom names provided", () => {
51
+ const tables = getAuthTables({});
52
+
53
+ const accountTable = tables.account;
54
+ const refreshTokenExpiresAtField =
55
+ accountTable!.fields.refreshTokenExpiresAt!;
56
+ const accessTokenExpiresAtField =
57
+ accountTable!.fields.accessTokenExpiresAt!;
58
+
59
+ expect(refreshTokenExpiresAtField.fieldName).toBe("refreshTokenExpiresAt");
60
+ expect(accessTokenExpiresAtField.fieldName).toBe("accessTokenExpiresAt");
61
+ });
62
+
63
+ it("should merge additionalFields into verification table metadata", () => {
64
+ const tables = getAuthTables({
65
+ verification: {
66
+ additionalFields: {
67
+ newField: {
68
+ fieldName: "new_field",
69
+ type: "string",
70
+ },
71
+ },
72
+ },
73
+ });
74
+
75
+ const verificationTable = tables.verification;
76
+ const newField = verificationTable!.fields.newField!;
77
+
78
+ console.log(newField);
79
+ expect(newField).not.toBeUndefined();
80
+ expect(newField.fieldName).toBe("new_field");
81
+ expect(newField.type).toBe("string");
82
+ });
83
+
84
+ it("should exclude verification table when secondaryStorage is configured", () => {
85
+ const tables = getAuthTables({
86
+ secondaryStorage: {
87
+ get: async () => null,
88
+ set: async () => {},
89
+ delete: async () => {},
90
+ },
91
+ });
92
+
93
+ expect(tables.verification).toBeUndefined();
94
+ });
95
+
96
+ it("should include verification table when storeInDatabase is true", () => {
97
+ const tables = getAuthTables({
98
+ secondaryStorage: {
99
+ get: async () => null,
100
+ set: async () => {},
101
+ delete: async () => {},
102
+ },
103
+ verification: {
104
+ storeInDatabase: true,
105
+ },
106
+ });
107
+
108
+ expect(tables.verification).toBeDefined();
109
+ });
110
+
111
+ it("should include verification table when no secondaryStorage", () => {
112
+ const tables = getAuthTables({});
113
+
114
+ expect(tables.verification).toBeDefined();
115
+ });
116
+ });