@better-auth/core 1.5.0-beta.9 → 1.5.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 (306) hide show
  1. package/README.md +17 -0
  2. package/dist/api/index.d.mts +144 -41
  3. package/dist/api/index.mjs +2 -1
  4. package/dist/api/index.mjs.map +1 -0
  5. package/dist/async_hooks/index.d.mts +2 -1
  6. package/dist/async_hooks/index.mjs +2 -1
  7. package/dist/async_hooks/index.mjs.map +1 -0
  8. package/dist/async_hooks/pure.index.d.mts +2 -1
  9. package/dist/async_hooks/pure.index.mjs +2 -1
  10. package/dist/async_hooks/pure.index.mjs.map +1 -0
  11. package/dist/context/endpoint-context.d.mts +2 -1
  12. package/dist/context/endpoint-context.mjs +4 -3
  13. package/dist/context/endpoint-context.mjs.map +1 -0
  14. package/dist/context/global.d.mts +2 -2
  15. package/dist/context/global.mjs +3 -2
  16. package/dist/context/global.mjs.map +1 -0
  17. package/dist/context/request-state.d.mts +2 -1
  18. package/dist/context/request-state.mjs +4 -3
  19. package/dist/context/request-state.mjs.map +1 -0
  20. package/dist/context/transaction.d.mts +2 -1
  21. package/dist/context/transaction.mjs +4 -3
  22. package/dist/context/transaction.mjs.map +1 -0
  23. package/dist/db/adapter/factory.d.mts +6 -13
  24. package/dist/db/adapter/factory.mjs +44 -57
  25. package/dist/db/adapter/factory.mjs.map +1 -0
  26. package/dist/db/adapter/get-default-field-name.d.mts +2 -1
  27. package/dist/db/adapter/get-default-field-name.mjs +3 -2
  28. package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
  29. package/dist/db/adapter/get-default-model-name.d.mts +2 -1
  30. package/dist/db/adapter/get-default-model-name.mjs +5 -4
  31. package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
  32. package/dist/db/adapter/get-field-attributes.d.mts +3 -2
  33. package/dist/db/adapter/get-field-attributes.mjs +2 -1
  34. package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
  35. package/dist/db/adapter/get-field-name.d.mts +2 -1
  36. package/dist/db/adapter/get-field-name.mjs +2 -1
  37. package/dist/db/adapter/get-field-name.mjs.map +1 -0
  38. package/dist/db/adapter/get-id-field.d.mts +3 -2
  39. package/dist/db/adapter/get-id-field.mjs +3 -2
  40. package/dist/db/adapter/get-id-field.mjs.map +1 -0
  41. package/dist/db/adapter/get-model-name.d.mts +2 -1
  42. package/dist/db/adapter/get-model-name.mjs +2 -1
  43. package/dist/db/adapter/get-model-name.mjs.map +1 -0
  44. package/dist/db/adapter/index.d.mts +10 -4
  45. package/dist/db/adapter/index.mjs +19 -2
  46. package/dist/db/adapter/index.mjs.map +1 -0
  47. package/dist/db/adapter/types.d.mts +3 -34
  48. package/dist/db/adapter/utils.d.mts +2 -1
  49. package/dist/db/adapter/utils.mjs +2 -1
  50. package/dist/db/adapter/utils.mjs.map +1 -0
  51. package/dist/db/get-tables.d.mts +2 -1
  52. package/dist/db/get-tables.mjs +46 -39
  53. package/dist/db/get-tables.mjs.map +1 -0
  54. package/dist/db/index.d.mts +7 -7
  55. package/dist/db/plugin.d.mts +2 -1
  56. package/dist/db/schema/account.d.mts +8 -4
  57. package/dist/db/schema/account.mjs +2 -1
  58. package/dist/db/schema/account.mjs.map +1 -0
  59. package/dist/db/schema/rate-limit.d.mts +8 -2
  60. package/dist/db/schema/rate-limit.mjs +2 -1
  61. package/dist/db/schema/rate-limit.mjs.map +1 -0
  62. package/dist/db/schema/session.d.mts +8 -4
  63. package/dist/db/schema/session.mjs +2 -1
  64. package/dist/db/schema/session.mjs.map +1 -0
  65. package/dist/db/schema/shared.d.mts +2 -1
  66. package/dist/db/schema/shared.mjs +2 -1
  67. package/dist/db/schema/shared.mjs.map +1 -0
  68. package/dist/db/schema/user.d.mts +8 -4
  69. package/dist/db/schema/user.mjs +2 -1
  70. package/dist/db/schema/user.mjs.map +1 -0
  71. package/dist/db/schema/verification.d.mts +8 -4
  72. package/dist/db/schema/verification.mjs +2 -1
  73. package/dist/db/schema/verification.mjs.map +1 -0
  74. package/dist/db/type.d.mts +28 -2
  75. package/dist/env/color-depth.d.mts +2 -1
  76. package/dist/env/color-depth.mjs +2 -1
  77. package/dist/env/color-depth.mjs.map +1 -0
  78. package/dist/env/env-impl.d.mts +3 -2
  79. package/dist/env/env-impl.mjs +9 -8
  80. package/dist/env/env-impl.mjs.map +1 -0
  81. package/dist/env/logger.d.mts +2 -1
  82. package/dist/env/logger.mjs +3 -2
  83. package/dist/env/logger.mjs.map +1 -0
  84. package/dist/error/codes.d.mts +64 -181
  85. package/dist/error/codes.mjs +6 -2
  86. package/dist/error/codes.mjs.map +1 -0
  87. package/dist/error/index.d.mts +2 -1
  88. package/dist/error/index.mjs +2 -1
  89. package/dist/error/index.mjs.map +1 -0
  90. package/dist/index.d.mts +5 -4
  91. package/dist/oauth2/client-credentials-token.d.mts +25 -3
  92. package/dist/oauth2/client-credentials-token.mjs +15 -2
  93. package/dist/oauth2/client-credentials-token.mjs.map +1 -0
  94. package/dist/oauth2/create-authorization-url.d.mts +5 -2
  95. package/dist/oauth2/create-authorization-url.mjs +3 -1
  96. package/dist/oauth2/create-authorization-url.mjs.map +1 -0
  97. package/dist/oauth2/index.d.mts +4 -4
  98. package/dist/oauth2/index.mjs +4 -4
  99. package/dist/oauth2/oauth-provider.d.mts +3 -2
  100. package/dist/oauth2/refresh-access-token.d.mts +24 -4
  101. package/dist/oauth2/refresh-access-token.mjs +20 -2
  102. package/dist/oauth2/refresh-access-token.mjs.map +1 -0
  103. package/dist/oauth2/utils.d.mts +2 -1
  104. package/dist/oauth2/utils.mjs +2 -1
  105. package/dist/oauth2/utils.mjs.map +1 -0
  106. package/dist/oauth2/validate-authorization-code.d.mts +37 -4
  107. package/dist/oauth2/validate-authorization-code.mjs +25 -13
  108. package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
  109. package/dist/oauth2/verify.d.mts +7 -13
  110. package/dist/oauth2/verify.mjs +2 -1
  111. package/dist/oauth2/verify.mjs.map +1 -0
  112. package/dist/social-providers/apple.d.mts +2 -1
  113. package/dist/social-providers/apple.mjs +22 -21
  114. package/dist/social-providers/apple.mjs.map +1 -0
  115. package/dist/social-providers/atlassian.d.mts +2 -1
  116. package/dist/social-providers/atlassian.mjs +2 -1
  117. package/dist/social-providers/atlassian.mjs.map +1 -0
  118. package/dist/social-providers/cognito.d.mts +2 -1
  119. package/dist/social-providers/cognito.mjs +4 -3
  120. package/dist/social-providers/cognito.mjs.map +1 -0
  121. package/dist/social-providers/discord.d.mts +2 -1
  122. package/dist/social-providers/discord.mjs +2 -1
  123. package/dist/social-providers/discord.mjs.map +1 -0
  124. package/dist/social-providers/dropbox.d.mts +2 -1
  125. package/dist/social-providers/dropbox.mjs +2 -1
  126. package/dist/social-providers/dropbox.mjs.map +1 -0
  127. package/dist/social-providers/facebook.d.mts +2 -1
  128. package/dist/social-providers/facebook.mjs +13 -12
  129. package/dist/social-providers/facebook.mjs.map +1 -0
  130. package/dist/social-providers/figma.d.mts +2 -1
  131. package/dist/social-providers/figma.mjs +2 -1
  132. package/dist/social-providers/figma.mjs.map +1 -0
  133. package/dist/social-providers/github.d.mts +3 -2
  134. package/dist/social-providers/github.mjs +23 -6
  135. package/dist/social-providers/github.mjs.map +1 -0
  136. package/dist/social-providers/gitlab.d.mts +2 -1
  137. package/dist/social-providers/gitlab.mjs +3 -2
  138. package/dist/social-providers/gitlab.mjs.map +1 -0
  139. package/dist/social-providers/google.d.mts +2 -1
  140. package/dist/social-providers/google.mjs +18 -13
  141. package/dist/social-providers/google.mjs.map +1 -0
  142. package/dist/social-providers/huggingface.d.mts +2 -1
  143. package/dist/social-providers/huggingface.mjs +3 -2
  144. package/dist/social-providers/huggingface.mjs.map +1 -0
  145. package/dist/social-providers/index.d.mts +61 -8
  146. package/dist/social-providers/index.mjs +5 -2
  147. package/dist/social-providers/index.mjs.map +1 -0
  148. package/dist/social-providers/kakao.d.mts +3 -2
  149. package/dist/social-providers/kakao.mjs +3 -2
  150. package/dist/social-providers/kakao.mjs.map +1 -0
  151. package/dist/social-providers/kick.d.mts +2 -1
  152. package/dist/social-providers/kick.mjs +2 -1
  153. package/dist/social-providers/kick.mjs.map +1 -0
  154. package/dist/social-providers/line.d.mts +2 -1
  155. package/dist/social-providers/line.mjs +3 -2
  156. package/dist/social-providers/line.mjs.map +1 -0
  157. package/dist/social-providers/linear.d.mts +2 -1
  158. package/dist/social-providers/linear.mjs +2 -1
  159. package/dist/social-providers/linear.mjs.map +1 -0
  160. package/dist/social-providers/linkedin.d.mts +2 -1
  161. package/dist/social-providers/linkedin.mjs +2 -1
  162. package/dist/social-providers/linkedin.mjs.map +1 -0
  163. package/dist/social-providers/microsoft-entra-id.d.mts +4 -1
  164. package/dist/social-providers/microsoft-entra-id.mjs +36 -2
  165. package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
  166. package/dist/social-providers/naver.d.mts +11 -20
  167. package/dist/social-providers/naver.mjs +3 -2
  168. package/dist/social-providers/naver.mjs.map +1 -0
  169. package/dist/social-providers/notion.d.mts +2 -1
  170. package/dist/social-providers/notion.mjs +3 -2
  171. package/dist/social-providers/notion.mjs.map +1 -0
  172. package/dist/social-providers/paybin.d.mts +2 -1
  173. package/dist/social-providers/paybin.mjs +3 -2
  174. package/dist/social-providers/paybin.mjs.map +1 -0
  175. package/dist/social-providers/paypal.d.mts +2 -1
  176. package/dist/social-providers/paypal.mjs +2 -1
  177. package/dist/social-providers/paypal.mjs.map +1 -0
  178. package/dist/social-providers/polar.d.mts +2 -1
  179. package/dist/social-providers/polar.mjs +3 -2
  180. package/dist/social-providers/polar.mjs.map +1 -0
  181. package/dist/social-providers/railway.d.mts +68 -0
  182. package/dist/social-providers/railway.mjs +78 -0
  183. package/dist/social-providers/railway.mjs.map +1 -0
  184. package/dist/social-providers/reddit.d.mts +2 -1
  185. package/dist/social-providers/reddit.mjs +2 -1
  186. package/dist/social-providers/reddit.mjs.map +1 -0
  187. package/dist/social-providers/roblox.d.mts +2 -1
  188. package/dist/social-providers/roblox.mjs +2 -1
  189. package/dist/social-providers/roblox.mjs.map +1 -0
  190. package/dist/social-providers/salesforce.d.mts +2 -1
  191. package/dist/social-providers/salesforce.mjs +2 -1
  192. package/dist/social-providers/salesforce.mjs.map +1 -0
  193. package/dist/social-providers/slack.d.mts +2 -1
  194. package/dist/social-providers/slack.mjs +2 -1
  195. package/dist/social-providers/slack.mjs.map +1 -0
  196. package/dist/social-providers/spotify.d.mts +2 -1
  197. package/dist/social-providers/spotify.mjs +2 -1
  198. package/dist/social-providers/spotify.mjs.map +1 -0
  199. package/dist/social-providers/tiktok.d.mts +3 -3
  200. package/dist/social-providers/tiktok.mjs +3 -2
  201. package/dist/social-providers/tiktok.mjs.map +1 -0
  202. package/dist/social-providers/twitch.d.mts +2 -1
  203. package/dist/social-providers/twitch.mjs +2 -1
  204. package/dist/social-providers/twitch.mjs.map +1 -0
  205. package/dist/social-providers/twitter.d.mts +14 -25
  206. package/dist/social-providers/twitter.mjs +2 -1
  207. package/dist/social-providers/twitter.mjs.map +1 -0
  208. package/dist/social-providers/vercel.d.mts +2 -1
  209. package/dist/social-providers/vercel.mjs +3 -2
  210. package/dist/social-providers/vercel.mjs.map +1 -0
  211. package/dist/social-providers/vk.d.mts +2 -1
  212. package/dist/social-providers/vk.mjs +2 -1
  213. package/dist/social-providers/vk.mjs.map +1 -0
  214. package/dist/social-providers/zoom.d.mts +3 -10
  215. package/dist/social-providers/zoom.mjs +2 -1
  216. package/dist/social-providers/zoom.mjs.map +1 -0
  217. package/dist/types/context.d.mts +53 -21
  218. package/dist/types/cookie.d.mts +2 -1
  219. package/dist/types/helper.d.mts +4 -1
  220. package/dist/types/index.d.mts +4 -3
  221. package/dist/types/init-options.d.mts +231 -159
  222. package/dist/types/plugin-client.d.mts +4 -1
  223. package/dist/types/plugin.d.mts +12 -11
  224. package/dist/types/secret.d.mts +12 -0
  225. package/dist/utils/db.d.mts +12 -0
  226. package/dist/utils/db.mjs +17 -0
  227. package/dist/utils/db.mjs.map +1 -0
  228. package/dist/utils/deprecate.d.mts +2 -2
  229. package/dist/utils/deprecate.mjs +2 -1
  230. package/dist/utils/deprecate.mjs.map +1 -0
  231. package/dist/utils/error-codes.d.mts +8 -6
  232. package/dist/utils/error-codes.mjs +3 -2
  233. package/dist/utils/error-codes.mjs.map +1 -0
  234. package/dist/utils/id.d.mts +2 -1
  235. package/dist/utils/id.mjs +2 -1
  236. package/dist/utils/id.mjs.map +1 -0
  237. package/dist/utils/ip.d.mts +2 -1
  238. package/dist/utils/ip.mjs +2 -1
  239. package/dist/utils/ip.mjs.map +1 -0
  240. package/dist/utils/json.d.mts +2 -1
  241. package/dist/utils/json.mjs +2 -1
  242. package/dist/utils/json.mjs.map +1 -0
  243. package/dist/utils/string.d.mts +2 -1
  244. package/dist/utils/string.mjs +2 -1
  245. package/dist/utils/string.mjs.map +1 -0
  246. package/dist/utils/url.d.mts +2 -1
  247. package/dist/utils/url.mjs +2 -1
  248. package/dist/utils/url.mjs.map +1 -0
  249. package/package.json +35 -13
  250. package/src/db/adapter/factory.ts +41 -73
  251. package/src/db/adapter/get-id-field.ts +1 -3
  252. package/src/db/adapter/index.ts +20 -15
  253. package/src/db/adapter/types.ts +2 -41
  254. package/src/db/get-tables.ts +48 -37
  255. package/src/db/index.ts +30 -5
  256. package/src/db/schema/account.ts +16 -3
  257. package/src/db/schema/rate-limit.ts +16 -1
  258. package/src/db/schema/session.ts +15 -3
  259. package/src/db/schema/user.ts +15 -3
  260. package/src/db/schema/verification.ts +16 -3
  261. package/src/db/test/get-tables.test.ts +33 -0
  262. package/src/db/type.ts +154 -1
  263. package/src/env/env-impl.ts +2 -2
  264. package/src/env/logger.ts +1 -1
  265. package/src/error/codes.ts +17 -0
  266. package/src/oauth2/client-credentials-token.ts +26 -2
  267. package/src/oauth2/create-authorization-url.ts +3 -1
  268. package/src/oauth2/index.ts +3 -0
  269. package/src/oauth2/oauth-provider.ts +1 -1
  270. package/src/oauth2/refresh-access-token.test.ts +90 -0
  271. package/src/oauth2/refresh-access-token.ts +37 -4
  272. package/src/oauth2/validate-authorization-code.ts +55 -24
  273. package/src/oauth2/validate-token.test.ts +107 -52
  274. package/src/social-providers/apple.ts +29 -29
  275. package/src/social-providers/cognito.ts +6 -5
  276. package/src/social-providers/facebook.ts +3 -3
  277. package/src/social-providers/github.ts +26 -4
  278. package/src/social-providers/gitlab.ts +1 -1
  279. package/src/social-providers/google.ts +18 -14
  280. package/src/social-providers/huggingface.ts +1 -1
  281. package/src/social-providers/index.ts +9 -5
  282. package/src/social-providers/kakao.ts +1 -1
  283. package/src/social-providers/line.ts +1 -1
  284. package/src/social-providers/microsoft-entra-id.ts +84 -1
  285. package/src/social-providers/naver.ts +1 -1
  286. package/src/social-providers/notion.ts +1 -1
  287. package/src/social-providers/paybin.ts +1 -5
  288. package/src/social-providers/polar.ts +1 -1
  289. package/src/social-providers/railway.ts +100 -0
  290. package/src/social-providers/tiktok.ts +2 -1
  291. package/src/social-providers/vercel.ts +1 -1
  292. package/src/social-providers/zoom.ts +0 -8
  293. package/src/types/context.ts +74 -14
  294. package/src/types/helper.ts +9 -0
  295. package/src/types/index.ts +14 -2
  296. package/src/types/init-options.ts +294 -186
  297. package/src/types/plugin-client.ts +1 -0
  298. package/src/types/plugin.ts +11 -6
  299. package/src/types/secret.ts +8 -0
  300. package/src/utils/db.ts +20 -0
  301. package/src/utils/deprecate.test.ts +0 -1
  302. package/src/utils/error-codes.ts +12 -9
  303. package/.turbo/turbo-build.log +0 -182
  304. package/tsconfig.json +0 -7
  305. package/tsdown.config.ts +0 -32
  306. package/vitest.config.ts +0 -3
