@better-auth/core 1.5.6 → 1.6.0-beta.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 (281) hide show
  1. package/dist/api/index.d.mts +42 -13
  2. package/dist/api/index.mjs +0 -4
  3. package/dist/async_hooks/index.d.mts +1 -2
  4. package/dist/async_hooks/index.mjs +0 -2
  5. package/dist/async_hooks/pure.index.d.mts +1 -2
  6. package/dist/async_hooks/pure.index.mjs +0 -2
  7. package/dist/context/endpoint-context.d.mts +2 -3
  8. package/dist/context/endpoint-context.mjs +0 -3
  9. package/dist/context/global.d.mts +1 -2
  10. package/dist/context/global.mjs +1 -3
  11. package/dist/context/index.mjs +1 -2
  12. package/dist/context/request-state.d.mts +1 -2
  13. package/dist/context/request-state.mjs +0 -3
  14. package/dist/context/transaction.d.mts +1 -2
  15. package/dist/context/transaction.mjs +0 -3
  16. package/dist/db/adapter/factory.d.mts +1 -2
  17. package/dist/db/adapter/factory.mjs +3 -7
  18. package/dist/db/adapter/get-default-field-name.d.mts +1 -2
  19. package/dist/db/adapter/get-default-field-name.mjs +0 -3
  20. package/dist/db/adapter/get-default-model-name.d.mts +1 -2
  21. package/dist/db/adapter/get-default-model-name.mjs +0 -3
  22. package/dist/db/adapter/get-field-attributes.d.mts +1 -2
  23. package/dist/db/adapter/get-field-attributes.mjs +0 -3
  24. package/dist/db/adapter/get-field-name.d.mts +1 -2
  25. package/dist/db/adapter/get-field-name.mjs +0 -3
  26. package/dist/db/adapter/get-id-field.d.mts +1 -2
  27. package/dist/db/adapter/get-id-field.mjs +0 -4
  28. package/dist/db/adapter/get-model-name.d.mts +1 -2
  29. package/dist/db/adapter/get-model-name.mjs +0 -3
  30. package/dist/db/adapter/index.d.mts +9 -2
  31. package/dist/db/adapter/index.mjs +0 -3
  32. package/dist/db/adapter/types.d.mts +1 -2
  33. package/dist/db/adapter/utils.d.mts +1 -2
  34. package/dist/db/adapter/utils.mjs +0 -2
  35. package/dist/db/get-tables.d.mts +1 -2
  36. package/dist/db/get-tables.mjs +0 -2
  37. package/dist/db/index.mjs +1 -2
  38. package/dist/db/plugin.d.mts +1 -2
  39. package/dist/db/schema/account.d.mts +1 -2
  40. package/dist/db/schema/account.mjs +0 -3
  41. package/dist/db/schema/rate-limit.d.mts +1 -2
  42. package/dist/db/schema/rate-limit.mjs +0 -3
  43. package/dist/db/schema/session.d.mts +1 -2
  44. package/dist/db/schema/session.mjs +0 -3
  45. package/dist/db/schema/shared.d.mts +1 -2
  46. package/dist/db/schema/shared.mjs +0 -3
  47. package/dist/db/schema/user.d.mts +1 -2
  48. package/dist/db/schema/user.mjs +0 -3
  49. package/dist/db/schema/verification.d.mts +1 -2
  50. package/dist/db/schema/verification.mjs +0 -3
  51. package/dist/db/type.d.mts +1 -2
  52. package/dist/env/color-depth.d.mts +1 -2
  53. package/dist/env/color-depth.mjs +0 -3
  54. package/dist/env/env-impl.d.mts +1 -2
  55. package/dist/env/env-impl.mjs +0 -2
  56. package/dist/env/index.mjs +1 -2
  57. package/dist/env/logger.d.mts +1 -2
  58. package/dist/env/logger.mjs +0 -3
  59. package/dist/error/codes.d.mts +1 -2
  60. package/dist/error/codes.mjs +0 -3
  61. package/dist/error/index.d.mts +1 -2
  62. package/dist/error/index.mjs +0 -3
  63. package/dist/index.mjs +1 -1
  64. package/dist/instrumentation/attributes.d.mts +1 -2
  65. package/dist/instrumentation/attributes.mjs +0 -3
  66. package/dist/instrumentation/index.mjs +1 -2
  67. package/dist/instrumentation/tracer.d.mts +1 -2
  68. package/dist/instrumentation/tracer.mjs +29 -16
  69. package/dist/oauth2/client-credentials-token.d.mts +1 -2
  70. package/dist/oauth2/client-credentials-token.mjs +0 -3
  71. package/dist/oauth2/create-authorization-url.d.mts +1 -2
  72. package/dist/oauth2/create-authorization-url.mjs +0 -3
  73. package/dist/oauth2/index.mjs +1 -2
  74. package/dist/oauth2/oauth-provider.d.mts +1 -2
  75. package/dist/oauth2/refresh-access-token.d.mts +1 -2
  76. package/dist/oauth2/refresh-access-token.mjs +0 -3
  77. package/dist/oauth2/utils.d.mts +1 -2
  78. package/dist/oauth2/utils.mjs +0 -3
  79. package/dist/oauth2/validate-authorization-code.d.mts +1 -2
  80. package/dist/oauth2/validate-authorization-code.mjs +0 -4
  81. package/dist/oauth2/verify.d.mts +1 -2
  82. package/dist/oauth2/verify.mjs +0 -4
  83. package/dist/social-providers/apple.d.mts +1 -2
  84. package/dist/social-providers/apple.mjs +0 -4
  85. package/dist/social-providers/atlassian.d.mts +1 -2
  86. package/dist/social-providers/atlassian.mjs +0 -5
  87. package/dist/social-providers/cognito.d.mts +1 -2
  88. package/dist/social-providers/cognito.mjs +0 -5
  89. package/dist/social-providers/discord.d.mts +1 -2
  90. package/dist/social-providers/discord.mjs +0 -4
  91. package/dist/social-providers/dropbox.d.mts +1 -2
  92. package/dist/social-providers/dropbox.mjs +0 -4
  93. package/dist/social-providers/facebook.d.mts +1 -2
  94. package/dist/social-providers/facebook.mjs +0 -4
  95. package/dist/social-providers/figma.d.mts +1 -2
  96. package/dist/social-providers/figma.mjs +0 -5
  97. package/dist/social-providers/github.d.mts +1 -2
  98. package/dist/social-providers/github.mjs +0 -5
  99. package/dist/social-providers/gitlab.d.mts +1 -2
  100. package/dist/social-providers/gitlab.mjs +0 -4
  101. package/dist/social-providers/google.d.mts +1 -2
  102. package/dist/social-providers/google.mjs +0 -5
  103. package/dist/social-providers/huggingface.d.mts +1 -2
  104. package/dist/social-providers/huggingface.mjs +0 -4
  105. package/dist/social-providers/index.d.mts +1 -2
  106. package/dist/social-providers/index.mjs +0 -3
  107. package/dist/social-providers/kakao.d.mts +1 -2
  108. package/dist/social-providers/kakao.mjs +0 -4
  109. package/dist/social-providers/kick.d.mts +1 -2
  110. package/dist/social-providers/kick.mjs +0 -4
  111. package/dist/social-providers/line.d.mts +1 -2
  112. package/dist/social-providers/line.mjs +0 -4
  113. package/dist/social-providers/linear.d.mts +1 -2
  114. package/dist/social-providers/linear.mjs +0 -4
  115. package/dist/social-providers/linkedin.d.mts +1 -2
  116. package/dist/social-providers/linkedin.mjs +0 -4
  117. package/dist/social-providers/microsoft-entra-id.d.mts +1 -2
  118. package/dist/social-providers/microsoft-entra-id.mjs +0 -5
  119. package/dist/social-providers/naver.d.mts +1 -2
  120. package/dist/social-providers/naver.mjs +0 -4
  121. package/dist/social-providers/notion.d.mts +1 -2
  122. package/dist/social-providers/notion.mjs +0 -4
  123. package/dist/social-providers/paybin.d.mts +1 -2
  124. package/dist/social-providers/paybin.mjs +0 -5
  125. package/dist/social-providers/paypal.d.mts +1 -2
  126. package/dist/social-providers/paypal.mjs +0 -5
  127. package/dist/social-providers/polar.d.mts +1 -2
  128. package/dist/social-providers/polar.mjs +0 -4
  129. package/dist/social-providers/railway.d.mts +1 -2
  130. package/dist/social-providers/railway.mjs +0 -4
  131. package/dist/social-providers/reddit.d.mts +1 -2
  132. package/dist/social-providers/reddit.mjs +0 -4
  133. package/dist/social-providers/roblox.d.mts +1 -2
  134. package/dist/social-providers/roblox.mjs +0 -4
  135. package/dist/social-providers/salesforce.d.mts +1 -2
  136. package/dist/social-providers/salesforce.mjs +0 -5
  137. package/dist/social-providers/slack.d.mts +1 -2
  138. package/dist/social-providers/slack.mjs +0 -4
  139. package/dist/social-providers/spotify.d.mts +1 -2
  140. package/dist/social-providers/spotify.mjs +0 -4
  141. package/dist/social-providers/tiktok.d.mts +1 -2
  142. package/dist/social-providers/tiktok.mjs +0 -4
  143. package/dist/social-providers/twitch.d.mts +1 -2
  144. package/dist/social-providers/twitch.mjs +0 -5
  145. package/dist/social-providers/twitter.d.mts +1 -2
  146. package/dist/social-providers/twitter.mjs +0 -4
  147. package/dist/social-providers/vercel.d.mts +1 -2
  148. package/dist/social-providers/vercel.mjs +0 -4
  149. package/dist/social-providers/vk.d.mts +1 -2
  150. package/dist/social-providers/vk.mjs +0 -4
  151. package/dist/social-providers/wechat.d.mts +1 -2
  152. package/dist/social-providers/wechat.mjs +0 -3
  153. package/dist/social-providers/zoom.d.mts +1 -2
  154. package/dist/social-providers/zoom.mjs +0 -4
  155. package/dist/types/context.d.mts +3 -5
  156. package/dist/types/cookie.d.mts +1 -2
  157. package/dist/types/helper.d.mts +1 -2
  158. package/dist/types/init-options.d.mts +14 -6
  159. package/dist/types/plugin-client.d.mts +2 -2
  160. package/dist/types/plugin.d.mts +6 -3
  161. package/dist/types/secret.d.mts +1 -2
  162. package/dist/utils/db.d.mts +1 -2
  163. package/dist/utils/db.mjs +0 -2
  164. package/dist/utils/deprecate.d.mts +1 -2
  165. package/dist/utils/deprecate.mjs +0 -2
  166. package/dist/utils/error-codes.d.mts +1 -2
  167. package/dist/utils/error-codes.mjs +0 -2
  168. package/dist/utils/fetch-metadata.d.mts +1 -2
  169. package/dist/utils/fetch-metadata.mjs +0 -2
  170. package/dist/utils/id.d.mts +1 -2
  171. package/dist/utils/id.mjs +0 -3
  172. package/dist/utils/ip.d.mts +1 -2
  173. package/dist/utils/ip.mjs +0 -3
  174. package/dist/utils/json.d.mts +1 -2
  175. package/dist/utils/json.mjs +0 -4
  176. package/dist/utils/string.d.mts +1 -2
  177. package/dist/utils/string.mjs +0 -2
  178. package/dist/utils/url.d.mts +1 -2
  179. package/dist/utils/url.mjs +0 -2
  180. package/package.json +11 -9
  181. package/src/api/index.ts +151 -41
  182. package/src/context/endpoint-context.ts +2 -1
  183. package/src/db/adapter/factory.ts +2 -0
  184. package/src/db/adapter/index.ts +8 -0
  185. package/src/instrumentation/tracer.ts +40 -12
  186. package/src/social-providers/index.ts +0 -2
  187. package/src/types/context.ts +2 -3
  188. package/src/types/init-options.ts +13 -4
  189. package/src/types/plugin-client.ts +1 -0
  190. package/src/types/plugin.ts +15 -1
  191. package/dist/api/index.mjs.map +0 -1
  192. package/dist/async_hooks/index.mjs.map +0 -1
  193. package/dist/async_hooks/pure.index.mjs.map +0 -1
  194. package/dist/context/endpoint-context.mjs.map +0 -1
  195. package/dist/context/global.mjs.map +0 -1
  196. package/dist/context/request-state.mjs.map +0 -1
  197. package/dist/context/transaction.mjs.map +0 -1
  198. package/dist/db/adapter/factory.mjs.map +0 -1
  199. package/dist/db/adapter/get-default-field-name.mjs.map +0 -1
  200. package/dist/db/adapter/get-default-model-name.mjs.map +0 -1
  201. package/dist/db/adapter/get-field-attributes.mjs.map +0 -1
  202. package/dist/db/adapter/get-field-name.mjs.map +0 -1
  203. package/dist/db/adapter/get-id-field.mjs.map +0 -1
  204. package/dist/db/adapter/get-model-name.mjs.map +0 -1
  205. package/dist/db/adapter/index.mjs.map +0 -1
  206. package/dist/db/adapter/utils.mjs.map +0 -1
  207. package/dist/db/get-tables.mjs.map +0 -1
  208. package/dist/db/schema/account.mjs.map +0 -1
  209. package/dist/db/schema/rate-limit.mjs.map +0 -1
  210. package/dist/db/schema/session.mjs.map +0 -1
  211. package/dist/db/schema/shared.mjs.map +0 -1
  212. package/dist/db/schema/user.mjs.map +0 -1
  213. package/dist/db/schema/verification.mjs.map +0 -1
  214. package/dist/env/color-depth.mjs.map +0 -1
  215. package/dist/env/env-impl.mjs.map +0 -1
  216. package/dist/env/logger.mjs.map +0 -1
  217. package/dist/error/codes.mjs.map +0 -1
  218. package/dist/error/index.mjs.map +0 -1
  219. package/dist/instrumentation/attributes.mjs.map +0 -1
  220. package/dist/instrumentation/tracer.mjs.map +0 -1
  221. package/dist/oauth2/client-credentials-token.mjs.map +0 -1
  222. package/dist/oauth2/create-authorization-url.mjs.map +0 -1
  223. package/dist/oauth2/refresh-access-token.mjs.map +0 -1
  224. package/dist/oauth2/utils.mjs.map +0 -1
  225. package/dist/oauth2/validate-authorization-code.mjs.map +0 -1
  226. package/dist/oauth2/verify.mjs.map +0 -1
  227. package/dist/social-providers/apple.mjs.map +0 -1
  228. package/dist/social-providers/atlassian.mjs.map +0 -1
  229. package/dist/social-providers/cognito.mjs.map +0 -1
  230. package/dist/social-providers/discord.mjs.map +0 -1
  231. package/dist/social-providers/dropbox.mjs.map +0 -1
  232. package/dist/social-providers/facebook.mjs.map +0 -1
  233. package/dist/social-providers/figma.mjs.map +0 -1
  234. package/dist/social-providers/github.mjs.map +0 -1
  235. package/dist/social-providers/gitlab.mjs.map +0 -1
  236. package/dist/social-providers/google.mjs.map +0 -1
  237. package/dist/social-providers/huggingface.mjs.map +0 -1
  238. package/dist/social-providers/index.mjs.map +0 -1
  239. package/dist/social-providers/kakao.mjs.map +0 -1
  240. package/dist/social-providers/kick.mjs.map +0 -1
  241. package/dist/social-providers/line.mjs.map +0 -1
  242. package/dist/social-providers/linear.mjs.map +0 -1
  243. package/dist/social-providers/linkedin.mjs.map +0 -1
  244. package/dist/social-providers/microsoft-entra-id.mjs.map +0 -1
  245. package/dist/social-providers/naver.mjs.map +0 -1
  246. package/dist/social-providers/notion.mjs.map +0 -1
  247. package/dist/social-providers/paybin.mjs.map +0 -1
  248. package/dist/social-providers/paypal.mjs.map +0 -1
  249. package/dist/social-providers/polar.mjs.map +0 -1
  250. package/dist/social-providers/railway.mjs.map +0 -1
  251. package/dist/social-providers/reddit.mjs.map +0 -1
  252. package/dist/social-providers/roblox.mjs.map +0 -1
  253. package/dist/social-providers/salesforce.mjs.map +0 -1
  254. package/dist/social-providers/slack.mjs.map +0 -1
  255. package/dist/social-providers/spotify.mjs.map +0 -1
  256. package/dist/social-providers/tiktok.mjs.map +0 -1
  257. package/dist/social-providers/twitch.mjs.map +0 -1
  258. package/dist/social-providers/twitter.mjs.map +0 -1
  259. package/dist/social-providers/vercel.mjs.map +0 -1
  260. package/dist/social-providers/vk.mjs.map +0 -1
  261. package/dist/social-providers/wechat.mjs.map +0 -1
  262. package/dist/social-providers/zoom.mjs.map +0 -1
  263. package/dist/utils/db.mjs.map +0 -1
  264. package/dist/utils/deprecate.mjs.map +0 -1
  265. package/dist/utils/error-codes.mjs.map +0 -1
  266. package/dist/utils/fetch-metadata.mjs.map +0 -1
  267. package/dist/utils/id.mjs.map +0 -1
  268. package/dist/utils/ip.mjs.map +0 -1
  269. package/dist/utils/json.mjs.map +0 -1
  270. package/dist/utils/string.mjs.map +0 -1
  271. package/dist/utils/url.mjs.map +0 -1
  272. package/src/context/request-state.test.ts +0 -94
  273. package/src/db/adapter/get-id-field.test.ts +0 -222
  274. package/src/db/test/get-tables.test.ts +0 -116
  275. package/src/env/logger.test.ts +0 -34
  276. package/src/instrumentation/instrumentation.test.ts +0 -139
  277. package/src/oauth2/refresh-access-token.test.ts +0 -90
  278. package/src/oauth2/validate-token.test.ts +0 -229
  279. package/src/utils/deprecate.test.ts +0 -71
  280. package/src/utils/fetch-metadata.test.ts +0 -28
  281. package/src/utils/ip.test.ts +0 -255
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.mjs","names":[],"sources":["../../../src/db/adapter/factory.ts"],"sourcesContent":["import { createLogger, getColorDepth, TTY_COLORS } from \"../../env\";\nimport { BetterAuthError } from \"../../error\";\nimport {\n\tATTR_DB_COLLECTION_NAME,\n\tATTR_DB_OPERATION_NAME,\n\twithSpan,\n} from \"../../instrumentation\";\nimport type { BetterAuthOptions } from \"../../types\";\nimport { safeJSONParse } from \"../../utils/json\";\nimport { getAuthTables } from \"../get-tables\";\nimport { initGetDefaultFieldName } from \"./get-default-field-name\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\nimport { initGetFieldAttributes } from \"./get-field-attributes\";\nimport { initGetFieldName } from \"./get-field-name\";\nimport { initGetIdField } from \"./get-id-field\";\nimport { initGetModelName } from \"./get-model-name\";\nimport type {\n\tCleanedWhere,\n\tDBAdapter,\n\tDBTransactionAdapter,\n\tJoinConfig,\n\tJoinOption,\n\tWhere,\n} from \"./index\";\nimport type {\n\tAdapterFactoryConfig,\n\tAdapterFactoryOptions,\n\tAdapterTestDebugLogs,\n} from \"./types\";\nimport { withApplyDefault } from \"./utils\";\n\nexport {\n\tinitGetDefaultModelName,\n\tinitGetDefaultFieldName,\n\tinitGetModelName,\n\tinitGetFieldName,\n\tinitGetFieldAttributes,\n\tinitGetIdField,\n};\nexport * from \"./types\";\n\nlet debugLogs: { instance: string; args: any[] }[] = [];\nlet transactionId = -1;\n\nconst createAsIsTransaction =\n\t<Options extends BetterAuthOptions>(adapter: DBAdapter<Options>) =>\n\t<R>(fn: (trx: DBTransactionAdapter<Options>) => Promise<R>) =>\n\t\tfn(adapter);\n\nexport type AdapterFactory<Options extends BetterAuthOptions> = (\n\toptions: Options,\n) => DBAdapter<Options>;\n\nexport const createAdapterFactory =\n\t<Options extends BetterAuthOptions>({\n\t\tadapter: customAdapter,\n\t\tconfig: cfg,\n\t}: AdapterFactoryOptions): AdapterFactory<Options> =>\n\t(options: Options): DBAdapter<Options> => {\n\t\tconst uniqueAdapterFactoryInstanceId = Math.random()\n\t\t\t.toString(36)\n\t\t\t.substring(2, 15);\n\n\t\tconst config = {\n\t\t\t...cfg,\n\t\t\tsupportsBooleans: cfg.supportsBooleans ?? true,\n\t\t\tsupportsDates: cfg.supportsDates ?? true,\n\t\t\tsupportsJSON: cfg.supportsJSON ?? false,\n\t\t\tadapterName: cfg.adapterName ?? cfg.adapterId,\n\t\t\tsupportsNumericIds: cfg.supportsNumericIds ?? true,\n\t\t\tsupportsUUIDs: cfg.supportsUUIDs ?? false,\n\t\t\tsupportsArrays: cfg.supportsArrays ?? false,\n\t\t\ttransaction: cfg.transaction ?? false,\n\t\t\tdisableTransformInput: cfg.disableTransformInput ?? false,\n\t\t\tdisableTransformOutput: cfg.disableTransformOutput ?? false,\n\t\t\tdisableTransformJoin: cfg.disableTransformJoin ?? false,\n\t\t} satisfies AdapterFactoryConfig;\n\n\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\tif (useNumberId && config.supportsNumericIds === false) {\n\t\t\tthrow new BetterAuthError(\n\t\t\t\t`[${config.adapterName}] Your database or database adapter does not support numeric ids. Please disable \"useNumberId\" in your config.`,\n\t\t\t);\n\t\t}\n\n\t\t// End-user's Better-Auth instance's schema\n\t\tconst schema = getAuthTables(options);\n\n\t\tconst debugLog = (...args: any[]) => {\n\t\t\tif (config.debugLogs === true || typeof config.debugLogs === \"object\") {\n\t\t\t\tconst logger = createLogger({ level: \"info\" });\n\t\t\t\t// If we're running adapter tests, we'll keep debug logs in memory, then print them out if a test fails.\n\t\t\t\tif (\n\t\t\t\t\ttypeof config.debugLogs === \"object\" &&\n\t\t\t\t\t\"isRunningAdapterTests\" in config.debugLogs\n\t\t\t\t) {\n\t\t\t\t\tif (config.debugLogs.isRunningAdapterTests) {\n\t\t\t\t\t\targs.shift(); // Removes the {method: \"...\"} object from the args array.\n\t\t\t\t\t\tdebugLogs.push({ instance: uniqueAdapterFactoryInstanceId, args });\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\ttypeof config.debugLogs === \"object\" &&\n\t\t\t\t\tconfig.debugLogs.logCondition &&\n\t\t\t\t\t!config.debugLogs.logCondition?.()\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (typeof args[0] === \"object\" && \"method\" in args[0]) {\n\t\t\t\t\tconst method = args.shift().method;\n\t\t\t\t\t// Make sure the method is enabled in the config.\n\t\t\t\t\tif (typeof config.debugLogs === \"object\") {\n\t\t\t\t\t\tif (method === \"create\" && !config.debugLogs.create) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (method === \"update\" && !config.debugLogs.update) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tmethod === \"updateMany\" &&\n\t\t\t\t\t\t\t!config.debugLogs.updateMany\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (method === \"findOne\" && !config.debugLogs.findOne) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (method === \"findMany\" && !config.debugLogs.findMany) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (method === \"delete\" && !config.debugLogs.delete) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tmethod === \"deleteMany\" &&\n\t\t\t\t\t\t\t!config.debugLogs.deleteMany\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (method === \"count\" && !config.debugLogs.count) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlogger.info(`[${config.adapterName}]`, ...args);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.info(`[${config.adapterName}]`, ...args);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst logger = createLogger(options.logger);\n\n\t\tconst getDefaultModelName = initGetDefaultModelName({\n\t\t\tusePlural: config.usePlural,\n\t\t\tschema,\n\t\t});\n\n\t\tconst getDefaultFieldName = initGetDefaultFieldName({\n\t\t\tusePlural: config.usePlural,\n\t\t\tschema,\n\t\t});\n\n\t\tconst getModelName = initGetModelName({\n\t\t\tusePlural: config.usePlural,\n\t\t\tschema,\n\t\t});\n\t\tconst getFieldName = initGetFieldName({\n\t\t\tschema,\n\t\t\tusePlural: config.usePlural,\n\t\t});\n\n\t\tconst idField = initGetIdField({\n\t\t\tschema,\n\t\t\toptions,\n\t\t\tusePlural: config.usePlural,\n\t\t\tdisableIdGeneration: config.disableIdGeneration,\n\t\t\tcustomIdGenerator: config.customIdGenerator,\n\t\t\tsupportsUUIDs: config.supportsUUIDs,\n\t\t});\n\n\t\tconst getFieldAttributes = initGetFieldAttributes({\n\t\t\tschema,\n\t\t\toptions,\n\t\t\tusePlural: config.usePlural,\n\t\t\tdisableIdGeneration: config.disableIdGeneration,\n\t\t\tcustomIdGenerator: config.customIdGenerator,\n\t\t});\n\n\t\tconst transformInput = async (\n\t\t\tdata: Record<string, any>,\n\t\t\tdefaultModelName: string,\n\t\t\taction: \"create\" | \"update\" | \"findOne\" | \"findMany\",\n\t\t\tforceAllowId?: boolean,\n\t\t) => {\n\t\t\tconst transformedData: Record<string, any> = {};\n\t\t\tconst fields = schema[defaultModelName]!.fields;\n\n\t\t\tconst newMappedKeys = config.mapKeysTransformInput ?? {};\n\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\tfields.id = idField({\n\t\t\t\tcustomModelName: defaultModelName,\n\t\t\t\tforceAllowId: forceAllowId && \"id\" in data,\n\t\t\t});\n\t\t\tfor (const field in fields) {\n\t\t\t\tlet value = data[field];\n\t\t\t\tconst fieldAttributes = fields[field];\n\n\t\t\t\tconst newFieldName: string =\n\t\t\t\t\tnewMappedKeys[field] || fields[field]!.fieldName || field;\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined &&\n\t\t\t\t\t((fieldAttributes!.defaultValue === undefined &&\n\t\t\t\t\t\t!fieldAttributes!.transform?.input &&\n\t\t\t\t\t\t!(action === \"update\" && fieldAttributes!.onUpdate)) ||\n\t\t\t\t\t\t(action === \"update\" && !fieldAttributes!.onUpdate))\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// In some endpoints (like signUpEmail) where there isn't proper Zod validation,\n\t\t\t\t// we might receive a date as a string (this is because of the client converting the Date to a string\n\t\t\t\t// when sending to the server). Because of this, we'll convert the string to a Date.\n\t\t\t\tif (\n\t\t\t\t\tfieldAttributes &&\n\t\t\t\t\tfieldAttributes.type === \"date\" &&\n\t\t\t\t\t!(value instanceof Date) &&\n\t\t\t\t\ttypeof value === \"string\"\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvalue = new Date(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tlogger.error(\"[Adapter Factory] Failed to convert string to date\", {\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If the value is undefined, but the fieldAttr provides a `defaultValue`, then we'll use that.\n\t\t\t\tlet newValue = withApplyDefault(value, fieldAttributes!, action);\n\n\t\t\t\t// If the field attr provides a custom transform input, then we'll let it handle the value transformation.\n\t\t\t\t// Afterwards, we'll continue to apply the default transformations just to make sure it saves in the correct format.\n\t\t\t\tif (fieldAttributes!.transform?.input) {\n\t\t\t\t\tnewValue = await fieldAttributes!.transform.input(newValue);\n\t\t\t\t}\n\n\t\t\t\tif (fieldAttributes!.references?.field === \"id\" && useNumberId) {\n\t\t\t\t\tif (Array.isArray(newValue)) {\n\t\t\t\t\t\tnewValue = newValue.map((x) => (x !== null ? Number(x) : null));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewValue = newValue !== null ? Number(newValue) : null;\n\t\t\t\t\t}\n\t\t\t\t} else if (\n\t\t\t\t\tconfig.supportsJSON === false &&\n\t\t\t\t\ttypeof newValue === \"object\" &&\n\t\t\t\t\tfieldAttributes!.type === \"json\"\n\t\t\t\t) {\n\t\t\t\t\tnewValue = JSON.stringify(newValue);\n\t\t\t\t} else if (\n\t\t\t\t\tconfig.supportsArrays === false &&\n\t\t\t\t\tArray.isArray(newValue) &&\n\t\t\t\t\t(fieldAttributes!.type === \"string[]\" ||\n\t\t\t\t\t\tfieldAttributes!.type === \"number[]\")\n\t\t\t\t) {\n\t\t\t\t\tnewValue = JSON.stringify(newValue);\n\t\t\t\t} else if (\n\t\t\t\t\tconfig.supportsDates === false &&\n\t\t\t\t\tnewValue instanceof Date &&\n\t\t\t\t\tfieldAttributes!.type === \"date\"\n\t\t\t\t) {\n\t\t\t\t\tnewValue = newValue.toISOString();\n\t\t\t\t} else if (\n\t\t\t\t\tconfig.supportsBooleans === false &&\n\t\t\t\t\ttypeof newValue === \"boolean\"\n\t\t\t\t) {\n\t\t\t\t\tnewValue = newValue ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\tif (config.customTransformInput) {\n\t\t\t\t\tnewValue = config.customTransformInput({\n\t\t\t\t\t\tdata: newValue,\n\t\t\t\t\t\taction,\n\t\t\t\t\t\tfield: newFieldName,\n\t\t\t\t\t\tfieldAttributes: fieldAttributes!,\n\t\t\t\t\t\tmodel: getModelName(defaultModelName),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (newValue !== undefined) {\n\t\t\t\t\ttransformedData[newFieldName] = newValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn transformedData;\n\t\t};\n\n\t\tconst transformOutput = async (\n\t\t\tdata: Record<string, any> | null,\n\t\t\tunsafe_model: string,\n\t\t\tselect: string[] = [],\n\t\t\tjoin: JoinConfig | undefined,\n\t\t) => {\n\t\t\tconst transformSingleOutput = async (\n\t\t\t\tdata: Record<string, any> | null,\n\t\t\t\tunsafe_model: string,\n\t\t\t\tselect: string[] = [],\n\t\t\t) => {\n\t\t\t\tif (!data) return null;\n\t\t\t\tconst newMappedKeys = config.mapKeysTransformOutput ?? {};\n\t\t\t\tconst transformedData: Record<string, any> = {};\n\t\t\t\tconst tableSchema = schema[getDefaultModelName(unsafe_model)]!.fields;\n\t\t\t\tconst idKey = Object.entries(newMappedKeys).find(\n\t\t\t\t\t([_, v]) => v === \"id\",\n\t\t\t\t)?.[0];\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\t\ttableSchema[idKey ?? \"id\"] = {\n\t\t\t\t\ttype: useNumberId ? \"number\" : \"string\",\n\t\t\t\t};\n\t\t\t\tfor (const key in tableSchema) {\n\t\t\t\t\tif (select.length && !select.includes(key)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst field = tableSchema[key];\n\t\t\t\t\tif (field) {\n\t\t\t\t\t\tconst originalKey = field.fieldName || key;\n\n\t\t\t\t\t\t// If the field is mapped, we'll use the mapped key. Otherwise, we'll use the original key.\n\t\t\t\t\t\tlet newValue =\n\t\t\t\t\t\t\tdata[\n\t\t\t\t\t\t\t\tObject.entries(newMappedKeys).find(\n\t\t\t\t\t\t\t\t\t([_, v]) => v === originalKey,\n\t\t\t\t\t\t\t\t)?.[0] || originalKey\n\t\t\t\t\t\t\t];\n\n\t\t\t\t\t\tif (field.transform?.output) {\n\t\t\t\t\t\t\tnewValue = await field.transform.output(newValue);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst newFieldName: string = newMappedKeys[key] || key;\n\n\t\t\t\t\t\tif (originalKey === \"id\" || field.references?.field === \"id\") {\n\t\t\t\t\t\t\t// Even if `useNumberId` is true, we must always return a string `id` output.\n\t\t\t\t\t\t\tif (typeof newValue !== \"undefined\" && newValue !== null)\n\t\t\t\t\t\t\t\tnewValue = String(newValue);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tconfig.supportsJSON === false &&\n\t\t\t\t\t\t\ttypeof newValue === \"string\" &&\n\t\t\t\t\t\t\tfield.type === \"json\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnewValue = safeJSONParse(newValue);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tconfig.supportsArrays === false &&\n\t\t\t\t\t\t\ttypeof newValue === \"string\" &&\n\t\t\t\t\t\t\t(field.type === \"string[]\" || field.type === \"number[]\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnewValue = safeJSONParse(newValue);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tconfig.supportsDates === false &&\n\t\t\t\t\t\t\ttypeof newValue === \"string\" &&\n\t\t\t\t\t\t\tfield.type === \"date\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnewValue = new Date(newValue);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tconfig.supportsBooleans === false &&\n\t\t\t\t\t\t\ttypeof newValue === \"number\" &&\n\t\t\t\t\t\t\tfield.type === \"boolean\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnewValue = newValue === 1;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (config.customTransformOutput) {\n\t\t\t\t\t\t\tnewValue = config.customTransformOutput({\n\t\t\t\t\t\t\t\tdata: newValue,\n\t\t\t\t\t\t\t\tfield: newFieldName,\n\t\t\t\t\t\t\t\tfieldAttributes: field,\n\t\t\t\t\t\t\t\tselect,\n\t\t\t\t\t\t\t\tmodel: getModelName(unsafe_model),\n\t\t\t\t\t\t\t\tschema,\n\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttransformedData[newFieldName] = newValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn transformedData as any;\n\t\t\t};\n\n\t\t\tif (!join || Object.keys(join).length === 0) {\n\t\t\t\treturn await transformSingleOutput(data, unsafe_model, select);\n\t\t\t}\n\n\t\t\tunsafe_model = getDefaultModelName(unsafe_model);\n\t\t\t// for now we just transform the base model\n\t\t\t// later we append the joined models to this object.\n\t\t\tconst transformedData: Record<string, any> = await transformSingleOutput(\n\t\t\t\tdata,\n\t\t\t\tunsafe_model,\n\t\t\t\tselect,\n\t\t\t);\n\n\t\t\t// Get all the models that are required to be joined.\n\t\t\tconst requiredModels = Object.entries(join).map(\n\t\t\t\t([model, joinConfig]) => ({\n\t\t\t\t\tmodelName: getModelName(model),\n\t\t\t\t\tdefaultModelName: getDefaultModelName(model),\n\t\t\t\t\tjoinConfig,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tif (!data) return null;\n\t\t\t// Data is now the base model object directly (not wrapped under a key)\n\n\t\t\tfor (const {\n\t\t\t\tmodelName,\n\t\t\t\tdefaultModelName,\n\t\t\t\tjoinConfig,\n\t\t\t} of requiredModels) {\n\t\t\t\tlet joinedData = await (async () => {\n\t\t\t\t\tif (options.experimental?.joins) {\n\t\t\t\t\t\tconst result = data[modelName];\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// doesn't support joins, so fallback to handleFallbackJoin\n\t\t\t\t\t\tconst result = await handleFallbackJoin({\n\t\t\t\t\t\t\tbaseModel: unsafe_model,\n\t\t\t\t\t\t\tbaseData: transformedData,\n\t\t\t\t\t\t\tjoinModel: modelName,\n\t\t\t\t\t\t\tspecificJoinConfig: joinConfig,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t})();\n\n\t\t\t\t// If joinedData is undefined, initialize it based on relationship type\n\t\t\t\tif (joinedData === undefined || joinedData === null) {\n\t\t\t\t\tjoinedData = joinConfig.relation === \"one-to-one\" ? null : [];\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tjoinConfig.relation === \"one-to-many\" &&\n\t\t\t\t\t!Array.isArray(joinedData)\n\t\t\t\t) {\n\t\t\t\t\tjoinedData = [joinedData];\n\t\t\t\t}\n\n\t\t\t\tconst transformed = [];\n\n\t\t\t\tif (Array.isArray(joinedData)) {\n\t\t\t\t\tfor (const item of joinedData) {\n\t\t\t\t\t\tconst transformedItem = await transformSingleOutput(\n\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\tmodelName,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t);\n\t\t\t\t\t\ttransformed.push(transformedItem);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst transformedItem = await transformSingleOutput(\n\t\t\t\t\t\tjoinedData,\n\t\t\t\t\t\tmodelName,\n\t\t\t\t\t\t[],\n\t\t\t\t\t);\n\t\t\t\t\ttransformed.push(transformedItem);\n\t\t\t\t}\n\n\t\t\t\tconst result =\n\t\t\t\t\tjoinConfig.relation === \"one-to-one\" ? transformed[0] : transformed;\n\t\t\t\ttransformedData[defaultModelName] = result ?? null;\n\t\t\t}\n\n\t\t\treturn transformedData as any;\n\t\t};\n\n\t\tconst transformWhereClause = <W extends Where[] | undefined>({\n\t\t\tmodel,\n\t\t\twhere,\n\t\t\taction,\n\t\t}: {\n\t\t\twhere: W;\n\t\t\tmodel: string;\n\t\t\taction:\n\t\t\t\t| \"create\"\n\t\t\t\t| \"update\"\n\t\t\t\t| \"findOne\"\n\t\t\t\t| \"findMany\"\n\t\t\t\t| \"updateMany\"\n\t\t\t\t| \"delete\"\n\t\t\t\t| \"deleteMany\"\n\t\t\t\t| \"count\";\n\t\t}): W extends undefined ? undefined : CleanedWhere[] => {\n\t\t\tif (!where) return undefined as any;\n\t\t\tconst newMappedKeys = config.mapKeysTransformInput ?? {};\n\n\t\t\treturn where.map((w) => {\n\t\t\t\tconst {\n\t\t\t\t\tfield: unsafe_field,\n\t\t\t\t\tvalue,\n\t\t\t\t\toperator = \"eq\",\n\t\t\t\t\tconnector = \"AND\",\n\t\t\t\t} = w;\n\t\t\t\tif (operator === \"in\") {\n\t\t\t\t\tif (!Array.isArray(value)) {\n\t\t\t\t\t\tthrow new BetterAuthError(\"Value must be an array\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet newValue = value;\n\n\t\t\t\tconst defaultModelName = getDefaultModelName(model);\n\t\t\t\tconst defaultFieldName = getDefaultFieldName({\n\t\t\t\t\tfield: unsafe_field,\n\t\t\t\t\tmodel,\n\t\t\t\t});\n\t\t\t\tconst fieldName: string =\n\t\t\t\t\tnewMappedKeys[defaultFieldName] ||\n\t\t\t\t\tgetFieldName({\n\t\t\t\t\t\tfield: defaultFieldName,\n\t\t\t\t\t\tmodel: defaultModelName,\n\t\t\t\t\t});\n\n\t\t\t\tconst fieldAttr = getFieldAttributes({\n\t\t\t\t\tfield: defaultFieldName,\n\t\t\t\t\tmodel: defaultModelName,\n\t\t\t\t});\n\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\n\t\t\t\tif (\n\t\t\t\t\tdefaultFieldName === \"id\" ||\n\t\t\t\t\tfieldAttr!.references?.field === \"id\"\n\t\t\t\t) {\n\t\t\t\t\tif (useNumberId) {\n\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\tnewValue = value.map(Number);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnewValue = Number(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tfieldAttr.type === \"date\" &&\n\t\t\t\t\tvalue instanceof Date &&\n\t\t\t\t\t!config.supportsDates\n\t\t\t\t) {\n\t\t\t\t\tnewValue = value.toISOString();\n\t\t\t\t}\n\n\t\t\t\tif (fieldAttr.type === \"boolean\" && typeof newValue === \"string\") {\n\t\t\t\t\tnewValue = newValue === \"true\";\n\t\t\t\t}\n\n\t\t\t\tif (fieldAttr.type === \"number\") {\n\t\t\t\t\tif (typeof newValue === \"string\" && newValue.trim() !== \"\") {\n\t\t\t\t\t\tconst parsed = Number(newValue);\n\t\t\t\t\t\tif (!Number.isNaN(parsed)) {\n\t\t\t\t\t\t\tnewValue = parsed;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (Array.isArray(newValue)) {\n\t\t\t\t\t\tconst parsed = newValue.map((v) =>\n\t\t\t\t\t\t\ttypeof v === \"string\" && v.trim() !== \"\" ? Number(v) : NaN,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (parsed.every((n) => !Number.isNaN(n))) {\n\t\t\t\t\t\t\tnewValue = parsed;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tfieldAttr.type === \"boolean\" &&\n\t\t\t\t\ttypeof newValue === \"boolean\" &&\n\t\t\t\t\t!config.supportsBooleans\n\t\t\t\t) {\n\t\t\t\t\tnewValue = newValue ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tfieldAttr.type === \"json\" &&\n\t\t\t\t\ttypeof value === \"object\" &&\n\t\t\t\t\t!config.supportsJSON\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst stringifiedJSON = JSON.stringify(value);\n\t\t\t\t\t\tnewValue = stringifiedJSON;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Failed to stringify JSON value for field ${fieldName}`,\n\t\t\t\t\t\t\t{ cause: error },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (config.customTransformInput) {\n\t\t\t\t\tnewValue = config.customTransformInput({\n\t\t\t\t\t\tdata: newValue,\n\t\t\t\t\t\tfieldAttributes: fieldAttr,\n\t\t\t\t\t\tfield: fieldName,\n\t\t\t\t\t\tmodel: getModelName(model),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\taction,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\toperator,\n\t\t\t\t\tconnector,\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t} satisfies CleanedWhere;\n\t\t\t}) as any;\n\t\t};\n\n\t\tconst transformJoinClause = (\n\t\t\tbaseModel: string,\n\t\t\tunsanitizedJoin: JoinOption | undefined,\n\t\t\tselect: string[] | undefined,\n\t\t): { join: JoinConfig; select: string[] | undefined } | undefined => {\n\t\t\tif (!unsanitizedJoin) return undefined;\n\t\t\tif (Object.keys(unsanitizedJoin).length === 0) return undefined;\n\t\t\tconst transformedJoin: JoinConfig = {};\n\t\t\tfor (const [model, join] of Object.entries(unsanitizedJoin)) {\n\t\t\t\tif (!join) continue;\n\t\t\t\tconst defaultModelName = getDefaultModelName(model);\n\t\t\t\tconst defaultBaseModelName = getDefaultModelName(baseModel);\n\n\t\t\t\t// First, check if the joined model has FKs to the base model (forward join)\n\t\t\t\tlet foreignKeys = Object.entries(\n\t\t\t\t\tschema[defaultModelName]!.fields,\n\t\t\t\t).filter(\n\t\t\t\t\t([field, fieldAttributes]) =>\n\t\t\t\t\t\tfieldAttributes.references &&\n\t\t\t\t\t\tgetDefaultModelName(fieldAttributes.references.model) ===\n\t\t\t\t\t\t\tdefaultBaseModelName,\n\t\t\t\t);\n\n\t\t\t\tlet isForwardJoin = true;\n\n\t\t\t\t// If no forward join found, check backwards: does the base model have FKs to the joined model?\n\t\t\t\tif (!foreignKeys.length) {\n\t\t\t\t\tforeignKeys = Object.entries(\n\t\t\t\t\t\tschema[defaultBaseModelName]!.fields,\n\t\t\t\t\t).filter(\n\t\t\t\t\t\t([field, fieldAttributes]) =>\n\t\t\t\t\t\t\tfieldAttributes.references &&\n\t\t\t\t\t\t\tgetDefaultModelName(fieldAttributes.references.model) ===\n\t\t\t\t\t\t\t\tdefaultModelName,\n\t\t\t\t\t);\n\t\t\t\t\tisForwardJoin = false;\n\t\t\t\t}\n\n\t\t\t\tif (!foreignKeys.length) {\n\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t`No foreign key found for model ${model} and base model ${baseModel} while performing join operation.`,\n\t\t\t\t\t);\n\t\t\t\t} else if (foreignKeys.length > 1) {\n\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t`Multiple foreign keys found for model ${model} and base model ${baseModel} while performing join operation. Only one foreign key is supported.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst [foreignKey, foreignKeyAttributes] = foreignKeys[0]!;\n\t\t\t\tif (!foreignKeyAttributes.references) {\n\t\t\t\t\t// this should never happen, as we filter for references in the foreign keys.\n\t\t\t\t\t// it's here for typescript to be happy.\n\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t`No references found for foreign key ${foreignKey} on model ${model} while performing join operation.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet from: string;\n\t\t\t\tlet to: string;\n\t\t\t\tlet requiredSelectField: string;\n\n\t\t\t\tif (isForwardJoin) {\n\t\t\t\t\t// joined model has FK to base model\n\t\t\t\t\t// The field we need in select is the referenced field in the base model\n\t\t\t\t\trequiredSelectField = foreignKeyAttributes.references.field;\n\t\t\t\t\tfrom = getFieldName({\n\t\t\t\t\t\tmodel: baseModel,\n\t\t\t\t\t\tfield: requiredSelectField,\n\t\t\t\t\t});\n\n\t\t\t\t\tto = getFieldName({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tfield: foreignKey,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// base model has FK to joined model\n\t\t\t\t\t// The field we need in select is the foreign key field in the base model\n\t\t\t\t\trequiredSelectField = foreignKey;\n\t\t\t\t\tfrom = getFieldName({\n\t\t\t\t\t\tmodel: baseModel,\n\t\t\t\t\t\tfield: requiredSelectField,\n\t\t\t\t\t});\n\n\t\t\t\t\tto = getFieldName({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tfield: foreignKeyAttributes.references.field,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Ensure the required field is in select if select is provided\n\t\t\t\tif (select && !select.includes(requiredSelectField)) {\n\t\t\t\t\tselect.push(requiredSelectField);\n\t\t\t\t}\n\n\t\t\t\tconst isUnique =\n\t\t\t\t\tto === \"id\" ? true : (foreignKeyAttributes.unique ?? false);\n\n\t\t\t\tlet limit: number =\n\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ?? 100;\n\t\t\t\tif (isUnique) {\n\t\t\t\t\tlimit = 1;\n\t\t\t\t} else if (typeof join === \"object\" && typeof join.limit === \"number\") {\n\t\t\t\t\tlimit = join.limit;\n\t\t\t\t}\n\n\t\t\t\ttransformedJoin[getModelName(model)] = {\n\t\t\t\t\ton: {\n\t\t\t\t\t\tfrom,\n\t\t\t\t\t\tto,\n\t\t\t\t\t},\n\t\t\t\t\tlimit,\n\t\t\t\t\trelation: isUnique ? \"one-to-one\" : \"one-to-many\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { join: transformedJoin, select };\n\t\t};\n\n\t\t/**\n\t\t * Handle joins by making separate queries and combining results (fallback for adapters that don't support native joins).\n\t\t */\n\t\tconst handleFallbackJoin = async <T extends Record<string, any> | null>({\n\t\t\tbaseModel,\n\t\t\tbaseData,\n\t\t\tjoinModel,\n\t\t\tspecificJoinConfig: joinConfig,\n\t\t}: {\n\t\t\tbaseModel: string;\n\t\t\tbaseData: T;\n\t\t\tjoinModel: string;\n\t\t\tspecificJoinConfig: JoinConfig[number];\n\t\t}) => {\n\t\t\tif (!baseData) return baseData;\n\t\t\tconst modelName = getModelName(joinModel);\n\t\t\tconst field = joinConfig.on.to;\n\t\t\tconst value =\n\t\t\t\tbaseData[\n\t\t\t\t\tgetDefaultFieldName({ field: joinConfig.on.from, model: baseModel })\n\t\t\t\t];\n\n\t\t\tif (value === null || value === undefined) {\n\t\t\t\t// If there is no value, it could mean that the query used a `select` clause that didn't include the field.\n\t\t\t\t// or the query result is purely empty.\n\t\t\t\t// In any case, we return null/empty array.\n\t\t\t\treturn joinConfig.relation === \"one-to-one\" ? null : [];\n\t\t\t}\n\t\t\tlet result: Record<string, any> | Record<string, any>[] | null;\n\t\t\tconst where = transformWhereClause({\n\t\t\t\tmodel: modelName,\n\t\t\t\twhere: [\n\t\t\t\t\t{\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\toperator: \"eq\",\n\t\t\t\t\t\tconnector: \"AND\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\taction: \"findOne\",\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tif (joinConfig.relation === \"one-to-one\") {\n\t\t\t\t\tresult = await withSpan(\n\t\t\t\t\t\t`db findOne ${modelName}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"findOne\",\n\t\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: modelName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tadapterInstance.findOne<Record<string, any>>({\n\t\t\t\t\t\t\t\tmodel: modelName,\n\t\t\t\t\t\t\t\twhere: where,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst limit =\n\t\t\t\t\t\tjoinConfig.limit ??\n\t\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t\t100;\n\t\t\t\t\tresult = await withSpan(\n\t\t\t\t\t\t`db findMany ${modelName}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"findMany\",\n\t\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: modelName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tadapterInstance.findMany<Record<string, any>>({\n\t\t\t\t\t\t\t\tmodel: modelName,\n\t\t\t\t\t\t\t\twhere: where,\n\t\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(`Failed to query fallback join for model ${modelName}:`, {\n\t\t\t\t\twhere,\n\t\t\t\t\tlimit: joinConfig.limit,\n\t\t\t\t});\n\t\t\t\tconsole.error(error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\n\t\tconst adapterInstance = customAdapter({\n\t\t\toptions,\n\t\t\tschema,\n\t\t\tdebugLog,\n\t\t\tgetFieldName,\n\t\t\tgetModelName,\n\t\t\tgetDefaultModelName,\n\t\t\tgetDefaultFieldName,\n\t\t\tgetFieldAttributes,\n\t\t\ttransformInput,\n\t\t\ttransformOutput,\n\t\t\ttransformWhereClause,\n\t\t});\n\n\t\tlet lazyLoadTransaction: DBAdapter<Options>[\"transaction\"] | null = null;\n\t\tconst adapter: DBAdapter<Options> = {\n\t\t\ttransaction: async (cb) => {\n\t\t\t\tif (!lazyLoadTransaction) {\n\t\t\t\t\tif (!config.transaction) {\n\t\t\t\t\t\tlazyLoadTransaction = createAsIsTransaction(adapter);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t`[${config.adapterName}] - Using provided transaction implementation.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlazyLoadTransaction = config.transaction;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn lazyLoadTransaction(cb);\n\t\t\t},\n\t\t\tcreate: async <T extends Record<string, any>, R = T>({\n\t\t\t\tdata: unsafeData,\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\tselect,\n\t\t\t\tforceAllowId = false,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\tdata: T;\n\t\t\t\tselect?: string[];\n\t\t\t\tforceAllowId?: boolean;\n\t\t\t}): Promise<R> => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tif (\n\t\t\t\t\t\"id\" in unsafeData &&\n\t\t\t\t\ttypeof unsafeData.id !== \"undefined\" &&\n\t\t\t\t\t!forceAllowId\n\t\t\t\t) {\n\t\t\t\t\t// The reason why `forceAllowId` was introduced was because we used to handle\n\t\t\t\t\t// id generation ourselves (eg adapter.create({ data: { id: \"123\" } }))\n\t\t\t\t\t// This was bad as certain things (such as number ids) would not work as expected.\n\t\t\t\t\t// Since then, we have introduced the `forceAllowId` parameter to allow users to\n\t\t\t\t\t// bypass this check. Otherwise, we would throw a warning stating that the id will be ignored\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`[${config.adapterName}] - You are trying to create a record with an id. This is not allowed as we handle id generation for you, unless you pass in the \\`forceAllowId\\` parameter. The id will be ignored.`,\n\t\t\t\t\t);\n\t\t\t\t\tconst err = new Error();\n\t\t\t\t\tconst stack = err.stack\n\t\t\t\t\t\t?.split(\"\\n\")\n\t\t\t\t\t\t.filter((_, i) => i !== 1)\n\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t\t.replace(\"Error:\", \"Create method with `id` being called at:\");\n\t\t\t\t\tconsole.log(stack);\n\t\t\t\t\t//@ts-expect-error\n\t\t\t\t\tunsafeData.id = undefined;\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"create\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 4)}`,\n\t\t\t\t\t`${formatMethod(\"create\")} ${formatAction(\"Unsafe Input\")}:`,\n\t\t\t\t\t{ model, data: unsafeData },\n\t\t\t\t);\n\t\t\t\tlet data = unsafeData;\n\t\t\t\tif (!config.disableTransformInput) {\n\t\t\t\t\tdata = (await transformInput(\n\t\t\t\t\t\tunsafeData,\n\t\t\t\t\t\tunsafeModel,\n\t\t\t\t\t\t\"create\",\n\t\t\t\t\t\tforceAllowId,\n\t\t\t\t\t)) as T;\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"create\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 4)}`,\n\t\t\t\t\t`${formatMethod(\"create\")} ${formatAction(\"Parsed Input\")}:`,\n\t\t\t\t\t{ model, data },\n\t\t\t\t);\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db create ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"create\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() => adapterInstance.create<T>({ data, model }),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"create\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(3, 4)}`,\n\t\t\t\t\t`${formatMethod(\"create\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, res },\n\t\t\t\t);\n\t\t\t\tlet transformed = res as any;\n\t\t\t\tif (!config.disableTransformOutput) {\n\t\t\t\t\ttransformed = await transformOutput(\n\t\t\t\t\t\tres as any,\n\t\t\t\t\t\tunsafeModel,\n\t\t\t\t\t\tselect,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"create\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(4, 4)}`,\n\t\t\t\t\t`${formatMethod(\"create\")} ${formatAction(\"Parsed Result\")}:`,\n\t\t\t\t\t{ model, data: transformed },\n\t\t\t\t);\n\t\t\t\treturn transformed;\n\t\t\t},\n\t\t\tupdate: async <T>({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t\tupdate: unsafeData,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere: Where[];\n\t\t\t\tupdate: Record<string, any>;\n\t\t\t}): Promise<T | null> => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"update\",\n\t\t\t\t});\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"update\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 4)}`,\n\t\t\t\t\t`${formatMethod(\"update\")} ${formatAction(\"Unsafe Input\")}:`,\n\t\t\t\t\t{ model, data: unsafeData },\n\t\t\t\t);\n\t\t\t\tlet data = unsafeData as T;\n\t\t\t\tif (!config.disableTransformInput) {\n\t\t\t\t\tdata = (await transformInput(unsafeData, unsafeModel, \"update\")) as T;\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"update\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 4)}`,\n\t\t\t\t\t`${formatMethod(\"update\")} ${formatAction(\"Parsed Input\")}:`,\n\t\t\t\t\t{ model, data },\n\t\t\t\t);\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db update ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"update\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() =>\n\t\t\t\t\t\tadapterInstance.update<T>({\n\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\twhere,\n\t\t\t\t\t\t\tupdate: data,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"update\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(3, 4)}`,\n\t\t\t\t\t`${formatMethod(\"update\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, data: res },\n\t\t\t\t);\n\t\t\t\tlet transformed = res as any;\n\t\t\t\tif (!config.disableTransformOutput) {\n\t\t\t\t\ttransformed = await transformOutput(\n\t\t\t\t\t\tres as any,\n\t\t\t\t\t\tunsafeModel,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"update\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(4, 4)}`,\n\t\t\t\t\t`${formatMethod(\"update\")} ${formatAction(\"Parsed Result\")}:`,\n\t\t\t\t\t{ model, data: transformed },\n\t\t\t\t);\n\t\t\t\treturn transformed;\n\t\t\t},\n\t\t\tupdateMany: async ({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t\tupdate: unsafeData,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere: Where[];\n\t\t\t\tupdate: Record<string, any>;\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"updateMany\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"updateMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 4)}`,\n\t\t\t\t\t`${formatMethod(\"updateMany\")} ${formatAction(\"Unsafe Input\")}:`,\n\t\t\t\t\t{ model, data: unsafeData },\n\t\t\t\t);\n\t\t\t\tlet data = unsafeData;\n\t\t\t\tif (!config.disableTransformInput) {\n\t\t\t\t\tdata = await transformInput(unsafeData, unsafeModel, \"update\");\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"updateMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 4)}`,\n\t\t\t\t\t`${formatMethod(\"updateMany\")} ${formatAction(\"Parsed Input\")}:`,\n\t\t\t\t\t{ model, data },\n\t\t\t\t);\n\n\t\t\t\tconst updatedCount = await withSpan(\n\t\t\t\t\t`db updateMany ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"updateMany\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() =>\n\t\t\t\t\t\tadapterInstance.updateMany({\n\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\twhere,\n\t\t\t\t\t\t\tupdate: data,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"updateMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(3, 4)}`,\n\t\t\t\t\t`${formatMethod(\"updateMany\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, data: updatedCount },\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"updateMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(4, 4)}`,\n\t\t\t\t\t`${formatMethod(\"updateMany\")} ${formatAction(\"Parsed Result\")}:`,\n\t\t\t\t\t{ model, data: updatedCount },\n\t\t\t\t);\n\t\t\t\treturn updatedCount;\n\t\t\t},\n\t\t\tfindOne: async <T extends Record<string, any>>({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t\tselect,\n\t\t\t\tjoin: unsafeJoin,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere: Where[];\n\t\t\t\tselect?: string[];\n\t\t\t\tjoin?: JoinOption;\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"findOne\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tlet join: JoinConfig | undefined;\n\t\t\t\tlet passJoinToAdapter = true;\n\t\t\t\tif (!config.disableTransformJoin) {\n\t\t\t\t\tconst result = transformJoinClause(unsafeModel, unsafeJoin, select);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tjoin = result.join;\n\t\t\t\t\t\tselect = result.select;\n\t\t\t\t\t}\n\t\t\t\t\t// If adapter doesn't support joins and we have joins, don't pass them to the adapter\n\t\t\t\t\tconst experimentalJoins = options.experimental?.joins;\n\t\t\t\t\tif (!experimentalJoins && join && Object.keys(join).length > 0) {\n\t\t\t\t\t\tpassJoinToAdapter = false;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// assume it's already transformed if transformation is disabled\n\t\t\t\t\tjoin = unsafeJoin as never as JoinConfig;\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findOne\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findOne\")}:`,\n\t\t\t\t\t{ model, where, select, join },\n\t\t\t\t);\n\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db findOne ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"findOne\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() =>\n\t\t\t\t\t\tadapterInstance.findOne<T>({\n\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\twhere,\n\t\t\t\t\t\t\tselect,\n\t\t\t\t\t\t\tjoin: passJoinToAdapter ? join : undefined,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findOne\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findOne\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, data: res },\n\t\t\t\t);\n\n\t\t\t\t// Handle fallback join if adapter doesn't support joins\n\t\t\t\tlet transformed = res as any;\n\t\t\t\tif (!config.disableTransformOutput) {\n\t\t\t\t\ttransformed = await transformOutput(res, unsafeModel, select, join);\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findOne\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(3, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findOne\")} ${formatAction(\"Parsed Result\")}:`,\n\t\t\t\t\t{ model, data: transformed },\n\t\t\t\t);\n\t\t\t\treturn transformed;\n\t\t\t},\n\t\t\tfindMany: async <T extends Record<string, any>>({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t\tlimit: unsafeLimit,\n\t\t\t\tselect,\n\t\t\t\tsortBy,\n\t\t\t\toffset,\n\t\t\t\tjoin: unsafeJoin,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere?: Where[];\n\t\t\t\tlimit?: number;\n\t\t\t\tselect?: string[] | undefined;\n\t\t\t\tsortBy?: { field: string; direction: \"asc\" | \"desc\" };\n\t\t\t\toffset?: number;\n\t\t\t\tjoin?: JoinOption;\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst limit =\n\t\t\t\t\tunsafeLimit ??\n\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t100;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"findMany\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tlet join: JoinConfig | undefined;\n\t\t\t\tlet passJoinToAdapter = true;\n\t\t\t\tif (!config.disableTransformJoin) {\n\t\t\t\t\tconst result = transformJoinClause(unsafeModel, unsafeJoin, select);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tjoin = result.join;\n\t\t\t\t\t\tselect = result.select;\n\t\t\t\t\t}\n\t\t\t\t\t// If adapter doesn't support joins and we have joins, don't pass them to the adapter\n\t\t\t\t\tconst experimentalJoins = options.experimental?.joins;\n\t\t\t\t\tif (!experimentalJoins && join && Object.keys(join).length > 0) {\n\t\t\t\t\t\tpassJoinToAdapter = false;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// assume it's already transformed if transformation is disabled\n\t\t\t\t\tjoin = unsafeJoin as never as JoinConfig;\n\t\t\t\t}\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findMany\")}:`,\n\t\t\t\t\t{ model, where, limit, sortBy, offset, join },\n\t\t\t\t);\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db findMany ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"findMany\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() =>\n\t\t\t\t\t\tadapterInstance.findMany<T>({\n\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\twhere,\n\t\t\t\t\t\t\tlimit: limit,\n\t\t\t\t\t\t\tselect,\n\t\t\t\t\t\t\tsortBy,\n\t\t\t\t\t\t\toffset,\n\t\t\t\t\t\t\tjoin: passJoinToAdapter ? join : undefined,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findMany\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, data: res },\n\t\t\t\t);\n\n\t\t\t\tlet transformed = res as any;\n\t\t\t\tif (!config.disableTransformOutput) {\n\t\t\t\t\ttransformed = await Promise.all(\n\t\t\t\t\t\tres.map(async (r: Record<string, any>) => {\n\t\t\t\t\t\t\treturn await transformOutput(r, unsafeModel, undefined, join);\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"findMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(3, 3)}`,\n\t\t\t\t\t`${formatMethod(\"findMany\")} ${formatAction(\"Parsed Result\")}:`,\n\t\t\t\t\t{ model, data: transformed },\n\t\t\t\t);\n\t\t\t\treturn transformed;\n\t\t\t},\n\t\t\tdelete: async ({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere: Where[];\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"delete\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"delete\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`,\n\t\t\t\t\t`${formatMethod(\"delete\")}:`,\n\t\t\t\t\t{ model, where },\n\t\t\t\t);\n\t\t\t\tawait withSpan(\n\t\t\t\t\t`db delete ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"delete\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() => adapterInstance.delete({ model, where }),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"delete\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 2)}`,\n\t\t\t\t\t`${formatMethod(\"delete\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model },\n\t\t\t\t);\n\t\t\t},\n\t\t\tdeleteMany: async ({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere: Where[];\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"deleteMany\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"deleteMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`,\n\t\t\t\t\t`${formatMethod(\"deleteMany\")} ${formatAction(\"DeleteMany\")}:`,\n\t\t\t\t\t{ model, where },\n\t\t\t\t);\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db deleteMany ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"deleteMany\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() => adapterInstance.deleteMany({ model, where }),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"deleteMany\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 2)}`,\n\t\t\t\t\t`${formatMethod(\"deleteMany\")} ${formatAction(\"DB Result\")}:`,\n\t\t\t\t\t{ model, data: res },\n\t\t\t\t);\n\t\t\t\treturn res;\n\t\t\t},\n\t\t\tcount: async ({\n\t\t\t\tmodel: unsafeModel,\n\t\t\t\twhere: unsafeWhere,\n\t\t\t}: {\n\t\t\t\tmodel: string;\n\t\t\t\twhere?: Where[];\n\t\t\t}) => {\n\t\t\t\ttransactionId++;\n\t\t\t\tconst thisTransactionId = transactionId;\n\t\t\t\tconst model = getModelName(unsafeModel);\n\t\t\t\tconst where = transformWhereClause({\n\t\t\t\t\tmodel: unsafeModel,\n\t\t\t\t\twhere: unsafeWhere,\n\t\t\t\t\taction: \"count\",\n\t\t\t\t});\n\t\t\t\tunsafeModel = getDefaultModelName(unsafeModel);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"count\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`,\n\t\t\t\t\t`${formatMethod(\"count\")}:`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\twhere,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst res = await withSpan(\n\t\t\t\t\t`db count ${model}`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[ATTR_DB_OPERATION_NAME]: \"count\",\n\t\t\t\t\t\t[ATTR_DB_COLLECTION_NAME]: model,\n\t\t\t\t\t},\n\t\t\t\t\t() => adapterInstance.count({ model, where }),\n\t\t\t\t);\n\t\t\t\tdebugLog(\n\t\t\t\t\t{ method: \"count\" },\n\t\t\t\t\t`${formatTransactionId(thisTransactionId)} ${formatStep(2, 2)}`,\n\t\t\t\t\t`${formatMethod(\"count\")}:`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tdata: res,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn res;\n\t\t\t},\n\t\t\tcreateSchema: adapterInstance.createSchema\n\t\t\t\t? async (_, file) => {\n\t\t\t\t\t\tconst tables = getAuthTables(options);\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\toptions.secondaryStorage &&\n\t\t\t\t\t\t\t!options.session?.storeSessionInDatabase\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// biome-ignore lint/performance/noDelete: If the user has enabled secondaryStorage, as well as not specifying to store session table in DB, then createSchema shouldn't generate schema table.\n\t\t\t\t\t\t\tdelete tables.session;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn adapterInstance.createSchema!({ file, tables });\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\toptions: {\n\t\t\t\tadapterConfig: config,\n\t\t\t\t...(adapterInstance.options ?? {}),\n\t\t\t},\n\t\t\tid: config.adapterId,\n\n\t\t\t// Secretly export values ONLY if this adapter has enabled adapter-test-debug-logs.\n\t\t\t// This would then be used during our adapter-tests to help print debug logs if a test fails.\n\t\t\t//@ts-expect-error - ^^\n\t\t\t...(config.debugLogs?.isRunningAdapterTests\n\t\t\t\t? {\n\t\t\t\t\t\tadapterTestDebugLogs: {\n\t\t\t\t\t\t\tresetDebugLogs() {\n\t\t\t\t\t\t\t\tdebugLogs = debugLogs.filter(\n\t\t\t\t\t\t\t\t\t(log) => log.instance !== uniqueAdapterFactoryInstanceId,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tprintDebugLogs() {\n\t\t\t\t\t\t\t\tconst separator = `─`.repeat(80);\n\t\t\t\t\t\t\t\tconst logs = debugLogs.filter(\n\t\t\t\t\t\t\t\t\t(log) => log.instance === uniqueAdapterFactoryInstanceId,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (logs.length === 0) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t//`${colors.fg.blue}|${colors.reset} `,\n\t\t\t\t\t\t\t\tconst log: any[] = logs\n\t\t\t\t\t\t\t\t\t.reverse()\n\t\t\t\t\t\t\t\t\t.map((log) => {\n\t\t\t\t\t\t\t\t\t\tlog.args[0] = `\\n${log.args[0]}`;\n\t\t\t\t\t\t\t\t\t\treturn [...log.args, \"\\n\"];\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.reduce(\n\t\t\t\t\t\t\t\t\t\t(prev, curr) => {\n\t\t\t\t\t\t\t\t\t\t\treturn [...curr, ...prev];\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t[`\\n${separator}`],\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tconsole.log(...log);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies AdapterTestDebugLogs,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t\treturn adapter;\n\t};\n\nfunction formatTransactionId(transactionId: number) {\n\tif (getColorDepth() < 8) {\n\t\treturn `#${transactionId}`;\n\t}\n\treturn `${TTY_COLORS.fg.magenta}#${transactionId}${TTY_COLORS.reset}`;\n}\n\nfunction formatStep(step: number, total: number) {\n\treturn `${TTY_COLORS.bg.black}${TTY_COLORS.fg.yellow}[${step}/${total}]${TTY_COLORS.reset}`;\n}\n\nfunction formatMethod(method: string) {\n\treturn `${TTY_COLORS.bright}${method}${TTY_COLORS.reset}`;\n}\n\nfunction formatAction(action: string) {\n\treturn `${TTY_COLORS.dim}(${action})${TTY_COLORS.reset}`;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-default-field-name.mjs","names":[],"sources":["../../../src/db/adapter/get-default-field-name.ts"],"sourcesContent":["import { BetterAuthError } from \"../../error\";\nimport type { BetterAuthDBSchema } from \"../type\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\n\nexport const initGetDefaultFieldName = ({\n\tschema,\n\tusePlural,\n}: {\n\tschema: BetterAuthDBSchema;\n\tusePlural: boolean | undefined;\n}) => {\n\tconst getDefaultModelName = initGetDefaultModelName({\n\t\tschema,\n\t\tusePlural,\n\t});\n\n\t/**\n\t * This function helps us get the default field name from the schema defined by devs.\n\t * Often times, the user will be using the `fieldName` which could had been customized by the users.\n\t * This function helps us get the actual field name useful to match against the schema. (eg: schema[model].fields[field])\n\t *\n\t * If it's still unclear what this does:\n\t *\n\t * 1. User can define a custom fieldName.\n\t * 2. When using a custom fieldName, doing something like `schema[model].fields[field]` will not work.\n\t */\n\tconst getDefaultFieldName = ({\n\t\tfield,\n\t\tmodel: unsafeModel,\n\t}: {\n\t\tmodel: string;\n\t\tfield: string;\n\t}) => {\n\t\t// Plugin `schema`s can't define their own `id`. Better-auth auto provides `id` to every schema model.\n\t\t// Given this, we can't just check if the `field` (that being `id`) is within the schema's fields, since it is never defined.\n\t\t// So we check if the `field` is `id` and if so, we return `id` itself. Otherwise, we return the `field` from the schema.\n\t\tif (field === \"id\" || field === \"_id\") {\n\t\t\treturn \"id\";\n\t\t}\n\t\tconst model = getDefaultModelName(unsafeModel); // Just to make sure the model name is correct.\n\n\t\tlet f = schema[model]?.fields[field];\n\t\tif (!f) {\n\t\t\tconst result = Object.entries(schema[model]!.fields!).find(\n\t\t\t\t([_, f]) => f.fieldName === field,\n\t\t\t);\n\t\t\tif (result) {\n\t\t\t\tf = result[1];\n\t\t\t\tfield = result[0];\n\t\t\t}\n\t\t}\n\t\tif (!f) {\n\t\t\tthrow new BetterAuthError(`Field ${field} not found in model ${model}`);\n\t\t}\n\t\treturn field;\n\t};\n\n\treturn getDefaultFieldName;\n};\n"],"mappings":";;;;AAIA,MAAa,2BAA2B,EACvC,QACA,gBAIK;CACL,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;;;;;;;;;;;CAYF,MAAM,uBAAuB,EAC5B,OACA,OAAO,kBAIF;AAIL,MAAI,UAAU,QAAQ,UAAU,MAC/B,QAAO;EAER,MAAM,QAAQ,oBAAoB,YAAY;EAE9C,IAAI,IAAI,OAAO,QAAQ,OAAO;AAC9B,MAAI,CAAC,GAAG;GACP,MAAM,SAAS,OAAO,QAAQ,OAAO,OAAQ,OAAQ,CAAC,MACpD,CAAC,GAAG,OAAO,EAAE,cAAc,MAC5B;AACD,OAAI,QAAQ;AACX,QAAI,OAAO;AACX,YAAQ,OAAO;;;AAGjB,MAAI,CAAC,EACJ,OAAM,IAAI,gBAAgB,SAAS,MAAM,sBAAsB,QAAQ;AAExE,SAAO;;AAGR,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-default-model-name.mjs","names":[],"sources":["../../../src/db/adapter/get-default-model-name.ts"],"sourcesContent":["import { BetterAuthError } from \"../../error\";\nimport type { BetterAuthDBSchema } from \"../type\";\n\nexport const initGetDefaultModelName = ({\n\tusePlural,\n\tschema,\n}: {\n\tusePlural: boolean | undefined;\n\tschema: BetterAuthDBSchema;\n}) => {\n\t/**\n\t * This function helps us get the default model name from the schema defined by devs.\n\t * Often times, the user will be using the `modelName` which could had been customized by the users.\n\t * This function helps us get the actual model name useful to match against the schema. (eg: schema[model])\n\t *\n\t * If it's still unclear what this does:\n\t *\n\t * 1. User can define a custom modelName.\n\t * 2. When using a custom modelName, doing something like `schema[model]` will not work.\n\t * 3. Using this function helps us get the actual model name based on the user's defined custom modelName.\n\t */\n\tconst getDefaultModelName = (model: string) => {\n\t\t// It's possible this `model` could had applied `usePlural`.\n\t\t// Thus we'll try the search but without the trailing `s`.\n\t\tif (usePlural && model.charAt(model.length - 1) === \"s\") {\n\t\t\tconst pluralessModel = model.slice(0, -1);\n\t\t\tlet m = schema[pluralessModel] ? pluralessModel : undefined;\n\t\t\tif (!m) {\n\t\t\t\tm = Object.entries(schema).find(\n\t\t\t\t\t([_, f]) => f.modelName === pluralessModel,\n\t\t\t\t)?.[0];\n\t\t\t}\n\n\t\t\tif (m) {\n\t\t\t\treturn m;\n\t\t\t}\n\t\t}\n\n\t\tlet m = schema[model] ? model : undefined;\n\t\tif (!m) {\n\t\t\tm = Object.entries(schema).find(([_, f]) => f.modelName === model)?.[0];\n\t\t}\n\n\t\tif (!m) {\n\t\t\tthrow new BetterAuthError(`Model \"${model}\" not found in schema`);\n\t\t}\n\t\treturn m;\n\t};\n\n\treturn getDefaultModelName;\n};\n"],"mappings":";;;AAGA,MAAa,2BAA2B,EACvC,WACA,aAIK;;;;;;;;;;;;CAYL,MAAM,uBAAuB,UAAkB;AAG9C,MAAI,aAAa,MAAM,OAAO,MAAM,SAAS,EAAE,KAAK,KAAK;GACxD,MAAM,iBAAiB,MAAM,MAAM,GAAG,GAAG;GACzC,IAAI,IAAI,OAAO,kBAAkB,iBAAiB;AAClD,OAAI,CAAC,EACJ,KAAI,OAAO,QAAQ,OAAO,CAAC,MACzB,CAAC,GAAG,OAAO,EAAE,cAAc,eAC5B,GAAG;AAGL,OAAI,EACH,QAAO;;EAIT,IAAI,IAAI,OAAO,SAAS,QAAQ;AAChC,MAAI,CAAC,EACJ,KAAI,OAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,EAAE,cAAc,MAAM,GAAG;AAGtE,MAAI,CAAC,EACJ,OAAM,IAAI,gBAAgB,UAAU,MAAM,uBAAuB;AAElE,SAAO;;AAGR,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-field-attributes.mjs","names":[],"sources":["../../../src/db/adapter/get-field-attributes.ts"],"sourcesContent":["import { BetterAuthError } from \"../../error\";\nimport type { BetterAuthOptions } from \"../../types\";\nimport type { BetterAuthDBSchema } from \"../type\";\nimport { initGetDefaultFieldName } from \"./get-default-field-name\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\nimport { initGetIdField } from \"./get-id-field\";\n\nexport const initGetFieldAttributes = ({\n\tusePlural,\n\tschema,\n\toptions,\n\tcustomIdGenerator,\n\tdisableIdGeneration,\n}: {\n\tusePlural?: boolean;\n\tschema: BetterAuthDBSchema;\n\toptions: BetterAuthOptions;\n\tdisableIdGeneration?: boolean;\n\tcustomIdGenerator?: ((props: { model: string }) => string) | undefined;\n}) => {\n\tconst getDefaultModelName = initGetDefaultModelName({\n\t\tusePlural,\n\t\tschema,\n\t});\n\n\tconst getDefaultFieldName = initGetDefaultFieldName({\n\t\tusePlural,\n\t\tschema,\n\t});\n\n\tconst idField = initGetIdField({\n\t\tusePlural,\n\t\tschema,\n\t\toptions,\n\t\tcustomIdGenerator,\n\t\tdisableIdGeneration,\n\t});\n\n\tconst getFieldAttributes = ({\n\t\tmodel,\n\t\tfield,\n\t}: {\n\t\tmodel: string;\n\t\tfield: string;\n\t}) => {\n\t\tconst defaultModelName = getDefaultModelName(model);\n\t\tconst defaultFieldName = getDefaultFieldName({\n\t\t\tfield: field,\n\t\t\tmodel: defaultModelName,\n\t\t});\n\n\t\tconst fields = schema[defaultModelName]!.fields;\n\t\tfields.id = idField({ customModelName: defaultModelName });\n\t\tconst fieldAttributes = fields[defaultFieldName];\n\t\tif (!fieldAttributes) {\n\t\t\tthrow new BetterAuthError(`Field ${field} not found in model ${model}`);\n\t\t}\n\t\treturn fieldAttributes;\n\t};\n\n\treturn getFieldAttributes;\n};\n"],"mappings":";;;;;;AAOA,MAAa,0BAA0B,EACtC,WACA,QACA,SACA,mBACA,0BAOK;CACL,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;CAEF,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;CAEF,MAAM,UAAU,eAAe;EAC9B;EACA;EACA;EACA;EACA;EACA,CAAC;CAEF,MAAM,sBAAsB,EAC3B,OACA,YAIK;EACL,MAAM,mBAAmB,oBAAoB,MAAM;EACnD,MAAM,mBAAmB,oBAAoB;GACrC;GACP,OAAO;GACP,CAAC;EAEF,MAAM,SAAS,OAAO,kBAAmB;AACzC,SAAO,KAAK,QAAQ,EAAE,iBAAiB,kBAAkB,CAAC;EAC1D,MAAM,kBAAkB,OAAO;AAC/B,MAAI,CAAC,gBACJ,OAAM,IAAI,gBAAgB,SAAS,MAAM,sBAAsB,QAAQ;AAExE,SAAO;;AAGR,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-field-name.mjs","names":[],"sources":["../../../src/db/adapter/get-field-name.ts"],"sourcesContent":["import type { BetterAuthDBSchema } from \"../type\";\nimport { initGetDefaultFieldName } from \"./get-default-field-name\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\n\nexport const initGetFieldName = ({\n\tschema,\n\tusePlural,\n}: {\n\tschema: BetterAuthDBSchema;\n\tusePlural: boolean | undefined;\n}) => {\n\tconst getDefaultModelName = initGetDefaultModelName({\n\t\tschema,\n\t\tusePlural,\n\t});\n\n\tconst getDefaultFieldName = initGetDefaultFieldName({\n\t\tschema,\n\t\tusePlural,\n\t});\n\n\t/**\n\t * Get the field name which is expected to be saved in the database based on the user's schema.\n\t *\n\t * This function is useful if you need to save the field name to the database.\n\t *\n\t * For example, if the user has defined a custom field name for the `user` model, then you can use this function to get the actual field name from the schema.\n\t */\n\tfunction getFieldName({\n\t\tmodel: modelName,\n\t\tfield: fieldName,\n\t}: {\n\t\tmodel: string;\n\t\tfield: string;\n\t}) {\n\t\tconst model = getDefaultModelName(modelName);\n\t\tconst field = getDefaultFieldName({ model, field: fieldName });\n\n\t\treturn schema[model]?.fields[field]?.fieldName || field;\n\t}\n\n\treturn getFieldName;\n};\n"],"mappings":";;;;AAIA,MAAa,oBAAoB,EAChC,QACA,gBAIK;CACL,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;CAEF,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;;;;;;;;CASF,SAAS,aAAa,EACrB,OAAO,WACP,OAAO,aAIL;EACF,MAAM,QAAQ,oBAAoB,UAAU;EAC5C,MAAM,QAAQ,oBAAoB;GAAE;GAAO,OAAO;GAAW,CAAC;AAE9D,SAAO,OAAO,QAAQ,OAAO,QAAQ,aAAa;;AAGnD,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-id-field.mjs","names":["generateId","defaultGenerateId"],"sources":["../../../src/db/adapter/get-id-field.ts"],"sourcesContent":["import { logger } from \"../../env\";\nimport type { BetterAuthOptions } from \"../../types\";\nimport { generateId as defaultGenerateId } from \"../../utils/id\";\nimport type { BetterAuthDBSchema, DBFieldAttribute } from \"../type\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\n\nexport const initGetIdField = ({\n\tusePlural,\n\tschema,\n\tdisableIdGeneration,\n\toptions,\n\tcustomIdGenerator,\n\tsupportsUUIDs,\n}: {\n\tusePlural?: boolean;\n\tschema: BetterAuthDBSchema;\n\toptions: BetterAuthOptions;\n\tdisableIdGeneration?: boolean;\n\tcustomIdGenerator?: ((props: { model: string }) => string) | undefined;\n\tsupportsUUIDs?: boolean;\n}) => {\n\tconst getDefaultModelName = initGetDefaultModelName({\n\t\tusePlural: usePlural,\n\t\tschema,\n\t});\n\n\tconst idField = ({\n\t\tcustomModelName,\n\t\tforceAllowId,\n\t}: {\n\t\tcustomModelName?: string;\n\t\tforceAllowId?: boolean;\n\t}) => {\n\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\t\tconst shouldGenerateId: boolean = (() => {\n\t\t\tif (disableIdGeneration) {\n\t\t\t\treturn false;\n\t\t\t} else if (useNumberId && !forceAllowId) {\n\t\t\t\t// if force allow is true, then we should be using their custom provided id.\n\t\t\t\treturn false;\n\t\t\t} else if (useUUIDs) {\n\t\t\t\t// should only generate UUIDs via JS if the database doesn't support natively generating UUIDs.\n\t\t\t\treturn !supportsUUIDs;\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t})();\n\n\t\tconst model = getDefaultModelName(customModelName ?? \"id\");\n\t\treturn {\n\t\t\ttype: useNumberId ? \"number\" : \"string\",\n\t\t\trequired: shouldGenerateId ? true : false,\n\t\t\t...(shouldGenerateId\n\t\t\t\t? {\n\t\t\t\t\t\tdefaultValue() {\n\t\t\t\t\t\t\tif (disableIdGeneration) return undefined;\n\t\t\t\t\t\t\tconst generateId = options.advanced?.database?.generateId;\n\n\t\t\t\t\t\t\t// let the database handle id generation\n\t\t\t\t\t\t\tif (generateId === false || generateId === \"serial\")\n\t\t\t\t\t\t\t\treturn undefined;\n\n\t\t\t\t\t\t\t// user-provided function takes highest priority\n\t\t\t\t\t\t\tif (typeof generateId === \"function\") {\n\t\t\t\t\t\t\t\treturn generateId({\n\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// user-provided \"uuid\" option\n\t\t\t\t\t\t\tif (generateId === \"uuid\") {\n\t\t\t\t\t\t\t\treturn crypto.randomUUID();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// database adapter-level custom id generator\n\t\t\t\t\t\t\tif (customIdGenerator) {\n\t\t\t\t\t\t\t\treturn customIdGenerator({ model });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// fallback to default id generation\n\t\t\t\t\t\t\treturn defaultGenerateId();\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\ttransform: {\n\t\t\t\tinput: (value) => {\n\t\t\t\t\t// Uncomment if need to debug id transformation\n\t\t\t\t\t// console.log(`transforming id: `, {\n\t\t\t\t\t// \tid: value,\n\t\t\t\t\t// \t...(useNumberId ? { useNumberId } : {}),\n\t\t\t\t\t// \t...(useUUIDs ? { useUUIDs } : {}),\n\t\t\t\t\t// \t...(forceAllowId ? { forceAllowId } : {}),\n\t\t\t\t\t// });\n\t\t\t\t\tif (!value) return undefined;\n\n\t\t\t\t\tif (useNumberId) {\n\t\t\t\t\t\tconst numberValue = Number(value);\n\t\t\t\t\t\t// if invalid number, fallback to DB generated number id.\n\t\t\t\t\t\tif (isNaN(numberValue)) {\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn numberValue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (useUUIDs) {\n\t\t\t\t\t\t// if it's generated by us, then we should return the value as is.\n\t\t\t\t\t\tif (shouldGenerateId && !forceAllowId) return value;\n\t\t\t\t\t\tif (disableIdGeneration) return undefined;\n\t\t\t\t\t\t// if DB will handle UUID generation, then we should return undefined.\n\t\t\t\t\t\tif (supportsUUIDs) return undefined;\n\t\t\t\t\t\t// if forceAllowId is true, it means we should be using the ID provided during the adapter call.\n\t\t\t\t\t\tif (forceAllowId && typeof value === \"string\") {\n\t\t\t\t\t\t\tconst uuidRegex =\n\t\t\t\t\t\t\t\t/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\t\t\t\t\t\t\tif (uuidRegex.test(value)) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst err = new Error();\n\t\t\t\t\t\t\t\tconst stack = err.stack\n\t\t\t\t\t\t\t\t\t?.split(\"\\n\")\n\t\t\t\t\t\t\t\t\t.filter((_, i) => i !== 1)\n\t\t\t\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t\t\t\t\t.replace(\"Error:\", \"\");\n\t\t\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t\t\t\"[Adapter Factory] - Invalid UUID value for field `id` provided when `forceAllowId` is true. Generating a new UUID.\",\n\t\t\t\t\t\t\t\t\tstack,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if the value is not a string, and the database doesn't support generating it's own UUIDs, then we should be generating the UUID.\n\t\t\t\t\t\tif (typeof value !== \"string\" && !supportsUUIDs) {\n\t\t\t\t\t\t\treturn crypto.randomUUID();\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t\toutput: (value) => {\n\t\t\t\t\tif (!value) return undefined;\n\t\t\t\t\treturn String(value);\n\t\t\t\t},\n\t\t\t},\n\t\t} satisfies DBFieldAttribute;\n\t};\n\n\treturn idField;\n};\n"],"mappings":";;;;;;AAMA,MAAa,kBAAkB,EAC9B,WACA,QACA,qBACA,SACA,mBACA,oBAQK;CACL,MAAM,sBAAsB,wBAAwB;EACxC;EACX;EACA,CAAC;CAEF,MAAM,WAAW,EAChB,iBACA,mBAIK;EACL,MAAM,cAAc,QAAQ,UAAU,UAAU,eAAe;EAC/D,MAAM,WAAW,QAAQ,UAAU,UAAU,eAAe;EAE5D,MAAM,0BAAmC;AACxC,OAAI,oBACH,QAAO;YACG,eAAe,CAAC,aAE1B,QAAO;YACG,SAEV,QAAO,CAAC;OAER,QAAO;MAEL;EAEJ,MAAM,QAAQ,oBAAoB,mBAAmB,KAAK;AAC1D,SAAO;GACN,MAAM,cAAc,WAAW;GAC/B,UAAU,mBAAmB,OAAO;GACpC,GAAI,mBACD,EACA,eAAe;AACd,QAAI,oBAAqB,QAAO;IAChC,MAAMA,eAAa,QAAQ,UAAU,UAAU;AAG/C,QAAIA,iBAAe,SAASA,iBAAe,SAC1C,QAAO;AAGR,QAAI,OAAOA,iBAAe,WACzB,QAAOA,aAAW,EACjB,OACA,CAAC;AAIH,QAAIA,iBAAe,OAClB,QAAO,OAAO,YAAY;AAI3B,QAAI,kBACH,QAAO,kBAAkB,EAAE,OAAO,CAAC;AAIpC,WAAOC,YAAmB;MAE3B,GACA,EAAE;GACL,WAAW;IACV,QAAQ,UAAU;AAQjB,SAAI,CAAC,MAAO,QAAO;AAEnB,SAAI,aAAa;MAChB,MAAM,cAAc,OAAO,MAAM;AAEjC,UAAI,MAAM,YAAY,CACrB;AAED,aAAO;;AAGR,SAAI,UAAU;AAEb,UAAI,oBAAoB,CAAC,aAAc,QAAO;AAC9C,UAAI,oBAAqB,QAAO;AAEhC,UAAI,cAAe,QAAO;AAE1B,UAAI,gBAAgB,OAAO,UAAU,SAGpC,KADC,6EACa,KAAK,MAAM,CACxB,QAAO;WACD;OAEN,MAAM,yBADM,IAAI,OAAO,EACL,OACf,MAAM,KAAK,CACZ,QAAQ,GAAG,MAAM,MAAM,EAAE,CACzB,KAAK,KAAK,CACV,QAAQ,UAAU,GAAG;AACvB,cAAO,KACN,sHACA,MACA;;AAIH,UAAI,OAAO,UAAU,YAAY,CAAC,cACjC,QAAO,OAAO,YAAY;AAE3B;;AAGD,YAAO;;IAER,SAAS,UAAU;AAClB,SAAI,CAAC,MAAO,QAAO;AACnB,YAAO,OAAO,MAAM;;IAErB;GACD;;AAGF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-model-name.mjs","names":[],"sources":["../../../src/db/adapter/get-model-name.ts"],"sourcesContent":["import type { BetterAuthDBSchema } from \"../type\";\nimport { initGetDefaultModelName } from \"./get-default-model-name\";\n\nexport const initGetModelName = ({\n\tusePlural,\n\tschema,\n}: {\n\tusePlural: boolean | undefined;\n\tschema: BetterAuthDBSchema;\n}) => {\n\tconst getDefaultModelName = initGetDefaultModelName({\n\t\tschema,\n\t\tusePlural,\n\t});\n\t/**\n\t * Users can overwrite the default model of some tables. This function helps find the correct model name.\n\t * Furthermore, if the user passes `usePlural` as true in their adapter config,\n\t * then we should return the model name ending with an `s`.\n\t */\n\tconst getModelName = (model: string) => {\n\t\tconst defaultModelKey = getDefaultModelName(model);\n\t\tconst useCustomModelName =\n\t\t\tschema &&\n\t\t\tschema[defaultModelKey] &&\n\t\t\tschema[defaultModelKey].modelName !== model;\n\n\t\tif (useCustomModelName) {\n\t\t\treturn usePlural\n\t\t\t\t? `${schema[defaultModelKey]!.modelName}s`\n\t\t\t\t: schema[defaultModelKey]!.modelName;\n\t\t}\n\n\t\treturn usePlural ? `${model}s` : model;\n\t};\n\treturn getModelName;\n};\n"],"mappings":";;;AAGA,MAAa,oBAAoB,EAChC,WACA,aAIK;CACL,MAAM,sBAAsB,wBAAwB;EACnD;EACA;EACA,CAAC;;;;;;CAMF,MAAM,gBAAgB,UAAkB;EACvC,MAAM,kBAAkB,oBAAoB,MAAM;AAMlD,MAJC,UACA,OAAO,oBACP,OAAO,iBAAiB,cAAc,MAGtC,QAAO,YACJ,GAAG,OAAO,iBAAkB,UAAU,KACtC,OAAO,iBAAkB;AAG7B,SAAO,YAAY,GAAG,MAAM,KAAK;;AAElC,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/db/adapter/index.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"../../types\";\nimport type { BetterAuthDBSchema, DBFieldAttribute } from \"../type\";\n\nexport type DBAdapterDebugLogOption =\n\t| boolean\n\t| {\n\t\t\t/**\n\t\t\t * Useful when you want to log only certain conditions.\n\t\t\t */\n\t\t\tlogCondition?: (() => boolean) | undefined;\n\t\t\tcreate?: boolean | undefined;\n\t\t\tupdate?: boolean | undefined;\n\t\t\tupdateMany?: boolean | undefined;\n\t\t\tfindOne?: boolean | undefined;\n\t\t\tfindMany?: boolean | undefined;\n\t\t\tdelete?: boolean | undefined;\n\t\t\tdeleteMany?: boolean | undefined;\n\t\t\tcount?: boolean | undefined;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Only used for adapter tests to show debug logs if a test fails.\n\t\t\t *\n\t\t\t * @deprecated Not actually deprecated. Doing this for IDEs to show this option at the very bottom and stop end-users from using this.\n\t\t\t */\n\t\t\tisRunningAdapterTests: boolean;\n\t };\n\nexport type DBAdapterSchemaCreation = {\n\t/**\n\t * Code to be inserted into the file\n\t */\n\tcode: string;\n\t/**\n\t * Path to the file, including the file name and extension.\n\t * Relative paths are supported, with the current working directory of the developer's project as the base.\n\t */\n\tpath: string;\n\t/**\n\t * Append the file if it already exists.\n\t * Note: This will not apply if `overwrite` is set to true.\n\t */\n\tappend?: boolean | undefined;\n\t/**\n\t * Overwrite the file if it already exists\n\t */\n\toverwrite?: boolean | undefined;\n};\n\nexport interface DBAdapterFactoryConfig<\n\tOptions extends BetterAuthOptions = BetterAuthOptions,\n> {\n\t/**\n\t * Use plural table names.\n\t *\n\t * All tables will be named with an `s` at the end.\n\t *\n\t * @default false\n\t */\n\tusePlural?: boolean | undefined;\n\t/**\n\t * Enable debug logs.\n\t *\n\t * @default false\n\t */\n\tdebugLogs?: DBAdapterDebugLogOption | undefined;\n\t/**\n\t * Name of the adapter.\n\t *\n\t * This is used to identify the adapter in the debug logs.\n\t *\n\t * @default `adapterId`\n\t */\n\tadapterName?: string | undefined;\n\t/**\n\t * Adapter id\n\t */\n\tadapterId: string;\n\t/**\n\t * If the database supports numeric ids, set this to `true`.\n\t *\n\t * @default true\n\t */\n\tsupportsNumericIds?: boolean | undefined;\n\t/**\n\t * If the database supports natively generating UUIDs, set this to `true`.\n\t *\n\t * @default false\n\t */\n\tsupportsUUIDs?: boolean | undefined;\n\t/**\n\t * If the database doesn't support JSON columns, set this to `false`.\n\t *\n\t * We will handle the translation between using `JSON` columns, and saving `string`s to the database.\n\t *\n\t * @default false\n\t */\n\tsupportsJSON?: boolean | undefined;\n\t/**\n\t * If the database doesn't support dates, set this to `false`.\n\t *\n\t * We will handle the translation between using `Date` objects, and saving `string`s to the database.\n\t *\n\t * @default true\n\t */\n\tsupportsDates?: boolean | undefined;\n\t/**\n\t * If the database doesn't support booleans, set this to `false`.\n\t *\n\t * We will handle the translation between using `boolean`s, and saving `0`s and `1`s to the database.\n\t *\n\t * @default true\n\t */\n\tsupportsBooleans?: boolean | undefined;\n\t/**\n\t * If the database doesn't support arrays, set this to `false`.\n\t *\n\t * We will handle the translation between using `array`s, and saving `string`s to the database.\n\t *\n\t * @default false\n\t */\n\tsupportsArrays?: boolean | undefined;\n\t/**\n\t * Execute multiple operations in a transaction.\n\t *\n\t * If the database doesn't support transactions, set this to `false` and operations will be executed sequentially.\n\t *\n\t * @default false\n\t */\n\ttransaction?:\n\t\t| (\n\t\t\t\t| false\n\t\t\t\t| (<R>(\n\t\t\t\t\t\tcallback: (trx: DBTransactionAdapter<Options>) => Promise<R>,\n\t\t\t\t ) => Promise<R>)\n\t\t )\n\t\t| undefined;\n\t/**\n\t * Disable id generation for the `create` method.\n\t *\n\t * This is useful for databases that don't support custom id values and would auto-generate them for you.\n\t *\n\t * @default false\n\t */\n\tdisableIdGeneration?: boolean | undefined;\n\t/**\n\t * Map the keys of the input data.\n\t *\n\t * This is useful for databases that expect a different key name for a given situation.\n\t *\n\t * For example, MongoDB uses `_id` while in Better-Auth we use `id`.\n\t *\n\t *\n\t * @example\n\t * Each key represents the old key to replace.\n\t * The value represents the new key\n\t *\n\t * This can be a partial object that only transforms some keys.\n\t *\n\t * ```ts\n\t * mapKeysTransformInput: {\n\t * id: \"_id\" // We want to replace `id` to `_id` to save into MongoDB\n\t * }\n\t * ```\n\t */\n\tmapKeysTransformInput?: Record<string, string> | undefined;\n\t/**\n\t * Map the keys of the output data.\n\t *\n\t * This is useful for databases that expect a different key name for a given situation.\n\t *\n\t * For example, MongoDB uses `_id` while in Better-Auth we use `id`.\n\t *\n\t * @example\n\t * Each key represents the old key to replace.\n\t * The value represents the new key\n\t *\n\t * This can be a partial object that only transforms some keys.\n\t *\n\t * ```ts\n\t * mapKeysTransformOutput: {\n\t * _id: \"id\" // In MongoDB, we save `id` as `_id`. So we want to replace `_id` with `id` when we get the data back.\n\t * }\n\t * ```\n\t */\n\tmapKeysTransformOutput?: Record<string, string> | undefined;\n\t/**\n\t * Custom transform input function.\n\t *\n\t * This function is used to transform the input data before it is saved to the database.\n\t */\n\tcustomTransformInput?:\n\t\t| ((props: {\n\t\t\t\tdata: any;\n\t\t\t\t/**\n\t\t\t\t * The fields of the model.\n\t\t\t\t */\n\t\t\t\tfieldAttributes: DBFieldAttribute;\n\t\t\t\t/**\n\t\t\t\t * The field to transform.\n\t\t\t\t */\n\t\t\t\tfield: string;\n\t\t\t\t/**\n\t\t\t\t * The action which was called from the adapter.\n\t\t\t\t */\n\t\t\t\taction:\n\t\t\t\t\t| \"create\"\n\t\t\t\t\t| \"update\"\n\t\t\t\t\t| \"findOne\"\n\t\t\t\t\t| \"findMany\"\n\t\t\t\t\t| \"updateMany\"\n\t\t\t\t\t| \"delete\"\n\t\t\t\t\t| \"deleteMany\"\n\t\t\t\t\t| \"count\";\n\t\t\t\t/**\n\t\t\t\t * The model name.\n\t\t\t\t */\n\t\t\t\tmodel: string;\n\t\t\t\t/**\n\t\t\t\t * The schema of the user's Better-Auth instance.\n\t\t\t\t */\n\t\t\t\tschema: BetterAuthDBSchema;\n\t\t\t\t/**\n\t\t\t\t * The options of the user's Better-Auth instance.\n\t\t\t\t */\n\t\t\t\toptions: Options;\n\t\t }) => any)\n\t\t| undefined;\n\t/**\n\t * Custom transform output function.\n\t *\n\t * This function is used to transform the output data before it is returned to the user.\n\t */\n\tcustomTransformOutput?:\n\t\t| ((props: {\n\t\t\t\tdata: any;\n\t\t\t\t/**\n\t\t\t\t * The fields of the model.\n\t\t\t\t */\n\t\t\t\tfieldAttributes: DBFieldAttribute;\n\t\t\t\t/**\n\t\t\t\t * The field to transform.\n\t\t\t\t */\n\t\t\t\tfield: string;\n\t\t\t\t/**\n\t\t\t\t * The fields to select.\n\t\t\t\t */\n\t\t\t\tselect: string[];\n\t\t\t\t/**\n\t\t\t\t * The model name.\n\t\t\t\t */\n\t\t\t\tmodel: string;\n\t\t\t\t/**\n\t\t\t\t * The schema of the user's Better-Auth instance.\n\t\t\t\t */\n\t\t\t\tschema: BetterAuthDBSchema;\n\t\t\t\t/**\n\t\t\t\t * The options of the user's Better-Auth instance.\n\t\t\t\t */\n\t\t\t\toptions: Options;\n\t\t }) => any)\n\t\t| undefined;\n\t/**\n\t * Custom ID generator function.\n\t *\n\t * By default, we can handle ID generation for you, however if the database your adapter is for only supports a specific custom id generation,\n\t * then you can use this function to generate your own IDs.\n\t *\n\t *\n\t * Notes:\n\t * - If the user enabled `useNumberId` or `generateId` set to `serial`, then this option will be ignored. Unless this adapter config has `supportsNumericIds` set to `false`.\n\t * - If `generateId` is `false` in the user's Better-Auth config, then this option will be ignored.\n\t * - If `generateId` is a function, then it will override this option.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * customIdGenerator: ({ model }) => {\n\t * return \"my-super-unique-id\";\n\t * }\n\t * ```\n\t */\n\tcustomIdGenerator?: ((props: { model: string }) => string) | undefined;\n\t/**\n\t * Whether to disable the transform output.\n\t * Do not use this option unless you know what you are doing.\n\t * @default false\n\t */\n\tdisableTransformOutput?: boolean | undefined;\n\t/**\n\t * Whether to disable the transform input.\n\t * Do not use this option unless you know what you are doing.\n\t * @default false\n\t */\n\tdisableTransformInput?: boolean | undefined;\n\t/**\n\t * Whether to disable the transform join.\n\t * Do not use this option unless you know what you are doing.\n\t * @default false\n\t */\n\tdisableTransformJoin?: boolean | undefined;\n}\n\nexport const whereOperators = [\n\t\"eq\",\n\t\"ne\",\n\t\"lt\",\n\t\"lte\",\n\t\"gt\",\n\t\"gte\",\n\t\"in\",\n\t\"not_in\",\n\t\"contains\",\n\t\"starts_with\",\n\t\"ends_with\",\n] as const;\n\nexport type WhereOperator = (typeof whereOperators)[number];\n\nexport type Where = {\n\t/**\n\t * @default eq\n\t */\n\toperator?: WhereOperator | undefined;\n\tvalue: string | number | boolean | string[] | number[] | Date | null;\n\tfield: string;\n\t/**\n\t * @default AND\n\t */\n\tconnector?: (\"AND\" | \"OR\") | undefined;\n};\n\n/**\n * JoinOption configuration for relational queries.\n *\n * Allows you to join related tables/models in a single query operation.\n * Each key represents the name of the joined table/model, and the value\n * configures how the join should be performed.\n */\nexport type JoinOption = {\n\t[model: string]: boolean | { limit?: number };\n};\n\n/**\n * Once `JoinOption` has gone through the adapter factory, it will be transformed into a `JoinConfig`.\n */\nexport type JoinConfig = {\n\t[model: string]: {\n\t\t/**\n\t\t * The joining column names.\n\t\t */\n\t\ton: {\n\t\t\t/**\n\t\t\t * Column name from the main table\n\t\t\t */\n\t\t\tfrom: string;\n\t\t\t/**\n\t\t\t * Column name from the joined table\n\t\t\t */\n\t\t\tto: string;\n\t\t};\n\t\t/**\n\t\t * Limit the number of rows to return.\n\t\t *\n\t\t * If the relation has `unique` constraint, then this option will be ignored and limit will be set to 1.\n\t\t *\n\t\t * @default 100\n\t\t */\n\t\tlimit?: number;\n\t\t/**\n\t\t * The relation type. Determines the output joined model data.\n\t\t *\n\t\t * `one-to-one` would have a single object in the output.\n\t\t * `one-to-many` would have an array of objects in the output.\n\t\t * `many-to-many` would have an array of objects in the output.\n\t\t *\n\t\t * @default \"one-to-many\"\n\t\t */\n\t\trelation?: \"one-to-one\" | \"one-to-many\" | \"many-to-many\";\n\t};\n};\n\nexport type DBTransactionAdapter<\n\tOptions extends BetterAuthOptions = BetterAuthOptions,\n> = Omit<DBAdapter<Options>, \"transaction\">;\n\nexport type DBAdapter<Options extends BetterAuthOptions = BetterAuthOptions> = {\n\tid: string;\n\tcreate: <T extends Record<string, any>, R = T>(data: {\n\t\tmodel: string;\n\t\tdata: Omit<T, \"id\">;\n\t\tselect?: string[] | undefined;\n\t\t/**\n\t\t * By default, any `id` provided in `data` will be ignored.\n\t\t *\n\t\t * If you want to force the `id` to be the same as the `data.id`, set this to `true`.\n\t\t */\n\t\tforceAllowId?: boolean | undefined;\n\t}) => Promise<R>;\n\tfindOne: <T>(data: {\n\t\tmodel: string;\n\t\twhere: Where[];\n\t\tselect?: string[] | undefined;\n\t\tjoin?: JoinOption | undefined;\n\t}) => Promise<T | null>;\n\tfindMany: <T>(data: {\n\t\tmodel: string;\n\t\twhere?: Where[] | undefined;\n\t\tlimit?: number | undefined;\n\t\tselect?: string[] | undefined;\n\t\tsortBy?:\n\t\t\t| {\n\t\t\t\t\tfield: string;\n\t\t\t\t\tdirection: \"asc\" | \"desc\";\n\t\t\t }\n\t\t\t| undefined;\n\t\toffset?: number | undefined;\n\t\tjoin?: JoinOption | undefined;\n\t}) => Promise<T[]>;\n\tcount: (data: {\n\t\tmodel: string;\n\t\twhere?: Where[] | undefined;\n\t}) => Promise<number>;\n\t/**\n\t * ⚠︎ Update may not return the updated data\n\t * if multiple where clauses are provided\n\t */\n\tupdate: <T>(data: {\n\t\tmodel: string;\n\t\twhere: Where[];\n\t\tupdate: Record<string, any>;\n\t}) => Promise<T | null>;\n\tupdateMany: (data: {\n\t\tmodel: string;\n\t\twhere: Where[];\n\t\tupdate: Record<string, any>;\n\t}) => Promise<number>;\n\tdelete: <_T>(data: { model: string; where: Where[] }) => Promise<void>;\n\tdeleteMany: (data: { model: string; where: Where[] }) => Promise<number>;\n\t/**\n\t * Execute multiple operations in a transaction.\n\t * If the adapter doesn't support transactions, operations will be executed sequentially.\n\t */\n\ttransaction: <R>(\n\t\tcallback: (trx: DBTransactionAdapter<Options>) => Promise<R>,\n\t) => Promise<R>;\n\t/**\n\t *\n\t * @param options\n\t * @param file - file path if provided by the user\n\t */\n\tcreateSchema?:\n\t\t| ((options: Options, file?: string) => Promise<DBAdapterSchemaCreation>)\n\t\t| undefined;\n\toptions?:\n\t\t| ({\n\t\t\t\tadapterConfig: DBAdapterFactoryConfig<Options>;\n\t\t } & CustomAdapter[\"options\"])\n\t\t| undefined;\n};\n\nexport type CleanedWhere = Required<Where>;\n\nexport interface CustomAdapter {\n\tcreate: <T extends Record<string, any>>({\n\t\tdata,\n\t\tmodel,\n\t\tselect,\n\t}: {\n\t\tmodel: string;\n\t\tdata: T;\n\t\tselect?: string[] | undefined;\n\t}) => Promise<T>;\n\tupdate: <T>(data: {\n\t\tmodel: string;\n\t\twhere: CleanedWhere[];\n\t\tupdate: T;\n\t}) => Promise<T | null>;\n\tupdateMany: (data: {\n\t\tmodel: string;\n\t\twhere: CleanedWhere[];\n\t\tupdate: Record<string, any>;\n\t}) => Promise<number>;\n\tfindOne: <T>({\n\t\tmodel,\n\t\twhere,\n\t\tselect,\n\t\tjoin,\n\t}: {\n\t\tmodel: string;\n\t\twhere: CleanedWhere[];\n\t\tselect?: string[] | undefined;\n\t\tjoin?: JoinConfig | undefined;\n\t}) => Promise<T | null>;\n\tfindMany: <T>({\n\t\tmodel,\n\t\twhere,\n\t\tlimit,\n\t\tselect,\n\t\tsortBy,\n\t\toffset,\n\t\tjoin,\n\t}: {\n\t\tmodel: string;\n\t\twhere?: CleanedWhere[] | undefined;\n\t\tlimit: number;\n\t\tselect?: string[] | undefined;\n\t\tsortBy?: { field: string; direction: \"asc\" | \"desc\" } | undefined;\n\t\toffset?: number | undefined;\n\t\tjoin?: JoinConfig | undefined;\n\t}) => Promise<T[]>;\n\tdelete: ({\n\t\tmodel,\n\t\twhere,\n\t}: {\n\t\tmodel: string;\n\t\twhere: CleanedWhere[];\n\t}) => Promise<void>;\n\tdeleteMany: ({\n\t\tmodel,\n\t\twhere,\n\t}: {\n\t\tmodel: string;\n\t\twhere: CleanedWhere[];\n\t}) => Promise<number>;\n\tcount: ({\n\t\tmodel,\n\t\twhere,\n\t}: {\n\t\tmodel: string;\n\t\twhere?: CleanedWhere[] | undefined;\n\t}) => Promise<number>;\n\tcreateSchema?:\n\t\t| ((props: {\n\t\t\t\t/**\n\t\t\t\t * The file the user may have passed in to the `generate` command as the expected schema file output path.\n\t\t\t\t */\n\t\t\t\tfile?: string;\n\t\t\t\t/**\n\t\t\t\t * The tables from the user's Better-Auth instance schema.\n\t\t\t\t */\n\t\t\t\ttables: BetterAuthDBSchema;\n\t\t }) => Promise<DBAdapterSchemaCreation>)\n\t\t| undefined;\n\t/**\n\t * Your adapter's options.\n\t */\n\toptions?: Record<string, any> | undefined;\n}\n\nexport interface DBAdapterInstance<\n\tOptions extends BetterAuthOptions = BetterAuthOptions,\n> {\n\t(options: BetterAuthOptions): DBAdapter<Options>;\n}\n\nexport * from \"./factory\";\nexport * from \"./types\";\nexport * from \"./utils\";\n"],"mappings":";;;;;;;;;;AA+SA,MAAa,iBAAiB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/db/adapter/utils.ts"],"sourcesContent":["import type { DBFieldAttribute } from \"../type\";\n\nexport function withApplyDefault(\n\tvalue: any,\n\tfield: DBFieldAttribute,\n\taction: \"create\" | \"update\" | \"findOne\" | \"findMany\",\n) {\n\tif (action === \"update\") {\n\t\t// Apply onUpdate if value is undefined\n\t\tif (value === undefined && field.onUpdate !== undefined) {\n\t\t\tif (typeof field.onUpdate === \"function\") {\n\t\t\t\treturn field.onUpdate();\n\t\t\t}\n\t\t\treturn field.onUpdate;\n\t\t}\n\t\treturn value;\n\t}\n\tif (action === \"create\") {\n\t\t// we do not want to apply default values if the value is null & not required\n\t\tif (value === undefined || (field.required === true && value === null)) {\n\t\t\tif (field.defaultValue !== undefined) {\n\t\t\t\tif (typeof field.defaultValue === \"function\") {\n\t\t\t\t\treturn field.defaultValue();\n\t\t\t\t}\n\t\t\t\treturn field.defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction isObject(item: unknown): item is Record<string, unknown> {\n\treturn item !== null && typeof item === \"object\" && !Array.isArray(item);\n}\n\nexport function deepmerge<T>(target: T, source: Partial<T>): T {\n\tif (Array.isArray(target) && Array.isArray(source)) {\n\t\t// merge arrays by concatenation\n\t\treturn [...target, ...source] as T;\n\t} else if (isObject(target) && isObject(source)) {\n\t\tconst result: Record<string, unknown> = { ...target };\n\n\t\tfor (const [key, value] of Object.entries(source)) {\n\t\t\tif (value === undefined) continue; // skip undefined\n\n\t\t\tif (key in target) {\n\t\t\t\tresult[key] = deepmerge(\n\t\t\t\t\t(target as Record<string, unknown>)[key],\n\t\t\t\t\tvalue as unknown as Partial<T>,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresult[key] = value;\n\t\t\t}\n\t\t}\n\n\t\treturn result as T;\n\t}\n\n\t// primitives and fallback: source overrides target\n\treturn source as T;\n}\n"],"mappings":";AAEA,SAAgB,iBACf,OACA,OACA,QACC;AACD,KAAI,WAAW,UAAU;AAExB,MAAI,UAAU,UAAa,MAAM,aAAa,QAAW;AACxD,OAAI,OAAO,MAAM,aAAa,WAC7B,QAAO,MAAM,UAAU;AAExB,UAAO,MAAM;;AAEd,SAAO;;AAER,KAAI,WAAW,UAEd;MAAI,UAAU,UAAc,MAAM,aAAa,QAAQ,UAAU,MAChE;OAAI,MAAM,iBAAiB,QAAW;AACrC,QAAI,OAAO,MAAM,iBAAiB,WACjC,QAAO,MAAM,cAAc;AAE5B,WAAO,MAAM;;;;AAIhB,QAAO;;AAGR,SAAS,SAAS,MAAgD;AACjE,QAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK;;AAGzE,SAAgB,UAAa,QAAW,QAAuB;AAC9D,KAAI,MAAM,QAAQ,OAAO,IAAI,MAAM,QAAQ,OAAO,CAEjD,QAAO,CAAC,GAAG,QAAQ,GAAG,OAAO;UACnB,SAAS,OAAO,IAAI,SAAS,OAAO,EAAE;EAChD,MAAM,SAAkC,EAAE,GAAG,QAAQ;AAErD,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;AAClD,OAAI,UAAU,OAAW;AAEzB,OAAI,OAAO,OACV,QAAO,OAAO,UACZ,OAAmC,MACpC,MACA;OAED,QAAO,OAAO;;AAIhB,SAAO;;AAIR,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-tables.mjs","names":[],"sources":["../../src/db/get-tables.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"../types\";\nimport type { BetterAuthDBSchema, DBFieldAttribute } from \"./type\";\n\nexport const getAuthTables = (\n\toptions: BetterAuthOptions,\n): BetterAuthDBSchema => {\n\tconst pluginSchema = (options.plugins ?? []).reduce(\n\t\t(acc, plugin) => {\n\t\t\tconst schema = plugin.schema;\n\t\t\tif (!schema) return acc;\n\t\t\tfor (const [key, value] of Object.entries(schema)) {\n\t\t\t\tacc[key] = {\n\t\t\t\t\tfields: {\n\t\t\t\t\t\t...acc[key]?.fields,\n\t\t\t\t\t\t...value.fields,\n\t\t\t\t\t},\n\t\t\t\t\tmodelName: value.modelName || key,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn acc;\n\t\t},\n\t\t{} as Record<\n\t\t\tstring,\n\t\t\t{ fields: Record<string, DBFieldAttribute>; modelName: string }\n\t\t>,\n\t);\n\n\tconst shouldAddRateLimitTable = options.rateLimit?.storage === \"database\";\n\tconst rateLimitTable = {\n\t\trateLimit: {\n\t\t\tmodelName: options.rateLimit?.modelName || \"rateLimit\",\n\t\t\tfields: {\n\t\t\t\tkey: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tunique: true,\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.rateLimit?.fields?.key || \"key\",\n\t\t\t\t},\n\t\t\t\tcount: {\n\t\t\t\t\ttype: \"number\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.rateLimit?.fields?.count || \"count\",\n\t\t\t\t},\n\t\t\t\tlastRequest: {\n\t\t\t\t\ttype: \"number\",\n\t\t\t\t\tbigint: true,\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.rateLimit?.fields?.lastRequest || \"lastRequest\",\n\t\t\t\t\tdefaultValue: () => Date.now(),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t} satisfies BetterAuthDBSchema;\n\n\tconst { user, session, account, verification, ...pluginTables } =\n\t\tpluginSchema;\n\n\tconst verificationTable = {\n\t\tverification: {\n\t\t\tmodelName: options.verification?.modelName || \"verification\",\n\t\t\tfields: {\n\t\t\t\tidentifier: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.verification?.fields?.identifier || \"identifier\",\n\t\t\t\t\tindex: true,\n\t\t\t\t},\n\t\t\t\tvalue: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.verification?.fields?.value || \"value\",\n\t\t\t\t},\n\t\t\t\texpiresAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.verification?.fields?.expiresAt || \"expiresAt\",\n\t\t\t\t},\n\t\t\t\tcreatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t\tfieldName: options.verification?.fields?.createdAt || \"createdAt\",\n\t\t\t\t},\n\t\t\t\tupdatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t\tonUpdate: () => new Date(),\n\t\t\t\t\tfieldName: options.verification?.fields?.updatedAt || \"updatedAt\",\n\t\t\t\t},\n\t\t\t\t...verification?.fields,\n\t\t\t\t...options.verification?.additionalFields,\n\t\t\t},\n\t\t\torder: 4,\n\t\t},\n\t} satisfies BetterAuthDBSchema;\n\n\tconst sessionTable = {\n\t\tsession: {\n\t\t\tmodelName: options.session?.modelName || \"session\",\n\t\t\tfields: {\n\t\t\t\texpiresAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.session?.fields?.expiresAt || \"expiresAt\",\n\t\t\t\t},\n\t\t\t\ttoken: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.session?.fields?.token || \"token\",\n\t\t\t\t\tunique: true,\n\t\t\t\t},\n\t\t\t\tcreatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.session?.fields?.createdAt || \"createdAt\",\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t},\n\t\t\t\tupdatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.session?.fields?.updatedAt || \"updatedAt\",\n\t\t\t\t\tonUpdate: () => new Date(),\n\t\t\t\t},\n\t\t\t\tipAddress: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\tfieldName: options.session?.fields?.ipAddress || \"ipAddress\",\n\t\t\t\t},\n\t\t\t\tuserAgent: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\tfieldName: options.session?.fields?.userAgent || \"userAgent\",\n\t\t\t\t},\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tfieldName: options.session?.fields?.userId || \"userId\",\n\t\t\t\t\treferences: {\n\t\t\t\t\t\tmodel: options.user?.modelName || \"user\",\n\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\tonDelete: \"cascade\",\n\t\t\t\t\t},\n\t\t\t\t\trequired: true,\n\t\t\t\t\tindex: true,\n\t\t\t\t},\n\t\t\t\t...session?.fields,\n\t\t\t\t...options.session?.additionalFields,\n\t\t\t},\n\t\t\torder: 2,\n\t\t},\n\t} satisfies BetterAuthDBSchema;\n\n\treturn {\n\t\tuser: {\n\t\t\tmodelName: options.user?.modelName || \"user\",\n\t\t\tfields: {\n\t\t\t\tname: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.user?.fields?.name || \"name\",\n\t\t\t\t\tsortable: true,\n\t\t\t\t},\n\t\t\t\temail: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tunique: true,\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.user?.fields?.email || \"email\",\n\t\t\t\t\tsortable: true,\n\t\t\t\t},\n\t\t\t\temailVerified: {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefaultValue: false,\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.user?.fields?.emailVerified || \"emailVerified\",\n\t\t\t\t\tinput: false,\n\t\t\t\t},\n\t\t\t\timage: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\tfieldName: options.user?.fields?.image || \"image\",\n\t\t\t\t},\n\t\t\t\tcreatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.user?.fields?.createdAt || \"createdAt\",\n\t\t\t\t},\n\t\t\t\tupdatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t\tonUpdate: () => new Date(),\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.user?.fields?.updatedAt || \"updatedAt\",\n\t\t\t\t},\n\t\t\t\t...user?.fields,\n\t\t\t\t...options.user?.additionalFields,\n\t\t\t},\n\t\t\torder: 1,\n\t\t},\n\t\t//only add session table if it's not stored in secondary storage\n\t\t...(!options.secondaryStorage || options.session?.storeSessionInDatabase\n\t\t\t? sessionTable\n\t\t\t: {}),\n\t\taccount: {\n\t\t\tmodelName: options.account?.modelName || \"account\",\n\t\t\tfields: {\n\t\t\t\taccountId: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.account?.fields?.accountId || \"accountId\",\n\t\t\t\t},\n\t\t\t\tproviderId: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.account?.fields?.providerId || \"providerId\",\n\t\t\t\t},\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\treferences: {\n\t\t\t\t\t\tmodel: options.user?.modelName || \"user\",\n\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\tonDelete: \"cascade\",\n\t\t\t\t\t},\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.account?.fields?.userId || \"userId\",\n\t\t\t\t\tindex: true,\n\t\t\t\t},\n\t\t\t\taccessToken: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName: options.account?.fields?.accessToken || \"accessToken\",\n\t\t\t\t},\n\t\t\t\trefreshToken: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName: options.account?.fields?.refreshToken || \"refreshToken\",\n\t\t\t\t},\n\t\t\t\tidToken: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName: options.account?.fields?.idToken || \"idToken\",\n\t\t\t\t},\n\t\t\t\taccessTokenExpiresAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName:\n\t\t\t\t\t\toptions.account?.fields?.accessTokenExpiresAt ||\n\t\t\t\t\t\t\"accessTokenExpiresAt\",\n\t\t\t\t},\n\t\t\t\trefreshTokenExpiresAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName:\n\t\t\t\t\t\toptions.account?.fields?.refreshTokenExpiresAt ||\n\t\t\t\t\t\t\"refreshTokenExpiresAt\",\n\t\t\t\t},\n\t\t\t\tscope: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\tfieldName: options.account?.fields?.scope || \"scope\",\n\t\t\t\t},\n\t\t\t\tpassword: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: false,\n\t\t\t\t\treturned: false,\n\t\t\t\t\tfieldName: options.account?.fields?.password || \"password\",\n\t\t\t\t},\n\t\t\t\tcreatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.account?.fields?.createdAt || \"createdAt\",\n\t\t\t\t\tdefaultValue: () => new Date(),\n\t\t\t\t},\n\t\t\t\tupdatedAt: {\n\t\t\t\t\ttype: \"date\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tfieldName: options.account?.fields?.updatedAt || \"updatedAt\",\n\t\t\t\t\tonUpdate: () => new Date(),\n\t\t\t\t},\n\t\t\t\t...account?.fields,\n\t\t\t\t...options.account?.additionalFields,\n\t\t\t},\n\t\t\torder: 3,\n\t\t},\n\t\t...(!options.secondaryStorage || options.verification?.storeInDatabase\n\t\t\t? verificationTable\n\t\t\t: {}),\n\t\t...pluginTables,\n\t\t...(shouldAddRateLimitTable ? rateLimitTable : {}),\n\t} satisfies BetterAuthDBSchema;\n};\n"],"mappings":";AAGA,MAAa,iBACZ,YACwB;CACxB,MAAM,gBAAgB,QAAQ,WAAW,EAAE,EAAE,QAC3C,KAAK,WAAW;EAChB,MAAM,SAAS,OAAO;AACtB,MAAI,CAAC,OAAQ,QAAO;AACpB,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAChD,KAAI,OAAO;GACV,QAAQ;IACP,GAAG,IAAI,MAAM;IACb,GAAG,MAAM;IACT;GACD,WAAW,MAAM,aAAa;GAC9B;AAEF,SAAO;IAER,EAAE,CAIF;CAED,MAAM,0BAA0B,QAAQ,WAAW,YAAY;CAC/D,MAAM,iBAAiB,EACtB,WAAW;EACV,WAAW,QAAQ,WAAW,aAAa;EAC3C,QAAQ;GACP,KAAK;IACJ,MAAM;IACN,QAAQ;IACR,UAAU;IACV,WAAW,QAAQ,WAAW,QAAQ,OAAO;IAC7C;GACD,OAAO;IACN,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,WAAW,QAAQ,SAAS;IAC/C;GACD,aAAa;IACZ,MAAM;IACN,QAAQ;IACR,UAAU;IACV,WAAW,QAAQ,WAAW,QAAQ,eAAe;IACrD,oBAAoB,KAAK,KAAK;IAC9B;GACD;EACD,EACD;CAED,MAAM,EAAE,MAAM,SAAS,SAAS,cAAc,GAAG,iBAChD;CAED,MAAM,oBAAoB,EACzB,cAAc;EACb,WAAW,QAAQ,cAAc,aAAa;EAC9C,QAAQ;GACP,YAAY;IACX,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,cAAc,QAAQ,cAAc;IACvD,OAAO;IACP;GACD,OAAO;IACN,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,cAAc,QAAQ,SAAS;IAClD;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,cAAc,QAAQ,aAAa;IACtD;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,oCAAoB,IAAI,MAAM;IAC9B,WAAW,QAAQ,cAAc,QAAQ,aAAa;IACtD;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,oCAAoB,IAAI,MAAM;IAC9B,gCAAgB,IAAI,MAAM;IAC1B,WAAW,QAAQ,cAAc,QAAQ,aAAa;IACtD;GACD,GAAG,cAAc;GACjB,GAAG,QAAQ,cAAc;GACzB;EACD,OAAO;EACP,EACD;CAED,MAAM,eAAe,EACpB,SAAS;EACR,WAAW,QAAQ,SAAS,aAAa;EACzC,QAAQ;GACP,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;IACjD;GACD,OAAO;IACN,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,SAAS;IAC7C,QAAQ;IACR;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;IACjD,oCAAoB,IAAI,MAAM;IAC9B;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;IACjD,gCAAgB,IAAI,MAAM;IAC1B;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;IACjD;GACD,WAAW;IACV,MAAM;IACN,UAAU;IACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;IACjD;GACD,QAAQ;IACP,MAAM;IACN,WAAW,QAAQ,SAAS,QAAQ,UAAU;IAC9C,YAAY;KACX,OAAO,QAAQ,MAAM,aAAa;KAClC,OAAO;KACP,UAAU;KACV;IACD,UAAU;IACV,OAAO;IACP;GACD,GAAG,SAAS;GACZ,GAAG,QAAQ,SAAS;GACpB;EACD,OAAO;EACP,EACD;AAED,QAAO;EACN,MAAM;GACL,WAAW,QAAQ,MAAM,aAAa;GACtC,QAAQ;IACP,MAAM;KACL,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,QAAQ;KACzC,UAAU;KACV;IACD,OAAO;KACN,MAAM;KACN,QAAQ;KACR,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,SAAS;KAC1C,UAAU;KACV;IACD,eAAe;KACd,MAAM;KACN,cAAc;KACd,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,iBAAiB;KAClD,OAAO;KACP;IACD,OAAO;KACN,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,SAAS;KAC1C;IACD,WAAW;KACV,MAAM;KACN,oCAAoB,IAAI,MAAM;KAC9B,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,aAAa;KAC9C;IACD,WAAW;KACV,MAAM;KACN,oCAAoB,IAAI,MAAM;KAC9B,gCAAgB,IAAI,MAAM;KAC1B,UAAU;KACV,WAAW,QAAQ,MAAM,QAAQ,aAAa;KAC9C;IACD,GAAG,MAAM;IACT,GAAG,QAAQ,MAAM;IACjB;GACD,OAAO;GACP;EAED,GAAI,CAAC,QAAQ,oBAAoB,QAAQ,SAAS,yBAC/C,eACA,EAAE;EACL,SAAS;GACR,WAAW,QAAQ,SAAS,aAAa;GACzC,QAAQ;IACP,WAAW;KACV,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;KACjD;IACD,YAAY;KACX,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,cAAc;KAClD;IACD,QAAQ;KACP,MAAM;KACN,YAAY;MACX,OAAO,QAAQ,MAAM,aAAa;MAClC,OAAO;MACP,UAAU;MACV;KACD,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,UAAU;KAC9C,OAAO;KACP;IACD,aAAa;KACZ,MAAM;KACN,UAAU;KACV,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,eAAe;KACnD;IACD,cAAc;KACb,MAAM;KACN,UAAU;KACV,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,gBAAgB;KACpD;IACD,SAAS;KACR,MAAM;KACN,UAAU;KACV,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,WAAW;KAC/C;IACD,sBAAsB;KACrB,MAAM;KACN,UAAU;KACV,UAAU;KACV,WACC,QAAQ,SAAS,QAAQ,wBACzB;KACD;IACD,uBAAuB;KACtB,MAAM;KACN,UAAU;KACV,UAAU;KACV,WACC,QAAQ,SAAS,QAAQ,yBACzB;KACD;IACD,OAAO;KACN,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,SAAS;KAC7C;IACD,UAAU;KACT,MAAM;KACN,UAAU;KACV,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,YAAY;KAChD;IACD,WAAW;KACV,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;KACjD,oCAAoB,IAAI,MAAM;KAC9B;IACD,WAAW;KACV,MAAM;KACN,UAAU;KACV,WAAW,QAAQ,SAAS,QAAQ,aAAa;KACjD,gCAAgB,IAAI,MAAM;KAC1B;IACD,GAAG,SAAS;IACZ,GAAG,QAAQ,SAAS;IACpB;GACD,OAAO;GACP;EACD,GAAI,CAAC,QAAQ,oBAAoB,QAAQ,cAAc,kBACpD,oBACA,EAAE;EACL,GAAG;EACH,GAAI,0BAA0B,iBAAiB,EAAE;EACjD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"account.mjs","names":[],"sources":["../../../src/db/schema/account.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { Prettify } from \"../../types\";\nimport type { BetterAuthOptions } from \"../../types/init-options\";\nimport type {\n\tInferDBFieldsFromOptions,\n\tInferDBFieldsFromPlugins,\n} from \"../type\";\nimport { coreSchema } from \"./shared\";\n\nexport const accountSchema = coreSchema.extend({\n\tproviderId: z.string(),\n\taccountId: z.string(),\n\tuserId: z.coerce.string(),\n\taccessToken: z.string().nullish(),\n\trefreshToken: z.string().nullish(),\n\tidToken: z.string().nullish(),\n\t/**\n\t * Access token expires at\n\t */\n\taccessTokenExpiresAt: z.date().nullish(),\n\t/**\n\t * Refresh token expires at\n\t */\n\trefreshTokenExpiresAt: z.date().nullish(),\n\t/**\n\t * The scopes that the user has authorized\n\t */\n\tscope: z.string().nullish(),\n\t/**\n\t * Password is only stored in the credential provider\n\t */\n\tpassword: z.string().nullish(),\n});\n\nexport type BaseAccount = z.infer<typeof accountSchema>;\n\n/**\n * Account schema type used by better-auth, note that it's possible that account could have additional fields\n */\nexport type Account<\n\tDBOptions extends BetterAuthOptions[\"account\"] = BetterAuthOptions[\"account\"],\n\tPlugins extends BetterAuthOptions[\"plugins\"] = BetterAuthOptions[\"plugins\"],\n> = Prettify<\n\tBaseAccount &\n\t\tInferDBFieldsFromOptions<DBOptions> &\n\t\tInferDBFieldsFromPlugins<\"account\", Plugins>\n>;\n"],"mappings":";;;;AASA,MAAa,gBAAgB,WAAW,OAAO;CAC9C,YAAY,EAAE,QAAQ;CACtB,WAAW,EAAE,QAAQ;CACrB,QAAQ,EAAE,OAAO,QAAQ;CACzB,aAAa,EAAE,QAAQ,CAAC,SAAS;CACjC,cAAc,EAAE,QAAQ,CAAC,SAAS;CAClC,SAAS,EAAE,QAAQ,CAAC,SAAS;CAI7B,sBAAsB,EAAE,MAAM,CAAC,SAAS;CAIxC,uBAAuB,EAAE,MAAM,CAAC,SAAS;CAIzC,OAAO,EAAE,QAAQ,CAAC,SAAS;CAI3B,UAAU,EAAE,QAAQ,CAAC,SAAS;CAC9B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"rate-limit.mjs","names":[],"sources":["../../../src/db/schema/rate-limit.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { BetterAuthOptions, Prettify } from \"../../types\";\nimport type {\n\tInferDBFieldsFromOptions,\n\tInferDBFieldsFromPlugins,\n} from \"../type\";\n\nexport const rateLimitSchema = z.object({\n\t/**\n\t * The key to use for rate limiting\n\t */\n\tkey: z.string(),\n\t/**\n\t * The number of requests made\n\t */\n\tcount: z.number(),\n\t/**\n\t * The last request time in milliseconds\n\t */\n\tlastRequest: z.number(),\n});\n\nexport type BaseRateLimit = z.infer<typeof rateLimitSchema>;\n\n/**\n * Rate limit schema type used by better-auth for rate limiting\n */\nexport type RateLimit<\n\tDBOptions extends\n\t\tBetterAuthOptions[\"rateLimit\"] = BetterAuthOptions[\"rateLimit\"],\n\tPlugins extends BetterAuthOptions[\"plugins\"] = BetterAuthOptions[\"plugins\"],\n> = Prettify<\n\tBaseRateLimit &\n\t\tInferDBFieldsFromOptions<DBOptions> &\n\t\tInferDBFieldsFromPlugins<\"rateLimit\", Plugins>\n>;\n"],"mappings":";;;AAOA,MAAa,kBAAkB,EAAE,OAAO;CAIvC,KAAK,EAAE,QAAQ;CAIf,OAAO,EAAE,QAAQ;CAIjB,aAAa,EAAE,QAAQ;CACvB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.mjs","names":[],"sources":["../../../src/db/schema/session.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { BetterAuthOptions, Prettify } from \"../../types\";\nimport type {\n\tInferDBFieldsFromOptions,\n\tInferDBFieldsFromPlugins,\n} from \"../type\";\nimport { coreSchema } from \"./shared\";\n\nexport const sessionSchema = coreSchema.extend({\n\tuserId: z.coerce.string(),\n\texpiresAt: z.date(),\n\ttoken: z.string(),\n\tipAddress: z.string().nullish(),\n\tuserAgent: z.string().nullish(),\n});\n\nexport type BaseSession = z.infer<typeof sessionSchema>;\n\n/**\n * Session schema type used by better-auth, note that it's possible that session could have additional fields\n */\nexport type Session<\n\tDBOptions extends BetterAuthOptions[\"session\"] = BetterAuthOptions[\"session\"],\n\tPlugins extends BetterAuthOptions[\"plugins\"] = BetterAuthOptions[\"plugins\"],\n> = Prettify<\n\tz.infer<typeof sessionSchema> &\n\t\tInferDBFieldsFromOptions<DBOptions> &\n\t\tInferDBFieldsFromPlugins<\"session\", Plugins>\n>;\n"],"mappings":";;;;AAQA,MAAa,gBAAgB,WAAW,OAAO;CAC9C,QAAQ,EAAE,OAAO,QAAQ;CACzB,WAAW,EAAE,MAAM;CACnB,OAAO,EAAE,QAAQ;CACjB,WAAW,EAAE,QAAQ,CAAC,SAAS;CAC/B,WAAW,EAAE,QAAQ,CAAC,SAAS;CAC/B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared.mjs","names":[],"sources":["../../../src/db/schema/shared.ts"],"sourcesContent":["import * as z from \"zod\";\n\nexport const coreSchema = z.object({\n\tid: z.string(),\n\tcreatedAt: z.date().default(() => new Date()),\n\tupdatedAt: z.date().default(() => new Date()),\n});\n"],"mappings":";;;AAEA,MAAa,aAAa,EAAE,OAAO;CAClC,IAAI,EAAE,QAAQ;CACd,WAAW,EAAE,MAAM,CAAC,8BAAc,IAAI,MAAM,CAAC;CAC7C,WAAW,EAAE,MAAM,CAAC,8BAAc,IAAI,MAAM,CAAC;CAC7C,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"user.mjs","names":[],"sources":["../../../src/db/schema/user.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { BetterAuthOptions, Prettify } from \"../../types\";\nimport type {\n\tInferDBFieldsFromOptions,\n\tInferDBFieldsFromPlugins,\n} from \"../type\";\nimport { coreSchema } from \"./shared\";\n\nexport const userSchema = coreSchema.extend({\n\temail: z.string().transform((val) => val.toLowerCase()),\n\temailVerified: z.boolean().default(false),\n\tname: z.string(),\n\timage: z.string().nullish(),\n});\n\nexport type BaseUser = z.infer<typeof userSchema>;\n\n/**\n * User schema type used by better-auth, note that it's possible that user could have additional fields\n */\nexport type User<\n\tDBOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n\tPlugins extends BetterAuthOptions[\"plugins\"] = BetterAuthOptions[\"plugins\"],\n> = Prettify<\n\tBaseUser &\n\t\tInferDBFieldsFromOptions<DBOptions> &\n\t\tInferDBFieldsFromPlugins<\"user\", Plugins>\n>;\n"],"mappings":";;;;AAQA,MAAa,aAAa,WAAW,OAAO;CAC3C,OAAO,EAAE,QAAQ,CAAC,WAAW,QAAQ,IAAI,aAAa,CAAC;CACvD,eAAe,EAAE,SAAS,CAAC,QAAQ,MAAM;CACzC,MAAM,EAAE,QAAQ;CAChB,OAAO,EAAE,QAAQ,CAAC,SAAS;CAC3B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"verification.mjs","names":[],"sources":["../../../src/db/schema/verification.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { BetterAuthOptions, Prettify } from \"../../types\";\nimport type {\n\tInferDBFieldsFromOptions,\n\tInferDBFieldsFromPlugins,\n} from \"../type\";\nimport { coreSchema } from \"./shared\";\n\nexport const verificationSchema = coreSchema.extend({\n\tvalue: z.string(),\n\texpiresAt: z.date(),\n\tidentifier: z.string(),\n});\n\nexport type BaseVerification = z.infer<typeof verificationSchema>;\n\n/**\n * Verification schema type used by better-auth, note that it's possible that verification could have additional fields\n */\nexport type Verification<\n\tDBOptions extends\n\t\tBetterAuthOptions[\"verification\"] = BetterAuthOptions[\"verification\"],\n\tPlugins extends BetterAuthOptions[\"plugins\"] = BetterAuthOptions[\"plugins\"],\n> = Prettify<\n\tBaseVerification &\n\t\tInferDBFieldsFromOptions<DBOptions> &\n\t\tInferDBFieldsFromPlugins<\"verification\", Plugins>\n>;\n"],"mappings":";;;;AAQA,MAAa,qBAAqB,WAAW,OAAO;CACnD,OAAO,EAAE,QAAQ;CACjB,WAAW,EAAE,MAAM;CACnB,YAAY,EAAE,QAAQ;CACtB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"color-depth.mjs","names":[],"sources":["../../src/env/color-depth.ts"],"sourcesContent":["// Source code copied & modified from node internals: https://github.com/nodejs/node/blob/5b32bb1573dace2dd058c05ac4fab1e4e446c775/lib/internal/tty.js#L123\nimport { env, getEnvVar } from \"./env-impl\";\n\nconst COLORS_2 = 1;\nconst COLORS_16 = 4;\nconst COLORS_256 = 8;\nconst COLORS_16m = 24;\n\nconst TERM_ENVS: Record<string, number> = {\n\teterm: COLORS_16,\n\tcons25: COLORS_16,\n\tconsole: COLORS_16,\n\tcygwin: COLORS_16,\n\tdtterm: COLORS_16,\n\tgnome: COLORS_16,\n\thurd: COLORS_16,\n\tjfbterm: COLORS_16,\n\tkonsole: COLORS_16,\n\tkterm: COLORS_16,\n\tmlterm: COLORS_16,\n\tmosh: COLORS_16m,\n\tputty: COLORS_16,\n\tst: COLORS_16,\n\t// http://lists.schmorp.de/pipermail/rxvt-unicode/2016q2/002261.html\n\t\"rxvt-unicode-24bit\": COLORS_16m,\n\t// https://bugs.launchpad.net/terminator/+bug/1030562\n\tterminator: COLORS_16m,\n\t\"xterm-kitty\": COLORS_16m,\n};\n\nconst CI_ENVS_MAP = new Map(\n\tObject.entries({\n\t\tAPPVEYOR: COLORS_256,\n\t\tBUILDKITE: COLORS_256,\n\t\tCIRCLECI: COLORS_16m,\n\t\tDRONE: COLORS_256,\n\t\tGITEA_ACTIONS: COLORS_16m,\n\t\tGITHUB_ACTIONS: COLORS_16m,\n\t\tGITLAB_CI: COLORS_256,\n\t\tTRAVIS: COLORS_256,\n\t}),\n);\n\nconst TERM_ENVS_REG_EXP = [\n\t/ansi/,\n\t/color/,\n\t/linux/,\n\t/direct/,\n\t/^con[0-9]*x[0-9]/,\n\t/^rxvt/,\n\t/^screen/,\n\t/^xterm/,\n\t/^vt100/,\n\t/^vt220/,\n];\n\n// The `getColorDepth` API got inspired by multiple sources such as\n// https://github.com/chalk/supports-color,\n// https://github.com/isaacs/color-support.\nexport function getColorDepth(): number {\n\t// Use level 0-3 to support the same levels as `chalk` does. This is done for\n\t// consistency throughout the ecosystem.\n\tif (getEnvVar(\"FORCE_COLOR\") !== undefined) {\n\t\tswitch (getEnvVar(\"FORCE_COLOR\")) {\n\t\t\tcase \"\":\n\t\t\tcase \"1\":\n\t\t\tcase \"true\":\n\t\t\t\treturn COLORS_16;\n\t\t\tcase \"2\":\n\t\t\t\treturn COLORS_256;\n\t\t\tcase \"3\":\n\t\t\t\treturn COLORS_16m;\n\t\t\tdefault:\n\t\t\t\treturn COLORS_2;\n\t\t}\n\t}\n\n\tif (\n\t\t(getEnvVar(\"NODE_DISABLE_COLORS\") !== undefined &&\n\t\t\tgetEnvVar(\"NODE_DISABLE_COLORS\") !== \"\") ||\n\t\t// See https://no-color.org/\n\t\t(getEnvVar(\"NO_COLOR\") !== undefined && getEnvVar(\"NO_COLOR\") !== \"\") ||\n\t\t// The \"dumb\" special terminal, as defined by terminfo, doesn't support\n\t\t// ANSI color control codes.\n\t\t// See https://invisible-island.net/ncurses/terminfo.ti.html#toc-_Specials\n\t\tgetEnvVar(\"TERM\") === \"dumb\"\n\t) {\n\t\treturn COLORS_2;\n\t}\n\n\t// Edge runtime doesn't support `process?.platform` syntax\n\t// if (typeof process !== \"undefined\" && process?.platform === \"win32\") {\n\t// \t// Windows 10 build 14931 (from 2016) has true color support\n\t// \treturn COLORS_16m;\n\t// }\n\n\tif (getEnvVar(\"TMUX\")) {\n\t\treturn COLORS_16m;\n\t}\n\n\t// Azure DevOps\n\tif (\"TF_BUILD\" in env && \"AGENT_NAME\" in env) {\n\t\treturn COLORS_16;\n\t}\n\n\tif (\"CI\" in env) {\n\t\tfor (const { 0: envName, 1: colors } of CI_ENVS_MAP) {\n\t\t\tif (envName in env) {\n\t\t\t\treturn colors;\n\t\t\t}\n\t\t}\n\t\tif (getEnvVar(\"CI_NAME\") === \"codeship\") {\n\t\t\treturn COLORS_256;\n\t\t}\n\t\treturn COLORS_2;\n\t}\n\n\tif (\"TEAMCITY_VERSION\" in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.exec(\n\t\t\tgetEnvVar(\"TEAMCITY_VERSION\"),\n\t\t) !== null\n\t\t\t? COLORS_16\n\t\t\t: COLORS_2;\n\t}\n\n\tswitch (getEnvVar(\"TERM_PROGRAM\")) {\n\t\tcase \"iTerm.app\":\n\t\t\tif (\n\t\t\t\t!getEnvVar(\"TERM_PROGRAM_VERSION\") ||\n\t\t\t\t/^[0-2]\\./.exec(getEnvVar(\"TERM_PROGRAM_VERSION\")) !== null\n\t\t\t) {\n\t\t\t\treturn COLORS_256;\n\t\t\t}\n\t\t\treturn COLORS_16m;\n\t\tcase \"HyperTerm\":\n\t\tcase \"MacTerm\":\n\t\t\treturn COLORS_16m;\n\t\tcase \"Apple_Terminal\":\n\t\t\treturn COLORS_256;\n\t}\n\n\tif (\n\t\tgetEnvVar(\"COLORTERM\") === \"truecolor\" ||\n\t\tgetEnvVar(\"COLORTERM\") === \"24bit\"\n\t) {\n\t\treturn COLORS_16m;\n\t}\n\n\tif (getEnvVar(\"TERM\")) {\n\t\tif (/truecolor/.exec(getEnvVar(\"TERM\")) !== null) {\n\t\t\treturn COLORS_16m;\n\t\t}\n\n\t\tif (/^xterm-256/.exec(getEnvVar(\"TERM\")) !== null) {\n\t\t\treturn COLORS_256;\n\t\t}\n\n\t\tconst termEnv = getEnvVar(\"TERM\").toLowerCase();\n\n\t\tif (TERM_ENVS[termEnv]) {\n\t\t\treturn TERM_ENVS[termEnv];\n\t\t}\n\t\tif (TERM_ENVS_REG_EXP.some((term) => term.exec(termEnv) !== null)) {\n\t\t\treturn COLORS_16;\n\t\t}\n\t}\n\t// Move 16 color COLORTERM below 16m and 256\n\tif (getEnvVar(\"COLORTERM\")) {\n\t\treturn COLORS_16;\n\t}\n\treturn COLORS_2;\n}\n"],"mappings":";;;AAGA,MAAM,WAAW;AACjB,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,aAAa;AAEnB,MAAM,YAAoC;CACzC,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,MAAM;CACN,SAAS;CACT,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,IAAI;CAEJ,sBAAsB;CAEtB,YAAY;CACZ,eAAe;CACf;AAED,MAAM,cAAc,IAAI,IACvB,OAAO,QAAQ;CACd,UAAU;CACV,WAAW;CACX,UAAU;CACV,OAAO;CACP,eAAe;CACf,gBAAgB;CAChB,WAAW;CACX,QAAQ;CACR,CAAC,CACF;AAED,MAAM,oBAAoB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAKD,SAAgB,gBAAwB;AAGvC,KAAI,UAAU,cAAc,KAAK,OAChC,SAAQ,UAAU,cAAc,EAAhC;EACC,KAAK;EACL,KAAK;EACL,KAAK,OACJ,QAAO;EACR,KAAK,IACJ,QAAO;EACR,KAAK,IACJ,QAAO;EACR,QACC,QAAO;;AAIV,KACE,UAAU,sBAAsB,KAAK,UACrC,UAAU,sBAAsB,KAAK,MAErC,UAAU,WAAW,KAAK,UAAa,UAAU,WAAW,KAAK,MAIlE,UAAU,OAAO,KAAK,OAEtB,QAAO;AASR,KAAI,UAAU,OAAO,CACpB,QAAO;AAIR,KAAI,cAAc,OAAO,gBAAgB,IACxC,QAAO;AAGR,KAAI,QAAQ,KAAK;AAChB,OAAK,MAAM,EAAE,GAAG,SAAS,GAAG,YAAY,YACvC,KAAI,WAAW,IACd,QAAO;AAGT,MAAI,UAAU,UAAU,KAAK,WAC5B,QAAO;AAER,SAAO;;AAGR,KAAI,sBAAsB,IACzB,QAAO,gCAAgC,KACtC,UAAU,mBAAmB,CAC7B,KAAK,OACH,YACA;AAGJ,SAAQ,UAAU,eAAe,EAAjC;EACC,KAAK;AACJ,OACC,CAAC,UAAU,uBAAuB,IAClC,WAAW,KAAK,UAAU,uBAAuB,CAAC,KAAK,KAEvD,QAAO;AAER,UAAO;EACR,KAAK;EACL,KAAK,UACJ,QAAO;EACR,KAAK,iBACJ,QAAO;;AAGT,KACC,UAAU,YAAY,KAAK,eAC3B,UAAU,YAAY,KAAK,QAE3B,QAAO;AAGR,KAAI,UAAU,OAAO,EAAE;AACtB,MAAI,YAAY,KAAK,UAAU,OAAO,CAAC,KAAK,KAC3C,QAAO;AAGR,MAAI,aAAa,KAAK,UAAU,OAAO,CAAC,KAAK,KAC5C,QAAO;EAGR,MAAM,UAAU,UAAU,OAAO,CAAC,aAAa;AAE/C,MAAI,UAAU,SACb,QAAO,UAAU;AAElB,MAAI,kBAAkB,MAAM,SAAS,KAAK,KAAK,QAAQ,KAAK,KAAK,CAChE,QAAO;;AAIT,KAAI,UAAU,YAAY,CACzB,QAAO;AAER,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"env-impl.mjs","names":[],"sources":["../../src/env/env-impl.ts"],"sourcesContent":["/// <reference types=\"node\" />\n/// <reference types=\"bun\" />\n//https://github.com/unjs/std-env/blob/main/src/env.ts\n\nconst _envShim = Object.create(null);\n\nexport type EnvObject = Record<string, string | undefined>;\n\nconst _getEnv = (useShim?: boolean) =>\n\tglobalThis.process?.env ||\n\t//@ts-expect-error\n\tglobalThis.Deno?.env.toObject() ||\n\t//@ts-expect-error\n\tglobalThis.__env__ ||\n\t(useShim ? _envShim : globalThis);\n\nexport const env = new Proxy<EnvObject>(_envShim, {\n\tget(_, prop) {\n\t\tconst env = _getEnv();\n\t\treturn env[prop as any] ?? _envShim[prop];\n\t},\n\thas(_, prop) {\n\t\tconst env = _getEnv();\n\t\treturn prop in env || prop in _envShim;\n\t},\n\tset(_, prop, value) {\n\t\tconst env = _getEnv(true);\n\t\tenv[prop as any] = value;\n\t\treturn true;\n\t},\n\tdeleteProperty(_, prop) {\n\t\tif (!prop) {\n\t\t\treturn false;\n\t\t}\n\t\tconst env = _getEnv(true);\n\t\tdelete env[prop as any];\n\t\treturn true;\n\t},\n\townKeys() {\n\t\tconst env = _getEnv(true);\n\t\treturn Object.keys(env);\n\t},\n});\n\nfunction toBoolean(val: boolean | string | undefined) {\n\treturn val ? val !== \"false\" : false;\n}\n\nexport const nodeENV =\n\t(typeof process !== \"undefined\" && process.env && process.env.NODE_ENV) || \"\";\n\n/** Detect if `NODE_ENV` environment variable is `production` */\nexport const isProduction = nodeENV === \"production\";\n\n/** Detect if `NODE_ENV` environment variable is `dev` or `development` */\nexport const isDevelopment = () =>\n\tnodeENV === \"dev\" || nodeENV === \"development\";\n\n/** Detect if `NODE_ENV` environment variable is `test` */\nexport const isTest = () => nodeENV === \"test\" || toBoolean(env.TEST);\n\n/**\n * Get environment variable with fallback\n */\nexport function getEnvVar<Fallback extends string>(\n\tkey: string,\n\tfallback?: Fallback,\n): Fallback extends string ? string : string | undefined {\n\tif (typeof process !== \"undefined\" && process.env) {\n\t\treturn process.env[key] ?? (fallback as any);\n\t}\n\n\t// @ts-expect-error deno\n\tif (typeof Deno !== \"undefined\") {\n\t\t// @ts-expect-error deno\n\t\treturn Deno.env.get(key) ?? (fallback as string);\n\t}\n\n\t// Handle Bun\n\tif (typeof Bun !== \"undefined\") {\n\t\treturn Bun.env[key] ?? (fallback as string);\n\t}\n\n\treturn fallback as any;\n}\n\n/**\n * Get boolean environment variable\n */\nexport function getBooleanEnvVar(key: string, fallback = true): boolean {\n\tconst value = getEnvVar(key);\n\tif (!value) return fallback;\n\treturn value !== \"0\" && value.toLowerCase() !== \"false\" && value !== \"\";\n}\n\n/**\n * Common environment variables used in Better Auth\n */\nexport const ENV = Object.freeze({\n\tget BETTER_AUTH_SECRET() {\n\t\treturn getEnvVar(\"BETTER_AUTH_SECRET\");\n\t},\n\tget AUTH_SECRET() {\n\t\treturn getEnvVar(\"AUTH_SECRET\");\n\t},\n\tget BETTER_AUTH_TELEMETRY() {\n\t\treturn getEnvVar(\"BETTER_AUTH_TELEMETRY\");\n\t},\n\tget BETTER_AUTH_TELEMETRY_ID() {\n\t\treturn getEnvVar(\"BETTER_AUTH_TELEMETRY_ID\");\n\t},\n\tget NODE_ENV() {\n\t\treturn getEnvVar(\"NODE_ENV\", \"development\");\n\t},\n\tget PACKAGE_VERSION() {\n\t\treturn getEnvVar(\"PACKAGE_VERSION\", \"0.0.0\");\n\t},\n\tget BETTER_AUTH_TELEMETRY_ENDPOINT(): string | undefined {\n\t\treturn getEnvVar(\n\t\t\t\"BETTER_AUTH_TELEMETRY_ENDPOINT\",\n\t\t\timport.meta.env.BETTER_AUTH_TELEMETRY_ENDPOINT,\n\t\t);\n\t},\n});\n"],"mappings":";AAIA,MAAM,WAAW,OAAO,OAAO,KAAK;AAIpC,MAAM,WAAW,YAChB,WAAW,SAAS,OAEpB,WAAW,MAAM,IAAI,UAAU,IAE/B,WAAW,YACV,UAAU,WAAW;AAEvB,MAAa,MAAM,IAAI,MAAiB,UAAU;CACjD,IAAI,GAAG,MAAM;AAEZ,SADY,SAAS,CACV,SAAgB,SAAS;;CAErC,IAAI,GAAG,MAAM;AAEZ,SAAO,QADK,SAAS,IACC,QAAQ;;CAE/B,IAAI,GAAG,MAAM,OAAO;EACnB,MAAM,MAAM,QAAQ,KAAK;AACzB,MAAI,QAAe;AACnB,SAAO;;CAER,eAAe,GAAG,MAAM;AACvB,MAAI,CAAC,KACJ,QAAO;EAER,MAAM,MAAM,QAAQ,KAAK;AACzB,SAAO,IAAI;AACX,SAAO;;CAER,UAAU;EACT,MAAM,MAAM,QAAQ,KAAK;AACzB,SAAO,OAAO,KAAK,IAAI;;CAExB,CAAC;AAEF,SAAS,UAAU,KAAmC;AACrD,QAAO,MAAM,QAAQ,UAAU;;AAGhC,MAAa,UACX,OAAO,YAAY,eAAe,QAAQ,OAAO,QAAQ,IAAI,YAAa;;AAG5E,MAAa,eAAe,YAAY;;AAGxC,MAAa,sBACZ,YAAY,SAAS,YAAY;;AAGlC,MAAa,eAAe,YAAY,UAAU,UAAU,IAAI,KAAK;;;;AAKrE,SAAgB,UACf,KACA,UACwD;AACxD,KAAI,OAAO,YAAY,eAAe,QAAQ,IAC7C,QAAO,QAAQ,IAAI,QAAS;AAI7B,KAAI,OAAO,SAAS,YAEnB,QAAO,KAAK,IAAI,IAAI,IAAI,IAAK;AAI9B,KAAI,OAAO,QAAQ,YAClB,QAAO,IAAI,IAAI,QAAS;AAGzB,QAAO;;;;;AAMR,SAAgB,iBAAiB,KAAa,WAAW,MAAe;CACvE,MAAM,QAAQ,UAAU,IAAI;AAC5B,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO,UAAU,OAAO,MAAM,aAAa,KAAK,WAAW,UAAU;;;;;AAMtE,MAAa,MAAM,OAAO,OAAO;CAChC,IAAI,qBAAqB;AACxB,SAAO,UAAU,qBAAqB;;CAEvC,IAAI,cAAc;AACjB,SAAO,UAAU,cAAc;;CAEhC,IAAI,wBAAwB;AAC3B,SAAO,UAAU,wBAAwB;;CAE1C,IAAI,2BAA2B;AAC9B,SAAO,UAAU,2BAA2B;;CAE7C,IAAI,WAAW;AACd,SAAO,UAAU,YAAY,cAAc;;CAE5C,IAAI,kBAAkB;AACrB,SAAO,UAAU,mBAAmB,QAAQ;;CAE7C,IAAI,iCAAqD;AACxD,SAAO,UACN,qCAEA;;CAEF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/env/logger.ts"],"sourcesContent":["import { getColorDepth } from \"./color-depth\";\n\nexport const TTY_COLORS = {\n\treset: \"\\x1b[0m\",\n\tbright: \"\\x1b[1m\",\n\tdim: \"\\x1b[2m\",\n\tundim: \"\\x1b[22m\",\n\tunderscore: \"\\x1b[4m\",\n\tblink: \"\\x1b[5m\",\n\treverse: \"\\x1b[7m\",\n\thidden: \"\\x1b[8m\",\n\tfg: {\n\t\tblack: \"\\x1b[30m\",\n\t\tred: \"\\x1b[31m\",\n\t\tgreen: \"\\x1b[32m\",\n\t\tyellow: \"\\x1b[33m\",\n\t\tblue: \"\\x1b[34m\",\n\t\tmagenta: \"\\x1b[35m\",\n\t\tcyan: \"\\x1b[36m\",\n\t\twhite: \"\\x1b[37m\",\n\t},\n\tbg: {\n\t\tblack: \"\\x1b[40m\",\n\t\tred: \"\\x1b[41m\",\n\t\tgreen: \"\\x1b[42m\",\n\t\tyellow: \"\\x1b[43m\",\n\t\tblue: \"\\x1b[44m\",\n\t\tmagenta: \"\\x1b[45m\",\n\t\tcyan: \"\\x1b[46m\",\n\t\twhite: \"\\x1b[47m\",\n\t},\n} as const;\n\nexport type LogLevel = \"debug\" | \"info\" | \"success\" | \"warn\" | \"error\";\n\nexport const levels = [\"debug\", \"info\", \"success\", \"warn\", \"error\"] as const;\n\nexport function shouldPublishLog(\n\tcurrentLogLevel: LogLevel,\n\tlogLevel: LogLevel,\n): boolean {\n\treturn levels.indexOf(logLevel) >= levels.indexOf(currentLogLevel);\n}\n\nexport interface Logger {\n\tdisabled?: boolean | undefined;\n\tdisableColors?: boolean | undefined;\n\tlevel?: Exclude<LogLevel, \"success\"> | undefined;\n\tlog?:\n\t\t| ((\n\t\t\t\tlevel: Exclude<LogLevel, \"success\">,\n\t\t\t\tmessage: string,\n\t\t\t\t...args: any[]\n\t\t ) => void)\n\t\t| undefined;\n}\n\nexport type LogHandlerParams =\n\tParameters<NonNullable<Logger[\"log\"]>> extends [LogLevel, ...infer Rest]\n\t\t? Rest\n\t\t: never;\n\nconst levelColors: Record<LogLevel, string> = {\n\tinfo: TTY_COLORS.fg.blue,\n\tsuccess: TTY_COLORS.fg.green,\n\twarn: TTY_COLORS.fg.yellow,\n\terror: TTY_COLORS.fg.red,\n\tdebug: TTY_COLORS.fg.magenta,\n};\n\nconst formatMessage = (\n\tlevel: LogLevel,\n\tmessage: string,\n\tcolorsEnabled: boolean,\n): string => {\n\tconst timestamp = new Date().toISOString();\n\n\tif (colorsEnabled) {\n\t\treturn `${TTY_COLORS.dim}${timestamp}${TTY_COLORS.reset} ${\n\t\t\tlevelColors[level]\n\t\t}${level.toUpperCase()}${TTY_COLORS.reset} ${TTY_COLORS.bright}[Better Auth]:${\n\t\t\tTTY_COLORS.reset\n\t\t} ${message}`;\n\t}\n\n\treturn `${timestamp} ${level.toUpperCase()} [Better Auth]: ${message}`;\n};\n\nexport type InternalLogger = {\n\t[K in LogLevel]: (...params: LogHandlerParams) => void;\n} & {\n\tget level(): LogLevel;\n};\n\nexport const createLogger = (options?: Logger | undefined): InternalLogger => {\n\tconst enabled = options?.disabled !== true;\n\tconst logLevel = options?.level ?? \"warn\";\n\n\tconst isDisableColorsSpecified = options?.disableColors !== undefined;\n\tconst colorsEnabled = isDisableColorsSpecified\n\t\t? !options.disableColors\n\t\t: getColorDepth() !== 1;\n\n\tconst LogFunc = (\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\targs: any[] = [],\n\t): void => {\n\t\tif (!enabled || !shouldPublishLog(logLevel, level)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst formattedMessage = formatMessage(level, message, colorsEnabled);\n\n\t\tif (!options || typeof options.log !== \"function\") {\n\t\t\tif (level === \"error\") {\n\t\t\t\tconsole.error(formattedMessage, ...args);\n\t\t\t} else if (level === \"warn\") {\n\t\t\t\tconsole.warn(formattedMessage, ...args);\n\t\t\t} else {\n\t\t\t\tconsole.log(formattedMessage, ...args);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\toptions.log(level === \"success\" ? \"info\" : level, message, ...args);\n\t};\n\n\tconst logger = Object.fromEntries(\n\t\tlevels.map((level) => [\n\t\t\tlevel,\n\t\t\t(...[message, ...args]: LogHandlerParams) =>\n\t\t\t\tLogFunc(level, message, args),\n\t\t]),\n\t) as Record<LogLevel, (...params: LogHandlerParams) => void>;\n\n\treturn {\n\t\t...logger,\n\t\tget level() {\n\t\t\treturn logLevel;\n\t\t},\n\t};\n};\n\nexport const logger = createLogger();\n"],"mappings":";;;AAEA,MAAa,aAAa;CACzB,OAAO;CACP,QAAQ;CACR,KAAK;CACL,OAAO;CACP,YAAY;CACZ,OAAO;CACP,SAAS;CACT,QAAQ;CACR,IAAI;EACH,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ;EACR,MAAM;EACN,SAAS;EACT,MAAM;EACN,OAAO;EACP;CACD,IAAI;EACH,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ;EACR,MAAM;EACN,SAAS;EACT,MAAM;EACN,OAAO;EACP;CACD;AAID,MAAa,SAAS;CAAC;CAAS;CAAQ;CAAW;CAAQ;CAAQ;AAEnE,SAAgB,iBACf,iBACA,UACU;AACV,QAAO,OAAO,QAAQ,SAAS,IAAI,OAAO,QAAQ,gBAAgB;;AAqBnE,MAAM,cAAwC;CAC7C,MAAM,WAAW,GAAG;CACpB,SAAS,WAAW,GAAG;CACvB,MAAM,WAAW,GAAG;CACpB,OAAO,WAAW,GAAG;CACrB,OAAO,WAAW,GAAG;CACrB;AAED,MAAM,iBACL,OACA,SACA,kBACY;CACZ,MAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAE1C,KAAI,cACH,QAAO,GAAG,WAAW,MAAM,YAAY,WAAW,MAAM,GACvD,YAAY,SACV,MAAM,aAAa,GAAG,WAAW,MAAM,GAAG,WAAW,OAAO,gBAC9D,WAAW,MACX,GAAG;AAGL,QAAO,GAAG,UAAU,GAAG,MAAM,aAAa,CAAC,kBAAkB;;AAS9D,MAAa,gBAAgB,YAAiD;CAC7E,MAAM,UAAU,SAAS,aAAa;CACtC,MAAM,WAAW,SAAS,SAAS;CAGnC,MAAM,gBAD2B,SAAS,kBAAkB,SAEzD,CAAC,QAAQ,gBACT,eAAe,KAAK;CAEvB,MAAM,WACL,OACA,SACA,OAAc,EAAE,KACN;AACV,MAAI,CAAC,WAAW,CAAC,iBAAiB,UAAU,MAAM,CACjD;EAGD,MAAM,mBAAmB,cAAc,OAAO,SAAS,cAAc;AAErE,MAAI,CAAC,WAAW,OAAO,QAAQ,QAAQ,YAAY;AAClD,OAAI,UAAU,QACb,SAAQ,MAAM,kBAAkB,GAAG,KAAK;YAC9B,UAAU,OACpB,SAAQ,KAAK,kBAAkB,GAAG,KAAK;OAEvC,SAAQ,IAAI,kBAAkB,GAAG,KAAK;AAEvC;;AAGD,UAAQ,IAAI,UAAU,YAAY,SAAS,OAAO,SAAS,GAAG,KAAK;;AAWpE,QAAO;EACN,GATc,OAAO,YACrB,OAAO,KAAK,UAAU,CACrB,QACC,GAAG,CAAC,SAAS,GAAG,UAChB,QAAQ,OAAO,SAAS,KAAK,CAC9B,CAAC,CACF;EAIA,IAAI,QAAQ;AACX,UAAO;;EAER;;AAGF,MAAa,SAAS,cAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"codes.mjs","names":[],"sources":["../../src/error/codes.ts"],"sourcesContent":["import { defineErrorCodes } from \"../utils/error-codes\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\t/**\n\t\t * This plugin does not exist, do not use it in runtime.\n\t\t */\n\t\t\"$internal:base\": {\n\t\t\tcreator: () => {\n\t\t\t\t$ERROR_CODES: typeof BASE_ERROR_CODES;\n\t\t\t};\n\t\t};\n\t}\n}\n\nexport const BASE_ERROR_CODES = defineErrorCodes({\n\tUSER_NOT_FOUND: \"User not found\",\n\tFAILED_TO_CREATE_USER: \"Failed to create user\",\n\tFAILED_TO_CREATE_SESSION: \"Failed to create session\",\n\tFAILED_TO_UPDATE_USER: \"Failed to update user\",\n\tFAILED_TO_GET_SESSION: \"Failed to get session\",\n\tINVALID_PASSWORD: \"Invalid password\",\n\tINVALID_EMAIL: \"Invalid email\",\n\tINVALID_EMAIL_OR_PASSWORD: \"Invalid email or password\",\n\tINVALID_USER: \"Invalid user\",\n\tSOCIAL_ACCOUNT_ALREADY_LINKED: \"Social account already linked\",\n\tPROVIDER_NOT_FOUND: \"Provider not found\",\n\tINVALID_TOKEN: \"Invalid token\",\n\tTOKEN_EXPIRED: \"Token expired\",\n\tID_TOKEN_NOT_SUPPORTED: \"id_token not supported\",\n\tFAILED_TO_GET_USER_INFO: \"Failed to get user info\",\n\tUSER_EMAIL_NOT_FOUND: \"User email not found\",\n\tEMAIL_NOT_VERIFIED: \"Email not verified\",\n\tPASSWORD_TOO_SHORT: \"Password too short\",\n\tPASSWORD_TOO_LONG: \"Password too long\",\n\tUSER_ALREADY_EXISTS: \"User already exists.\",\n\tUSER_ALREADY_EXISTS_USE_ANOTHER_EMAIL:\n\t\t\"User already exists. Use another email.\",\n\tEMAIL_CAN_NOT_BE_UPDATED: \"Email can not be updated\",\n\tCREDENTIAL_ACCOUNT_NOT_FOUND: \"Credential account not found\",\n\tSESSION_EXPIRED: \"Session expired. Re-authenticate to perform this action.\",\n\tFAILED_TO_UNLINK_LAST_ACCOUNT: \"You can't unlink your last account\",\n\tACCOUNT_NOT_FOUND: \"Account not found\",\n\tUSER_ALREADY_HAS_PASSWORD:\n\t\t\"User already has a password. Provide that to delete the account.\",\n\tCROSS_SITE_NAVIGATION_LOGIN_BLOCKED:\n\t\t\"Cross-site navigation login blocked. This request appears to be a CSRF attack.\",\n\tVERIFICATION_EMAIL_NOT_ENABLED: \"Verification email isn't enabled\",\n\tEMAIL_ALREADY_VERIFIED: \"Email is already verified\",\n\tEMAIL_MISMATCH: \"Email mismatch\",\n\tSESSION_NOT_FRESH: \"Session is not fresh\",\n\tLINKED_ACCOUNT_ALREADY_EXISTS: \"Linked account already exists\",\n\tINVALID_ORIGIN: \"Invalid origin\",\n\tINVALID_CALLBACK_URL: \"Invalid callbackURL\",\n\tINVALID_REDIRECT_URL: \"Invalid redirectURL\",\n\tINVALID_ERROR_CALLBACK_URL: \"Invalid errorCallbackURL\",\n\tINVALID_NEW_USER_CALLBACK_URL: \"Invalid newUserCallbackURL\",\n\tMISSING_OR_NULL_ORIGIN: \"Missing or null Origin\",\n\tCALLBACK_URL_REQUIRED: \"callbackURL is required\",\n\tFAILED_TO_CREATE_VERIFICATION: \"Unable to create verification\",\n\tFIELD_NOT_ALLOWED: \"Field not allowed to be set\",\n\tASYNC_VALIDATION_NOT_SUPPORTED: \"Async validation is not supported\",\n\tVALIDATION_ERROR: \"Validation Error\",\n\tMISSING_FIELD: \"Field is required\",\n\tMETHOD_NOT_ALLOWED_DEFER_SESSION_REQUIRED:\n\t\t\"POST method requires deferSessionRefresh to be enabled in session config\",\n\tBODY_MUST_BE_AN_OBJECT: \"Body must be an object\",\n\tPASSWORD_ALREADY_SET: \"User already has a password set\",\n});\n\nexport type APIErrorCode = keyof typeof BASE_ERROR_CODES;\n"],"mappings":";;;AAeA,MAAa,mBAAmB,iBAAiB;CAChD,gBAAgB;CAChB,uBAAuB;CACvB,0BAA0B;CAC1B,uBAAuB;CACvB,uBAAuB;CACvB,kBAAkB;CAClB,eAAe;CACf,2BAA2B;CAC3B,cAAc;CACd,+BAA+B;CAC/B,oBAAoB;CACpB,eAAe;CACf,eAAe;CACf,wBAAwB;CACxB,yBAAyB;CACzB,sBAAsB;CACtB,oBAAoB;CACpB,oBAAoB;CACpB,mBAAmB;CACnB,qBAAqB;CACrB,uCACC;CACD,0BAA0B;CAC1B,8BAA8B;CAC9B,iBAAiB;CACjB,+BAA+B;CAC/B,mBAAmB;CACnB,2BACC;CACD,qCACC;CACD,gCAAgC;CAChC,wBAAwB;CACxB,gBAAgB;CAChB,mBAAmB;CACnB,+BAA+B;CAC/B,gBAAgB;CAChB,sBAAsB;CACtB,sBAAsB;CACtB,4BAA4B;CAC5B,+BAA+B;CAC/B,wBAAwB;CACxB,uBAAuB;CACvB,+BAA+B;CAC/B,mBAAmB;CACnB,gCAAgC;CAChC,kBAAkB;CAClB,eAAe;CACf,2CACC;CACD,wBAAwB;CACxB,sBAAsB;CACtB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":["BaseAPIError"],"sources":["../../src/error/index.ts"],"sourcesContent":["import { APIError as BaseAPIError } from \"better-call/error\";\n\nexport class BetterAuthError extends Error {\n\tconstructor(message: string, options?: { cause?: unknown | undefined }) {\n\t\tsuper(message, options);\n\t\tthis.name = \"BetterAuthError\";\n\t\tthis.message = message;\n\t\tthis.stack = \"\";\n\t}\n}\n\nexport { type APIErrorCode, BASE_ERROR_CODES } from \"./codes\";\n\nexport class APIError extends BaseAPIError {\n\tconstructor(...args: ConstructorParameters<typeof BaseAPIError>) {\n\t\tsuper(...args);\n\t}\n\n\tstatic fromStatus(\n\t\tstatus: ConstructorParameters<typeof BaseAPIError>[0],\n\t\tbody?: ConstructorParameters<typeof BaseAPIError>[1],\n\t) {\n\t\treturn new APIError(status, body);\n\t}\n\n\tstatic from(\n\t\tstatus: ConstructorParameters<typeof BaseAPIError>[0],\n\t\terror: { code: string; message: string },\n\t) {\n\t\treturn new APIError(status, {\n\t\t\tmessage: error.message,\n\t\t\tcode: error.code,\n\t\t});\n\t}\n}\n"],"mappings":";;;;AAEA,IAAa,kBAAb,cAAqC,MAAM;CAC1C,YAAY,SAAiB,SAA2C;AACvE,QAAM,SAAS,QAAQ;AACvB,OAAK,OAAO;AACZ,OAAK,UAAU;AACf,OAAK,QAAQ;;;AAMf,IAAa,WAAb,MAAa,iBAAiBA,WAAa;CAC1C,YAAY,GAAG,MAAkD;AAChE,QAAM,GAAG,KAAK;;CAGf,OAAO,WACN,QACA,MACC;AACD,SAAO,IAAI,SAAS,QAAQ,KAAK;;CAGlC,OAAO,KACN,QACA,OACC;AACD,SAAO,IAAI,SAAS,QAAQ;GAC3B,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"attributes.mjs","names":[],"sources":["../../src/instrumentation/attributes.ts"],"sourcesContent":["import {\n\tATTR_DB_COLLECTION_NAME,\n\tATTR_DB_OPERATION_NAME,\n\tATTR_HTTP_RESPONSE_STATUS_CODE,\n\tATTR_HTTP_ROUTE,\n} from \"@opentelemetry/semantic-conventions\";\n\nexport {\n\tATTR_DB_COLLECTION_NAME,\n\tATTR_DB_OPERATION_NAME,\n\tATTR_HTTP_RESPONSE_STATUS_CODE,\n\tATTR_HTTP_ROUTE,\n};\n\n/** Operation identifier (e.g. getSession, signUpWithEmailAndPassword). Uses endpoint operationId when set, otherwise the endpoint key. */\nexport const ATTR_OPERATION_ID = \"better_auth.operation_id\" as const;\n\n/** Hook type (e.g. before, after, create.before). */\nexport const ATTR_HOOK_TYPE = \"better_auth.hook.type\" as const;\n\n/** Execution context (e.g. user, plugin:id). */\nexport const ATTR_CONTEXT = \"better_auth.context\" as const;\n"],"mappings":";;;;AAeA,MAAa,oBAAoB;;AAGjC,MAAa,iBAAiB;;AAG9B,MAAa,eAAe"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tracer.mjs","names":[],"sources":["../../src/instrumentation/tracer.ts"],"sourcesContent":["import { SpanStatusCode, trace } from \"@opentelemetry/api\";\n\nconst INSTRUMENTATION_SCOPE = \"better-auth\";\nconst INSTRUMENTATION_VERSION = import.meta.env?.BETTER_AUTH_VERSION ?? \"1.0.0\";\n\nconst tracer = trace.getTracer(INSTRUMENTATION_SCOPE, INSTRUMENTATION_VERSION);\n\n/**\n * Creates a child span whose lifetime is bound to the execution of the given function\n *\n * @param name - The name of the span.\n * @param attributes - The attributes of the span.\n * @param fn - The function to execute within the span.\n * @returns The result of the function.\n */\nexport function withSpan<T>(\n\tname: string,\n\tattributes: Record<string, string | number | boolean>,\n\tfn: () => T,\n): T;\nexport function withSpan<T>(\n\tname: string,\n\tattributes: Record<string, string | number | boolean>,\n\tfn: () => Promise<T>,\n): Promise<T>;\nexport function withSpan<T>(\n\tname: string,\n\tattributes: Record<string, string | number | boolean>,\n\tfn: () => T | Promise<T>,\n): T | Promise<T> {\n\treturn tracer.startActiveSpan(name, { attributes }, (span) => {\n\t\ttry {\n\t\t\tconst result = fn();\n\t\t\tif (result instanceof Promise) {\n\t\t\t\treturn result\n\t\t\t\t\t.then((value) => {\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tspan.recordException(err);\n\t\t\t\t\t\tspan.setStatus({\n\t\t\t\t\t\t\tcode: SpanStatusCode.ERROR,\n\t\t\t\t\t\t\tmessage: String(err.message ?? err),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}) as Promise<T>;\n\t\t\t}\n\t\t\tspan.end();\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tspan.recordException(err as Error);\n\t\t\tspan.setStatus({\n\t\t\t\tcode: SpanStatusCode.ERROR,\n\t\t\t\tmessage: String((err as Error)?.message ?? err),\n\t\t\t});\n\t\t\tspan.end();\n\t\t\tthrow err;\n\t\t}\n\t});\n}\n"],"mappings":";;;AAKA,MAAM,SAAS,MAAM,UAHS,uBAGgD;AAoB9E,SAAgB,SACf,MACA,YACA,IACiB;AACjB,QAAO,OAAO,gBAAgB,MAAM,EAAE,YAAY,GAAG,SAAS;AAC7D,MAAI;GACH,MAAM,SAAS,IAAI;AACnB,OAAI,kBAAkB,QACrB,QAAO,OACL,MAAM,UAAU;AAChB,SAAK,KAAK;AACV,WAAO;KACN,CACD,OAAO,QAAQ;AACf,SAAK,gBAAgB,IAAI;AACzB,SAAK,UAAU;KACd,MAAM,eAAe;KACrB,SAAS,OAAO,IAAI,WAAW,IAAI;KACnC,CAAC;AACF,SAAK,KAAK;AACV,UAAM;KACL;AAEJ,QAAK,KAAK;AACV,UAAO;WACC,KAAK;AACb,QAAK,gBAAgB,IAAa;AAClC,QAAK,UAAU;IACd,MAAM,eAAe;IACrB,SAAS,OAAQ,KAAe,WAAW,IAAI;IAC/C,CAAC;AACF,QAAK,KAAK;AACV,SAAM;;GAEN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-credentials-token.mjs","names":[],"sources":["../../src/oauth2/client-credentials-token.ts"],"sourcesContent":["import { base64Url } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport type { AwaitableFunction } from \"../types\";\nimport type { OAuth2Tokens, ProviderOptions } from \"./oauth-provider\";\n\nexport async function clientCredentialsTokenRequest({\n\toptions,\n\tscope,\n\tauthentication,\n\tresource,\n}: {\n\toptions: AwaitableFunction<ProviderOptions & { clientSecret: string }>;\n\tscope?: string | undefined;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\toptions = typeof options === \"function\" ? await options() : options;\n\treturn createClientCredentialsTokenRequest({\n\t\toptions,\n\t\tscope,\n\t\tauthentication,\n\t\tresource,\n\t});\n}\n\n/**\n * @deprecated use async'd clientCredentialsTokenRequest instead\n */\nexport function createClientCredentialsTokenRequest({\n\toptions,\n\tscope,\n\tauthentication,\n\tresource,\n}: {\n\toptions: ProviderOptions & { clientSecret: string };\n\tscope?: string | undefined;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\tconst body = new URLSearchParams();\n\tconst headers: Record<string, any> = {\n\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\taccept: \"application/json\",\n\t};\n\n\tbody.set(\"grant_type\", \"client_credentials\");\n\tscope && body.set(\"scope\", scope);\n\tif (resource) {\n\t\tif (typeof resource === \"string\") {\n\t\t\tbody.append(\"resource\", resource);\n\t\t} else {\n\t\t\tfor (const _resource of resource) {\n\t\t\t\tbody.append(\"resource\", _resource);\n\t\t\t}\n\t\t}\n\t}\n\tif (authentication === \"basic\") {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tconst encodedCredentials = base64Url.encode(\n\t\t\t`${primaryClientId}:${options.clientSecret}`,\n\t\t);\n\t\theaders[\"authorization\"] = `Basic ${encodedCredentials}`;\n\t} else {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tbody.set(\"client_id\", primaryClientId);\n\t\tbody.set(\"client_secret\", options.clientSecret);\n\t}\n\n\treturn {\n\t\tbody,\n\t\theaders,\n\t};\n}\n\nexport async function clientCredentialsToken({\n\toptions,\n\ttokenEndpoint,\n\tscope,\n\tauthentication,\n\tresource,\n}: {\n\toptions: AwaitableFunction<ProviderOptions & { clientSecret: string }>;\n\ttokenEndpoint: string;\n\tscope: string;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\tresource?: (string | string[]) | undefined;\n}): Promise<OAuth2Tokens> {\n\tconst { body, headers } = await clientCredentialsTokenRequest({\n\t\toptions,\n\t\tscope,\n\t\tauthentication,\n\t\tresource,\n\t});\n\n\tconst { data, error } = await betterFetch<{\n\t\taccess_token: string;\n\t\texpires_in?: number | undefined;\n\t\ttoken_type?: string | undefined;\n\t\tscope?: string | undefined;\n\t}>(tokenEndpoint, {\n\t\tmethod: \"POST\",\n\t\tbody,\n\t\theaders,\n\t});\n\tif (error) {\n\t\tthrow error;\n\t}\n\tconst tokens: OAuth2Tokens = {\n\t\taccessToken: data.access_token,\n\t\ttokenType: data.token_type,\n\t\tscopes: data.scope?.split(\" \"),\n\t};\n\n\tif (data.expires_in) {\n\t\tconst now = new Date();\n\t\ttokens.accessTokenExpiresAt = new Date(\n\t\t\tnow.getTime() + data.expires_in * 1000,\n\t\t);\n\t}\n\n\treturn tokens;\n}\n"],"mappings":";;;;AAKA,eAAsB,8BAA8B,EACnD,SACA,OACA,gBACA,YAME;AACF,WAAU,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG;AAC5D,QAAO,oCAAoC;EAC1C;EACA;EACA;EACA;EACA,CAAC;;;;;AAMH,SAAgB,oCAAoC,EACnD,SACA,OACA,gBACA,YAME;CACF,MAAM,OAAO,IAAI,iBAAiB;CAClC,MAAM,UAA+B;EACpC,gBAAgB;EAChB,QAAQ;EACR;AAED,MAAK,IAAI,cAAc,qBAAqB;AAC5C,UAAS,KAAK,IAAI,SAAS,MAAM;AACjC,KAAI,SACH,KAAI,OAAO,aAAa,SACvB,MAAK,OAAO,YAAY,SAAS;KAEjC,MAAK,MAAM,aAAa,SACvB,MAAK,OAAO,YAAY,UAAU;AAIrC,KAAI,mBAAmB,SAAS;EAC/B,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AAIX,UAAQ,mBAAmB,SAHA,UAAU,OACpC,GAAG,gBAAgB,GAAG,QAAQ,eAC9B;QAEK;EACN,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AACX,OAAK,IAAI,aAAa,gBAAgB;AACtC,OAAK,IAAI,iBAAiB,QAAQ,aAAa;;AAGhD,QAAO;EACN;EACA;EACA;;AAGF,eAAsB,uBAAuB,EAC5C,SACA,eACA,OACA,gBACA,YAOyB;CACzB,MAAM,EAAE,MAAM,YAAY,MAAM,8BAA8B;EAC7D;EACA;EACA;EACA;EACA,CAAC;CAEF,MAAM,EAAE,MAAM,UAAU,MAAM,YAK3B,eAAe;EACjB,QAAQ;EACR;EACA;EACA,CAAC;AACF,KAAI,MACH,OAAM;CAEP,MAAM,SAAuB;EAC5B,aAAa,KAAK;EAClB,WAAW,KAAK;EAChB,QAAQ,KAAK,OAAO,MAAM,IAAI;EAC9B;AAED,KAAI,KAAK,YAAY;EACpB,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAO,uBAAuB,IAAI,KACjC,IAAI,SAAS,GAAG,KAAK,aAAa,IAClC;;AAGF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-authorization-url.mjs","names":[],"sources":["../../src/oauth2/create-authorization-url.ts"],"sourcesContent":["import type { AwaitableFunction } from \"../types\";\nimport type { ProviderOptions } from \"./index\";\nimport { generateCodeChallenge } from \"./utils\";\n\nexport async function createAuthorizationURL({\n\tid,\n\toptions,\n\tauthorizationEndpoint,\n\tstate,\n\tcodeVerifier,\n\tscopes,\n\tclaims,\n\tredirectURI,\n\tduration,\n\tprompt,\n\taccessType,\n\tresponseType,\n\tdisplay,\n\tloginHint,\n\thd,\n\tresponseMode,\n\tadditionalParams,\n\tscopeJoiner,\n}: {\n\tid: string;\n\toptions: AwaitableFunction<ProviderOptions>;\n\tredirectURI: string;\n\tauthorizationEndpoint: string;\n\tstate: string;\n\tcodeVerifier?: string | undefined;\n\tscopes?: string[] | undefined;\n\tclaims?: string[] | undefined;\n\tduration?: string | undefined;\n\tprompt?: string | undefined;\n\taccessType?: string | undefined;\n\tresponseType?: string | undefined;\n\tdisplay?: string | undefined;\n\tloginHint?: string | undefined;\n\thd?: string | undefined;\n\tresponseMode?: string | undefined;\n\tadditionalParams?: Record<string, string> | undefined;\n\tscopeJoiner?: string | undefined;\n}) {\n\toptions = typeof options === \"function\" ? await options() : options;\n\tconst url = new URL(options.authorizationEndpoint || authorizationEndpoint);\n\turl.searchParams.set(\"response_type\", responseType || \"code\");\n\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t? options.clientId[0]\n\t\t: options.clientId;\n\turl.searchParams.set(\"client_id\", primaryClientId);\n\turl.searchParams.set(\"state\", state);\n\tif (scopes) {\n\t\turl.searchParams.set(\"scope\", scopes.join(scopeJoiner || \" \"));\n\t}\n\turl.searchParams.set(\"redirect_uri\", options.redirectURI || redirectURI);\n\tduration && url.searchParams.set(\"duration\", duration);\n\tdisplay && url.searchParams.set(\"display\", display);\n\tloginHint && url.searchParams.set(\"login_hint\", loginHint);\n\tprompt && url.searchParams.set(\"prompt\", prompt);\n\thd && url.searchParams.set(\"hd\", hd);\n\taccessType && url.searchParams.set(\"access_type\", accessType);\n\tresponseMode && url.searchParams.set(\"response_mode\", responseMode);\n\tif (codeVerifier) {\n\t\tconst codeChallenge = await generateCodeChallenge(codeVerifier);\n\t\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\t\turl.searchParams.set(\"code_challenge\", codeChallenge);\n\t}\n\tif (claims) {\n\t\tconst claimsObj = claims.reduce(\n\t\t\t(acc, claim) => {\n\t\t\t\tacc[claim] = null;\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, null>,\n\t\t);\n\t\turl.searchParams.set(\n\t\t\t\"claims\",\n\t\t\tJSON.stringify({\n\t\t\t\tid_token: { email: null, email_verified: null, ...claimsObj },\n\t\t\t}),\n\t\t);\n\t}\n\tif (additionalParams) {\n\t\tObject.entries(additionalParams).forEach(([key, value]) => {\n\t\t\turl.searchParams.set(key, value);\n\t\t});\n\t}\n\treturn url;\n}\n"],"mappings":";;;AAIA,eAAsB,uBAAuB,EAC5C,IACA,SACA,uBACA,OACA,cACA,QACA,QACA,aACA,UACA,QACA,YACA,cACA,SACA,WACA,IACA,cACA,kBACA,eAoBE;AACF,WAAU,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG;CAC5D,MAAM,MAAM,IAAI,IAAI,QAAQ,yBAAyB,sBAAsB;AAC3E,KAAI,aAAa,IAAI,iBAAiB,gBAAgB,OAAO;CAC7D,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AACX,KAAI,aAAa,IAAI,aAAa,gBAAgB;AAClD,KAAI,aAAa,IAAI,SAAS,MAAM;AACpC,KAAI,OACH,KAAI,aAAa,IAAI,SAAS,OAAO,KAAK,eAAe,IAAI,CAAC;AAE/D,KAAI,aAAa,IAAI,gBAAgB,QAAQ,eAAe,YAAY;AACxE,aAAY,IAAI,aAAa,IAAI,YAAY,SAAS;AACtD,YAAW,IAAI,aAAa,IAAI,WAAW,QAAQ;AACnD,cAAa,IAAI,aAAa,IAAI,cAAc,UAAU;AAC1D,WAAU,IAAI,aAAa,IAAI,UAAU,OAAO;AAChD,OAAM,IAAI,aAAa,IAAI,MAAM,GAAG;AACpC,eAAc,IAAI,aAAa,IAAI,eAAe,WAAW;AAC7D,iBAAgB,IAAI,aAAa,IAAI,iBAAiB,aAAa;AACnE,KAAI,cAAc;EACjB,MAAM,gBAAgB,MAAM,sBAAsB,aAAa;AAC/D,MAAI,aAAa,IAAI,yBAAyB,OAAO;AACrD,MAAI,aAAa,IAAI,kBAAkB,cAAc;;AAEtD,KAAI,QAAQ;EACX,MAAM,YAAY,OAAO,QACvB,KAAK,UAAU;AACf,OAAI,SAAS;AACb,UAAO;KAER,EAAE,CACF;AACD,MAAI,aAAa,IAChB,UACA,KAAK,UAAU,EACd,UAAU;GAAE,OAAO;GAAM,gBAAgB;GAAM,GAAG;GAAW,EAC7D,CAAC,CACF;;AAEF,KAAI,iBACH,QAAO,QAAQ,iBAAiB,CAAC,SAAS,CAAC,KAAK,WAAW;AAC1D,MAAI,aAAa,IAAI,KAAK,MAAM;GAC/B;AAEH,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"refresh-access-token.mjs","names":[],"sources":["../../src/oauth2/refresh-access-token.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport type { AwaitableFunction } from \"../types\";\nimport type { OAuth2Tokens, ProviderOptions } from \"./oauth-provider\";\n\nexport async function refreshAccessTokenRequest({\n\trefreshToken,\n\toptions,\n\tauthentication,\n\textraParams,\n\tresource,\n}: {\n\trefreshToken: string;\n\toptions: AwaitableFunction<Partial<ProviderOptions>>;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\textraParams?: Record<string, string> | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\toptions = typeof options === \"function\" ? await options() : options;\n\treturn createRefreshAccessTokenRequest({\n\t\trefreshToken,\n\t\toptions,\n\t\tauthentication,\n\t\textraParams,\n\t\tresource,\n\t});\n}\n\n/**\n * @deprecated use async'd refreshAccessTokenRequest instead\n */\nexport function createRefreshAccessTokenRequest({\n\trefreshToken,\n\toptions,\n\tauthentication,\n\textraParams,\n\tresource,\n}: {\n\trefreshToken: string;\n\toptions: ProviderOptions;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\textraParams?: Record<string, string> | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\tconst body = new URLSearchParams();\n\tconst headers: Record<string, any> = {\n\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\taccept: \"application/json\",\n\t};\n\n\tbody.set(\"grant_type\", \"refresh_token\");\n\tbody.set(\"refresh_token\", refreshToken);\n\t// Use standard Base64 encoding for HTTP Basic Auth (OAuth2 spec, RFC 7617)\n\t// Fixes compatibility with providers like Notion, Twitter, etc.\n\tif (authentication === \"basic\") {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tif (primaryClientId) {\n\t\t\theaders[\"authorization\"] =\n\t\t\t\t\"Basic \" +\n\t\t\t\tbase64.encode(`${primaryClientId}:${options.clientSecret ?? \"\"}`);\n\t\t} else {\n\t\t\theaders[\"authorization\"] =\n\t\t\t\t\"Basic \" + base64.encode(`:${options.clientSecret ?? \"\"}`);\n\t\t}\n\t} else {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tbody.set(\"client_id\", primaryClientId);\n\t\tif (options.clientSecret) {\n\t\t\tbody.set(\"client_secret\", options.clientSecret);\n\t\t}\n\t}\n\n\tif (resource) {\n\t\tif (typeof resource === \"string\") {\n\t\t\tbody.append(\"resource\", resource);\n\t\t} else {\n\t\t\tfor (const _resource of resource) {\n\t\t\t\tbody.append(\"resource\", _resource);\n\t\t\t}\n\t\t}\n\t}\n\tif (extraParams) {\n\t\tfor (const [key, value] of Object.entries(extraParams)) {\n\t\t\tbody.set(key, value);\n\t\t}\n\t}\n\n\treturn {\n\t\tbody,\n\t\theaders,\n\t};\n}\n\nexport async function refreshAccessToken({\n\trefreshToken,\n\toptions,\n\ttokenEndpoint,\n\tauthentication,\n\textraParams,\n}: {\n\trefreshToken: string;\n\toptions: Partial<ProviderOptions>;\n\ttokenEndpoint: string;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\textraParams?: Record<string, string> | undefined;\n}): Promise<OAuth2Tokens> {\n\tconst { body, headers } = await createRefreshAccessTokenRequest({\n\t\trefreshToken,\n\t\toptions,\n\t\tauthentication,\n\t\textraParams,\n\t});\n\n\tconst { data, error } = await betterFetch<{\n\t\taccess_token: string;\n\t\trefresh_token?: string | undefined;\n\t\texpires_in?: number | undefined;\n\t\trefresh_token_expires_in?: number | undefined;\n\t\ttoken_type?: string | undefined;\n\t\tscope?: string | undefined;\n\t\tid_token?: string | undefined;\n\t}>(tokenEndpoint, {\n\t\tmethod: \"POST\",\n\t\tbody,\n\t\theaders,\n\t});\n\tif (error) {\n\t\tthrow error;\n\t}\n\tconst tokens: OAuth2Tokens = {\n\t\taccessToken: data.access_token,\n\t\trefreshToken: data.refresh_token,\n\t\ttokenType: data.token_type,\n\t\tscopes: data.scope?.split(\" \"),\n\t\tidToken: data.id_token,\n\t};\n\n\tif (data.expires_in) {\n\t\tconst now = new Date();\n\t\ttokens.accessTokenExpiresAt = new Date(\n\t\t\tnow.getTime() + data.expires_in * 1000,\n\t\t);\n\t}\n\n\tif (data.refresh_token_expires_in) {\n\t\tconst now = new Date();\n\t\ttokens.refreshTokenExpiresAt = new Date(\n\t\t\tnow.getTime() + data.refresh_token_expires_in * 1000,\n\t\t);\n\t}\n\n\treturn tokens;\n}\n"],"mappings":";;;;AAKA,eAAsB,0BAA0B,EAC/C,cACA,SACA,gBACA,aACA,YAOE;AACF,WAAU,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG;AAC5D,QAAO,gCAAgC;EACtC;EACA;EACA;EACA;EACA;EACA,CAAC;;;;;AAMH,SAAgB,gCAAgC,EAC/C,cACA,SACA,gBACA,aACA,YAOE;CACF,MAAM,OAAO,IAAI,iBAAiB;CAClC,MAAM,UAA+B;EACpC,gBAAgB;EAChB,QAAQ;EACR;AAED,MAAK,IAAI,cAAc,gBAAgB;AACvC,MAAK,IAAI,iBAAiB,aAAa;AAGvC,KAAI,mBAAmB,SAAS;EAC/B,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AACX,MAAI,gBACH,SAAQ,mBACP,WACA,OAAO,OAAO,GAAG,gBAAgB,GAAG,QAAQ,gBAAgB,KAAK;MAElE,SAAQ,mBACP,WAAW,OAAO,OAAO,IAAI,QAAQ,gBAAgB,KAAK;QAEtD;EACN,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AACX,OAAK,IAAI,aAAa,gBAAgB;AACtC,MAAI,QAAQ,aACX,MAAK,IAAI,iBAAiB,QAAQ,aAAa;;AAIjD,KAAI,SACH,KAAI,OAAO,aAAa,SACvB,MAAK,OAAO,YAAY,SAAS;KAEjC,MAAK,MAAM,aAAa,SACvB,MAAK,OAAO,YAAY,UAAU;AAIrC,KAAI,YACH,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,YAAY,CACrD,MAAK,IAAI,KAAK,MAAM;AAItB,QAAO;EACN;EACA;EACA;;AAGF,eAAsB,mBAAmB,EACxC,cACA,SACA,eACA,gBACA,eAOyB;CACzB,MAAM,EAAE,MAAM,YAAY,MAAM,gCAAgC;EAC/D;EACA;EACA;EACA;EACA,CAAC;CAEF,MAAM,EAAE,MAAM,UAAU,MAAM,YAQ3B,eAAe;EACjB,QAAQ;EACR;EACA;EACA,CAAC;AACF,KAAI,MACH,OAAM;CAEP,MAAM,SAAuB;EAC5B,aAAa,KAAK;EAClB,cAAc,KAAK;EACnB,WAAW,KAAK;EAChB,QAAQ,KAAK,OAAO,MAAM,IAAI;EAC9B,SAAS,KAAK;EACd;AAED,KAAI,KAAK,YAAY;EACpB,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAO,uBAAuB,IAAI,KACjC,IAAI,SAAS,GAAG,KAAK,aAAa,IAClC;;AAGF,KAAI,KAAK,0BAA0B;EAClC,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAO,wBAAwB,IAAI,KAClC,IAAI,SAAS,GAAG,KAAK,2BAA2B,IAChD;;AAGF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/oauth2/utils.ts"],"sourcesContent":["import { base64Url } from \"@better-auth/utils/base64\";\nimport type { OAuth2Tokens } from \"./oauth-provider\";\n\nexport function getOAuth2Tokens(data: Record<string, any>): OAuth2Tokens {\n\tconst getDate = (seconds: number) => {\n\t\tconst now = new Date();\n\t\treturn new Date(now.getTime() + seconds * 1000);\n\t};\n\n\treturn {\n\t\ttokenType: data.token_type,\n\t\taccessToken: data.access_token,\n\t\trefreshToken: data.refresh_token,\n\t\taccessTokenExpiresAt: data.expires_in\n\t\t\t? getDate(data.expires_in)\n\t\t\t: undefined,\n\t\trefreshTokenExpiresAt: data.refresh_token_expires_in\n\t\t\t? getDate(data.refresh_token_expires_in)\n\t\t\t: undefined,\n\t\tscopes: data?.scope\n\t\t\t? typeof data.scope === \"string\"\n\t\t\t\t? data.scope.split(\" \")\n\t\t\t\t: data.scope\n\t\t\t: [],\n\t\tidToken: data.id_token,\n\t\t// Preserve the raw token response for provider-specific fields\n\t\traw: data,\n\t};\n}\n\nexport async function generateCodeChallenge(codeVerifier: string) {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(codeVerifier);\n\tconst hash = await crypto.subtle.digest(\"SHA-256\", data);\n\treturn base64Url.encode(new Uint8Array(hash), {\n\t\tpadding: false,\n\t});\n}\n"],"mappings":";;;AAGA,SAAgB,gBAAgB,MAAyC;CACxE,MAAM,WAAW,YAAoB;EACpC,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAO,IAAI,KAAK,IAAI,SAAS,GAAG,UAAU,IAAK;;AAGhD,QAAO;EACN,WAAW,KAAK;EAChB,aAAa,KAAK;EAClB,cAAc,KAAK;EACnB,sBAAsB,KAAK,aACxB,QAAQ,KAAK,WAAW,GACxB;EACH,uBAAuB,KAAK,2BACzB,QAAQ,KAAK,yBAAyB,GACtC;EACH,QAAQ,MAAM,QACX,OAAO,KAAK,UAAU,WACrB,KAAK,MAAM,MAAM,IAAI,GACrB,KAAK,QACN,EAAE;EACL,SAAS,KAAK;EAEd,KAAK;EACL;;AAGF,eAAsB,sBAAsB,cAAsB;CAEjE,MAAM,OADU,IAAI,aAAa,CACZ,OAAO,aAAa;CACzC,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;AACxD,QAAO,UAAU,OAAO,IAAI,WAAW,KAAK,EAAE,EAC7C,SAAS,OACT,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-authorization-code.mjs","names":[],"sources":["../../src/oauth2/validate-authorization-code.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport type { AwaitableFunction } from \"../types\";\nimport type { ProviderOptions } from \"./index\";\nimport { getOAuth2Tokens } from \"./index\";\n\nexport async function authorizationCodeRequest({\n\tcode,\n\tcodeVerifier,\n\tredirectURI,\n\toptions,\n\tauthentication,\n\tdeviceId,\n\theaders,\n\tadditionalParams = {},\n\tresource,\n}: {\n\tcode: string;\n\tredirectURI: string;\n\toptions: AwaitableFunction<Partial<ProviderOptions>>;\n\tcodeVerifier?: string | undefined;\n\tdeviceId?: string | undefined;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\theaders?: Record<string, string> | undefined;\n\tadditionalParams?: Record<string, string> | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\toptions = typeof options === \"function\" ? await options() : options;\n\treturn createAuthorizationCodeRequest({\n\t\tcode,\n\t\tcodeVerifier,\n\t\tredirectURI,\n\t\toptions,\n\t\tauthentication,\n\t\tdeviceId,\n\t\theaders,\n\t\tadditionalParams,\n\t\tresource,\n\t});\n}\n\n/**\n * @deprecated use async'd authorizationCodeRequest instead\n */\nexport function createAuthorizationCodeRequest({\n\tcode,\n\tcodeVerifier,\n\tredirectURI,\n\toptions,\n\tauthentication,\n\tdeviceId,\n\theaders,\n\tadditionalParams = {},\n\tresource,\n}: {\n\tcode: string;\n\tredirectURI: string;\n\toptions: Partial<ProviderOptions>;\n\tcodeVerifier?: string | undefined;\n\tdeviceId?: string | undefined;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\theaders?: Record<string, string> | undefined;\n\tadditionalParams?: Record<string, string> | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\tconst body = new URLSearchParams();\n\tconst requestHeaders: Record<string, any> = {\n\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\taccept: \"application/json\",\n\t\t...headers,\n\t};\n\n\tbody.set(\"grant_type\", \"authorization_code\");\n\tbody.set(\"code\", code);\n\tcodeVerifier && body.set(\"code_verifier\", codeVerifier);\n\toptions.clientKey && body.set(\"client_key\", options.clientKey);\n\tdeviceId && body.set(\"device_id\", deviceId);\n\tbody.set(\"redirect_uri\", options.redirectURI || redirectURI);\n\tif (resource) {\n\t\tif (typeof resource === \"string\") {\n\t\t\tbody.append(\"resource\", resource);\n\t\t} else {\n\t\t\tfor (const _resource of resource) {\n\t\t\t\tbody.append(\"resource\", _resource);\n\t\t\t}\n\t\t}\n\t}\n\t// Use standard Base64 encoding for HTTP Basic Auth (OAuth2 spec, RFC 7617)\n\t// Fixes compatibility with providers like Notion, Twitter, etc.\n\tif (authentication === \"basic\") {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tconst encodedCredentials = base64.encode(\n\t\t\t`${primaryClientId}:${options.clientSecret ?? \"\"}`,\n\t\t);\n\t\trequestHeaders[\"authorization\"] = `Basic ${encodedCredentials}`;\n\t} else {\n\t\tconst primaryClientId = Array.isArray(options.clientId)\n\t\t\t? options.clientId[0]\n\t\t\t: options.clientId;\n\t\tbody.set(\"client_id\", primaryClientId);\n\t\tif (options.clientSecret) {\n\t\t\tbody.set(\"client_secret\", options.clientSecret);\n\t\t}\n\t}\n\n\tfor (const [key, value] of Object.entries(additionalParams)) {\n\t\tif (!body.has(key)) body.append(key, value);\n\t}\n\n\treturn {\n\t\tbody,\n\t\theaders: requestHeaders,\n\t};\n}\n\nexport async function validateAuthorizationCode({\n\tcode,\n\tcodeVerifier,\n\tredirectURI,\n\toptions,\n\ttokenEndpoint,\n\tauthentication,\n\tdeviceId,\n\theaders,\n\tadditionalParams = {},\n\tresource,\n}: {\n\tcode: string;\n\tredirectURI: string;\n\toptions: AwaitableFunction<Partial<ProviderOptions>>;\n\tcodeVerifier?: string | undefined;\n\tdeviceId?: string | undefined;\n\ttokenEndpoint: string;\n\tauthentication?: (\"basic\" | \"post\") | undefined;\n\theaders?: Record<string, string> | undefined;\n\tadditionalParams?: Record<string, string> | undefined;\n\tresource?: (string | string[]) | undefined;\n}) {\n\tconst { body, headers: requestHeaders } = await authorizationCodeRequest({\n\t\tcode,\n\t\tcodeVerifier,\n\t\tredirectURI,\n\t\toptions,\n\t\tauthentication,\n\t\tdeviceId,\n\t\theaders,\n\t\tadditionalParams,\n\t\tresource,\n\t});\n\n\tconst { data, error } = await betterFetch<object>(tokenEndpoint, {\n\t\tmethod: \"POST\",\n\t\tbody: body,\n\t\theaders: requestHeaders,\n\t});\n\tif (error) {\n\t\tthrow error;\n\t}\n\tconst tokens = getOAuth2Tokens(data);\n\treturn tokens;\n}\n\nexport async function validateToken(\n\ttoken: string,\n\tjwksEndpoint: string,\n\toptions?: {\n\t\taudience?: string | string[];\n\t\tissuer?: string | string[];\n\t},\n) {\n\tconst jwks = createRemoteJWKSet(new URL(jwksEndpoint));\n\tconst verified = await jwtVerify(token, jwks, {\n\t\taudience: options?.audience,\n\t\tissuer: options?.issuer,\n\t});\n\treturn verified;\n}\n"],"mappings":";;;;;;;AAOA,eAAsB,yBAAyB,EAC9C,MACA,cACA,aACA,SACA,gBACA,UACA,SACA,mBAAmB,EAAE,EACrB,YAWE;AACF,WAAU,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG;AAC5D,QAAO,+BAA+B;EACrC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CAAC;;;;;AAMH,SAAgB,+BAA+B,EAC9C,MACA,cACA,aACA,SACA,gBACA,UACA,SACA,mBAAmB,EAAE,EACrB,YAWE;CACF,MAAM,OAAO,IAAI,iBAAiB;CAClC,MAAM,iBAAsC;EAC3C,gBAAgB;EAChB,QAAQ;EACR,GAAG;EACH;AAED,MAAK,IAAI,cAAc,qBAAqB;AAC5C,MAAK,IAAI,QAAQ,KAAK;AACtB,iBAAgB,KAAK,IAAI,iBAAiB,aAAa;AACvD,SAAQ,aAAa,KAAK,IAAI,cAAc,QAAQ,UAAU;AAC9D,aAAY,KAAK,IAAI,aAAa,SAAS;AAC3C,MAAK,IAAI,gBAAgB,QAAQ,eAAe,YAAY;AAC5D,KAAI,SACH,KAAI,OAAO,aAAa,SACvB,MAAK,OAAO,YAAY,SAAS;KAEjC,MAAK,MAAM,aAAa,SACvB,MAAK,OAAO,YAAY,UAAU;AAMrC,KAAI,mBAAmB,SAAS;EAC/B,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AAIX,iBAAe,mBAAmB,SAHP,OAAO,OACjC,GAAG,gBAAgB,GAAG,QAAQ,gBAAgB,KAC9C;QAEK;EACN,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,SAAS,GACpD,QAAQ,SAAS,KACjB,QAAQ;AACX,OAAK,IAAI,aAAa,gBAAgB;AACtC,MAAI,QAAQ,aACX,MAAK,IAAI,iBAAiB,QAAQ,aAAa;;AAIjD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,iBAAiB,CAC1D,KAAI,CAAC,KAAK,IAAI,IAAI,CAAE,MAAK,OAAO,KAAK,MAAM;AAG5C,QAAO;EACN;EACA,SAAS;EACT;;AAGF,eAAsB,0BAA0B,EAC/C,MACA,cACA,aACA,SACA,eACA,gBACA,UACA,SACA,mBAAmB,EAAE,EACrB,YAYE;CACF,MAAM,EAAE,MAAM,SAAS,mBAAmB,MAAM,yBAAyB;EACxE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CAAC;CAEF,MAAM,EAAE,MAAM,UAAU,MAAM,YAAoB,eAAe;EAChE,QAAQ;EACF;EACN,SAAS;EACT,CAAC;AACF,KAAI,MACH,OAAM;AAGP,QADe,gBAAgB,KAAK;;AAIrC,eAAsB,cACrB,OACA,cACA,SAIC;AAMD,QAJiB,MAAM,UAAU,OADpB,mBAAmB,IAAI,IAAI,aAAa,CAAC,EACR;EAC7C,UAAU,SAAS;EACnB,QAAQ,SAAS;EACjB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"verify.mjs","names":[],"sources":["../../src/oauth2/verify.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { APIError } from \"better-call\";\nimport type {\n\tJSONWebKeySet,\n\tJWTPayload,\n\tJWTVerifyOptions,\n\tProtectedHeaderParameters,\n} from \"jose\";\nimport {\n\tcreateLocalJWKSet,\n\tdecodeProtectedHeader,\n\tjwtVerify,\n\tUnsecuredJWT,\n} from \"jose\";\nimport { logger } from \"../env\";\n\n/** Last fetched jwks used locally in getJwks @internal */\nlet jwks: JSONWebKeySet | undefined;\n\nexport interface VerifyAccessTokenRemote {\n\t/** Full url of the introspect endpoint. Should end with `/oauth2/introspect` */\n\tintrospectUrl: string;\n\t/** Client Secret */\n\tclientId: string;\n\t/** Client Secret */\n\tclientSecret: string;\n\t/**\n\t * Forces remote verification of a token.\n\t * This ensures attached session (if applicable)\n\t * is also still active.\n\t */\n\tforce?: boolean;\n}\n\n/**\n * Performs local verification of an access token for your APIs.\n *\n * Can also be configured for remote verification.\n */\nexport async function verifyJwsAccessToken(\n\ttoken: string,\n\topts: {\n\t\t/** Jwks url or promise of a Jwks */\n\t\tjwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);\n\t\t/** Verify options */\n\t\tverifyOptions: JWTVerifyOptions &\n\t\t\tRequired<Pick<JWTVerifyOptions, \"audience\" | \"issuer\">>;\n\t},\n) {\n\ttry {\n\t\tconst jwks = await getJwks(token, opts);\n\t\tconst jwt = await jwtVerify<JWTPayload>(\n\t\t\ttoken,\n\t\t\tcreateLocalJWKSet(jwks),\n\t\t\topts.verifyOptions,\n\t\t);\n\t\t// Return the JWT payload in introspection format\n\t\t// https://datatracker.ietf.org/doc/html/rfc7662#section-2.2\n\t\tif (jwt.payload.azp) {\n\t\t\tjwt.payload.client_id = jwt.payload.azp;\n\t\t}\n\t\treturn jwt.payload;\n\t} catch (error) {\n\t\tif (error instanceof Error) throw error;\n\t\tthrow new Error(error as unknown as string);\n\t}\n}\n\nexport async function getJwks(\n\ttoken: string,\n\topts: {\n\t\t/** Jwks url or promise of a Jwks */\n\t\tjwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);\n\t},\n) {\n\t// Attempt to decode the token and find a matching kid in jwks\n\tlet jwtHeaders: ProtectedHeaderParameters | undefined;\n\ttry {\n\t\tjwtHeaders = decodeProtectedHeader(token);\n\t} catch (error) {\n\t\tif (error instanceof Error) throw error;\n\t\tthrow new Error(error as unknown as string);\n\t}\n\n\tif (!jwtHeaders.kid) throw new Error(\"Missing jwt kid\");\n\n\t// Fetch jwks if not set or has a different kid than the one stored\n\tif (!jwks || !jwks.keys.find((jwk) => jwk.kid === jwtHeaders.kid)) {\n\t\tjwks =\n\t\t\ttypeof opts.jwksFetch === \"string\"\n\t\t\t\t? await betterFetch<JSONWebKeySet>(opts.jwksFetch, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}).then(async (res) => {\n\t\t\t\t\t\tif (res.error)\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Jwks failed: ${res.error.message ?? res.error.statusText}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn res.data;\n\t\t\t\t\t})\n\t\t\t\t: await opts.jwksFetch();\n\t\tif (!jwks) throw new Error(\"No jwks found\");\n\t}\n\n\treturn jwks;\n}\n\n/**\n * Performs local verification of an access token for your API.\n *\n * Can also be configured for remote verification.\n */\nexport async function verifyAccessToken(\n\ttoken: string,\n\topts: {\n\t\t/** Verify options */\n\t\tverifyOptions: JWTVerifyOptions &\n\t\t\tRequired<Pick<JWTVerifyOptions, \"audience\" | \"issuer\">>;\n\t\t/** Scopes to additionally verify. Token must include all but not exact. */\n\t\tscopes?: string[];\n\t\t/** Required to verify access token locally */\n\t\tjwksUrl?: string;\n\t\t/** If provided, can verify a token remotely */\n\t\tremoteVerify?: VerifyAccessTokenRemote;\n\t},\n) {\n\tlet payload: JWTPayload | undefined;\n\t// Locally verify\n\tif (opts.jwksUrl && !opts?.remoteVerify?.force) {\n\t\ttry {\n\t\t\tpayload = await verifyJwsAccessToken(token, {\n\t\t\t\tjwksFetch: opts.jwksUrl,\n\t\t\t\tverifyOptions: opts.verifyOptions,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"TypeError\" || error.name === \"JWSInvalid\") {\n\t\t\t\t\t// likely an opaque token (continue)\n\t\t\t\t} else if (error.name === \"JWTExpired\") {\n\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\tmessage: \"token expired\",\n\t\t\t\t\t});\n\t\t\t\t} else if (error.name === \"JWTInvalid\") {\n\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\tmessage: \"token invalid\",\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(error as unknown as string);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remote verify\n\tif (opts?.remoteVerify) {\n\t\tconst { data: introspect, error: introspectError } = await betterFetch<\n\t\t\tJWTPayload & {\n\t\t\t\tactive: boolean;\n\t\t\t}\n\t\t>(opts.remoteVerify.introspectUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tclient_id: opts.remoteVerify.clientId,\n\t\t\t\tclient_secret: opts.remoteVerify.clientSecret,\n\t\t\t\ttoken,\n\t\t\t\ttoken_type_hint: \"access_token\",\n\t\t\t}).toString(),\n\t\t});\n\t\tif (introspectError)\n\t\t\tlogger.error(\n\t\t\t\t`Introspection failed: ${introspectError.message ?? introspectError.statusText}`,\n\t\t\t);\n\t\tif (!introspect)\n\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\tmessage: \"introspection failed\",\n\t\t\t});\n\t\tif (!introspect.active)\n\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\tmessage: \"token inactive\",\n\t\t\t});\n\t\t// Verifies payload using verify options (token valid through introspect)\n\t\ttry {\n\t\t\tconst unsecuredJwt = new UnsecuredJWT(introspect).encode();\n\t\t\tconst { audience: _audience, ...verifyOptions } = opts.verifyOptions;\n\t\t\tconst verify = introspect.aud\n\t\t\t\t? UnsecuredJWT.decode(unsecuredJwt, opts.verifyOptions)\n\t\t\t\t: UnsecuredJWT.decode(unsecuredJwt, verifyOptions);\n\t\t\tpayload = verify.payload;\n\t\t} catch (error) {\n\t\t\tthrow new Error(error as unknown as string);\n\t\t}\n\t}\n\n\tif (!payload)\n\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\tmessage: `no token payload`,\n\t\t});\n\n\t// Check scopes if provided\n\tif (opts.scopes) {\n\t\tconst validScopes = new Set(\n\t\t\t(payload.scope as string | undefined)?.split(\" \"),\n\t\t);\n\t\tfor (const sc of opts.scopes) {\n\t\t\tif (!validScopes.has(sc)) {\n\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\tmessage: `invalid scope ${sc}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn payload;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"apple.mjs","names":[],"sources":["../../src/social-providers/apple.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\n\nimport { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from \"jose\";\nimport { APIError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\nexport interface AppleProfile {\n\t/**\n\t * The subject registered claim identifies the principal that’s the subject\n\t * of the identity token. Because this token is for your app, the value is\n\t * the unique identifier for the user.\n\t */\n\tsub: string;\n\t/**\n\t * A String value representing the user's email address.\n\t * The email address is either the user's real email address or the proxy\n\t * address, depending on their status private email relay service.\n\t */\n\temail: string;\n\t/**\n\t * A string or Boolean value that indicates whether the service verifies\n\t * the email. The value can either be a string (\"true\" or \"false\") or a\n\t * Boolean (true or false). The system may not verify email addresses for\n\t * Sign in with Apple at Work & School users, and this claim is \"false\" or\n\t * false for those users.\n\t */\n\temail_verified: true | \"true\";\n\t/**\n\t * A string or Boolean value that indicates whether the email that the user\n\t * shares is the proxy address. The value can either be a string (\"true\" or\n\t * \"false\") or a Boolean (true or false).\n\t */\n\tis_private_email: boolean;\n\t/**\n\t * An Integer value that indicates whether the user appears to be a real\n\t * person. Use the value of this claim to mitigate fraud. The possible\n\t * values are: 0 (or Unsupported), 1 (or Unknown), 2 (or LikelyReal). For\n\t * more information, see ASUserDetectionStatus. This claim is present only\n\t * in iOS 14 and later, macOS 11 and later, watchOS 7 and later, tvOS 14\n\t * and later. The claim isn’t present or supported for web-based apps.\n\t */\n\treal_user_status: number;\n\t/**\n\t * The user’s full name in the format provided during the authorization\n\t * process.\n\t */\n\tname: string;\n\t/**\n\t * The URL to the user's profile picture.\n\t */\n\tpicture: string;\n\tuser?: AppleNonConformUser | undefined;\n}\n\n/**\n * This is the shape of the `user` query parameter that Apple sends the first\n * time the user consents to the app.\n * @see https://developer.apple.com/documentation/signinwithapplerestapi/request-an-authorization-to-the-sign-in-with-apple-server./\n */\nexport interface AppleNonConformUser {\n\tname: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t};\n\temail: string;\n}\n\nexport interface AppleOptions extends ProviderOptions<AppleProfile> {\n\tclientId: string;\n\tappBundleIdentifier?: string | undefined;\n\taudience?: (string | string[]) | undefined;\n}\n\nexport const apple = (options: AppleOptions) => {\n\tconst tokenEndpoint = \"https://appleid.apple.com/auth/token\";\n\treturn {\n\t\tid: \"apple\",\n\t\tname: \"Apple\",\n\t\tasync createAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scope = options.disableDefaultScope ? [] : [\"email\", \"name\"];\n\t\t\tif (options.scope) _scope.push(...options.scope);\n\t\t\tif (scopes) _scope.push(...scopes);\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"apple\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://appleid.apple.com/auth/authorize\",\n\t\t\t\tscopes: _scope,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tresponseMode: \"form_post\",\n\t\t\t\tresponseType: \"code id_token\",\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst decodedHeader = decodeProtectedHeader(token);\n\t\t\t\tconst { kid, alg: jwtAlg } = decodedHeader;\n\t\t\t\tif (!kid || !jwtAlg) return false;\n\t\t\t\tconst publicKey = await getApplePublicKey(kid);\n\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(token, publicKey, {\n\t\t\t\t\talgorithms: [jwtAlg],\n\t\t\t\t\tissuer: \"https://appleid.apple.com\",\n\t\t\t\t\taudience:\n\t\t\t\t\t\toptions.audience && options.audience.length\n\t\t\t\t\t\t\t? options.audience\n\t\t\t\t\t\t\t: options.appBundleIdentifier\n\t\t\t\t\t\t\t\t? options.appBundleIdentifier\n\t\t\t\t\t\t\t\t: options.clientId,\n\t\t\t\t\tmaxTokenAge: \"1h\",\n\t\t\t\t});\n\t\t\t\t[\"email_verified\", \"is_private_email\"].forEach((field) => {\n\t\t\t\t\tif (jwtClaims[field] !== undefined) {\n\t\t\t\t\t\tjwtClaims[field] = Boolean(jwtClaims[field]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn !!jwtClaims;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tif (!token.idToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst profile = decodeJwt<AppleProfile>(token.idToken);\n\t\t\tif (!profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// TODO: \"\" masking will be removed when the name field is made optional\n\t\t\tlet name: string;\n\t\t\tif (token.user?.name) {\n\t\t\t\tconst firstName = token.user.name.firstName || \"\";\n\t\t\t\tconst lastName = token.user.name.lastName || \"\";\n\t\t\t\tconst fullName = `${firstName} ${lastName}`.trim();\n\t\t\t\tname = fullName;\n\t\t\t} else {\n\t\t\t\tname = profile.name || \"\";\n\t\t\t}\n\n\t\t\tconst emailVerified =\n\t\t\t\ttypeof profile.email_verified === \"boolean\"\n\t\t\t\t\t? profile.email_verified\n\t\t\t\t\t: profile.email_verified === \"true\";\n\t\t\tconst enrichedProfile = {\n\t\t\t\t...profile,\n\t\t\t\tname,\n\t\t\t};\n\t\t\tconst userMap = await options.mapProfileToUser?.(enrichedProfile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: enrichedProfile.name,\n\t\t\t\t\temailVerified: emailVerified,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: enrichedProfile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<AppleProfile>;\n};\n\nexport const getApplePublicKey = async (kid: string) => {\n\tconst APPLE_BASE_URL = \"https://appleid.apple.com\";\n\tconst JWKS_APPLE_URI = \"/auth/keys\";\n\tconst { data } = await betterFetch<{\n\t\tkeys: Array<{\n\t\t\tkid: string;\n\t\t\talg: string;\n\t\t\tkty: string;\n\t\t\tuse: string;\n\t\t\tn: string;\n\t\t\te: string;\n\t\t}>;\n\t}>(`${APPLE_BASE_URL}${JWKS_APPLE_URI}`);\n\tif (!data?.keys) {\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Keys not found\",\n\t\t});\n\t}\n\tconst jwk = data.keys.find((key) => key.kid === kid);\n\tif (!jwk) {\n\t\tthrow new Error(`JWK with kid ${kid} not found`);\n\t}\n\treturn await importJWK(jwk, jwk.alg);\n};\n"],"mappings":";;;;;;;;;AA6EA,MAAa,SAAS,YAA0B;CAC/C,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GAC5D,MAAM,SAAS,QAAQ,sBAAsB,EAAE,GAAG,CAAC,SAAS,OAAO;AACnE,OAAI,QAAQ,MAAO,QAAO,KAAK,GAAG,QAAQ,MAAM;AAChD,OAAI,OAAQ,QAAO,KAAK,GAAG,OAAO;AAWlC,UAVY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA,cAAc;IACd,cAAc;IACd,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAER,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAE3C,OAAI;IAEH,MAAM,EAAE,KAAK,KAAK,WADI,sBAAsB,MAAM;AAElD,QAAI,CAAC,OAAO,CAAC,OAAQ,QAAO;IAE5B,MAAM,EAAE,SAAS,cAAc,MAAM,UAAU,OAD7B,MAAM,kBAAkB,IAAI,EACmB;KAChE,YAAY,CAAC,OAAO;KACpB,QAAQ;KACR,UACC,QAAQ,YAAY,QAAQ,SAAS,SAClC,QAAQ,WACR,QAAQ,sBACP,QAAQ,sBACR,QAAQ;KACb,aAAa;KACb,CAAC;AACF,KAAC,kBAAkB,mBAAmB,CAAC,SAAS,UAAU;AACzD,SAAI,UAAU,WAAW,OACxB,WAAU,SAAS,QAAQ,UAAU,OAAO;MAE5C;AACF,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAER,WAAO,CAAC,CAAC;WACF;AACP,WAAO;;;EAGT,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA;IACA;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAElC,OAAI,CAAC,MAAM,QACV,QAAO;GAER,MAAM,UAAU,UAAwB,MAAM,QAAQ;AACtD,OAAI,CAAC,QACJ,QAAO;GAIR,IAAI;AACJ,OAAI,MAAM,MAAM,KAIf,QADiB,GAFC,MAAM,KAAK,KAAK,aAAa,GAEjB,GADb,MAAM,KAAK,KAAK,YAAY,KACD,MAAM;OAGlD,QAAO,QAAQ,QAAQ;GAGxB,MAAM,gBACL,OAAO,QAAQ,mBAAmB,YAC/B,QAAQ,iBACR,QAAQ,mBAAmB;GAC/B,MAAM,kBAAkB;IACvB,GAAG;IACH;IACA;GACD,MAAM,UAAU,MAAM,QAAQ,mBAAmB,gBAAgB;AACjE,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,gBAAgB;KACP;KACf,OAAO,QAAQ;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA;;AAGF,MAAa,oBAAoB,OAAO,QAAgB;CAGvD,MAAM,EAAE,SAAS,MAAM,YASpB,sCAAqC;AACxC,KAAI,CAAC,MAAM,KACV,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,kBACT,CAAC;CAEH,MAAM,MAAM,KAAK,KAAK,MAAM,QAAQ,IAAI,QAAQ,IAAI;AACpD,KAAI,CAAC,IACJ,OAAM,IAAI,MAAM,gBAAgB,IAAI,YAAY;AAEjD,QAAO,MAAM,UAAU,KAAK,IAAI,IAAI"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"atlassian.mjs","names":[],"sources":["../../src/social-providers/atlassian.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface AtlassianProfile {\n\taccount_type?: string | undefined;\n\taccount_id: string;\n\temail?: string | undefined;\n\tname: string;\n\tpicture?: string | undefined;\n\tnickname?: string | undefined;\n\tlocale?: string | undefined;\n\textended_profile?:\n\t\t| {\n\t\t\t\tjob_title?: string;\n\t\t\t\torganization?: string;\n\t\t\t\tdepartment?: string;\n\t\t\t\tlocation?: string;\n\t\t }\n\t\t| undefined;\n}\nexport interface AtlassianOptions extends ProviderOptions<AtlassianProfile> {\n\tclientId: string;\n}\n\nexport const atlassian = (options: AtlassianOptions) => {\n\tconst tokenEndpoint = \"https://auth.atlassian.com/oauth/token\";\n\treturn {\n\t\tid: \"atlassian\",\n\t\tname: \"Atlassian\",\n\n\t\tasync createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\"Client Id and Secret are required for Atlassian\");\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Atlassian\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"read:jira-user\", \"offline_access\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"atlassian\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://auth.atlassian.com/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\taudience: \"api.atlassian.com\",\n\t\t\t\t},\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tif (!token.accessToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { data: profile } = await betterFetch<{\n\t\t\t\t\taccount_id: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\temail?: string | undefined;\n\t\t\t\t\tpicture?: string | undefined;\n\t\t\t\t}>(\"https://api.atlassian.com/me\", {\n\t\t\t\t\theaders: { Authorization: `Bearer ${token.accessToken}` },\n\t\t\t\t});\n\n\t\t\t\tif (!profile) return null;\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: profile.account_id,\n\t\t\t\t\t\tname: profile.name,\n\t\t\t\t\t\temail: profile.email,\n\t\t\t\t\t\timage: profile.picture,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Figma:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<AtlassianProfile>;\n};\n"],"mappings":";;;;;;;;;;AA+BA,MAAa,aAAa,YAA8B;CACvD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EAEN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;AAC1E,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MAAM,kDAAkD;AAC/D,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,yCAAyC;GAGpE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF,CAAC,kBAAkB,iBAAiB;AACvC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAEnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,kBAAkB,EACjB,UAAU,qBACV;IACD,QAAQ,QAAQ;IAChB,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAGH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAGL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI,CAAC,MAAM,YACV,QAAO;AAGR,OAAI;IACH,MAAM,EAAE,MAAM,YAAY,MAAM,YAK7B,gCAAgC,EAClC,SAAS,EAAE,eAAe,UAAU,MAAM,eAAe,EACzD,CAAC;AAEF,QAAI,CAAC,QAAS,QAAO;IAErB,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAEzD,WAAO;KACN,MAAM;MACL,IAAI,QAAQ;MACZ,MAAM,QAAQ;MACd,OAAO,QAAQ;MACf,OAAO,QAAQ;MACf,eAAe;MACf,GAAG;MACH;KACD,MAAM;KACN;YACO,OAAO;AACf,WAAO,MAAM,yCAAyC,MAAM;AAC5D,WAAO;;;EAIT;EACA"}