@depup/better-auth__core 1.6.23-depup.2

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 (310) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +32 -0
  3. package/changes.json +14 -0
  4. package/dist/api/index.d.mts +281 -0
  5. package/dist/api/index.mjs +92 -0
  6. package/dist/async_hooks/index.d.mts +6 -0
  7. package/dist/async_hooks/index.mjs +20 -0
  8. package/dist/async_hooks/pure.index.d.mts +6 -0
  9. package/dist/async_hooks/pure.index.mjs +33 -0
  10. package/dist/context/endpoint-context.d.mts +18 -0
  11. package/dist/context/endpoint-context.mjs +29 -0
  12. package/dist/context/global.d.mts +6 -0
  13. package/dist/context/global.mjs +36 -0
  14. package/dist/context/index.d.mts +5 -0
  15. package/dist/context/index.mjs +5 -0
  16. package/dist/context/request-state.d.mts +27 -0
  17. package/dist/context/request-state.mjs +47 -0
  18. package/dist/context/transaction.d.mts +27 -0
  19. package/dist/context/transaction.mjs +96 -0
  20. package/dist/db/adapter/factory.d.mts +17 -0
  21. package/dist/db/adapter/factory.mjs +905 -0
  22. package/dist/db/adapter/get-default-field-name.d.mts +18 -0
  23. package/dist/db/adapter/get-default-field-name.mjs +36 -0
  24. package/dist/db/adapter/get-default-model-name.d.mts +12 -0
  25. package/dist/db/adapter/get-default-model-name.mjs +30 -0
  26. package/dist/db/adapter/get-field-attributes.d.mts +26 -0
  27. package/dist/db/adapter/get-field-attributes.mjs +37 -0
  28. package/dist/db/adapter/get-field-name.d.mts +18 -0
  29. package/dist/db/adapter/get-field-name.mjs +31 -0
  30. package/dist/db/adapter/get-id-field.d.mts +36 -0
  31. package/dist/db/adapter/get-id-field.mjs +64 -0
  32. package/dist/db/adapter/get-model-name.d.mts +12 -0
  33. package/dist/db/adapter/get-model-name.mjs +21 -0
  34. package/dist/db/adapter/index.d.mts +615 -0
  35. package/dist/db/adapter/index.mjs +24 -0
  36. package/dist/db/adapter/types.d.mts +105 -0
  37. package/dist/db/adapter/utils.d.mts +7 -0
  38. package/dist/db/adapter/utils.mjs +37 -0
  39. package/dist/db/get-tables.d.mts +6 -0
  40. package/dist/db/get-tables.mjs +266 -0
  41. package/dist/db/index.d.mts +10 -0
  42. package/dist/db/index.mjs +8 -0
  43. package/dist/db/plugin.d.mts +12 -0
  44. package/dist/db/schema/account.d.mts +28 -0
  45. package/dist/db/schema/account.mjs +17 -0
  46. package/dist/db/schema/rate-limit.d.mts +18 -0
  47. package/dist/db/schema/rate-limit.mjs +9 -0
  48. package/dist/db/schema/session.d.mts +23 -0
  49. package/dist/db/schema/session.mjs +12 -0
  50. package/dist/db/schema/shared.d.mts +10 -0
  51. package/dist/db/schema/shared.mjs +9 -0
  52. package/dist/db/schema/user.d.mts +22 -0
  53. package/dist/db/schema/user.mjs +11 -0
  54. package/dist/db/schema/verification.d.mts +21 -0
  55. package/dist/db/schema/verification.mjs +10 -0
  56. package/dist/db/type.d.mts +194 -0
  57. package/dist/env/color-depth.d.mts +4 -0
  58. package/dist/env/color-depth.mjs +86 -0
  59. package/dist/env/env-impl.d.mts +32 -0
  60. package/dist/env/env-impl.mjs +81 -0
  61. package/dist/env/index.d.mts +4 -0
  62. package/dist/env/index.mjs +4 -0
  63. package/dist/env/logger.d.mts +48 -0
  64. package/dist/env/logger.mjs +79 -0
  65. package/dist/error/codes.d.mts +69 -0
  66. package/dist/error/codes.mjs +55 -0
  67. package/dist/error/index.d.mts +26 -0
  68. package/dist/error/index.mjs +27 -0
  69. package/dist/index.d.mts +9 -0
  70. package/dist/index.mjs +1 -0
  71. package/dist/instrumentation/api.mjs +12 -0
  72. package/dist/instrumentation/attributes.d.mts +11 -0
  73. package/dist/instrumentation/attributes.mjs +10 -0
  74. package/dist/instrumentation/index.d.mts +3 -0
  75. package/dist/instrumentation/index.mjs +3 -0
  76. package/dist/instrumentation/noop.mjs +42 -0
  77. package/dist/instrumentation/pure.index.d.mts +7 -0
  78. package/dist/instrumentation/pure.index.mjs +7 -0
  79. package/dist/instrumentation/tracer.d.mts +13 -0
  80. package/dist/instrumentation/tracer.mjs +53 -0
  81. package/dist/oauth2/client-credentials-token.d.mts +56 -0
  82. package/dist/oauth2/client-credentials-token.mjs +64 -0
  83. package/dist/oauth2/create-authorization-url.d.mts +44 -0
  84. package/dist/oauth2/create-authorization-url.mjs +41 -0
  85. package/dist/oauth2/index.d.mts +8 -0
  86. package/dist/oauth2/index.mjs +7 -0
  87. package/dist/oauth2/oauth-provider.d.mts +192 -0
  88. package/dist/oauth2/refresh-access-token.d.mts +54 -0
  89. package/dist/oauth2/refresh-access-token.mjs +73 -0
  90. package/dist/oauth2/reject-redirects.mjs +60 -0
  91. package/dist/oauth2/utils.d.mts +24 -0
  92. package/dist/oauth2/utils.mjs +48 -0
  93. package/dist/oauth2/validate-authorization-code.d.mts +85 -0
  94. package/dist/oauth2/validate-authorization-code.mjs +86 -0
  95. package/dist/oauth2/verify.d.mts +65 -0
  96. package/dist/oauth2/verify.mjs +202 -0
  97. package/dist/social-providers/apple.d.mts +133 -0
  98. package/dist/social-providers/apple.mjs +117 -0
  99. package/dist/social-providers/atlassian.d.mts +70 -0
  100. package/dist/social-providers/atlassian.mjs +80 -0
  101. package/dist/social-providers/cognito.d.mts +85 -0
  102. package/dist/social-providers/cognito.mjs +162 -0
  103. package/dist/social-providers/discord.d.mts +124 -0
  104. package/dist/social-providers/discord.mjs +62 -0
  105. package/dist/social-providers/dropbox.d.mts +69 -0
  106. package/dist/social-providers/dropbox.mjs +72 -0
  107. package/dist/social-providers/facebook.d.mts +79 -0
  108. package/dist/social-providers/facebook.mjs +157 -0
  109. package/dist/social-providers/figma.d.mts +61 -0
  110. package/dist/social-providers/figma.mjs +83 -0
  111. package/dist/social-providers/github.d.mts +102 -0
  112. package/dist/social-providers/github.mjs +92 -0
  113. package/dist/social-providers/gitlab.d.mts +123 -0
  114. package/dist/social-providers/gitlab.mjs +79 -0
  115. package/dist/social-providers/google.d.mts +123 -0
  116. package/dist/social-providers/google.mjs +137 -0
  117. package/dist/social-providers/huggingface.d.mts +83 -0
  118. package/dist/social-providers/huggingface.mjs +73 -0
  119. package/dist/social-providers/index.d.mts +1834 -0
  120. package/dist/social-providers/index.mjs +78 -0
  121. package/dist/social-providers/kakao.d.mts +161 -0
  122. package/dist/social-providers/kakao.mjs +70 -0
  123. package/dist/social-providers/kick.d.mts +73 -0
  124. package/dist/social-providers/kick.mjs +68 -0
  125. package/dist/social-providers/line.d.mts +105 -0
  126. package/dist/social-providers/line.mjs +110 -0
  127. package/dist/social-providers/linear.d.mts +68 -0
  128. package/dist/social-providers/linear.mjs +85 -0
  129. package/dist/social-providers/linkedin.d.mts +67 -0
  130. package/dist/social-providers/linkedin.mjs +73 -0
  131. package/dist/social-providers/microsoft-entra-id.d.mts +174 -0
  132. package/dist/social-providers/microsoft-entra-id.mjs +152 -0
  133. package/dist/social-providers/naver.d.mts +92 -0
  134. package/dist/social-providers/naver.mjs +65 -0
  135. package/dist/social-providers/notion.d.mts +64 -0
  136. package/dist/social-providers/notion.mjs +72 -0
  137. package/dist/social-providers/paybin.d.mts +71 -0
  138. package/dist/social-providers/paybin.mjs +81 -0
  139. package/dist/social-providers/paypal.d.mts +131 -0
  140. package/dist/social-providers/paypal.mjs +188 -0
  141. package/dist/social-providers/polar.d.mts +74 -0
  142. package/dist/social-providers/polar.mjs +71 -0
  143. package/dist/social-providers/railway.d.mts +65 -0
  144. package/dist/social-providers/railway.mjs +74 -0
  145. package/dist/social-providers/reddit.d.mts +62 -0
  146. package/dist/social-providers/reddit.mjs +81 -0
  147. package/dist/social-providers/roblox.d.mts +70 -0
  148. package/dist/social-providers/roblox.mjs +57 -0
  149. package/dist/social-providers/salesforce.d.mts +79 -0
  150. package/dist/social-providers/salesforce.mjs +87 -0
  151. package/dist/social-providers/slack.d.mts +83 -0
  152. package/dist/social-providers/slack.mjs +66 -0
  153. package/dist/social-providers/spotify.d.mts +63 -0
  154. package/dist/social-providers/spotify.mjs +69 -0
  155. package/dist/social-providers/tiktok.d.mts +168 -0
  156. package/dist/social-providers/tiktok.mjs +60 -0
  157. package/dist/social-providers/twitch.d.mts +79 -0
  158. package/dist/social-providers/twitch.mjs +75 -0
  159. package/dist/social-providers/twitter.d.mts +126 -0
  160. package/dist/social-providers/twitter.mjs +85 -0
  161. package/dist/social-providers/vercel.d.mts +62 -0
  162. package/dist/social-providers/vercel.mjs +58 -0
  163. package/dist/social-providers/vk.d.mts +70 -0
  164. package/dist/social-providers/vk.mjs +81 -0
  165. package/dist/social-providers/wechat.d.mts +113 -0
  166. package/dist/social-providers/wechat.mjs +81 -0
  167. package/dist/social-providers/zoom.d.mts +163 -0
  168. package/dist/social-providers/zoom.mjs +69 -0
  169. package/dist/types/context.d.mts +319 -0
  170. package/dist/types/cookie.d.mts +15 -0
  171. package/dist/types/helper.d.mts +10 -0
  172. package/dist/types/index.d.mts +9 -0
  173. package/dist/types/init-options.d.mts +1430 -0
  174. package/dist/types/plugin-client.d.mts +123 -0
  175. package/dist/types/plugin.d.mts +124 -0
  176. package/dist/types/secret.d.mts +11 -0
  177. package/dist/utils/async.d.mts +22 -0
  178. package/dist/utils/async.mjs +32 -0
  179. package/dist/utils/db.d.mts +9 -0
  180. package/dist/utils/db.mjs +15 -0
  181. package/dist/utils/deprecate.d.mts +9 -0
  182. package/dist/utils/deprecate.mjs +16 -0
  183. package/dist/utils/error-codes.d.mts +13 -0
  184. package/dist/utils/error-codes.mjs +10 -0
  185. package/dist/utils/fetch-metadata.d.mts +4 -0
  186. package/dist/utils/fetch-metadata.mjs +6 -0
  187. package/dist/utils/host.d.mts +147 -0
  188. package/dist/utils/host.mjs +295 -0
  189. package/dist/utils/id.d.mts +4 -0
  190. package/dist/utils/id.mjs +7 -0
  191. package/dist/utils/ip.d.mts +77 -0
  192. package/dist/utils/ip.mjs +230 -0
  193. package/dist/utils/is-api-error.d.mts +6 -0
  194. package/dist/utils/is-api-error.mjs +8 -0
  195. package/dist/utils/json.d.mts +4 -0
  196. package/dist/utils/json.mjs +41 -0
  197. package/dist/utils/redirect-uri.d.mts +20 -0
  198. package/dist/utils/redirect-uri.mjs +48 -0
  199. package/dist/utils/string.d.mts +8 -0
  200. package/dist/utils/string.mjs +25 -0
  201. package/dist/utils/url.d.mts +37 -0
  202. package/dist/utils/url.mjs +61 -0
  203. package/package.json +216 -0
  204. package/src/api/index.ts +185 -0
  205. package/src/async_hooks/index.ts +40 -0
  206. package/src/async_hooks/pure.index.ts +46 -0
  207. package/src/context/endpoint-context.ts +50 -0
  208. package/src/context/global.ts +57 -0
  209. package/src/context/index.ts +23 -0
  210. package/src/context/request-state.ts +91 -0
  211. package/src/context/transaction.ts +169 -0
  212. package/src/db/adapter/factory.ts +1740 -0
  213. package/src/db/adapter/get-default-field-name.ts +59 -0
  214. package/src/db/adapter/get-default-model-name.ts +51 -0
  215. package/src/db/adapter/get-field-attributes.ts +62 -0
  216. package/src/db/adapter/get-field-name.ts +43 -0
  217. package/src/db/adapter/get-id-field.ts +150 -0
  218. package/src/db/adapter/get-model-name.ts +36 -0
  219. package/src/db/adapter/index.ts +656 -0
  220. package/src/db/adapter/types.ts +134 -0
  221. package/src/db/adapter/utils.ts +61 -0
  222. package/src/db/get-tables.ts +304 -0
  223. package/src/db/index.ts +43 -0
  224. package/src/db/plugin.ts +11 -0
  225. package/src/db/schema/account.ts +47 -0
  226. package/src/db/schema/rate-limit.ts +36 -0
  227. package/src/db/schema/session.ts +29 -0
  228. package/src/db/schema/shared.ts +7 -0
  229. package/src/db/schema/user.ts +31 -0
  230. package/src/db/schema/verification.ts +28 -0
  231. package/src/db/type.ts +360 -0
  232. package/src/env/color-depth.ts +172 -0
  233. package/src/env/env-impl.ts +123 -0
  234. package/src/env/index.ts +23 -0
  235. package/src/env/logger.ts +145 -0
  236. package/src/error/codes.ts +72 -0
  237. package/src/error/index.ts +44 -0
  238. package/src/index.ts +1 -0
  239. package/src/instrumentation/api.ts +17 -0
  240. package/src/instrumentation/attributes.ts +22 -0
  241. package/src/instrumentation/index.ts +2 -0
  242. package/src/instrumentation/noop.ts +74 -0
  243. package/src/instrumentation/pure.index.ts +31 -0
  244. package/src/instrumentation/tracer.ts +95 -0
  245. package/src/oauth2/client-credentials-token.ts +126 -0
  246. package/src/oauth2/create-authorization-url.ts +89 -0
  247. package/src/oauth2/index.ts +34 -0
  248. package/src/oauth2/oauth-provider.ts +222 -0
  249. package/src/oauth2/refresh-access-token.ts +157 -0
  250. package/src/oauth2/reject-redirects.ts +70 -0
  251. package/src/oauth2/utils.ts +70 -0
  252. package/src/oauth2/validate-authorization-code.ts +190 -0
  253. package/src/oauth2/verify.ts +408 -0
  254. package/src/social-providers/apple.ts +249 -0
  255. package/src/social-providers/atlassian.ts +133 -0
  256. package/src/social-providers/cognito.ts +281 -0
  257. package/src/social-providers/discord.ts +170 -0
  258. package/src/social-providers/dropbox.ts +112 -0
  259. package/src/social-providers/facebook.ts +288 -0
  260. package/src/social-providers/figma.ts +118 -0
  261. package/src/social-providers/github.ts +184 -0
  262. package/src/social-providers/gitlab.ts +155 -0
  263. package/src/social-providers/google.ts +263 -0
  264. package/src/social-providers/huggingface.ts +119 -0
  265. package/src/social-providers/index.ts +132 -0
  266. package/src/social-providers/kakao.ts +179 -0
  267. package/src/social-providers/kick.ts +109 -0
  268. package/src/social-providers/line.ts +169 -0
  269. package/src/social-providers/linear.ts +121 -0
  270. package/src/social-providers/linkedin.ts +110 -0
  271. package/src/social-providers/microsoft-entra-id.ts +391 -0
  272. package/src/social-providers/naver.ts +113 -0
  273. package/src/social-providers/notion.ts +108 -0
  274. package/src/social-providers/paybin.ts +118 -0
  275. package/src/social-providers/paypal.ts +371 -0
  276. package/src/social-providers/polar.ts +111 -0
  277. package/src/social-providers/railway.ts +100 -0
  278. package/src/social-providers/reddit.ts +126 -0
  279. package/src/social-providers/roblox.ts +112 -0
  280. package/src/social-providers/salesforce.ts +159 -0
  281. package/src/social-providers/slack.ts +112 -0
  282. package/src/social-providers/spotify.ts +94 -0
  283. package/src/social-providers/tiktok.ts +211 -0
  284. package/src/social-providers/twitch.ts +112 -0
  285. package/src/social-providers/twitter.ts +199 -0
  286. package/src/social-providers/vercel.ts +87 -0
  287. package/src/social-providers/vk.ts +125 -0
  288. package/src/social-providers/wechat.ts +220 -0
  289. package/src/social-providers/zoom.ts +230 -0
  290. package/src/types/context.ts +460 -0
  291. package/src/types/cookie.ts +10 -0
  292. package/src/types/helper.ts +27 -0
  293. package/src/types/index.ts +40 -0
  294. package/src/types/init-options.ts +1679 -0
  295. package/src/types/plugin-client.ts +143 -0
  296. package/src/types/plugin.ts +163 -0
  297. package/src/types/secret.ts +8 -0
  298. package/src/utils/async.ts +53 -0
  299. package/src/utils/db.ts +20 -0
  300. package/src/utils/deprecate.ts +21 -0
  301. package/src/utils/error-codes.ts +68 -0
  302. package/src/utils/fetch-metadata.ts +3 -0
  303. package/src/utils/host.ts +416 -0
  304. package/src/utils/id.ts +5 -0
  305. package/src/utils/ip.ts +395 -0
  306. package/src/utils/is-api-error.ts +10 -0
  307. package/src/utils/json.ts +56 -0
  308. package/src/utils/redirect-uri.ts +54 -0
  309. package/src/utils/string.ts +40 -0
  310. package/src/utils/url.ts +77 -0