@@ -14,4 +14,5 @@ function deprecate(fn, message, logger) {
14
14
  }
15
15
 
16
16
  //#endregion
17
- export { deprecate };
17
+ export { deprecate };
18
+ //# sourceMappingURL=deprecate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecate.mjs","names":[],"sources":["../../src/utils/deprecate.ts"],"sourcesContent":["import type { InternalLogger } from \"../env\";\n\n/**\n * Wraps a function to log a deprecation warning at once.\n */\nexport function deprecate<T extends (...args: any[]) => any>(\n\tfn: T,\n\tmessage: string,\n\tlogger?: InternalLogger,\n): T {\n\tlet warned = false;\n\n\treturn function (this: any, ...args: Parameters<T>): ReturnType<T> {\n\t\tif (!warned) {\n\t\t\tconst warn = logger?.warn ?? console.warn;\n\t\t\twarn(`[Deprecation] ${message}`);\n\t\t\twarned = true;\n\t\t}\n\t\treturn fn.apply(this, args);\n\t} as T;\n}\n"],"mappings":";;;;AAKA,SAAgB,UACf,IACA,SACA,QACI;CACJ,IAAI,SAAS;AAEb,QAAO,SAAqB,GAAG,MAAoC;AAClE,MAAI,CAAC,QAAQ;AAEZ,IADa,QAAQ,QAAQ,QAAQ,MAChC,iBAAiB,UAAU;AAChC,YAAS;;AAEV,SAAO,GAAG,MAAM,MAAM,KAAK"}
@@ -2,11 +2,13 @@
2
2
  type UpperLetter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z";
3
3
  type SpecialCharacter = "_";
4
4
  type IsValidUpperSnakeCase<S extends string> = S extends `${infer F}${infer R}` ? F extends UpperLetter | SpecialCharacter ? IsValidUpperSnakeCase<R> : false : true;
5
- type InvalidKeyError<K$1 extends string> = `Invalid error code key: "${K$1}" - must only contain uppercase letters (A-Z) and underscores (_)`;
5
+ type InvalidKeyError<K extends string> = `Invalid error code key: "${K}" - must only contain uppercase letters (A-Z) and underscores (_)`;
6
6
  type ValidateErrorCodes<T> = { [K in keyof T]: K extends string ? IsValidUpperSnakeCase<K> extends false ? InvalidKeyError<K> : T[K] : T[K] };
7
- declare function defineErrorCodes<const T extends Record<string, string>>(codes: ValidateErrorCodes<T>): { [K in keyof T]: {
8
- code: K;
9
- message: T[K];
10
- } };
7
+ type RawError<K extends string = string> = {
8
+ readonly code: K;
9
+ message: string;
10
+ };
11
+ declare function defineErrorCodes<const T extends Record<string, string>, R extends { [K in keyof T & string]: RawError<K> }>(codes: ValidateErrorCodes<T>): R;
11
12
  //#endregion