@@ -0,0 +1,134 @@
1
+ import type { BetterAuthOptions } from "../../types";
2
+ import type { BetterAuthDBSchema, DBFieldAttribute } from "../type";
3
+ import type {
4
+ CleanedWhere,
5
+ CustomAdapter,
6
+ DBAdapterFactoryConfig,
7
+ JoinConfig,
8
+ DBTransactionAdapter as TransactionAdapter,
9
+ Where,
10
+ } from "./index";
11
+
12
+ export type AdapterFactoryOptions = {
13
+ config: AdapterFactoryConfig;
14
+ adapter: AdapterFactoryCustomizeAdapterCreator;
15
+ };
16
+
17
+ export interface AdapterFactoryConfig
18
+ extends Omit<DBAdapterFactoryConfig<BetterAuthOptions>, "transaction"> {
19
+ /**
20
+ * Execute multiple operations in a transaction.
21
+ *
22
+ * If the database doesn't support transactions, set this to `false` and operations will be executed sequentially.
23
+ *
24
+ * @default false
25
+ */
26
+ transaction?:
27
+ | (
28
+ | false
29
+ | (<R>(callback: (trx: TransactionAdapter) => Promise<R>) => Promise<R>)
30
+ )
31
+ | undefined;
32
+ }
33
+
34
+ export type AdapterFactoryCustomizeAdapterCreator = (config: {
35
+ options: BetterAuthOptions;
36
+ /**
37
+ * The schema of the user's Better-Auth instance.
38
+ */
39
+ schema: BetterAuthDBSchema;
40
+ /**
41
+ * The debug log function.
42
+ *
43
+ * If the config has defined `debugLogs` as `false`, no logs will be shown.
44
+ */
45
+ debugLog: (...args: unknown[]) => void;
46
+ /**
47
+ * Get the model name which is expected to be saved in the database based on the user's schema.
48
+ */
49
+ getModelName: (model: string) => string;
50
+ /**
51
+ * Get the field name which is expected to be saved in the database based on the user's schema.
52
+ */
53
+ getFieldName: ({ model, field }: { model: string; field: string }) => string;
54
+ /**
55
+ * This function helps us get the default model name from the schema defined by devs.
56
+ * Often times, the user will be using the `modelName` which could had been customized by the users.
57
+ * This function helps us get the actual model name useful to match against the schema. (eg: schema[model])
58
+ *
59
+ * If it's still unclear what this does:
60
+ *
61
+ * 1. User can define a custom modelName.
62
+ * 2. When using a custom modelName, doing something like `schema[model]` will not work.
63
+ * 3. Using this function helps us get the actual model name based on the user's defined custom modelName.
64
+ * 4. Thus allowing us to use `schema[model]`.
65
+ */
66
+ getDefaultModelName: (model: string) => string;
67
+ /**
68
+ * This function helps us get the default field name from the schema defined by devs.
69
+ * Often times, the user will be using the `fieldName` which could had been customized by the users.
70
+ * This function helps us get the actual field name useful to match against the schema. (eg: schema[model].fields[field])
71
+ *
72
+ * If it's still unclear what this does:
73
+ *
74
+ * 1. User can define a custom fieldName.
75
+ * 2. When using a custom fieldName, doing something like `schema[model].fields[field]` will not work.
76
+ *
77
+ */
78
+ getDefaultFieldName: ({
79
+ model,
80
+ field,
81
+ }: {
82
+ model: string;
83
+ field: string;
84
+ }) => string;
85
+ /**
86
+ * Get the field attributes for a given model and field.
87
+ *
88
+ * Note: any model name or field name is allowed, whether default to schema or not.
89
+ */
90
+ getFieldAttributes: ({
91
+ model,
92
+ field,
93
+ }: {
94
+ model: string;
95
+ field: string;
96
+ }) => DBFieldAttribute;
97
+ // The following functions are exposed primarily for the purpose of having wrapper adapters.
98
+ transformInput: (
99
+ data: Record<string, unknown>,
100
+ defaultModelName: string,
101
+ action: "create" | "update",
102
+ forceAllowId?: boolean | undefined,
103
+ ) => Promise<Record<string, unknown>>;
104
+ transformOutput: (
105
+ data: Record<string, unknown>,
106
+ defaultModelName: string,
107
+ select?: string[] | undefined,
108
+ joinConfig?: JoinConfig | undefined,
109
+ ) => Promise<Record<string, unknown>>;
110
+ transformWhereClause: <W extends Where[] | undefined>({
111
+ model,
112
+ where,
113
+ action,
114
+ }: {
115
+ where: W;
116
+ model: string;
117
+ action:
118
+ | "create"
119
+ | "update"
120
+ | "findOne"
121
+ | "findMany"
122
+ | "updateMany"
123
+ | "delete"
124
+ | "deleteMany"
125
+ | "consumeOne"
126
+ | "incrementOne"
127
+ | "count";
128
+ }) => W extends undefined ? undefined : CleanedWhere[];
129
+ }) => CustomAdapter;
130
+
131
+ export type AdapterTestDebugLogs = {
132
+ resetDebugLogs: () => void;
133
+ printDebugLogs: () => void;
134
+ };
@@ -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,304 @@
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
+ disableMigrations:
19
+ value.disableMigration ?? acc[key]?.disableMigrations,
20
+ };
21
+ }
22
+ return acc;
23
+ },
24
+ {} as Record<
25
+ string,
26
+ {
27
+ fields: Record<string, DBFieldAttribute>;
28
+ modelName: string;
29
+ disableMigrations?: boolean | undefined;
30
+ }
31
+ >,
32
+ );
33
+
34
+ const shouldAddRateLimitTable = options.rateLimit?.storage === "database";
35
+ const rateLimitTable = {
36
+ rateLimit: {
37
+ modelName: options.rateLimit?.modelName || "rateLimit",
38
+ fields: {
39
+ key: {
40
+ type: "string",
41
+ unique: true,
42
+ required: true,
43
+ fieldName: options.rateLimit?.fields?.key || "key",
44
+ },
45
+ count: {
46
+ type: "number",
47
+ required: true,
48
+ fieldName: options.rateLimit?.fields?.count || "count",
49
+ },
50
+ lastRequest: {
51
+ type: "number",
52
+ bigint: true,
53
+ required: true,
54
+ fieldName: options.rateLimit?.fields?.lastRequest || "lastRequest",
55
+ defaultValue: () => Date.now(),
56
+ },
57
+ },
58
+ },
59
+ } satisfies BetterAuthDBSchema;
60
+
61
+ const { user, session, account, verification, ...pluginTables } =
62
+ pluginSchema;
63
+
64
+ const verificationTable = {
65
+ verification: {
66
+ modelName: options.verification?.modelName || "verification",
67
+ fields: {
68
+ identifier: {
69
+ type: "string",
70
+ required: true,
71
+ fieldName: options.verification?.fields?.identifier || "identifier",
72
+ index: true,
73
+ },
74
+ value: {
75
+ type: "string",
76
+ required: true,
77
+ fieldName: options.verification?.fields?.value || "value",
78
+ },
79
+ expiresAt: {
80
+ type: "date",
81
+ required: true,
82
+ fieldName: options.verification?.fields?.expiresAt || "expiresAt",
83
+ },
84
+ createdAt: {
85
+ type: "date",
86
+ required: true,
87
+ defaultValue: () => new Date(),
88
+ fieldName: options.verification?.fields?.createdAt || "createdAt",
89
+ },
90
+ updatedAt: {
91
+ type: "date",
92
+ required: true,
93
+ defaultValue: () => new Date(),
94
+ onUpdate: () => new Date(),
95
+ fieldName: options.verification?.fields?.updatedAt || "updatedAt",
96
+ },
97
+ ...verification?.fields,
98
+ ...options.verification?.additionalFields,
99
+ },
100
+ order: 4,
101
+ },
102
+ } satisfies BetterAuthDBSchema;
103
+
104
+ const sessionTable = {
105
+ session: {
106
+ modelName: options.session?.modelName || "session",
107
+ fields: {
108
+ expiresAt: {
109
+ type: "date",
110
+ required: true,
111
+ fieldName: options.session?.fields?.expiresAt || "expiresAt",
112
+ },
113
+ token: {
114
+ type: "string",
115
+ required: true,
116
+ fieldName: options.session?.fields?.token || "token",
117
+ unique: true,
118
+ },
119
+ createdAt: {
120
+ type: "date",
121
+ required: true,
122
+ fieldName: options.session?.fields?.createdAt || "createdAt",
123
+ defaultValue: () => new Date(),
124
+ },
125
+ updatedAt: {
126
+ type: "date",
127
+ required: true,
128
+ fieldName: options.session?.fields?.updatedAt || "updatedAt",
129
+ onUpdate: () => new Date(),
130
+ },
131
+ ipAddress: {
132
+ type: "string",
133
+ required: false,
134
+ fieldName: options.session?.fields?.ipAddress || "ipAddress",
135
+ },
136
+ userAgent: {
137
+ type: "string",
138
+ required: false,
139
+ fieldName: options.session?.fields?.userAgent || "userAgent",
140
+ },
141
+ userId: {
142
+ type: "string",
143
+ fieldName: options.session?.fields?.userId || "userId",
144
+ references: {
145
+ model: options.user?.modelName || "user",
146
+ field: "id",
147
+ onDelete: "cascade",
148
+ },
149
+ required: true,
150
+ index: true,
151
+ },
152
+ ...session?.fields,
153
+ ...options.session?.additionalFields,
154
+ },
155
+ order: 2,
156
+ },
157
+ } satisfies BetterAuthDBSchema;
158
+
159
+ return {
160
+ user: {
161
+ modelName: options.user?.modelName || "user",
162
+ fields: {
163
+ name: {
164
+ type: "string",
165
+ required: true,
166
+ fieldName: options.user?.fields?.name || "name",
167
+ sortable: true,
168
+ },
169
+ email: {
170
+ type: "string",
171
+ // TODO(#9124): drop required+unique in v2; use a partial unique
172
+ // index where email is not null (see schema/user.ts).
173
+ unique: true,
174
+ required: true,
175
+ fieldName: options.user?.fields?.email || "email",
176
+ sortable: true,
177
+ },
178
+ emailVerified: {
179
+ type: "boolean",
180
+ defaultValue: false,
181
+ required: true,
182
+ fieldName: options.user?.fields?.emailVerified || "emailVerified",
183
+ input: false,
184
+ },
185
+ image: {
186
+ type: "string",
187
+ required: false,
188
+ fieldName: options.user?.fields?.image || "image",
189
+ },
190
+ createdAt: {
191
+ type: "date",
192
+ defaultValue: () => new Date(),
193
+ required: true,
194
+ fieldName: options.user?.fields?.createdAt || "createdAt",
195
+ },
196
+ updatedAt: {
197
+ type: "date",
198
+ defaultValue: () => new Date(),
199
+ onUpdate: () => new Date(),
200
+ required: true,
201
+ fieldName: options.user?.fields?.updatedAt || "updatedAt",
202
+ },
203
+ ...user?.fields,
204
+ ...options.user?.additionalFields,
205
+ },
206
+ order: 1,
207
+ },
208
+ //only add session table if it's not stored in secondary storage
209
+ ...(!options.secondaryStorage || options.session?.storeSessionInDatabase
210
+ ? sessionTable
211
+ : {}),
212
+ account: {
213
+ modelName: options.account?.modelName || "account",
214
+ fields: {
215
+ accountId: {
216
+ type: "string",
217
+ required: true,
218
+ fieldName: options.account?.fields?.accountId || "accountId",
219
+ },
220
+ providerId: {
221
+ type: "string",
222
+ required: true,
223
+ fieldName: options.account?.fields?.providerId || "providerId",
224
+ },
225
+ userId: {
226
+ type: "string",
227
+ references: {
228
+ model: options.user?.modelName || "user",
229
+ field: "id",
230
+ onDelete: "cascade",
231
+ },
232
+ required: true,
233
+ fieldName: options.account?.fields?.userId || "userId",
234
+ index: true,
235
+ },
236
+ accessToken: {
237
+ type: "string",
238
+ required: false,
239
+ returned: false,
240
+ fieldName: options.account?.fields?.accessToken || "accessToken",
241
+ },
242
+ refreshToken: {
243
+ type: "string",
244
+ required: false,
245
+ returned: false,
246
+ fieldName: options.account?.fields?.refreshToken || "refreshToken",
247
+ },
248
+ idToken: {
249
+ type: "string",
250
+ required: false,
251
+ returned: false,
252
+ fieldName: options.account?.fields?.idToken || "idToken",
253
+ },
254
+ accessTokenExpiresAt: {
255
+ type: "date",
256
+ required: false,
257
+ returned: false,
258
+ fieldName:
259
+ options.account?.fields?.accessTokenExpiresAt ||
260
+ "accessTokenExpiresAt",
261
+ },
262
+ refreshTokenExpiresAt: {
263
+ type: "date",
264
+ required: false,
265
+ returned: false,
266
+ fieldName:
267
+ options.account?.fields?.refreshTokenExpiresAt ||
268
+ "refreshTokenExpiresAt",
269
+ },
270
+ scope: {
271
+ type: "string",
272
+ required: false,
273
+ fieldName: options.account?.fields?.scope || "scope",
274
+ },
275
+ password: {
276
+ type: "string",
277
+ required: false,
278
+ returned: false,
279
+ fieldName: options.account?.fields?.password || "password",
280
+ },
281
+ createdAt: {
282
+ type: "date",
283
+ required: true,
284
+ fieldName: options.account?.fields?.createdAt || "createdAt",
285
+ defaultValue: () => new Date(),
286
+ },
287
+ updatedAt: {
288
+ type: "date",
289
+ required: true,
290
+ fieldName: options.account?.fields?.updatedAt || "updatedAt",
291
+ onUpdate: () => new Date(),
292
+ },
293
+ ...account?.fields,
294
+ ...options.account?.additionalFields,
295
+ },
296
+ order: 3,
297
+ },
298
+ ...(!options.secondaryStorage || options.verification?.storeInDatabase
299
+ ? verificationTable
300
+ : {}),
301
+ ...pluginTables,
302
+ ...(shouldAddRateLimitTable ? rateLimitTable : {}),
303
+ } satisfies BetterAuthDBSchema;
304
+ };
@@ -0,0 +1,43 @@
1
+ export { getAuthTables } from "./get-tables";
2
+ export type { BetterAuthPluginDBSchema } from "./plugin";
3
+ export {
4
+ type Account,
5
+ accountSchema,
6
+ type BaseAccount,
7
+ } from "./schema/account";
8
+ export {
9
+ type BaseRateLimit,
10
+ type RateLimit,
11
+ rateLimitSchema,
12
+ } from "./schema/rate-limit";
13
+ export {
14
+ type BaseSession,
15
+ type Session,
16
+ sessionSchema,
17
+ } from "./schema/session";
18
+ export { coreSchema } from "./schema/shared";
19
+ export { type BaseUser, type User, userSchema } from "./schema/user";
20
+ export {
21
+ type BaseVerification,
22
+ type Verification,
23
+ verificationSchema,
24
+ } from "./schema/verification";
25
+ export type {
26
+ BaseModelNames,
27
+ BetterAuthDBSchema,
28
+ DBFieldAttribute,
29
+ DBFieldAttributeConfig,
30
+ DBFieldType,
31
+ DBPrimitive,
32
+ InferDBFieldInput,
33
+ InferDBFieldOutput,
34
+ InferDBFieldsFromOptions,
35
+ InferDBFieldsFromOptionsInput,
36
+ InferDBFieldsFromPlugins,
37
+ InferDBFieldsFromPluginsInput,
38
+ InferDBFieldsInput,
39
+ InferDBFieldsOutput,
40
+ InferDBValueType,
41
+ ModelNames,
42
+ SecondaryStorage,
43
+ } 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,47 @@
1
+ import * as z from "zod";
2
+ import type { Prettify } from "../../types";
3
+ import type { BetterAuthOptions } from "../../types/init-options";
4
+ import type {
5
+ InferDBFieldsFromOptions,
6
+ InferDBFieldsFromPlugins,
7
+ } from "../type";
8
+ import { coreSchema } from "./shared";
9
+
10
+ export const accountSchema = coreSchema.extend({
11
+ providerId: z.string(),
12
+ accountId: z.string(),
13
+ userId: z.coerce.string(),
14
+ accessToken: z.string().nullish(),
15
+ refreshToken: z.string().nullish(),
16
+ idToken: z.string().nullish(),
17
+ /**
18
+ * Access token expires at
19
+ */
20
+ accessTokenExpiresAt: z.date().nullish(),
21
+ /**
22
+ * Refresh token expires at
23
+ */
24
+ refreshTokenExpiresAt: z.date().nullish(),
25
+ /**
26
+ * The scopes that the user has authorized
27
+ */
28
+ scope: z.string().nullish(),
29
+ /**
30
+ * Password is only stored in the credential provider
31
+ */
32
+ password: z.string().nullish(),
33
+ });
34
+
35
+ export type BaseAccount = z.infer<typeof accountSchema>;
36
+
37
+ /**
38
+ * Account schema type used by better-auth, note that it's possible that account could have additional fields
39
+ */
40
+ export type Account<
41
+ DBOptions extends BetterAuthOptions["account"] = BetterAuthOptions["account"],
42
+ Plugins extends BetterAuthOptions["plugins"] = BetterAuthOptions["plugins"],
43
+ > = Prettify<
44
+ BaseAccount &
45
+ InferDBFieldsFromOptions<DBOptions> &
46
+ InferDBFieldsFromPlugins<"account", Plugins>
47
+ >;
@@ -0,0 +1,36 @@
1
+ import * as z from "zod";
2
+ import type { BetterAuthOptions, Prettify } from "../../types";
3
+ import type {
4
+ InferDBFieldsFromOptions,
5
+ InferDBFieldsFromPlugins,
6
+ } from "../type";
7
+
8
+ export const rateLimitSchema = z.object({
9
+ /**
10
+ * The key to use for rate limiting
11
+ */
12
+ key: z.string(),
13
+ /**
14
+ * The number of requests made
15
+ */
16
+ count: z.number(),
17
+ /**
18
+ * The last request time in milliseconds
19
+ */
20
+ lastRequest: z.number(),
21
+ });
22
+
23
+ export type BaseRateLimit = z.infer<typeof rateLimitSchema>;
24
+
25
+ /**
26
+ * Rate limit schema type used by better-auth for rate limiting
27
+ */
28
+ export type RateLimit<
29
+ DBOptions extends
30
+ BetterAuthOptions["rateLimit"] = BetterAuthOptions["rateLimit"],
31
+ Plugins extends BetterAuthOptions["plugins"] = BetterAuthOptions["plugins"],
32
+ > = Prettify<
33
+ BaseRateLimit &
34
+ InferDBFieldsFromOptions<DBOptions> &
35
+ InferDBFieldsFromPlugins<"rateLimit", Plugins>
36
+ >;
@@ -0,0 +1,29 @@
1
+ import * as z from "zod";
2
+ import type { BetterAuthOptions, Prettify } from "../../types";
3
+ import type {
4
+ InferDBFieldsFromOptions,
5
+ InferDBFieldsFromPlugins,
6
+ } from "../type";
7
+ import { coreSchema } from "./shared";
8
+
9
+ export const sessionSchema = coreSchema.extend({
10
+ userId: z.coerce.string(),
11
+ expiresAt: z.date(),
12
+ token: z.string(),
13
+ ipAddress: z.string().nullish(),
14
+ userAgent: z.string().nullish(),
15
+ });
16
+
17
+ export type BaseSession = z.infer<typeof sessionSchema>;
18
+
19
+ /**
20
+ * Session schema type used by better-auth, note that it's possible that session could have additional fields
21
+ */
22
+ export type Session<
23
+ DBOptions extends BetterAuthOptions["session"] = BetterAuthOptions["session"],
24
+ Plugins extends BetterAuthOptions["plugins"] = BetterAuthOptions["plugins"],
25
+ > = Prettify<
26
+ z.infer<typeof sessionSchema> &
27
+ InferDBFieldsFromOptions<DBOptions> &
28
+ InferDBFieldsFromPlugins<"session", Plugins>
29
+ >;
@@ -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
+ });