12
- export { defineErrorCodes };
13
+ export { RawError, defineErrorCodes };
14
+ //# sourceMappingURL=error-codes.d.mts.map
@@ -3,9 +3,10 @@ function defineErrorCodes(codes) {
3
3
  return Object.fromEntries(Object.entries(codes).map(([key, value]) => [key, {
4
4
  code: key,
5
5
  message: value,
6
- toString: () => value
6
+ toString: () => key
7
7
  }]));
8
8
  }
9
9
 
10
10
  //#endregion
11
- export { defineErrorCodes };
11
+ export { defineErrorCodes };
12
+ //# sourceMappingURL=error-codes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-codes.mjs","names":[],"sources":["../../src/utils/error-codes.ts"],"sourcesContent":["type UpperLetter =\n\t| \"A\"\n\t| \"B\"\n\t| \"C\"\n\t| \"D\"\n\t| \"E\"\n\t| \"F\"\n\t| \"G\"\n\t| \"H\"\n\t| \"I\"\n\t| \"J\"\n\t| \"K\"\n\t| \"L\"\n\t| \"M\"\n\t| \"N\"\n\t| \"O\"\n\t| \"P\"\n\t| \"Q\"\n\t| \"R\"\n\t| \"S\"\n\t| \"T\"\n\t| \"U\"\n\t| \"V\"\n\t| \"W\"\n\t| \"X\"\n\t| \"Y\"\n\t| \"Z\";\ntype SpecialCharacter = \"_\";\n\ntype IsValidUpperSnakeCase<S extends string> = S extends `${infer F}${infer R}`\n\t? F extends UpperLetter | SpecialCharacter\n\t\t? IsValidUpperSnakeCase<R>\n\t\t: false\n\t: true;\n\ntype InvalidKeyError<K extends string> =\n\t`Invalid error code key: \"${K}\" - must only contain uppercase letters (A-Z) and underscores (_)`;\n\ntype ValidateErrorCodes<T> = {\n\t[K in keyof T]: K extends string\n\t\t? IsValidUpperSnakeCase<K> extends false\n\t\t\t? InvalidKeyError<K>\n\t\t\t: T[K]\n\t\t: T[K];\n};\n\nexport type RawError<K extends string = string> = {\n\treadonly code: K;\n\tmessage: string;\n};\n\nexport function defineErrorCodes<\n\tconst T extends Record<string, string>,\n\tR extends {\n\t\t[K in keyof T & string]: RawError<K>;\n\t},\n>(codes: ValidateErrorCodes<T>): R {\n\treturn Object.fromEntries(\n\t\tObject.entries(codes).map(([key, value]) => [\n\t\t\tkey,\n\t\t\t{\n\t\t\t\tcode: key,\n\t\t\t\tmessage: value,\n\t\t\t\ttoString: () => key,\n\t\t\t},\n\t\t]),\n\t) as any;\n}\n"],"mappings":";AAmDA,SAAgB,iBAKd,OAAiC;AAClC,QAAO,OAAO,YACb,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,KAAK,WAAW,CAC3C,KACA;EACC,MAAM;EACN,SAAS;EACT,gBAAgB;EAChB,CACD,CAAC,CACF"}
@@ -1,4 +1,5 @@
1
1
  //#region src/utils/id.d.ts
2
2
  declare const generateId: (size?: number) => string;
3
3
  //#endregion
4
- export { generateId };
4
+ export { generateId };
5
+ //# sourceMappingURL=id.d.mts.map
package/dist/utils/id.mjs CHANGED
@@ -6,4 +6,5 @@ const generateId = (size) => {
6
6
  };
7
7
 
8
8
  //#endregion
9
- export { generateId };
9
+ export { generateId };
10
+ //# sourceMappingURL=id.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.mjs","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["import { createRandomStringGenerator } from \"@better-auth/utils/random\";\n\nexport const generateId = (size?: number) => {\n\treturn createRandomStringGenerator(\"a-z\", \"A-Z\", \"0-9\")(size || 32);\n};\n"],"mappings":";;;AAEA,MAAa,cAAc,SAAkB;AAC5C,QAAO,4BAA4B,OAAO,OAAO,MAAM,CAAC,QAAQ,GAAG"}
@@ -51,4 +51,5 @@ declare function normalizeIP(ip: string, options?: NormalizeIPOptions): string;
51
51
  */
52
52
  declare function createRateLimitKey(ip: string, path: string): string;
53
53
  //#endregion
54
- export { createRateLimitKey, isValidIP, normalizeIP };
54
+ export { createRateLimitKey, isValidIP, normalizeIP };
55
+ //# sourceMappingURL=ip.d.mts.map
package/dist/utils/ip.mjs CHANGED
@@ -115,4 +115,5 @@ function createRateLimitKey(ip, path) {
115
115
  }
116
116
 
117
117
  //#endregion
118
- export { createRateLimitKey, isValidIP, normalizeIP };
118
+ export { createRateLimitKey, isValidIP, normalizeIP };
119
+ //# sourceMappingURL=ip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip.mjs","names":[],"sources":["../../src/utils/ip.ts"],"sourcesContent":["import * as z from \"zod\";\n\n/**\n * Normalizes an IP address for consistent rate limiting.\n *\n * Features:\n * - Normalizes IPv6 to canonical lowercase form\n * - Converts IPv4-mapped IPv6 to IPv4\n * - Supports IPv6 subnet extraction\n * - Handles all edge cases (::1, ::, etc.)\n */\n\ninterface NormalizeIPOptions {\n\t/**\n\t * For IPv6 addresses, extract the subnet prefix instead of full address.\n\t * Common values: 32, 48, 64, 128 (default: 128 = full address)\n\t *\n\t * @default 128\n\t */\n\tipv6Subnet?: 128 | 64 | 48 | 32;\n}\n\n/**\n * Checks if an IP is valid IPv4 or IPv6\n */\nexport function isValidIP(ip: string): boolean {\n\treturn z.ipv4().safeParse(ip).success || z.ipv6().safeParse(ip).success;\n}\n\n/**\n * Checks if an IP is IPv6\n */\nfunction isIPv6(ip: string): boolean {\n\treturn z.ipv6().safeParse(ip).success;\n}\n\n/**\n * Converts IPv4-mapped IPv6 address to IPv4\n * e.g., \"::ffff:192.0.2.1\" -> \"192.0.2.1\"\n */\nfunction extractIPv4FromMapped(ipv6: string): string | null {\n\tconst lower = ipv6.toLowerCase();\n\n\t// Handle ::ffff:192.0.2.1 format\n\tif (lower.startsWith(\"::ffff:\")) {\n\t\tconst ipv4Part = lower.substring(7);\n\t\t// Check if it's a valid IPv4\n\t\tif (z.ipv4().safeParse(ipv4Part).success) {\n\t\t\treturn ipv4Part;\n\t\t}\n\t}\n\n\t// Handle full form: 0:0:0:0:0:ffff:192.0.2.1\n\tconst parts = ipv6.split(\":\");\n\tif (parts.length === 7 && parts[5]?.toLowerCase() === \"ffff\") {\n\t\tconst ipv4Part = parts[6];\n\t\tif (ipv4Part && z.ipv4().safeParse(ipv4Part).success) {\n\t\t\treturn ipv4Part;\n\t\t}\n\t}\n\n\t// Handle hex-encoded IPv4 in mapped address\n\t// e.g., ::ffff:c000:0201 -> 192.0.2.1\n\tif (lower.includes(\"::ffff:\") || lower.includes(\":ffff:\")) {\n\t\tconst groups = expandIPv6(ipv6);\n\t\tif (\n\t\t\tgroups.length === 8 &&\n\t\t\tgroups[0] === \"0000\" &&\n\t\t\tgroups[1] === \"0000\" &&\n\t\t\tgroups[2] === \"0000\" &&\n\t\t\tgroups[3] === \"0000\" &&\n\t\t\tgroups[4] === \"0000\" &&\n\t\t\tgroups[5] === \"ffff\" &&\n\t\t\tgroups[6] &&\n\t\t\tgroups[7]\n\t\t) {\n\t\t\t// Convert last two groups to IPv4\n\t\t\tconst byte1 = Number.parseInt(groups[6].substring(0, 2), 16);\n\t\t\tconst byte2 = Number.parseInt(groups[6].substring(2, 4), 16);\n\t\t\tconst byte3 = Number.parseInt(groups[7].substring(0, 2), 16);\n\t\t\tconst byte4 = Number.parseInt(groups[7].substring(2, 4), 16);\n\t\t\treturn `${byte1}.${byte2}.${byte3}.${byte4}`;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Expands a compressed IPv6 address to full form\n * e.g., \"2001:db8::1\" -> [\"2001\", \"0db8\", \"0000\", \"0000\", \"0000\", \"0000\", \"0000\", \"0001\"]\n */\nfunction expandIPv6(ipv6: string): string[] {\n\t// Handle :: notation (zero compression)\n\tif (ipv6.includes(\"::\")) {\n\t\tconst sides = ipv6.split(\"::\");\n\t\tconst left = sides[0] ? sides[0].split(\":\") : [];\n\t\tconst right = sides[1] ? sides[1].split(\":\") : [];\n\n\t\t// Calculate missing groups\n\t\tconst totalGroups = 8;\n\t\tconst missingGroups = totalGroups - left.length - right.length;\n\t\tconst zeros = Array(missingGroups).fill(\"0000\");\n\n\t\t// Pad existing groups to 4 digits\n\t\tconst paddedLeft = left.map((g) => g.padStart(4, \"0\"));\n\t\tconst paddedRight = right.map((g) => g.padStart(4, \"0\"));\n\n\t\treturn [...paddedLeft, ...zeros, ...paddedRight];\n\t}\n\n\t// No compression, just pad each group\n\treturn ipv6.split(\":\").map((g) => g.padStart(4, \"0\"));\n}\n\n/**\n * Normalizes an IPv6 address to canonical form\n * e.g., \"2001:DB8::1\" -> \"2001:0db8:0000:0000:0000:0000:0000:0001\"\n */\nfunction normalizeIPv6(\n\tipv6: string,\n\tsubnetPrefix?: 128 | 32 | 48 | 64,\n): string {\n\tconst groups = expandIPv6(ipv6);\n\n\tif (subnetPrefix && subnetPrefix < 128) {\n\t\t// Apply subnet mask\n\t\tconst prefix = subnetPrefix;\n\t\tlet bitsRemaining: number = prefix;\n\n\t\tconst maskedGroups = groups.map((group) => {\n\t\t\tif (bitsRemaining <= 0) {\n\t\t\t\treturn \"0000\";\n\t\t\t}\n\t\t\tif (bitsRemaining >= 16) {\n\t\t\t\tbitsRemaining -= 16;\n\t\t\t\treturn group;\n\t\t\t}\n\n\t\t\t// Partial mask for this group\n\t\t\tconst value = Number.parseInt(group, 16);\n\t\t\tconst mask = (0xffff << (16 - bitsRemaining)) & 0xffff;\n\t\t\tconst masked = value & mask;\n\t\t\tbitsRemaining = 0;\n\t\t\treturn masked.toString(16).padStart(4, \"0\");\n\t\t});\n\n\t\treturn maskedGroups.join(\":\").toLowerCase();\n\t}\n\n\treturn groups.join(\":\").toLowerCase();\n}\n\n/**\n * Normalizes an IP address (IPv4 or IPv6) for consistent rate limiting.\n *\n * @param ip - The IP address to normalize\n * @param options - Normalization options\n * @returns Normalized IP address\n *\n * @example\n * normalizeIP(\"2001:DB8::1\")\n * // -> \"2001:0db8:0000:0000:0000:0000:0000:0000\"\n *\n * @example\n * normalizeIP(\"::ffff:192.0.2.1\")\n * // -> \"192.0.2.1\" (converted to IPv4)\n *\n * @example\n * normalizeIP(\"2001:db8::1\", { ipv6Subnet: 64 })\n * // -> \"2001:0db8:0000:0000:0000:0000:0000:0000\" (subnet /64)\n */\nexport function normalizeIP(\n\tip: string,\n\toptions: NormalizeIPOptions = {},\n): string {\n\t// IPv4 addresses are already normalized\n\tif (z.ipv4().safeParse(ip).success) {\n\t\treturn ip.toLowerCase();\n\t}\n\n\t// Check if it's IPv6\n\tif (!isIPv6(ip)) {\n\t\t// Return as-is if not valid (shouldn't happen due to prior validation)\n\t\treturn ip.toLowerCase();\n\t}\n\n\t// Check for IPv4-mapped IPv6\n\tconst ipv4 = extractIPv4FromMapped(ip);\n\tif (ipv4) {\n\t\treturn ipv4.toLowerCase();\n\t}\n\n\t// Normalize IPv6\n\tconst subnetPrefix = options.ipv6Subnet || 64;\n\treturn normalizeIPv6(ip, subnetPrefix);\n}\n\n/**\n * Creates a rate limit key from IP and path\n * Uses a separator to prevent collision attacks\n *\n * @param ip - The IP address (should be normalized)\n * @param path - The request path\n * @returns Rate limit key\n */\nexport function createRateLimitKey(ip: string, path: string): string {\n\t// Use | as separator to prevent collision attacks\n\t// e.g., \"192.0.2.1\" + \"/sign-in\" vs \"192.0.2\" + \".1/sign-in\"\n\treturn `${ip}|${path}`;\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  //#region src/utils/json.d.ts
2
2
  declare function safeJSONParse<T>(data: unknown): T | null;
3
3
  //#endregion
4
- export { safeJSONParse };
4
+ export { safeJSONParse };
5
+ //# sourceMappingURL=json.d.mts.map
@@ -22,4 +22,5 @@ function safeJSONParse(data) {
22
22
  }
23
23
 
24
24
  //#endregion
25
- export { safeJSONParse };
25
+ export { safeJSONParse };
26
+ //# sourceMappingURL=json.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.mjs","names":[],"sources":["../../src/utils/json.ts"],"sourcesContent":["import { logger } from \"../env\";\n\nexport function safeJSONParse<T>(data: unknown): T | null {\n\tfunction reviver(_: string, value: any): any {\n\t\tif (typeof value === \"string\") {\n\t\t\tconst iso8601Regex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$/;\n\t\t\tif (iso8601Regex.test(value)) {\n\t\t\t\tconst date = new Date(value);\n\t\t\t\tif (!isNaN(date.getTime())) {\n\t\t\t\t\treturn date;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn value;\n\t}\n\ttry {\n\t\tif (typeof data !== \"string\") {\n\t\t\treturn data as T;\n\t\t}\n\t\treturn JSON.parse(data, reviver);\n\t} catch (e) {\n\t\tlogger.error(\"Error parsing JSON\", { error: e });\n\t\treturn null;\n\t}\n}\n"],"mappings":";;;;AAEA,SAAgB,cAAiB,MAAyB;CACzD,SAAS,QAAQ,GAAW,OAAiB;AAC5C,MAAI,OAAO,UAAU,UAEpB;OADqB,mDACJ,KAAK,MAAM,EAAE;IAC7B,MAAM,OAAO,IAAI,KAAK,MAAM;AAC5B,QAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CACzB,QAAO;;;AAIV,SAAO;;AAER,KAAI;AACH,MAAI,OAAO,SAAS,SACnB,QAAO;AAER,SAAO,KAAK,MAAM,MAAM,QAAQ;UACxB,GAAG;AACX,SAAO,MAAM,sBAAsB,EAAE,OAAO,GAAG,CAAC;AAChD,SAAO"}
@@ -1,4 +1,5 @@
1
1
  //#region src/utils/string.d.ts
2
2
  declare function capitalizeFirstLetter(str: string): string;
3
3
  //#endregion
4
- export { capitalizeFirstLetter };
4
+ export { capitalizeFirstLetter };
5
+ //# sourceMappingURL=string.d.mts.map
@@ -4,4 +4,5 @@ function capitalizeFirstLetter(str) {
4
4
  }
5
5
 
6
6
  //#endregion
7
- export { capitalizeFirstLetter };
7
+ export { capitalizeFirstLetter };
8
+ //# sourceMappingURL=string.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.mjs","names":[],"sources":["../../src/utils/string.ts"],"sourcesContent":["export function capitalizeFirstLetter(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n"],"mappings":";AAAA,SAAgB,sBAAsB,KAAa;AAClD,QAAO,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE"}
@@ -17,4 +17,5 @@
17
17
  */
18
18
  declare function normalizePathname(requestUrl: string, basePath: string): string;
19
19
  //#endregion
20
- export { normalizePathname };
20
+ export { normalizePathname };
21
+ //# sourceMappingURL=url.d.mts.map
@@ -29,4 +29,5 @@ function normalizePathname(requestUrl, basePath) {
29
29
  }
30
30
 
31
31
  //#endregion
32
- export { normalizePathname };
32
+ export { normalizePathname };
33
+ //# sourceMappingURL=url.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.mjs","names":[],"sources":["../../src/utils/url.ts"],"sourcesContent":["/**\n * Normalizes a request pathname by removing the basePath prefix and trailing slashes.\n * This is useful for matching paths against configured path lists.\n *\n * @param requestUrl - The full request URL\n * @param basePath - The base path of the auth API (e.g., \"/api/auth\")\n * @returns The normalized path without basePath prefix or trailing slashes,\n * or \"/\" if URL parsing fails\n *\n * @example\n * normalizePathname(\"http://localhost:3000/api/auth/sso/saml2/callback/provider1\", \"/api/auth\")\n * // Returns: \"/sso/saml2/callback/provider1\"\n *\n * normalizePathname(\"http://localhost:3000/sso/saml2/callback/provider1/\", \"/\")\n * // Returns: \"/sso/saml2/callback/provider1\"\n */\nexport function normalizePathname(\n\trequestUrl: string,\n\tbasePath: string,\n): string {\n\tlet pathname: string;\n\ttry {\n\t\tpathname = new URL(requestUrl).pathname.replace(/\\/+$/, \"\") || \"/\";\n\t} catch {\n\t\treturn \"/\";\n\t}\n\n\tif (basePath === \"/\" || basePath === \"\") {\n\t\treturn pathname;\n\t}\n\n\t// Check for exact match or proper path boundary (basePath followed by \"/\" or end)\n\t// This prevents \"/api/auth\" from matching \"/api/authevil/...\"\n\tif (pathname === basePath) {\n\t\treturn \"/\";\n\t}\n\n\tif (pathname.startsWith(basePath + \"/\")) {\n\t\treturn pathname.slice(basePath.length).replace(/\\/+$/, \"\") || \"/\";\n\t}\n\n\treturn pathname;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,SAAgB,kBACf,YACA,UACS;CACT,IAAI;AACJ,KAAI;AACH,aAAW,IAAI,IAAI,WAAW,CAAC,SAAS,QAAQ,QAAQ,GAAG,IAAI;SACxD;AACP,SAAO;;AAGR,KAAI,aAAa,OAAO,aAAa,GACpC,QAAO;AAKR,KAAI,aAAa,SAChB,QAAO;AAGR,KAAI,SAAS,WAAW,WAAW,IAAI,CACtC,QAAO,SAAS,MAAM,SAAS,OAAO,CAAC,QAAQ,QAAQ,GAAG,IAAI;AAG/D,QAAO"}
package/package.json CHANGED
@@ -1,13 +1,28 @@
1
1
  {
2
2
  "name": "@better-auth/core",
3
- "version": "1.5.0-beta.9",
3
+ "version": "1.5.0",
4
4
  "description": "The most comprehensive authentication framework for TypeScript.",
5
5
  "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://www.better-auth.com",
6
8
  "repository": {
7
9
  "type": "git",
8
10
  "url": "git+https://github.com/better-auth/better-auth.git",
9
11
  "directory": "packages/core"
10
12
  },
13
+ "keywords": [
14
+ "auth",
15
+ "core",
16
+ "typescript",
17
+ "better-auth"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "src"
25
+ ],
11
26
  "main": "./dist/index.mjs",
12
27
  "module": "./dist/index.mjs",
13
28
  "types": "./dist/index.d.mts",
@@ -114,27 +129,34 @@
114
129
  ]
115
130
  }
116
131
  },
132
+ "dependencies": {
133
+ "@standard-schema/spec": "^1.1.0",
134
+ "zod": "^4.3.6"
135
+ },
117
136
  "devDependencies": {
118
- "@better-auth/utils": "0.3.0",
137
+ "@better-auth/utils": "0.3.1",
119
138
  "@better-fetch/fetch": "1.1.21",
120
- "better-call": "1.2.0",
121
- "jose": "^6.1.0",
122
- "kysely": "^0.28.10",
123
- "nanostores": "^1.1.0",
124
- "tsdown": "^0.19.0"
125
- },
126
- "dependencies": {
127
- "@standard-schema/spec": "^1.0.0",
128
- "zod": "^4.3.5"
139
+ "better-call": "1.3.2",
140
+ "@cloudflare/workers-types": "^4.20250121.0",
141
+ "jose": "^6.1.3",
142
+ "kysely": "^0.28.11",
143
+ "nanostores": "^1.1.1",
144
+ "tsdown": "^0.20.3"
129
145
  },
130
146
  "peerDependencies": {
131
- "@better-auth/utils": "0.3.0",
147
+ "@better-auth/utils": "0.3.1",
132
148
  "@better-fetch/fetch": "1.1.21",
133
- "better-call": "1.2.0",
149
+ "better-call": "1.3.2",
150
+ "@cloudflare/workers-types": ">=4",
134
151
  "jose": "^6.1.0",
135
152
  "kysely": "^0.28.5",
136
153
  "nanostores": "^1.0.1"
137
154
  },
155
+ "peerDependenciesMeta": {
156
+ "@cloudflare/workers-types": {
157
+ "optional": true
158
+ }
159
+ },
138
160
  "scripts": {
139
161
  "build": "tsdown",
140
162
  "dev": "tsdown --watch",
@@ -38,20 +38,20 @@ let debugLogs: { instance: string; args: any[] }[] = [];
38
38
  let transactionId = -1;
39
39
 
40
40
  const createAsIsTransaction =
41
- (adapter: DBAdapter<BetterAuthOptions>) =>
42
- <R>(fn: (trx: DBTransactionAdapter<BetterAuthOptions>) => Promise<R>) =>
41
+ <Options extends BetterAuthOptions>(adapter: DBAdapter<Options>) =>
42
+ <R>(fn: (trx: DBTransactionAdapter<Options>) => Promise<R>) =>
43
43
  fn(adapter);
44
44
 
45
- export type AdapterFactory = (
46
- options: BetterAuthOptions,
47
- ) => DBAdapter<BetterAuthOptions>;
45
+ export type AdapterFactory<Options extends BetterAuthOptions> = (
46
+ options: Options,
47
+ ) => DBAdapter<Options>;
48
48
 
49
49
  export const createAdapterFactory =
50
- ({
50
+ <Options extends BetterAuthOptions>({
51
51
  adapter: customAdapter,
52
52
  config: cfg,
53
- }: AdapterFactoryOptions): AdapterFactory =>
54
- (options: BetterAuthOptions): DBAdapter<BetterAuthOptions> => {
53
+ }: AdapterFactoryOptions): AdapterFactory<Options> =>
54
+ (options: Options): DBAdapter<Options> => {
55
55
  const uniqueAdapterFactoryInstanceId = Math.random()
56
56
  .toString(36)
57
57
  .substring(2, 15);
@@ -71,9 +71,7 @@ export const createAdapterFactory =
71
71
  disableTransformJoin: cfg.disableTransformJoin ?? false,
72
72
  } satisfies AdapterFactoryConfig;
73
73
 
74
- const useNumberId =
75
- options.advanced?.database?.useNumberId === true ||
76
- options.advanced?.database?.generateId === "serial";
74
+ const useNumberId = options.advanced?.database?.generateId === "serial";
77
75
  if (useNumberId && config.supportsNumericIds === false) {
78
76
  throw new BetterAuthError(
79
77
  `[${config.adapterName}] Your database or database adapter does not support numeric ids. Please disable "useNumberId" in your config.`,
@@ -189,9 +187,7 @@ export const createAdapterFactory =
189
187
  const fields = schema[defaultModelName]!.fields;
190
188
 
191
189
  const newMappedKeys = config.mapKeysTransformInput ?? {};
192
- const useNumberId =
193
- options.advanced?.database?.useNumberId ||
194
- options.advanced?.database?.generateId === "serial";
190
+ const useNumberId = options.advanced?.database?.generateId === "serial";
195
191
  fields.id = idField({
196
192
  customModelName: defaultModelName,
197
193
  forceAllowId: forceAllowId && "id" in data,
@@ -309,9 +305,7 @@ export const createAdapterFactory =
309
305
  const idKey = Object.entries(newMappedKeys).find(
310
306
  ([_, v]) => v === "id",
311
307
  )?.[0];
312
- const useNumberId =
313
- options.advanced?.database?.useNumberId ||
314
- options.advanced?.database?.generateId === "serial";
308
+ const useNumberId = options.advanced?.database?.generateId === "serial";
315
309
  tableSchema[idKey ?? "id"] = {
316
310
  type: useNumberId ? "number" : "string",
317
311
  };
@@ -523,9 +517,7 @@ export const createAdapterFactory =
523
517
  model: defaultModelName,
524
518
  });
525
519
 
526
- const useNumberId =
527
- options.advanced?.database?.useNumberId ||
528
- options.advanced?.database?.generateId === "serial";
520
+ const useNumberId = options.advanced?.database?.generateId === "serial";
529
521
 
530
522
  if (
531
523
  defaultFieldName === "id" ||
@@ -548,12 +540,32 @@ export const createAdapterFactory =
548
540
  newValue = value.toISOString();
549
541
  }
550
542
 
543
+ if (fieldAttr.type === "boolean" && typeof newValue === "string") {
544
+ newValue = newValue === "true";
545
+ }
546
+
547
+ if (fieldAttr.type === "number") {
548
+ if (typeof newValue === "string" && newValue.trim() !== "") {
549
+ const parsed = Number(newValue);
550
+ if (!Number.isNaN(parsed)) {
551
+ newValue = parsed;
552
+ }
553
+ } else if (Array.isArray(newValue)) {
554
+ const parsed = newValue.map((v) =>
555
+ typeof v === "string" && v.trim() !== "" ? Number(v) : NaN,
556
+ );
557
+ if (parsed.every((n) => !Number.isNaN(n))) {
558
+ newValue = parsed;
559
+ }
560
+ }
561
+ }
562
+
551
563
  if (
552
564
  fieldAttr.type === "boolean" &&
553
- typeof value === "boolean" &&
565
+ typeof newValue === "boolean" &&
554
566
  !config.supportsBooleans
555
567
  ) {
556
- newValue = value ? 1 : 0;
568
+ newValue = newValue ? 1 : 0;
557
569
  }
558
570
 
559
571
  if (
@@ -793,10 +805,8 @@ export const createAdapterFactory =
793
805
  transformWhereClause,
794
806
  });
795
807
 
796
- let lazyLoadTransaction:
797
- | DBAdapter<BetterAuthOptions>["transaction"]
798
- | null = null;
799
- const adapter: DBAdapter<BetterAuthOptions> = {
808
+ let lazyLoadTransaction: DBAdapter<Options>["transaction"] | null = null;
809
+ const adapter: DBAdapter<Options> = {
800
810
  transaction: async (cb) => {
801
811
  if (!lazyLoadTransaction) {
802
812
  if (!config.transaction) {
@@ -1083,6 +1093,7 @@ export const createAdapterFactory =
1083
1093
  model: unsafeModel,
1084
1094
  where: unsafeWhere,
1085
1095
  limit: unsafeLimit,
1096
+ select,
1086
1097
  sortBy,
1087
1098
  offset,
1088
1099
  join: unsafeJoin,
@@ -1090,6 +1101,7 @@ export const createAdapterFactory =
1090
1101
  model: string;
1091
1102
  where?: Where[];
1092
1103
  limit?: number;
1104
+ select?: string[] | undefined;
1093
1105
  sortBy?: { field: string; direction: "asc" | "desc" };
1094
1106
  offset?: number;
1095
1107
  join?: JoinOption;
@@ -1110,13 +1122,10 @@ export const createAdapterFactory =
1110
1122
  let join: JoinConfig | undefined;
1111
1123
  let passJoinToAdapter = true;
1112
1124
  if (!config.disableTransformJoin) {
1113
- const result = transformJoinClause(
1114
- unsafeModel,
1115
- unsafeJoin,
1116
- undefined,
1117
- );
1125
+ const result = transformJoinClause(unsafeModel, unsafeJoin, select);
1118
1126
  if (result) {
1119
1127
  join = result.join;
1128
+ select = result.select;
1120
1129
  }
1121
1130
  // If adapter doesn't support joins and we have joins, don't pass them to the adapter
1122
1131
  const experimentalJoins = options.experimental?.joins;
@@ -1137,6 +1146,7 @@ export const createAdapterFactory =
1137
1146
  model,
1138
1147
  where,
1139
1148
  limit: limit,
1149
+ select,
1140
1150
  sortBy,
1141
1151
  offset,
1142
1152
  join: passJoinToAdapter ? join : undefined,
@@ -1284,42 +1294,6 @@ export const createAdapterFactory =
1284
1294
  delete tables.session;
1285
1295
  }
1286
1296
 
1287
- if (
1288
- options.rateLimit &&
1289
- options.rateLimit.storage === "database" &&
1290
- // rate-limit will default to enabled in production,
1291
- // and given storage is database, it will try to use the rate-limit table,
1292
- // so we should make sure to generate rate-limit table schema
1293
- (typeof options.rateLimit.enabled === "undefined" ||
1294
- // and of course if they forcefully set to true, then they want rate-limit,
1295
- // thus we should also generate rate-limit table schema
1296
- options.rateLimit.enabled === true)
1297
- ) {
1298
- tables.ratelimit = {
1299
- modelName: options.rateLimit.modelName ?? "ratelimit",
1300
- fields: {
1301
- key: {
1302
- type: "string",
1303
- unique: true,
1304
- required: true,
1305
- fieldName: options.rateLimit.fields?.key ?? "key",
1306
- },
1307
- count: {
1308
- type: "number",
1309
- required: true,
1310
- fieldName: options.rateLimit.fields?.count ?? "count",
1311
- },
1312
- lastRequest: {
1313
- type: "number",
1314
- required: true,
1315
- bigint: true,
1316
- defaultValue: () => Date.now(),
1317
- fieldName:
1318
- options.rateLimit.fields?.lastRequest ?? "lastRequest",
1319
- },
1320
- },
1321
- };
1322
- }
1323
1297
  return adapterInstance.createSchema!({ file, tables });
1324
1298
  }
1325
1299
  : undefined,
@@ -1390,9 +1364,3 @@ function formatMethod(method: string) {
1390
1364
  function formatAction(action: string) {
1391
1365
  return `${TTY_COLORS.dim}(${action})${TTY_COLORS.reset}`;
1392
1366
  }
1393
-
1394
- /**
1395
- * @deprecated Use `createAdapterFactory` instead. This export will be removed in a future version.
1396
- * @alias
1397
- */
1398
- export const createAdapter = createAdapterFactory;
@@ -31,9 +31,7 @@ export const initGetIdField = ({
31
31
  customModelName?: string;
32
32
  forceAllowId?: boolean;
33
33
  }) => {
34
- const useNumberId =
35
- options.advanced?.database?.useNumberId ||
36
- options.advanced?.database?.generateId === "serial";
34
+ const useNumberId = options.advanced?.database?.generateId === "serial";
37
35
  const useUUIDs = options.advanced?.database?.generateId === "uuid";
38
36
 
39
37
  const shouldGenerateId: boolean = (() => {
@@ -301,25 +301,27 @@ export interface DBAdapterFactoryConfig<
301
301
  disableTransformJoin?: boolean | undefined;
302
302
  }
303
303
 
304
+ export const whereOperators = [
305
+ "eq",
306
+ "ne",
307
+ "lt",
308
+ "lte",
309
+ "gt",
310
+ "gte",
311
+ "in",
312
+ "not_in",
313
+ "contains",
314
+ "starts_with",
315
+ "ends_with",
316
+ ] as const;
317
+
318
+ export type WhereOperator = (typeof whereOperators)[number];
319
+
304
320
  export type Where = {
305
321
  /**
306
322
  * @default eq
307
323
  */
308
- operator?:
309
- | (
310
- | "eq"
311
- | "ne"
312
- | "lt"
313
- | "lte"
314
- | "gt"
315
- | "gte"
316
- | "in"
317
- | "not_in"
318
- | "contains"
319
- | "starts_with"
320
- | "ends_with"
321
- )
322
- | undefined;
324
+ operator?: WhereOperator | undefined;
323
325
  value: string | number | boolean | string[] | number[] | Date | null;
324
326
  field: string;
325
327
  /**
@@ -405,6 +407,7 @@ export type DBAdapter<Options extends BetterAuthOptions = BetterAuthOptions> = {
405
407
  model: string;
406
408
  where?: Where[] | undefined;
407
409
  limit?: number | undefined;
410
+ select?: string[] | undefined;
408
411
  sortBy?:
409
412
  | {
410
413
  field: string;
@@ -493,6 +496,7 @@ export interface CustomAdapter {
493
496
  model,
494
497
  where,
495
498
  limit,
499
+ select,
496
500
  sortBy,
497
501
  offset,
498
502
  join,
@@ -500,6 +504,7 @@ export interface CustomAdapter {
500
504
  model: string;
501
505
  where?: CleanedWhere[] | undefined;
502
506
  limit: number;
507
+ select?: string[] | undefined;
503
508
  sortBy?: { field: string; direction: "asc" | "desc" } | undefined;
504
509
  offset?: number | undefined;
505
510
  join?: JoinConfig | undefined;
@@ -1,9 +1,8 @@
1
1
  import type { BetterAuthOptions } from "../../types";
2
- import type { Prettify } from "../../types/helper";
3
2
  import type { BetterAuthDBSchema, DBFieldAttribute } from "../type";
4
3
  import type {
5
- DBAdapterSchemaCreation as AdapterSchemaCreation,
6
- CustomAdapter as CoreCustomAdapter,
4
+ CleanedWhere,
5
+ CustomAdapter,
7
6
  DBAdapterFactoryConfig,
8
7
  JoinConfig,
9
8
  DBTransactionAdapter as TransactionAdapter,
@@ -127,45 +126,7 @@ export type AdapterFactoryCustomizeAdapterCreator = (config: {
127
126
  }) => W extends undefined ? undefined : CleanedWhere[];
128
127
  }) => CustomAdapter;
129
128
 
130
- /**
131
- * @deprecated Use `CustomAdapter` from `@better-auth/core/db/adapter` instead.
132
- */
133
- export interface CustomAdapter extends Omit<CoreCustomAdapter, "createSchema"> {
134
- createSchema?:
135
- | ((props: {
136
- /**
137
- * The file the user may have passed in to the `generate` command as the expected schema file output path.
138
- */
139
- file?: string;
140
- /**
141
- * The tables from the user's Better-Auth instance schema.
142
- */
143
- tables: BetterAuthDBSchema;
144
- }) => Promise<AdapterSchemaCreation>)
145
- | undefined;
146
- }
147
-
148
- /**
149
- * @deprecated Use `CleanedWhere` from `@better-auth/core/db/adapter` instead.
150
- */
151
- export type CleanedWhere = Prettify<Required<Where>>;
152
-
153
129
  export type AdapterTestDebugLogs = {
154
130
  resetDebugLogs: () => void;
155
131
  printDebugLogs: () => void;
156
132
  };
157
-
158
- /**
159
- * @deprecated Use `AdapterFactoryOptions` instead. This export will be removed in a future version.
160
- */
161
- export type CreateAdapterOptions = AdapterFactoryOptions;
162
-
163
- /**
164
- * @deprecated Use `AdapterFactoryConfig` instead. This export will be removed in a future version.
165
- */
166
- export type AdapterConfig = AdapterFactoryConfig;
167
-
168
- /**
169
- * @deprecated Use `AdapterFactoryCustomizeAdapterCreator` instead. This export will be removed in a future version.
170
- */
171
- export type CreateCustomAdapter = AdapterFactoryCustomizeAdapterCreator;