@imran3113/surreal-better-auth 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 - present, Oskar Gmerek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
9
+ is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/oskar-gmerek/surreal-better-auth/blob/beta/packages/surreal-better-auth/hero.webp?raw=true">
4
+ <source media="(prefers-color-scheme: light)" srcset="https://github.com/oskar-gmerek/surreal-better-auth/blob/beta/packages/surreal-better-auth/hero-white.webp?raw=true">
5
+ <img alt="surreal-better-auth banner" src="https://github.com/oskar-gmerek/surreal-better-auth/blob/beta/packages/surreal-better-auth/hero.webp?raw=true">
6
+ </picture>
7
+ </p>
8
+
9
+ <h1 style="margin-top:40px;"> 🔐 SurrealDB Adapter for Better Auth </h1>
10
+
11
+ ![GitHub Created At](https://img.shields.io/github/created-at/oskar-gmerek/surreal-better-auth?style=for-the-badge&color=%233ca916)
12
+ ![NPM Last Update](https://img.shields.io/npm/last-update/surreal-better-auth?style=for-the-badge&color=%233ca916)
13
+ ![NPM Version](https://img.shields.io/npm/v/surreal-better-auth?style=for-the-badge&color=%233ca916)
14
+ ![NPM Unpacked Size](https://img.shields.io/npm/unpacked-size/surreal-better-auth?style=for-the-badge&color=%233ca916)
15
+ ![NPM Downloads](https://img.shields.io/npm/dy/surreal-better-auth?style=for-the-badge&color=%233ca916)
16
+ ![NPM License](https://img.shields.io/npm/l/surreal-better-auth?style=for-the-badge&color=%233ca916)
17
+ [![Sponsor](https://img.shields.io/badge/sponsor-💖-ff69b4?style=for-the-badge&color=%23ffbdbd)](https://github.com/sponsors/oskar-gmerek)
18
+
19
+ **The unofficial [SurrealDB](https://app.surrealdb.com/referral?code=4pn5aba943lpbn8l) adapter for [better-auth](https://better-auth.com)** - bringing the power of the multi-model database to your authentication system.
20
+
21
+ This adapter seamlessly integrates SurrealDB's advanced querying capabilities with better-auth's comprehensive authentication features, giving you a robust, scalable, and developer-friendly auth solution.
22
+
23
+ > [!NOTE]
24
+ > 🎁 **New to SurrealDB?** [Sign up with our referral link](https://app.surrealdb.com/referral?code=4pn5aba943lpbn8l) and get **free cloud hosting** plus a **special welcome discount** to kickstart your project!
25
+
26
+ ---
27
+
28
+ ## ✨ Features
29
+
30
+ - 🚀 **Full better-auth compatibility** - Works with all better-auth features and plugins
31
+ - 🔄 **Optimized for SurrealDB** - Uses direct record operations for maximum performance
32
+ - 🎯 **Smart record links** - Uses record links instead of raw string wherever possible
33
+ - 📋 **Schema generation support** - Works with Better Auth CLI, include support for official and unofficial plugins
34
+ - 🔍 **Generating Indexes** - Creates necessary database indexes out of the box
35
+ - 🆔 **Flexible ID formats** - Supports multiple ID generation strategies, full flexibility
36
+ - 🌐 **Multi-format support** - ESM and CommonJS builds included
37
+ - ⚡ **Lightweight** - Optimized bundle size
38
+ - 📦 **No extra bloat** - This is a pure adapter. It has no direct dependencies and uses the `better-auth` and `surrealdb` you've already installed, giving you full control.
39
+
40
+ ---
41
+
42
+ ## ⭐ Show Your Support
43
+
44
+ If this adapter helps your project, please consider:
45
+
46
+ - ⭐ **Starring the project** - It helps others discover this adapter
47
+ [![GitHub stars](https://img.shields.io/github/stars/oskar-gmerek/surreal-better-auth?style=social)](https://github.com/oskar-gmerek/surreal-better-auth)
48
+ - 💖 **[Sponsoring the development](https://github.com/sponsors/oskar-gmerek)** - Even small contributions help maintain and improve the project
49
+ [![Sponsor](https://img.shields.io/badge/sponsor-💖-ff69b4)](https://github.com/sponsors/oskar-gmerek)
50
+
51
+ Your support helps us maintain and improve this adapter for the entire community.
52
+
53
+ ---
54
+
55
+ ## 📋 Requirements
56
+
57
+ - **Node.js**: >= 20.0.0 or **Bun**: >= 1.2.0
58
+ - **better-auth**: ^1.3.7
59
+ - **surrealdb**: ^1.3.2
60
+
61
+ ---
62
+
63
+ ## 🚀 Installation
64
+
65
+ ```bash
66
+ bun add surreal-better-auth
67
+ ```
68
+
69
+ ```bash
70
+ # Using other package managers
71
+ npm install surreal-better-auth
72
+ yarn add surreal-better-auth
73
+ pnpm add surreal-better-auth
74
+ ```
75
+
76
+ ---
77
+
78
+ ## ⚙️ Configuration
79
+
80
+ ### Adapter Options
81
+
82
+ | Option | Type | Default | Description |
83
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | --------------------------------------------------- |
84
+ | `debugLogs` | `boolean` | `false` | Enable detailed logging for debugging |
85
+ | `idGenerator` | `sdk.UUIDv4` \| `sdk.UUIDv7` \| `surreal` \| `surreal.ULID` \| `surreal.UUID` \| `surreal.UUIDv4` \| `surreal.UUIDv7` \| `surreal.guid` \| `undefined` | `undefined` | ID generation strategy (see ID Configuration below) |
86
+ | `usePlural` | `boolean` | `false` | Use plural table names (e.g., `users` vs `user`) |
87
+ | `allowPassingId` | `boolean` | `false` | Allow passing custom IDs when creating records |
88
+
89
+ ### ID Configuration Options
90
+
91
+ You can configure ID generation in two ways:
92
+
93
+ #### 1. Via Adapter Configuration
94
+
95
+ | `idGenerator` Value | Generated By | Description |
96
+ | ------------------- | ------------ | ---------------------------------------------------------------------------- |
97
+ | `"sdk.UUIDv4"` | Better Auth | Better Auth generates UUID via SurrealDB JS SDK function `Uuid.v4()` |
98
+ | `"sdk.UUIDv7"` | Better Auth | Better Auth generates UUID via SurrealDB JS SDK function `Uuid.v7()` |
99
+ | `"surreal"` | Database | SurrealDB generates `default` SurrealDB ID |
100
+ | `"surreal.guid"` | Database | SurrealDB generates 20 digit alphanumeric `GUID` |
101
+ | `"surreal.ULID"` | Database | SurrealDB generates `ULID` |
102
+ | `"surreal.UUID"` | Database | SurrealDB generates default version `UUID` (currently v7) |
103
+ | `"surreal.UUIDv4"` | Database | SurrealDB generates `UUID v4` (random-based, most common) |
104
+ | `"surreal.UUIDv7"` | Database | SurrealDB generates `UUID v7` (time-based, sortable) |
105
+ | `undefined` | Better Auth | Better Auth generates ID (`default`, or generated via `generateId` function) |
106
+
107
+ #### 2. Via Better-Auth Advanced Configuration
108
+
109
+ ```typescript
110
+ // lib/auth.ts
111
+ export const auth = betterAuth({
112
+ database: surrealAdapter(db, {
113
+ idGenerator: "surreal.UUIDv4", // This will be ignored, when generateId is provided!
114
+ }),
115
+ advanced: {
116
+ database: {
117
+ generateId() {
118
+ return "custom_" + Math.random().toString(36).substr(2, 9);
119
+ },
120
+ },
121
+ },
122
+ });
123
+ ```
124
+
125
+ ### ID Generation Precedence
126
+
127
+ The ID generation follows this priority order:
128
+
129
+ 1. **`advanced.database.generateId()`** - Highest priority, overrides everything
130
+ 2. **`idGenerator`** - Used only if `generateId()` is not defined
131
+ 3. **Custom ID from data** - Used if `allowPassingId` is `true` and ID is provided in the data
132
+ 4. **Better Auth default** - Used if `allowPassingId` is `true` and ID is NOT provided in the data
133
+ 5. **Database default ID** - Used as fallback when all above conditions are not met, database generates default ID (same as setting `idGenerator: 'surreal'`)
134
+
135
+ ---
136
+
137
+ ## 🏃‍♂️ Quick Start
138
+
139
+ ### 1. Set up your SurrealDB connection
140
+
141
+ ```typescript
142
+ // lib/db.ts
143
+ import Surreal from "surrealdb";
144
+
145
+ const db = new Surreal();
146
+ await db.connect("ws://localhost:8000");
147
+ await db.use({ namespace: "production", database: "myapp" });
148
+
149
+ export { db };
150
+ ```
151
+
152
+ ### 2. Configure better-auth with the SurrealDB adapter
153
+
154
+ ```typescript
155
+ // lib/auth.ts
156
+ import { betterAuth } from "better-auth";
157
+ import { surrealAdapter } from "surreal-better-auth";
158
+ import { db } from "./db";
159
+
160
+ export const auth = betterAuth({
161
+ database: surrealAdapter(db),
162
+ emailAndPassword: {
163
+ enabled: true,
164
+ },
165
+ socialProviders: {
166
+ github: {
167
+ clientId: process.env.GITHUB_CLIENT_ID!,
168
+ clientSecret: process.env.GITHUB_CLIENT_SECRET!,
169
+ },
170
+ },
171
+ });
172
+ ```
173
+
174
+ ### 3. Use in your application
175
+
176
+ Example for [SvelteKit](https://svelte.dev/)
177
+
178
+ ```typescript
179
+ // src/hooks.server.ts
180
+ import { auth } from "$lib/auth";
181
+ import { svelteKitHandler } from "better-auth/svelte-kit";
182
+ import { building } from "$app/environment";
183
+
184
+ export const handle: Handle = async ({ event, resolve }) => {
185
+ return svelteKitHandler({ event, resolve, auth, building });
186
+ };
187
+ ```
188
+
189
+ ```typescript
190
+ // src/lib/auth-client.ts
191
+ import { createAuthClient } from "better-auth/client";
192
+
193
+ export const authClient = createAuthClient({
194
+ baseURL: "http://localhost:5173", // Your app URL
195
+ });
196
+ ```
197
+
198
+ ```typescript
199
+ // src/routes/+page.svelte
200
+ <script lang="ts">
201
+ import { authClient } from "$lib/client";
202
+ const session = authClient.useSession();
203
+ </script>
204
+
205
+ <div>
206
+ {#if $session.data}
207
+ <div>
208
+ <p>
209
+ {$session?.data?.user.name}
210
+ </p>
211
+ <button
212
+ onclick={async () => {
213
+ await authClient.signOut();
214
+ }}
215
+ >
216
+ Sign Out
217
+ </button>
218
+ </div>
219
+ {:else}
220
+ <button
221
+ onclick={async () => {
222
+ await authClient.signIn.social({
223
+ provider: "github",
224
+ });
225
+ }}
226
+ >
227
+ Continue with GitHub
228
+ </button>
229
+ {/if}
230
+ </div>
231
+ ```
232
+
233
+ ---
234
+
235
+ ## 🔧 Advanced Configuration
236
+
237
+ ```typescript
238
+ // lib/auth.ts
239
+ import { betterAuth } from "better-auth";
240
+ import { surrealdbAdapter } from "surreal-better-auth";
241
+ import { db } from "./db";
242
+
243
+ export const auth = betterAuth({
244
+ database: surrealdbAdapter(db, {
245
+ // Enable debug logging
246
+ debugLogs: true,
247
+ // Let SurrealDB generate ULID
248
+ idGenerator: "surreal.ULID",
249
+ // Use singular table names
250
+ usePlural: false,
251
+ // Allow passing custom IDs
252
+ allowPassingId: true,
253
+ }),
254
+ emailAndPassword: {
255
+ enabled: true,
256
+ requireEmailVerification: true,
257
+ },
258
+ socialProviders: {
259
+ github: {
260
+ clientId: process.env.GITHUB_CLIENT_ID!,
261
+ clientSecret: process.env.GITHUB_CLIENT_SECRET!,
262
+ },
263
+ google: {
264
+ clientId: process.env.GOOGLE_CLIENT_ID!,
265
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
266
+ },
267
+ },
268
+ plugins: [
269
+ // Add any better-auth plugins here and configure them as usual.
270
+ ],
271
+ });
272
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict';var surrealdb=require('surrealdb'),adapters=require('better-auth/adapters'),betterAuth=require('better-auth');var ee={userId:"user",organizationId:"organization",teamId:"team",inviterId:"user",activeOrganizationId:"organization",activeTeamId:"team"},q={eq:"=",ne:"!=",gt:">",gte:">=",lt:"<",lte:"<="},N={contains:"CONTAINS",starts_with:"starts_with",ends_with:"ends_with"},re=[{sourceModel:"account",sourceField:"accountId",targetModel:"user",condition:e=>e.providerId==="credential"},{sourceModel:"oauthAccessToken",sourceField:"clientId",targetModel:"oauthApplication"},{sourceModel:"oauthConsent",sourceField:"clientId",targetModel:"oauthApplication"}];function k(e){let r={...e};for(let a of Object.keys(r))r[a]===null&&(r[a]=void 0);return r}function T(e,r){return r instanceof surrealdb.RecordId?r:typeof r=="string"?r.includes(":")?new surrealdb.RecordId(r.split(":")[0],r.split(":")[1]):new surrealdb.RecordId(e,r):new surrealdb.RecordId(e,r)}function x(e){if(e==null)return e;if(e instanceof surrealdb.RecordId)return e.toString();if(e instanceof Date)return e;if(Array.isArray(e))return e.map(r=>x(r));if(typeof e=="object"){let r={};for(let[a,s]of Object.entries(e))r[a]=x(s);return r}return e}function te(e,r,a){let s={tableSpecific:{}};if(!e)return s;for(let d in e){let l=e[d];if(!l?.fields)continue;let o=r(d);s.tableSpecific[o]||(s.tableSpecific[o]={});for(let n in l.fields){let y=l.fields[n];if(y?.references?.model){let b=a({model:d,field:n}),p=r(y.references.model);s.tableSpecific[o][b]=p;}}}return s}function F(e,r,a,s){if(!e?.debugLogs||e.debugLogs&&typeof e.debugLogs=="object"&&!("isRunningAdapterTests"in e.debugLogs)&&(a==="create"&&!e.debugLogs.create||a==="update"&&!e.debugLogs.update||a==="updateMany"&&!e.debugLogs.updateMany||a==="findOne"&&!e.debugLogs.findOne||a==="findMany"&&!e.debugLogs.findMany||a==="delete"&&!e.debugLogs.delete||a==="deleteMany"&&!e.debugLogs.deleteMany||a==="count"&&!e.debugLogs.count))return;let d=s.query,l=s.bindings,o=d;Object.entries(l).forEach(([b,p])=>{let $=new RegExp(`\\$${b}\\b`,"g"),u;p instanceof surrealdb.RecordId?u=p.toString():typeof p=="string"&&p.includes(":")?u=p:u=JSON.stringify(p),o=o.replace($,u);});let n={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",fg:{surreal_pink:"\x1B[38;5;200m",surreal_purple:"\x1B[38;5;93m",yellow:"\x1B[33m",magenta:"\x1B[35m"},bg:{obsidian_violet:"\x1B[48;5;233m",black:"\x1B[40m"}};function y(b,p){let $=`${n.fg.magenta}###`,u=`${n.bg.black}${n.fg.yellow}[0/#]${n.reset}`,R=`${n.bright}${a}`,h=`${n.dim}(BoundQuery)${n.reset}`,I=" ",m=`${n.bg.obsidian_violet}`;return m+=I,m+=`${n.fg.surreal_purple}[${b}]`,m+=` ${n.fg.surreal_pink}${p}`,m+=I,m+=`${n.reset}`,`${$} ${u} ${R} ${h}
2
+
3
+ ${m}
4
+
5
+ `}r(`${y("SurrealQL",o)}`);}var W={modelNotFound:(e,r)=>{r?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Model '${e}' not found in schema, skipping operation `);},fieldMappingSkipped:(e,r,a)=>{a?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Skipping field mapping rule for '${e}': ${r} `);},unsupportedOperator:(e,r)=>{r?.debugLogs&&betterAuth.logger.warn(`[surreal-better-auth]: Unknown operator '${e}', falling back to equality comparison `);}};function ne(e,r,a,s,d,l,o){let n=s(e),y=d({model:n,field:r}),b=ee[y];if(b)try{let $=l(b);return o?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Found default reference: ${e}.${r} -> ${$} `),$}catch{W.modelNotFound(b,o);}let p=a.tableSpecific[e]?.[r];return p&&o?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Found table-specific reference: ${e}.${r} -> ${p} `),p||null}function oe(e,r,a){let s={};for(let d of re)try{let l=e(d.sourceModel),o=e(d.targetModel),n=r({model:d.sourceModel,field:d.sourceField});s[l]||(s[l]={}),s[l][n]={recordTable:o,condition:d.condition},a?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Registered field mapping: ${l}.${n} -> to record ${o} `);}catch(l){let o=l;W.fieldMappingSkipped(`${d.sourceModel}.${d.sourceField}`,o.message,a);}return s}function se(e,r,a,s,d){let l={...r},o=s();d?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Serializing record ID fields for table: ${e} `,{fieldCount:Object.keys(l).length,hasSpecialCases:!!o[e]});for(let n in l){let y=l[n];if(typeof y!="string"||!y)continue;let b=o[e]?.[n];if(b)if(!b.condition||b.condition(l)){let $=T(b.recordTable,y);l[n]=$,d?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Applied special case mapping: ${e}.${n} = "${y}" -> "${$}" `);}else d?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Special case condition not met for: ${e}.${n} `);else {let p=a(e,n);if(p){let $=T(p,y);l[n]=$,d?.debugLogs&&betterAuth.logger.debug(`[surreal-better-auth]: Applied default reference mapping: ${e}.${n} = "${y}" -> "${$}" `);}}}return l}function ie(e,r,a){if(!e||e.length===0)return null;let s=a(r),d=e.findIndex(o=>o.field==="id"&&o.operator==="eq");if(d!==-1){let o=e[d],n=T(s,o.value),y=e.filter((b,p)=>p!==d);return {recordIds:[n],remainingWhere:y}}let l=e.findIndex(o=>o.field==="id"&&o.operator==="in"&&Array.isArray(o.value));if(l!==-1){let n=e[l].value.map(b=>T(s,b)),y=e.filter((b,p)=>p!==l);return {recordIds:n,remainingWhere:y}}return null}function v(e={},r){let{sortBy:a,limit:s,offset:d,groupAll:l,returnAfter:o,returnFields:n,limitOne:y,model:b}=e,p="";if(a&&b&&r){let $=r({model:b,field:a.field}),u=a.direction==="desc"?"DESC":"ASC";p+=` ORDER BY ${$} ${u}`;}return y?p+=" LIMIT 1":typeof s=="number"&&(p+=` LIMIT ${s}`),typeof d=="number"&&(p+=` START AT ${d}`),l&&(p+=" GROUP ALL"),o?p+=" RETURN AFTER":n&&(p+=` RETURN ${n}`),p}function ae(e,{where:r,model:a},s,d,l,o){if(!r||r.length===0)return "";let n=[],y=s(a);return r.forEach((b,p)=>{let{field:$,value:u,operator:R="eq",connector:h="AND"}=b;if(R==="in"&&Array.isArray(u)&&u.length===0||R==="not_in"&&Array.isArray(u)&&u.length===0)return;let I=d({model:a,field:$}),m=`where_${p}`,f="";if(R==="in"){f=`${I} IN $${m}`;let t=Array.isArray(u)?u:[u],i=t;if($==="id")i=t.map(c=>T(y,c));else {let c=l(y,I);c&&(i=t.map(g=>typeof g=="string"?T(c,g):g));}e[m]=i;}else if(R==="not_in"){f=`${I} NOT IN $${m}`;let t=Array.isArray(u)?u:[u],i=t;if($==="id")i=t.map(c=>T(y,c));else {let c=l(y,I);c&&(i=t.map(g=>typeof g=="string"?T(c,g):g));}e[m]=i;}else if(R in q)if(f=`${I} ${q[R]} $${m}`,$==="id")e[m]=T(y,u);else {let t=l(y,I);t&&typeof u=="string"?e[m]=T(t,u):e[m]=u;}else R in N?(N[R]==="CONTAINS"?f=`${I} CONTAINS $${m}`:f=`string::${N[R]}(${I}, $${m})`,e[m]=u):(f=`${I} = $${m}`,e[m]=u,W.unsupportedOperator(R,o));n.length>0?n.push(` ${h.toUpperCase()} ${f}`):n.push(f);}),n.length===0?"":` WHERE ${n.join("")}`}function de(e,r,a,s,d,l){let o,n=s??(l?l():null);if(n)o=T(e,n).toString();else switch(a?.idGenerator){case "surreal.ULID":o=`type::record('${e}', rand::ulid())`;break;case "surreal.UUID":o=`type::record('${e}', rand::uuid())`;break;case "surreal.UUIDv4":o=`type::record('${e}', rand::uuid::v4())`;break;case "surreal.UUIDv7":o=`type::record('${e}', rand::uuid::v7())`;break;case "surreal.guid":o=`type::record('${e}', rand::guid())`;break;default:o=`type::record('${e}')`;break}let y=v({returnFields:d}),b=`CREATE ${o} CONTENT $content${y}`;return {query:new surrealdb.BoundQuery(b,{content:r})}}function j(e){let{file:r,tables:a,getModelName:s,getFieldName:d,getReferencedModel:l}=e,o=[],n=new Date,y=`${n.getUTCFullYear()}-${String(n.getUTCMonth()+1).padStart(2,"0")}-${String(n.getUTCDate()).padStart(2,"0")} at ${String(n.getUTCHours()).padStart(2,"0")}:${String(n.getUTCMinutes()).padStart(2,"0")}:${String(n.getUTCSeconds()).padStart(2,"0")} UTC`;o.push("-- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","-- \u2551 SurrealDB Better Auth Schema \u2551","-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 This schema was auto-generated for BetterAuth integration \u2551","-- \u2551 Adapter: surreal-better-auth \u2551","-- \u2551 Repo: https://github.com/oskar-gmerek/surreal-better-auth \u2551","-- \u2551 Author: Oskar Gmerek \u2551","-- \u2551 \u2551",`-- \u2551 Generation Date: ${y.padEnd(53)}\u2551`,"-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 Warning: It is strongly recommended to manually review the schema \u2551","-- \u2551 after each generation to ensure it fully meets your \u2551","-- \u2551 project's specific requirements. \u2551","-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 Tip: The easiest way to apply this schema to your db is to copy its \u2551","-- \u2551 contents and paste them directly into the Surrealist. \u2551","-- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","","","");function b(u,R=76){let h=R-8,I=u.padEnd(h," "),m=`-- \u2554${"\u2550".repeat(R-4)}\u2557`,f=`-- \u2551 ${I} \u2551`,t=`-- \u255A${"\u2550".repeat(R-4)}\u255D`;return [m,f,t]}function p(u,R,h){try{let f=s("account"),t=s("user"),i=d({model:"account",field:"accountId"});if(u===f&&R===i)return `record<${t}> | string`}catch{}try{let f=s("oauthAccessToken"),t=s("oauthApplication"),i=d({model:"oauthAccessToken",field:"clientId"});if(u===f&&R===i)return `record<${t}>`}catch{}try{let f=s("oauthConsent"),t=s("oauthApplication"),i=d({model:"oauthConsent",field:"clientId"});if(u===f&&R===i)return `record<${t}>`}catch{}let I=l(u,R);return I?`record<${I}>`:{boolean:"bool",date:"datetime"}[h||""]||h||"any"}for(let[u,R]of Object.entries(a)){let h=s(u);if(!R.disableMigrations){o.push(...b(`TABLE: ${h}`)),o.push(`DEFINE TABLE OVERWRITE ${h} SCHEMAFULL;`);for(let[I,m]of Object.entries(R.fields)){let f=d({model:u,field:I}),t=p(h,f,m.type?.toString()),i=m.required===false?`option<${t}>`:t;o.push(`DEFINE FIELD OVERWRITE ${f} ON TABLE ${h} TYPE ${i};`);}o.push("");for(let[I,m]of Object.entries(R.fields)){let f=d({model:u,field:I}),i={user:"email",account:"userId",session:["userId","token"],verification:"identifier",invitation:["email","organizationId"],member:["userId","organizationId"],organization:"slug",passkey:"userId",twoFactor:"secret"}[u];i&&(Array.isArray(i)&&i.includes(I)||i===I)&&o.push(`DEFINE INDEX OVERWRITE idx_${h}_${f} ON ${h} COLUMNS ${f}${m.unique?" UNIQUE":""};`);}o.push("");}}return {path:r??"schema.surql",code:o.join(`
6
+ `),overwrite:true}}var be=(e,r)=>adapters.createAdapter({config:{adapterId:"surrealdb_adapter",adapterName:"surreal-better-auth",usePlural:r?.usePlural??false,debugLogs:r?.debugLogs??false,supportsNumericIds:false,supportsBooleans:true,supportsDates:true,supportsJSON:true,customIdGenerator:r?.idGenerator?.startsWith("sdk.")?({model:a})=>{switch(r?.debugLogs&&betterAuth.logger.info(`[surreal-better-auth]: Generating custom ID for model: ${a} using ${r.idGenerator} `),r.idGenerator){case "sdk.UUIDv4":return surrealdb.Uuid.v4().toString();case "sdk.UUIDv7":return surrealdb.Uuid.v7().toString();default:throw new Error(`Invalid ID generator type: ${r.idGenerator}. Supported types: "sdk.UUIDv4", "sdk.UUIDv7", "surreal", "surreal.ULID", "surreal.UUID", "surreal.UUIDv4", "surreal.UUIDv7", "surreal.guid"`)}}:void 0,disableIdGeneration:r?.idGenerator?.startsWith("surreal")??false,customTransformOutput({data:a}){return a===void 0?null:x(a)}},adapter:({options:a,getModelName:s,getFieldName:d,getDefaultModelName:l,getDefaultFieldName:o,debugLog:n})=>{let y=te(a?.schema?.tables,s,d),b=a?.advanced?.database?.generateId,p=(t,i)=>ne(t,i,y,l,o,s,r),$=()=>oe(s,d,r),u=(t,i)=>se(t,i,p,$,r),R=(t,i)=>ie(t,i,s),h=(t={})=>v(t,d),I=(t,{where:i,model:c})=>ae(t,{where:i,model:c},s,d,p,r),m=(t,i,c,g)=>de(t,i,r,c,g,b);async function f(t){let{method:i,model:c,where:g,baseQuery:S,directRecordQuery:E,content:A,suffix:D="",processResult:C=G=>G,returnCount:O=false,singleRecord:U=false}=t,Y=R(g,c);if(Y&&E){let{recordIds:G,remainingWhere:H}=Y,J=E(G);if(H.length===0){let K={};A!==void 0&&(K.content=A);let Z=new surrealdb.BoundQuery(J+D,K);F(r,n,i,Z);let P=await e.query(Z).collect();return O?P[0]?.length||0:C(P[0])}let _={};A!==void 0&&(_.content=A);let pe=I(_,{where:H,model:c}),fe=J+pe+D,X=new surrealdb.BoundQuery(fe,_);F(r,n,i,X);let B=await e.query(X).collect();return O?B[0]?.length||0:C(B[0])}let Q={};A!==void 0&&(Q.content=A);let ce=I(Q,{where:g||[],model:c}),le=S+ce+D,V=new surrealdb.BoundQuery(le,Q);F(r,n,i,V);let w=await e.query(V).collect();return O?w[0]?.length||0:C(w[0])}return {async create({model:t,data:i,select:c}){let g=s(t),S=u(g,k(i)),E=(r?.allowPassingId||r?.idGenerator?.startsWith("sdk."))&&S.id?S.id:void 0;S.id=void 0;let A;if(c&&Array.isArray(c)&&c.length>0){let O=c.map(U=>d({model:t,field:U}));O.includes("id")||O.unshift("id"),A=O.join(", ");}let{query:D}=m(g,S,E,A);F(r,n,"create",D);let C=await e.query(D).collect();return x(C[0][0])},async findOne({model:t,where:i,select:c}){let g=s(t),S=c?typeof c=="string"?d({model:t,field:c}):c.map(E=>d({model:t,field:E})).join(", "):"*";return f({method:"findOne",model:t,where:i,baseQuery:`SELECT ${S} FROM ONLY ${g}`,directRecordQuery:E=>`SELECT ${S} FROM ONLY ${E[0].toString()}`,suffix:h({limitOne:true}),processResult:E=>x(E)||null,singleRecord:true})},async findMany({model:t,where:i,limit:c,offset:g,sortBy:S}){let E=s(t),A="*";return f({method:"findMany",model:t,where:i,baseQuery:`SELECT ${A} FROM ${E}`,directRecordQuery:D=>`SELECT ${A} FROM [${D.map(C=>C.toString()).join(", ")}]`,suffix:h({sortBy:S,limit:c,offset:g,model:t}),processResult:x})},async count({model:t,where:i}){let c=s(t);return f({method:"count",model:t,where:i,baseQuery:`SELECT count() FROM ${c}`,directRecordQuery:g=>`SELECT count() FROM [${g.map(S=>S.toString()).join(", ")}]`,suffix:h({groupAll:true}),processResult:g=>g[0].count||0,singleRecord:true})},async update({model:t,where:i,update:c}){let g=s(t),S=u(g,k(c));return f({method:"update",model:t,where:i,baseQuery:`UPDATE ONLY ${g} MERGE $content`,directRecordQuery:E=>`UPDATE ONLY ${E[0].toString()} MERGE $content`,content:S,suffix:h({returnAfter:true}),processResult:E=>x(E)||null,singleRecord:true})},async updateMany({model:t,where:i,update:c}){let g=s(t),S=u(g,k(c));return f({method:"updateMany",model:t,where:i,baseQuery:`UPDATE ${g} MERGE $content`,directRecordQuery:E=>`UPDATE [${E.map(A=>A.toString()).join(", ")}] MERGE $content`,content:S,returnCount:true})},async delete({model:t,where:i}){let c=s(t);return f({method:"delete",model:t,where:i,baseQuery:`DELETE ${c}`,directRecordQuery:g=>`DELETE ${g[0].toString()}`,processResult:()=>{}})},async deleteMany({model:t,where:i}){let c=s(t);return f({method:"deleteMany",model:t,where:i,baseQuery:`DELETE ${c}`,directRecordQuery:g=>`DELETE [${g.map(S=>S.toString()).join(", ")}]`,returnCount:true})},async createSchema({file:t,tables:i}){return j({file:t,tables:i,getModelName:s,getFieldName:d,getReferencedModel:p})}}}});exports.generateSchema=j;exports.surrealdbAdapter=be;//# sourceMappingURL=index.cjs.map
7
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/helpers.ts","../src/schema.ts","../src/surreal-adapter.ts"],"names":["DEFAULT_FIELD_REFERENCES","COMPARISON_OPERATORS","STRING_OPERATORS","FIELD_MAPPING_RULES","data","mapNullToUndefined","out","k","toRecordId","model","id","RecordId","recordIdsToStrings","value","v","buildRecordIdMap","tables","getModelName","getFieldName","map","internalModelName","tableDef","actualTableName","internalFieldName","fieldDef","actualFieldName","referencedActualTableName","logQuery","config","debugLog","method","query","queryTemplate","params","readableQuery","paramName","paramPattern","formattedValue","colors","formatLogLine","lang","transationId","stepString","methodString","preparedString","PADDING","formattedString","ERROR_HANDLERS","modelName","logger","rule","reason","operator","getReferencedModel","tableName","fieldName","recordIdMap","getDefaultModelName","getDefaultFieldName","defaultModel","defaultField","referencedModel","tableSpecificRef","buildSpecialCasesMapping","specialCases","sourceModelName","targetModelName","e","error","serializeRecordIdFields","getReferencedModelFn","buildSpecialCasesFn","specialCase","recordId","extractDirectRecords","where","idEqIndex","w","idEqCondition","remainingWhere","_","index","idInIndex","recordIds","buildQuerySuffix","options","sortBy","limit","offset","groupAll","returnAfter","returnFields","limitOne","suffix","field","direction","buildWhereClauseParts","bindings","conditions","idx","internalField","connector","param","conditionStr","vals","finalVals","referencedModelName","generateCreateQuery","content","customId","selectFields","generateId","targetClause","providedId","queryString","BoundQuery","generateSchema","file","schemaLines","date","formatted","buildTableBox","text","totalWidth","contentWidth","lineContent","top","mid","bot","mapFieldType","type","accountModelName","userModelName","accountIdFieldName","oauthAccessTokenModelName","oauthApplicationModelName","oauthAccessTokenIdFieldName","oauthConsentModelName","oauthConsentIdFieldName","baseType","finalType","fieldsToIndex","surrealdbAdapter","db","createAdapter","Uuid","serializeRecordIdFieldsFn","extractDirectRecordsFn","buildQuerySuffixFn","buildWhereClausePartsFn","generateCreateQueryFn","executeOptimizedQuery","baseQuery","directRecordQuery","processResult","r","returnCount","singleRecord","directRecordInfo","directQuery","result","whereStr","values","select","mappedFields","f","selectClause"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AdapterDebugLogs } from \"better-auth/adapters\";\n\n/**\n * ID generation strategies for SurrealDB records.\n */\nexport type IdGenerator =\n | \"sdk.UUIDv4\"\n | \"sdk.UUIDv7\"\n | \"surreal\"\n | \"surreal.ULID\"\n | \"surreal.UUID\"\n | \"surreal.UUIDv4\"\n | \"surreal.UUIDv7\"\n | \"surreal.guid\";\n\n/**\n * Maps table fields to their referenced tables for RecordId conversion.\n */\nexport interface RecordIdMap {\n tableSpecific: Record<string, Record<string, string>>;\n}\n\n/**\n * Configuration options for the SurrealDB adapter.\n */\nexport interface SurrealDBAdapterConfig {\n /** Enable debug logging for adapter operations. */\n debugLogs?: AdapterDebugLogs;\n\n /** Use plural table names (e.g., 'users' instead of 'user'). @default false */\n usePlural?: boolean;\n\n /** ID generation strategy. @default undefined (uses Better Auth default) */\n idGenerator?: IdGenerator;\n\n /** Allow passing custom IDs in data objects. @default false */\n allowPassingId?: boolean;\n}\n\n/**\n * Adapter method names for logging and debugging.\n */\nexport type AdapterMethod =\n | \"create\"\n | \"update\"\n | \"updateMany\"\n | \"findOne\"\n | \"findMany\"\n | \"delete\"\n | \"deleteMany\"\n | \"count\";\n\n/**\n * Rule for special field-to-table mappings with optional conditions.\n */\nexport interface FieldMappingRule {\n sourceModel: string;\n sourceField: string;\n targetModel: string;\n condition?: (data: Record<string, any>) => boolean;\n}\n\n/**\n * Options for building query suffix clauses (ORDER BY, LIMIT, etc.).\n */\nexport interface QuerySuffixOptions {\n sortBy?: { field: string; direction?: \"asc\" | \"desc\" };\n limit?: number;\n offset?: number;\n groupAll?: boolean;\n returnAfter?: boolean;\n returnFields?: string;\n limitOne?: boolean;\n model?: string;\n}\n\n/**\n * Options for optimized query execution with direct record access.\n */\nexport interface ExecuteOptimizedQueryOptions {\n method: AdapterMethod;\n model: string;\n where?: any[];\n baseQuery: string;\n directRecordQuery?: (recordIds: any[]) => string;\n content?: any;\n suffix?: string;\n processResult?: (result: any) => any;\n returnCount?: boolean;\n singleRecord?: boolean;\n}\n\n/**\n * Default field-to-table reference mappings for common Better Auth fields.\n */\nexport const DEFAULT_FIELD_REFERENCES: Record<string, string> = {\n userId: \"user\",\n organizationId: \"organization\",\n teamId: \"team\",\n inviterId: \"user\",\n activeOrganizationId: \"organization\",\n activeTeamId: \"team\",\n};\n\n/**\n * Comparison operator mappings for SurrealDB WHERE clauses.\n */\nexport const COMPARISON_OPERATORS: Record<string, string> = {\n eq: \"=\",\n ne: \"!=\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/**\n * String operator mappings for SurrealDB text operations.\n */\nexport const STRING_OPERATORS: Record<string, string> = {\n contains: \"CONTAINS\",\n starts_with: \"starts_with\",\n ends_with: \"ends_with\",\n};\n\n/**\n * Special field mapping rules with conditional logic.\n */\nexport const FIELD_MAPPING_RULES: FieldMappingRule[] = [\n {\n sourceModel: \"account\",\n sourceField: \"accountId\",\n targetModel: \"user\",\n condition: (data) => data.providerId === \"credential\",\n },\n {\n sourceModel: \"oauthAccessToken\",\n sourceField: \"clientId\",\n targetModel: \"oauthApplication\",\n },\n {\n sourceModel: \"oauthConsent\",\n sourceField: \"clientId\",\n targetModel: \"oauthApplication\",\n },\n];\n\n/**\n * Parameters for schema generation from Better Auth tables.\n */\nexport interface GenerateSchemaParams {\n file?: string;\n tables: Record<string, any>;\n getModelName: (model: string) => string;\n getFieldName: (opts: { model: string; field: string }) => string;\n getReferencedModel: (tableName: string, fieldName: string) => string | null;\n}\n\n/**\n * Result of schema generation with path and content.\n */\nexport interface GenerateSchemaResult {\n path: string;\n code: string;\n overwrite: boolean;\n}\n","/**\n * Helper utilities for SurrealDB Better Auth adapter.\n * Handles ID conversion, data transformation, and schema mapping.\n */\n\nimport { BoundQuery, RecordId } from \"surrealdb\";\nimport type { Where } from \"better-auth/types\";\nimport { logger } from \"better-auth\";\nimport type {\n AdapterMethod,\n RecordIdMap,\n SurrealDBAdapterConfig,\n QuerySuffixOptions,\n // FieldMappingRule\n} from \"./types\";\nimport {\n COMPARISON_OPERATORS,\n STRING_OPERATORS,\n DEFAULT_FIELD_REFERENCES,\n FIELD_MAPPING_RULES,\n} from \"./types\";\n\n/**\n * Converts null values to undefined to prevent SurrealDB errors with option<record<table>> fields.\n */\nexport function mapNullToUndefined(\n data: Record<string, any>,\n): Record<string, any> {\n const out: Record<string, any> = { ...data };\n for (const k of Object.keys(out)) {\n if (out[k] === null) out[k] = undefined;\n }\n return out;\n}\n\n/**\n * Converts various ID formats to SurrealDB RecordId.\n * Handles RecordId instances, \"table:id\" strings, plain IDs, and numbers.\n */\nexport function toRecordId(model: string, id: any): RecordId {\n if (id instanceof RecordId) return id;\n if (typeof id === \"string\") {\n if (id.includes(\":\"))\n return new RecordId(id.split(\":\")[0], id.split(\":\")[1]);\n return new RecordId(model, id);\n }\n return new RecordId(model, id);\n}\n\n/**\n * Recursively converts RecordId objects to \"table:id\" strings throughout data structures.\n */\nexport function recordIdsToStrings<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (value instanceof RecordId)\n return value.toString() as unknown as T;\n if (value instanceof Date) {\n return value;\n }\n if (Array.isArray(value))\n return value.map((v) => recordIdsToStrings(v)) as unknown as T;\n if (typeof value === \"object\") {\n const out: any = {};\n for (const [k, v] of Object.entries(value as any)) {\n out[k] = recordIdsToStrings(v as any);\n }\n return out as T;\n }\n return value;\n}\n\n/**\n * Builds field-to-table reference mappings from Better Auth schema for RecordId conversion.\n */\nexport function buildRecordIdMap(\n tables: any,\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n): RecordIdMap {\n const map: RecordIdMap = { tableSpecific: {} };\n if (!tables) return map;\n\n for (const internalModelName in tables) {\n const tableDef = tables[internalModelName];\n if (!tableDef?.fields) continue;\n\n const actualTableName = getModelName(internalModelName);\n if (!map.tableSpecific[actualTableName]) {\n map.tableSpecific[actualTableName] = {};\n }\n\n for (const internalFieldName in tableDef.fields) {\n const fieldDef = tableDef.fields[internalFieldName];\n if (fieldDef?.references?.model) {\n const actualFieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n const referencedActualTableName = getModelName(\n fieldDef.references.model,\n );\n map.tableSpecific[actualTableName][actualFieldName] =\n referencedActualTableName;\n }\n }\n }\n return map;\n}\n\n/**\n * Logs SurrealDB queries with formatted output when debug logging is enabled.\n */\nexport function logQuery(\n config: SurrealDBAdapterConfig | undefined,\n debugLog: (...args: any[]) => void,\n method: AdapterMethod,\n query: BoundQuery,\n): void {\n if (!config?.debugLogs) return;\n if (\n config.debugLogs &&\n typeof config.debugLogs === \"object\" &&\n !(\"isRunningAdapterTests\" in config.debugLogs)\n ) {\n if (method === \"create\" && !config.debugLogs.create) {\n return;\n }\n if (method === \"update\" && !config.debugLogs.update) {\n return;\n }\n if (method === \"updateMany\" && !config.debugLogs.updateMany) {\n return;\n }\n if (method === \"findOne\" && !config.debugLogs.findOne) {\n return;\n }\n if (method === \"findMany\" && !config.debugLogs.findMany) {\n return;\n }\n if (method === \"delete\" && !config.debugLogs.delete) {\n return;\n }\n if (method === \"deleteMany\" && !config.debugLogs.deleteMany) {\n return;\n }\n if (method === \"count\" && !config.debugLogs.count) {\n return;\n }\n }\n\n const queryTemplate = query.query;\n const params = query.bindings;\n let readableQuery = queryTemplate;\n\n // Replace parameters with actual values\n Object.entries(params).forEach(([paramName, value]) => {\n const paramPattern = new RegExp(`\\\\$${paramName}\\\\b`, \"g\");\n let formattedValue: string;\n\n if (value instanceof RecordId) {\n // RecordId should be displayed without quotes\n formattedValue = value.toString();\n } else if (typeof value === \"string\" && value.includes(\":\")) {\n // String that looks like RecordId should be displayed without quotes\n formattedValue = value;\n } else {\n // Other values should be JSON stringified\n formattedValue = JSON.stringify(value);\n }\n\n readableQuery = readableQuery.replace(paramPattern, formattedValue);\n });\n const colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n fg: {\n surreal_pink: \"\\x1b[38;5;200m\",\n surreal_purple: \"\\x1b[38;5;93m\",\n yellow: \"\\x1b[33m\",\n magenta: \"\\x1b[35m\",\n },\n bg: {\n obsidian_violet: \"\\x1b[48;5;233m\",\n black: \"\\x1b[40m\",\n },\n };\n function formatLogLine(lang: string, query: string) {\n const transationId = `${colors.fg.magenta}###`;\n const stepString = `${colors.bg.black}${colors.fg.yellow}[0/#]${colors.reset}`;\n const methodString = `${colors.bright}${method}`;\n const preparedString = `${colors.dim}(BoundQuery)${colors.reset}`;\n const PADDING = \" \";\n let formattedString = `${colors.bg.obsidian_violet}`;\n formattedString += PADDING;\n formattedString += `${colors.fg.surreal_purple}[${lang}]`;\n formattedString += ` ${colors.fg.surreal_pink}${query}`;\n formattedString += PADDING;\n formattedString += `${colors.reset}`;\n return `${transationId} ${stepString} ${methodString} ${preparedString} \\n\\n${formattedString}\\n\\n`;\n }\n\n debugLog(`${formatLogLine(\"SurrealQL\", readableQuery)}`);\n}\n/**\n * Declarative error handling configuration for adapter operations.\n */\nexport const ERROR_HANDLERS = {\n modelNotFound: (modelName: string, config?: SurrealDBAdapterConfig) => {\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Model '${modelName}' not found in schema, skipping operation `,\n );\n }\n },\n fieldMappingSkipped: (\n rule: string,\n reason: string,\n config?: SurrealDBAdapterConfig,\n ) => {\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Skipping field mapping rule for '${rule}': ${reason} `,\n );\n }\n },\n unsupportedOperator: (operator: string, config?: SurrealDBAdapterConfig) => {\n if (config?.debugLogs) {\n logger.warn(\n `[surreal-better-auth]: Unknown operator '${operator}', falling back to equality comparison `,\n );\n }\n },\n};\n\n/**\n * Gets the referenced table name for a field using default mappings and schema.\n */\nexport function getReferencedModel(\n tableName: string,\n fieldName: string,\n recordIdMap: RecordIdMap,\n getDefaultModelName: (tableName: string) => string,\n getDefaultFieldName: (opts: { model: string; field: string }) => string,\n getModelName: (model: string) => string,\n config?: SurrealDBAdapterConfig,\n): string | null {\n const defaultModel = getDefaultModelName(tableName);\n const defaultField = getDefaultFieldName({\n model: defaultModel,\n field: fieldName,\n });\n\n // Check default references first\n const referencedModel = DEFAULT_FIELD_REFERENCES[defaultField];\n if (referencedModel) {\n try {\n const modelName = getModelName(referencedModel);\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Found default reference: ${tableName}.${fieldName} -> ${modelName} `,\n );\n }\n return modelName;\n } catch (error) {\n ERROR_HANDLERS.modelNotFound(referencedModel, config);\n }\n }\n\n // Fallback to table-specific mappings\n const tableSpecificRef = recordIdMap.tableSpecific[tableName]?.[fieldName];\n if (tableSpecificRef && config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Found table-specific reference: ${tableName}.${fieldName} -> ${tableSpecificRef} `,\n );\n }\n\n return tableSpecificRef || null;\n}\n\n/**\n * Builds special field mapping cases from declarative rules.\n */\nexport function buildSpecialCasesMapping(\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n config?: SurrealDBAdapterConfig,\n): Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n> {\n const specialCases: Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n > = {};\n\n for (const rule of FIELD_MAPPING_RULES) {\n try {\n const sourceModelName = getModelName(rule.sourceModel);\n const targetModelName = getModelName(rule.targetModel);\n const fieldName = getFieldName({\n model: rule.sourceModel,\n field: rule.sourceField,\n });\n\n if (!specialCases[sourceModelName]) {\n specialCases[sourceModelName] = {};\n }\n\n specialCases[sourceModelName][fieldName] = {\n recordTable: targetModelName,\n condition: rule.condition,\n };\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Registered field mapping: ${sourceModelName}.${fieldName} -> to record ${targetModelName} `,\n );\n }\n } catch (e) {\n const error = e as Error;\n ERROR_HANDLERS.fieldMappingSkipped(\n `${rule.sourceModel}.${rule.sourceField}`,\n error.message,\n config,\n );\n }\n }\n\n return specialCases;\n}\n\n/**\n * Converts string IDs to RecordId objects for fields that reference other tables.\n */\nexport function serializeRecordIdFields(\n tableName: string,\n data: Record<string, any>,\n getReferencedModelFn: (tableName: string, fieldName: string) => string | null,\n buildSpecialCasesFn: () => Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n >,\n config?: SurrealDBAdapterConfig,\n): Record<string, any> {\n const out = { ...data };\n const specialCases = buildSpecialCasesFn();\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Serializing record ID fields for table: ${tableName} `,\n {\n fieldCount: Object.keys(out).length,\n hasSpecialCases: !!specialCases[tableName],\n },\n );\n }\n\n for (const fieldName in out) {\n const value = out[fieldName];\n\n if (typeof value !== \"string\" || !value) {\n continue;\n }\n\n const specialCase = specialCases[tableName]?.[fieldName];\n\n if (specialCase) {\n const shouldApply = !specialCase.condition || specialCase.condition(out);\n\n if (shouldApply) {\n const recordId = toRecordId(specialCase.recordTable, value);\n out[fieldName] = recordId;\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Applied special case mapping: ${tableName}.${fieldName} = \"${value}\" -> \"${recordId}\" `,\n );\n }\n } else if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Special case condition not met for: ${tableName}.${fieldName} `,\n );\n }\n } else {\n const referencedModel = getReferencedModelFn(tableName, fieldName);\n\n if (referencedModel) {\n const recordId = toRecordId(referencedModel, value);\n out[fieldName] = recordId;\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Applied default reference mapping: ${tableName}.${fieldName} = \"${value}\" -> \"${recordId}\" `,\n );\n }\n }\n }\n }\n\n return out;\n}\n\n/**\n * Extracts direct record IDs from WHERE conditions for query optimization.\n */\nexport function extractDirectRecords(\n where: Where[] | undefined,\n model: string,\n getModelName: (model: string) => string,\n): { recordIds: RecordId[]; remainingWhere: Where[] } | null {\n if (!where || where.length === 0) return null;\n\n const tableName = getModelName(model);\n\n // Find id = value condition (single record)\n const idEqIndex = where.findIndex(\n (w) => w.field === \"id\" && w.operator === \"eq\",\n );\n if (idEqIndex !== -1) {\n const idEqCondition = where[idEqIndex];\n const recordId = toRecordId(tableName, idEqCondition.value as any);\n const remainingWhere = where.filter((_, index) => index !== idEqIndex);\n return { recordIds: [recordId], remainingWhere };\n }\n\n // Find id IN [...] condition (multiple records)\n const idInIndex = where.findIndex(\n (w) => w.field === \"id\" && w.operator === \"in\" && Array.isArray(w.value),\n );\n if (idInIndex !== -1) {\n const idInCondition = where[idInIndex];\n const recordIds = (idInCondition.value as any[]).map((id) =>\n toRecordId(tableName, id),\n );\n const remainingWhere = where.filter((_, index) => index !== idInIndex);\n return { recordIds, remainingWhere };\n }\n\n return null;\n}\n\n/**\n * Builds query suffix with ORDER BY, LIMIT, RETURN clauses.\n */\nexport function buildQuerySuffix(\n options: QuerySuffixOptions = {},\n getFieldName?: (opts: { model: string; field: string }) => string,\n): string {\n const {\n sortBy,\n limit,\n offset,\n groupAll,\n returnAfter,\n returnFields,\n limitOne,\n model,\n } = options;\n\n let suffix = \"\";\n\n // ORDER BY clause\n if (sortBy && model && getFieldName) {\n const field = getFieldName({ model, field: sortBy.field });\n const direction = sortBy.direction === \"desc\" ? \"DESC\" : \"ASC\";\n suffix += ` ORDER BY ${field} ${direction}`;\n }\n\n // LIMIT clause\n if (limitOne) {\n suffix += \" LIMIT 1\";\n } else if (typeof limit === \"number\") {\n suffix += ` LIMIT ${limit}`;\n }\n\n // START AT clause (offset)\n if (typeof offset === \"number\") {\n suffix += ` START AT ${offset}`;\n }\n\n // GROUP ALL clause\n if (groupAll) {\n suffix += \" GROUP ALL\";\n }\n\n // RETURN clauses\n if (returnAfter) {\n suffix += \" RETURN AFTER\";\n } else if (returnFields) {\n suffix += ` RETURN ${returnFields}`;\n }\n\n return suffix;\n}\n\n/**\n * Builds WHERE clause with proper parameter binding and RecordId conversion.\n */\nexport function buildWhereClauseParts(\n bindings: Record<string, unknown>,\n { where, model }: { where: Where[]; model: string },\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n getReferencedModelFn: (tableName: string, fieldName: string) => string | null,\n config?: SurrealDBAdapterConfig,\n): string {\n if (!where || where.length === 0) return \"\";\n\n const conditions: string[] = [];\n const tableName = getModelName(model);\n\n where.forEach((w, idx) => {\n const {\n field: internalField,\n value,\n operator = \"eq\",\n connector = \"AND\",\n } = w;\n if (operator === \"in\" && Array.isArray(value) && value.length === 0) return;\n if (operator === \"not_in\" && Array.isArray(value) && value.length === 0) return;\n\n const fieldName = getFieldName({ model, field: internalField });\n\n const param = `where_${idx}`;\n let conditionStr = \"\";\n\n if (operator === \"in\") {\n conditionStr = `${fieldName} IN $${param}`;\n const vals = Array.isArray(value) ? value : [value];\n let finalVals: (RecordId | string | number | boolean | Date | null)[] = vals;\n\n if (internalField === \"id\") {\n finalVals = vals.map((v) => toRecordId(tableName, v));\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName) {\n finalVals = vals.map((v) =>\n typeof v === \"string\" ? toRecordId(referencedModelName, v) : v,\n );\n }\n }\n bindings[param] = finalVals;\n } else if (operator === \"not_in\") {\n conditionStr = `${fieldName} NOT IN $${param}`;\n const vals = Array.isArray(value) ? value : [value];\n let finalVals: (RecordId | string | number | boolean | Date | null)[] = vals;\n\n if (internalField === \"id\") {\n finalVals = vals.map((v) => toRecordId(tableName, v));\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName) {\n finalVals = vals.map((v) =>\n typeof v === \"string\" ? toRecordId(referencedModelName, v) : v,\n );\n }\n }\n bindings[param] = finalVals;\n } else if (operator in COMPARISON_OPERATORS) {\n conditionStr = `${fieldName} ${COMPARISON_OPERATORS[operator]} $${param}`;\n if (internalField === \"id\") {\n bindings[param] = toRecordId(tableName, value);\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName && typeof value === \"string\") {\n bindings[param] = toRecordId(referencedModelName, value);\n } else {\n bindings[param] = value;\n }\n }\n } else if (operator in STRING_OPERATORS) {\n if (STRING_OPERATORS[operator] === \"CONTAINS\") {\n conditionStr = `${fieldName} CONTAINS $${param}`;\n } else {\n conditionStr = `string::${STRING_OPERATORS[operator]}(${fieldName}, $${param})`;\n }\n bindings[param] = value;\n } else {\n // Fallback for unknown operators - treat as generic value comparison\n conditionStr = `${fieldName} = $${param}`;\n bindings[param] = value;\n\n ERROR_HANDLERS.unsupportedOperator(operator, config);\n }\n\n if (conditions.length > 0)\n conditions.push(` ${connector.toUpperCase()} ${conditionStr}`);\n else conditions.push(conditionStr);\n });\n\n if (conditions.length === 0) return \"\";\n return ` WHERE ${conditions.join(\"\")}`;\n}\n\n/**\n * Generates CREATE query with appropriate ID generation strategy.\n */\nexport function generateCreateQuery(\n tableName: string,\n content: Record<string, any>,\n config?: SurrealDBAdapterConfig,\n customId?: string,\n selectFields?: string,\n generateId?: () => string,\n): { query: BoundQuery } {\n let targetClause: string;\n const providedId = customId ?? (generateId ? generateId() : null);\n\n if (providedId) {\n targetClause = toRecordId(tableName, providedId).toString();\n } else {\n switch (config?.idGenerator) {\n case \"surreal.ULID\":\n targetClause = `type::record('${tableName}', rand::ulid())`;\n break;\n case \"surreal.UUID\":\n targetClause = `type::record('${tableName}', rand::uuid())`;\n break;\n case \"surreal.UUIDv4\":\n targetClause = `type::record('${tableName}', rand::uuid::v4())`;\n break;\n case \"surreal.UUIDv7\":\n targetClause = `type::record('${tableName}', rand::uuid::v7())`;\n break;\n case \"surreal.guid\":\n targetClause = `type::record('${tableName}', rand::guid())`;\n break;\n default: // Includes `sdk.*` and undefined\n targetClause = `type::record('${tableName}')`;\n break;\n }\n }\n\n const suffix = buildQuerySuffix({ returnFields: selectFields });\n const queryString = `CREATE ${targetClause} CONTENT $content${suffix}`;\n\n return {\n query: new BoundQuery(queryString, { content }),\n };\n}\n","/**\n * Schema generation utilities for SurrealDB Better Auth adapter.\n * Generates SurrealDB schema definitions with proper field types and indexes.\n */\n\nimport type { GenerateSchemaParams, GenerateSchemaResult } from \"./types\";\n\n/**\n * Generates SurrealDB schema from Better Auth table definitions with proper field types and indexes.\n */\nexport function generateSchema(\n params: GenerateSchemaParams,\n): GenerateSchemaResult {\n const { file, tables, getModelName, getFieldName, getReferencedModel } =\n params;\n\n const schemaLines: string[] = [];\n const date = new Date();\n const formatted = `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, \"0\")}-${String(date.getUTCDate()).padStart(2, \"0\")} at ${String(date.getUTCHours()).padStart(2, \"0\")}:${String(date.getUTCMinutes()).padStart(2, \"0\")}:${String(date.getUTCSeconds()).padStart(2, \"0\")} UTC`;\n\n schemaLines.push(\n \"-- ╔════════════════════════════════════════════════════════════════════════╗\",\n \"-- ║ SurrealDB Better Auth Schema ║\",\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ This schema was auto-generated for BetterAuth integration ║\",\n \"-- ║ Adapter: surreal-better-auth ║\",\n \"-- ║ Repo: https://github.com/oskar-gmerek/surreal-better-auth ║\",\n \"-- ║ Author: Oskar Gmerek ║\",\n \"-- ║ ║\",\n `-- ║ Generation Date: ${formatted.padEnd(53)}║`,\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ Warning: It is strongly recommended to manually review the schema ║\",\n \"-- ║ after each generation to ensure it fully meets your ║\",\n `-- ║ project's specific requirements. ║`,\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ Tip: The easiest way to apply this schema to your db is to copy its ║\",\n \"-- ║ contents and paste them directly into the Surrealist. ║\",\n \"-- ╚════════════════════════════════════════════════════════════════════════╝\",\n \"\",\n \"\",\n \"\",\n );\n\n /**\n * Builds decorative box around table names in schema output.\n */\n function buildTableBox(text: string, totalWidth = 76): string[] {\n const contentWidth = totalWidth - 8;\n const lineContent = text.padEnd(contentWidth, \" \");\n const top = `-- ╔${\"═\".repeat(totalWidth - 4)}╗`;\n const mid = `-- ║ ${lineContent} ║`;\n const bot = `-- ╚${\"═\".repeat(totalWidth - 4)}╝`;\n return [top, mid, bot];\n }\n\n /**\n * Maps Better Auth field types to SurrealDB types with special cases for references.\n */\n function mapFieldType(\n tableName: string,\n fieldName: string,\n type?: string,\n ): string {\n // Special cases for field-to-table mappings in schema generation\n try {\n const accountModelName = getModelName(\"account\");\n const userModelName = getModelName(\"user\");\n const accountIdFieldName = getFieldName({\n model: \"account\",\n field: \"accountId\",\n });\n\n if (tableName === accountModelName && fieldName === accountIdFieldName) {\n return `record<${userModelName}> | string`;\n }\n } catch (e) {\n // account or user model not in schema, skip\n }\n\n try {\n const oauthAccessTokenModelName = getModelName(\"oauthAccessToken\");\n const oauthApplicationModelName = getModelName(\"oauthApplication\");\n const oauthAccessTokenIdFieldName = getFieldName({\n model: \"oauthAccessToken\",\n field: \"clientId\",\n });\n\n if (\n tableName === oauthAccessTokenModelName &&\n fieldName === oauthAccessTokenIdFieldName\n ) {\n return `record<${oauthApplicationModelName}>`;\n }\n } catch (e) {\n // oauthAccessToken or oauthApplication model not in schema, skip\n }\n\n try {\n const oauthConsentModelName = getModelName(\"oauthConsent\");\n const oauthApplicationModelName = getModelName(\"oauthApplication\");\n const oauthConsentIdFieldName = getFieldName({\n model: \"oauthConsent\",\n field: \"clientId\",\n });\n\n if (\n tableName === oauthConsentModelName &&\n fieldName === oauthConsentIdFieldName\n ) {\n return `record<${oauthApplicationModelName}>`;\n }\n } catch (e) {\n // oauthConsent or oauthApplication model not in schema, skip\n }\n\n const referencedModel = getReferencedModel(tableName, fieldName);\n if (referencedModel) {\n return `record<${referencedModel}>`;\n }\n\n const typeMap: Record<string, string> = {\n boolean: \"bool\",\n date: \"datetime\",\n };\n\n return typeMap[type || \"\"] || type || \"any\";\n }\n\n // Generate schema for each table\n for (const [internalModelName, tableDef] of Object.entries(tables)) {\n const tableName = getModelName(internalModelName);\n if ((tableDef as any).disableMigrations) continue;\n\n schemaLines.push(...buildTableBox(`TABLE: ${tableName}`));\n schemaLines.push(`DEFINE TABLE OVERWRITE ${tableName} SCHEMAFULL;`);\n\n // Generate field definitions\n for (const [internalFieldName, field] of Object.entries(\n (tableDef as any).fields,\n )) {\n const fieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n const baseType = mapFieldType(\n tableName,\n fieldName,\n (field as any).type?.toString(),\n );\n const finalType =\n (field as any).required === false ? `option<${baseType}>` : baseType;\n schemaLines.push(\n `DEFINE FIELD OVERWRITE ${fieldName} ON TABLE ${tableName} TYPE ${finalType};`,\n );\n }\n\n schemaLines.push(\"\");\n // Generate indexes for specific fields\n for (const [internalFieldName, field] of Object.entries(\n (tableDef as any).fields,\n )) {\n const fieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n\n const indexedFields: Record<string, string | string[]> = {\n user: \"email\",\n account: \"userId\",\n session: [\"userId\", \"token\"],\n verification: \"identifier\",\n invitation: [\"email\", \"organizationId\"],\n member: [\"userId\", \"organizationId\"],\n organization: \"slug\",\n passkey: \"userId\",\n twoFactor: \"secret\",\n };\n\n const fieldsToIndex = indexedFields[internalModelName];\n const shouldIndex =\n fieldsToIndex &&\n ((Array.isArray(fieldsToIndex) &&\n fieldsToIndex.includes(internalFieldName)) ||\n fieldsToIndex === internalFieldName);\n\n if (shouldIndex) {\n schemaLines.push(\n `DEFINE INDEX OVERWRITE idx_${tableName}_${fieldName} ON ${tableName} COLUMNS ${fieldName}${(field as any).unique ? \" UNIQUE\" : \"\"};`,\n );\n }\n }\n schemaLines.push(\"\");\n }\n\n const path = file ?? \"schema.surql\";\n return {\n path,\n code: schemaLines.join(\"\\n\"),\n overwrite: true,\n };\n}\n","import {\n type RecordId,\n BoundQuery,\n Uuid,\n type Surreal,\n} from \"surrealdb\";\nimport type { Where } from \"better-auth/types\";\nimport { createAdapter } from \"better-auth/adapters\";\nimport { logger } from \"better-auth\";\nimport {\n mapNullToUndefined,\n recordIdsToStrings,\n buildRecordIdMap,\n logQuery,\n getReferencedModel,\n buildSpecialCasesMapping,\n serializeRecordIdFields,\n extractDirectRecords,\n buildQuerySuffix,\n buildWhereClauseParts,\n generateCreateQuery,\n} from \"./helpers\";\nimport { generateSchema } from \"./schema\";\nimport type {\n ExecuteOptimizedQueryOptions,\n SurrealDBAdapterConfig,\n} from \"./types\";\n\nexport const surrealdbAdapter = (\n db: Surreal,\n config?: SurrealDBAdapterConfig,\n) => {\n return createAdapter({\n config: {\n adapterId: \"surrealdb_adapter\",\n adapterName: \"surreal-better-auth\",\n usePlural: config?.usePlural ?? false,\n debugLogs: config?.debugLogs ?? false,\n supportsNumericIds: false,\n supportsBooleans: true,\n supportsDates: true,\n supportsJSON: true,\n customIdGenerator: config?.idGenerator?.startsWith(\"sdk.\")\n ? ({ model }: { model: string }) => {\n if (config?.debugLogs) {\n logger.info(\n `[surreal-better-auth]: Generating custom ID for model: ${model} using ${config.idGenerator} `,\n );\n }\n switch (config.idGenerator) {\n case \"sdk.UUIDv4\":\n return Uuid.v4().toString();\n case \"sdk.UUIDv7\":\n return Uuid.v7().toString();\n default:\n throw new Error(\n `Invalid ID generator type: ${config.idGenerator}. Supported types: \"sdk.UUIDv4\", \"sdk.UUIDv7\", \"surreal\", \"surreal.ULID\", \"surreal.UUID\", \"surreal.UUIDv4\", \"surreal.UUIDv7\", \"surreal.guid\"`,\n );\n }\n }\n : undefined,\n disableIdGeneration: config?.idGenerator?.startsWith(\"surreal\") ?? false,\n customTransformOutput({ data }) {\n if (data === undefined) return null;\n return recordIdsToStrings(data);\n },\n },\n adapter: ({\n options,\n getModelName,\n getFieldName,\n getDefaultModelName,\n getDefaultFieldName,\n debugLog,\n }) => {\n const recordIdMap = buildRecordIdMap(\n (options as any)?.schema?.tables,\n getModelName,\n getFieldName,\n );\n\n // Extract generateId from options if provided by Better Auth\n const generateId = (options as any)?.advanced?.database?.generateId;\n\n // Create helper functions with bound dependencies\n const getReferencedModelFn = (tableName: string, fieldName: string) =>\n getReferencedModel(\n tableName,\n fieldName,\n recordIdMap,\n getDefaultModelName,\n getDefaultFieldName,\n getModelName,\n config,\n );\n\n const buildSpecialCasesFn = () =>\n buildSpecialCasesMapping(getModelName, getFieldName, config);\n\n const serializeRecordIdFieldsFn = (\n tableName: string,\n data: Record<string, any>,\n ) =>\n serializeRecordIdFields(\n tableName,\n data,\n getReferencedModelFn,\n buildSpecialCasesFn,\n config,\n );\n\n const extractDirectRecordsFn = (\n where: Where[] | undefined,\n model: string,\n ) => extractDirectRecords(where, model, getModelName);\n\n const buildQuerySuffixFn = (options: any = {}) =>\n buildQuerySuffix(options, getFieldName);\n\n const buildWhereClausePartsFn = (\n bindings: Record<string, unknown>,\n { where, model }: { where: Where[]; model: string },\n ) =>\n buildWhereClauseParts(\n bindings,\n { where, model },\n getModelName,\n getFieldName,\n getReferencedModelFn,\n config,\n );\n\n const generateCreateQueryFn = (\n tableName: string,\n content: Record<string, any>,\n customId?: string,\n selectFields?: string,\n ) =>\n generateCreateQuery(\n tableName,\n content,\n config,\n customId,\n selectFields,\n generateId,\n );\n\n async function executeOptimizedQuery(\n options: ExecuteOptimizedQueryOptions,\n ): Promise<any> {\n const {\n method,\n model,\n where,\n baseQuery,\n directRecordQuery,\n content,\n suffix = \"\",\n processResult = (r: any) => r,\n returnCount = false,\n singleRecord = false,\n } = options;\n\n // Check for direct record access optimization\n const directRecordInfo = extractDirectRecordsFn(where, model);\n\n if (directRecordInfo && directRecordQuery) {\n const { recordIds, remainingWhere } = directRecordInfo;\n const directQuery = directRecordQuery(recordIds);\n\n if (remainingWhere.length === 0) {\n // Pure direct record operation\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const query = new BoundQuery(directQuery + suffix, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n // Direct record operation with additional WHERE conditions\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const whereStr = buildWhereClausePartsFn(bindings, {\n where: remainingWhere,\n model,\n });\n const queryString = directQuery + whereStr + suffix;\n\n const query = new BoundQuery(queryString, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n\n // Fallback to standard WHERE clause query\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const whereStr = buildWhereClausePartsFn(bindings, {\n where: where || [],\n model,\n });\n const queryString = baseQuery + whereStr + suffix;\n\n const query = new BoundQuery(queryString, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n\n return {\n async create({ model, data: values, select }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n // Extract custom ID if allowed or if using sdk.* generator (Better Auth passes generated ID)\n const customId =\n (config?.allowPassingId ||\n config?.idGenerator?.startsWith(\"sdk.\")) &&\n content.id\n ? content.id\n : undefined;\n // Always remove id field from content\n content.id = undefined;\n\n // Process select parameter\n let selectFields: string | undefined;\n if (select && Array.isArray(select) && select.length > 0) {\n const mappedFields = select.map((field) =>\n getFieldName({ model, field }),\n );\n // Always include id in the return fields\n if (!mappedFields.includes(\"id\")) {\n mappedFields.unshift(\"id\");\n }\n selectFields = mappedFields.join(\", \");\n }\n\n // Generate query\n const { query } = generateCreateQueryFn(\n tableName,\n content,\n customId,\n selectFields,\n );\n\n logQuery(config, debugLog, \"create\", query);\n\n const result = await db.query<[any[]]>(query).collect();\n return recordIdsToStrings(result[0][0]);\n },\n\n async findOne({ model, where, select }) {\n const tableName = getModelName(model);\n const selectFields = select\n ? typeof select === \"string\"\n ? getFieldName({ model, field: select })\n : (select as string[])\n .map((f) => getFieldName({ model, field: f }))\n .join(\", \")\n : \"*\";\n\n return executeOptimizedQuery({\n method: \"findOne\",\n model,\n where,\n baseQuery: `SELECT ${selectFields} FROM ONLY ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT ${selectFields} FROM ONLY ${recordIds[0].toString()}`,\n suffix: buildQuerySuffixFn({ limitOne: true }),\n processResult: (result: any) => recordIdsToStrings(result) || null,\n singleRecord: true,\n });\n },\n\n async findMany({ model, where, limit, offset, sortBy }) {\n const tableName = getModelName(model);\n const selectClause = \"*\";\n\n return executeOptimizedQuery({\n method: \"findMany\",\n model,\n where,\n baseQuery: `SELECT ${selectClause} FROM ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT ${selectClause} FROM [${recordIds.map((id: RecordId) => id.toString()).join(\", \")}]`,\n suffix: buildQuerySuffixFn({ sortBy, limit, offset, model }),\n processResult: recordIdsToStrings,\n });\n },\n\n async count({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"count\",\n model,\n where,\n baseQuery: `SELECT count() FROM ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT count() FROM [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}]`,\n suffix: buildQuerySuffixFn({ groupAll: true }),\n processResult: (result: any) => result[0].count || 0,\n singleRecord: true,\n });\n },\n\n async update({ model, where, update: values }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n return executeOptimizedQuery({\n method: \"update\",\n model,\n where,\n baseQuery: `UPDATE ONLY ${tableName} MERGE $content`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `UPDATE ONLY ${recordIds[0].toString()} MERGE $content`,\n content,\n suffix: buildQuerySuffixFn({ returnAfter: true }),\n processResult: (result: any) => recordIdsToStrings(result) || null,\n singleRecord: true,\n });\n },\n\n async updateMany({ model, where, update: values }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n return executeOptimizedQuery({\n method: \"updateMany\",\n model,\n where,\n baseQuery: `UPDATE ${tableName} MERGE $content`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `UPDATE [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}] MERGE $content`,\n content,\n returnCount: true,\n });\n },\n\n async delete({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"delete\",\n model,\n where,\n baseQuery: `DELETE ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `DELETE ${recordIds[0].toString()}`,\n processResult: () => undefined,\n });\n },\n\n async deleteMany({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"deleteMany\",\n model,\n where,\n baseQuery: `DELETE ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `DELETE [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}]`,\n returnCount: true,\n });\n },\n\n async createSchema({ file, tables }) {\n return generateSchema({\n file,\n tables,\n getModelName,\n getFieldName,\n getReferencedModel: getReferencedModelFn,\n });\n },\n };\n },\n });\n};\n"]}
@@ -0,0 +1,56 @@
1
+ import * as better_auth from 'better-auth';
2
+ import { Surreal } from 'surrealdb';
3
+ import { AdapterDebugLogs } from 'better-auth/adapters';
4
+
5
+ /**
6
+ * ID generation strategies for SurrealDB records.
7
+ */
8
+ type IdGenerator = "sdk.UUIDv4" | "sdk.UUIDv7" | "surreal" | "surreal.ULID" | "surreal.UUID" | "surreal.UUIDv4" | "surreal.UUIDv7" | "surreal.guid";
9
+ /**
10
+ * Configuration options for the SurrealDB adapter.
11
+ */
12
+ interface SurrealDBAdapterConfig {
13
+ /** Enable debug logging for adapter operations. */
14
+ debugLogs?: AdapterDebugLogs;
15
+ /** Use plural table names (e.g., 'users' instead of 'user'). @default false */
16
+ usePlural?: boolean;
17
+ /** ID generation strategy. @default undefined (uses Better Auth default) */
18
+ idGenerator?: IdGenerator;
19
+ /** Allow passing custom IDs in data objects. @default false */
20
+ allowPassingId?: boolean;
21
+ }
22
+ /**
23
+ * Parameters for schema generation from Better Auth tables.
24
+ */
25
+ interface GenerateSchemaParams {
26
+ file?: string;
27
+ tables: Record<string, any>;
28
+ getModelName: (model: string) => string;
29
+ getFieldName: (opts: {
30
+ model: string;
31
+ field: string;
32
+ }) => string;
33
+ getReferencedModel: (tableName: string, fieldName: string) => string | null;
34
+ }
35
+ /**
36
+ * Result of schema generation with path and content.
37
+ */
38
+ interface GenerateSchemaResult {
39
+ path: string;
40
+ code: string;
41
+ overwrite: boolean;
42
+ }
43
+
44
+ declare const surrealdbAdapter: (db: Surreal, config?: SurrealDBAdapterConfig) => (options: better_auth.BetterAuthOptions) => better_auth.Adapter;
45
+
46
+ /**
47
+ * Schema generation utilities for SurrealDB Better Auth adapter.
48
+ * Generates SurrealDB schema definitions with proper field types and indexes.
49
+ */
50
+
51
+ /**
52
+ * Generates SurrealDB schema from Better Auth table definitions with proper field types and indexes.
53
+ */
54
+ declare function generateSchema(params: GenerateSchemaParams): GenerateSchemaResult;
55
+
56
+ export { type IdGenerator, type SurrealDBAdapterConfig, generateSchema, surrealdbAdapter };
@@ -0,0 +1,56 @@
1
+ import * as better_auth from 'better-auth';
2
+ import { Surreal } from 'surrealdb';
3
+ import { AdapterDebugLogs } from 'better-auth/adapters';
4
+
5
+ /**
6
+ * ID generation strategies for SurrealDB records.
7
+ */
8
+ type IdGenerator = "sdk.UUIDv4" | "sdk.UUIDv7" | "surreal" | "surreal.ULID" | "surreal.UUID" | "surreal.UUIDv4" | "surreal.UUIDv7" | "surreal.guid";
9
+ /**
10
+ * Configuration options for the SurrealDB adapter.
11
+ */
12
+ interface SurrealDBAdapterConfig {
13
+ /** Enable debug logging for adapter operations. */
14
+ debugLogs?: AdapterDebugLogs;
15
+ /** Use plural table names (e.g., 'users' instead of 'user'). @default false */
16
+ usePlural?: boolean;
17
+ /** ID generation strategy. @default undefined (uses Better Auth default) */
18
+ idGenerator?: IdGenerator;
19
+ /** Allow passing custom IDs in data objects. @default false */
20
+ allowPassingId?: boolean;
21
+ }
22
+ /**
23
+ * Parameters for schema generation from Better Auth tables.
24
+ */
25
+ interface GenerateSchemaParams {
26
+ file?: string;
27
+ tables: Record<string, any>;
28
+ getModelName: (model: string) => string;
29
+ getFieldName: (opts: {
30
+ model: string;
31
+ field: string;
32
+ }) => string;
33
+ getReferencedModel: (tableName: string, fieldName: string) => string | null;
34
+ }
35
+ /**
36
+ * Result of schema generation with path and content.
37
+ */
38
+ interface GenerateSchemaResult {
39
+ path: string;
40
+ code: string;
41
+ overwrite: boolean;
42
+ }
43
+
44
+ declare const surrealdbAdapter: (db: Surreal, config?: SurrealDBAdapterConfig) => (options: better_auth.BetterAuthOptions) => better_auth.Adapter;
45
+
46
+ /**
47
+ * Schema generation utilities for SurrealDB Better Auth adapter.
48
+ * Generates SurrealDB schema definitions with proper field types and indexes.
49
+ */
50
+
51
+ /**
52
+ * Generates SurrealDB schema from Better Auth table definitions with proper field types and indexes.
53
+ */
54
+ declare function generateSchema(params: GenerateSchemaParams): GenerateSchemaResult;
55
+
56
+ export { type IdGenerator, type SurrealDBAdapterConfig, generateSchema, surrealdbAdapter };
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import {Uuid,BoundQuery,RecordId}from'surrealdb';import {createAdapter}from'better-auth/adapters';import {logger}from'better-auth';var ee={userId:"user",organizationId:"organization",teamId:"team",inviterId:"user",activeOrganizationId:"organization",activeTeamId:"team"},q={eq:"=",ne:"!=",gt:">",gte:">=",lt:"<",lte:"<="},N={contains:"CONTAINS",starts_with:"starts_with",ends_with:"ends_with"},re=[{sourceModel:"account",sourceField:"accountId",targetModel:"user",condition:e=>e.providerId==="credential"},{sourceModel:"oauthAccessToken",sourceField:"clientId",targetModel:"oauthApplication"},{sourceModel:"oauthConsent",sourceField:"clientId",targetModel:"oauthApplication"}];function k(e){let r={...e};for(let a of Object.keys(r))r[a]===null&&(r[a]=void 0);return r}function T(e,r){return r instanceof RecordId?r:typeof r=="string"?r.includes(":")?new RecordId(r.split(":")[0],r.split(":")[1]):new RecordId(e,r):new RecordId(e,r)}function x(e){if(e==null)return e;if(e instanceof RecordId)return e.toString();if(e instanceof Date)return e;if(Array.isArray(e))return e.map(r=>x(r));if(typeof e=="object"){let r={};for(let[a,s]of Object.entries(e))r[a]=x(s);return r}return e}function te(e,r,a){let s={tableSpecific:{}};if(!e)return s;for(let d in e){let l=e[d];if(!l?.fields)continue;let o=r(d);s.tableSpecific[o]||(s.tableSpecific[o]={});for(let n in l.fields){let y=l.fields[n];if(y?.references?.model){let b=a({model:d,field:n}),p=r(y.references.model);s.tableSpecific[o][b]=p;}}}return s}function F(e,r,a,s){if(!e?.debugLogs||e.debugLogs&&typeof e.debugLogs=="object"&&!("isRunningAdapterTests"in e.debugLogs)&&(a==="create"&&!e.debugLogs.create||a==="update"&&!e.debugLogs.update||a==="updateMany"&&!e.debugLogs.updateMany||a==="findOne"&&!e.debugLogs.findOne||a==="findMany"&&!e.debugLogs.findMany||a==="delete"&&!e.debugLogs.delete||a==="deleteMany"&&!e.debugLogs.deleteMany||a==="count"&&!e.debugLogs.count))return;let d=s.query,l=s.bindings,o=d;Object.entries(l).forEach(([b,p])=>{let $=new RegExp(`\\$${b}\\b`,"g"),u;p instanceof RecordId?u=p.toString():typeof p=="string"&&p.includes(":")?u=p:u=JSON.stringify(p),o=o.replace($,u);});let n={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",fg:{surreal_pink:"\x1B[38;5;200m",surreal_purple:"\x1B[38;5;93m",yellow:"\x1B[33m",magenta:"\x1B[35m"},bg:{obsidian_violet:"\x1B[48;5;233m",black:"\x1B[40m"}};function y(b,p){let $=`${n.fg.magenta}###`,u=`${n.bg.black}${n.fg.yellow}[0/#]${n.reset}`,R=`${n.bright}${a}`,h=`${n.dim}(BoundQuery)${n.reset}`,I=" ",m=`${n.bg.obsidian_violet}`;return m+=I,m+=`${n.fg.surreal_purple}[${b}]`,m+=` ${n.fg.surreal_pink}${p}`,m+=I,m+=`${n.reset}`,`${$} ${u} ${R} ${h}
2
+
3
+ ${m}
4
+
5
+ `}r(`${y("SurrealQL",o)}`);}var W={modelNotFound:(e,r)=>{r?.debugLogs&&logger.debug(`[surreal-better-auth]: Model '${e}' not found in schema, skipping operation `);},fieldMappingSkipped:(e,r,a)=>{a?.debugLogs&&logger.debug(`[surreal-better-auth]: Skipping field mapping rule for '${e}': ${r} `);},unsupportedOperator:(e,r)=>{r?.debugLogs&&logger.warn(`[surreal-better-auth]: Unknown operator '${e}', falling back to equality comparison `);}};function ne(e,r,a,s,d,l,o){let n=s(e),y=d({model:n,field:r}),b=ee[y];if(b)try{let $=l(b);return o?.debugLogs&&logger.debug(`[surreal-better-auth]: Found default reference: ${e}.${r} -> ${$} `),$}catch{W.modelNotFound(b,o);}let p=a.tableSpecific[e]?.[r];return p&&o?.debugLogs&&logger.debug(`[surreal-better-auth]: Found table-specific reference: ${e}.${r} -> ${p} `),p||null}function oe(e,r,a){let s={};for(let d of re)try{let l=e(d.sourceModel),o=e(d.targetModel),n=r({model:d.sourceModel,field:d.sourceField});s[l]||(s[l]={}),s[l][n]={recordTable:o,condition:d.condition},a?.debugLogs&&logger.debug(`[surreal-better-auth]: Registered field mapping: ${l}.${n} -> to record ${o} `);}catch(l){let o=l;W.fieldMappingSkipped(`${d.sourceModel}.${d.sourceField}`,o.message,a);}return s}function se(e,r,a,s,d){let l={...r},o=s();d?.debugLogs&&logger.debug(`[surreal-better-auth]: Serializing record ID fields for table: ${e} `,{fieldCount:Object.keys(l).length,hasSpecialCases:!!o[e]});for(let n in l){let y=l[n];if(typeof y!="string"||!y)continue;let b=o[e]?.[n];if(b)if(!b.condition||b.condition(l)){let $=T(b.recordTable,y);l[n]=$,d?.debugLogs&&logger.debug(`[surreal-better-auth]: Applied special case mapping: ${e}.${n} = "${y}" -> "${$}" `);}else d?.debugLogs&&logger.debug(`[surreal-better-auth]: Special case condition not met for: ${e}.${n} `);else {let p=a(e,n);if(p){let $=T(p,y);l[n]=$,d?.debugLogs&&logger.debug(`[surreal-better-auth]: Applied default reference mapping: ${e}.${n} = "${y}" -> "${$}" `);}}}return l}function ie(e,r,a){if(!e||e.length===0)return null;let s=a(r),d=e.findIndex(o=>o.field==="id"&&o.operator==="eq");if(d!==-1){let o=e[d],n=T(s,o.value),y=e.filter((b,p)=>p!==d);return {recordIds:[n],remainingWhere:y}}let l=e.findIndex(o=>o.field==="id"&&o.operator==="in"&&Array.isArray(o.value));if(l!==-1){let n=e[l].value.map(b=>T(s,b)),y=e.filter((b,p)=>p!==l);return {recordIds:n,remainingWhere:y}}return null}function v(e={},r){let{sortBy:a,limit:s,offset:d,groupAll:l,returnAfter:o,returnFields:n,limitOne:y,model:b}=e,p="";if(a&&b&&r){let $=r({model:b,field:a.field}),u=a.direction==="desc"?"DESC":"ASC";p+=` ORDER BY ${$} ${u}`;}return y?p+=" LIMIT 1":typeof s=="number"&&(p+=` LIMIT ${s}`),typeof d=="number"&&(p+=` START AT ${d}`),l&&(p+=" GROUP ALL"),o?p+=" RETURN AFTER":n&&(p+=` RETURN ${n}`),p}function ae(e,{where:r,model:a},s,d,l,o){if(!r||r.length===0)return "";let n=[],y=s(a);return r.forEach((b,p)=>{let{field:$,value:u,operator:R="eq",connector:h="AND"}=b;if(R==="in"&&Array.isArray(u)&&u.length===0||R==="not_in"&&Array.isArray(u)&&u.length===0)return;let I=d({model:a,field:$}),m=`where_${p}`,f="";if(R==="in"){f=`${I} IN $${m}`;let t=Array.isArray(u)?u:[u],i=t;if($==="id")i=t.map(c=>T(y,c));else {let c=l(y,I);c&&(i=t.map(g=>typeof g=="string"?T(c,g):g));}e[m]=i;}else if(R==="not_in"){f=`${I} NOT IN $${m}`;let t=Array.isArray(u)?u:[u],i=t;if($==="id")i=t.map(c=>T(y,c));else {let c=l(y,I);c&&(i=t.map(g=>typeof g=="string"?T(c,g):g));}e[m]=i;}else if(R in q)if(f=`${I} ${q[R]} $${m}`,$==="id")e[m]=T(y,u);else {let t=l(y,I);t&&typeof u=="string"?e[m]=T(t,u):e[m]=u;}else R in N?(N[R]==="CONTAINS"?f=`${I} CONTAINS $${m}`:f=`string::${N[R]}(${I}, $${m})`,e[m]=u):(f=`${I} = $${m}`,e[m]=u,W.unsupportedOperator(R,o));n.length>0?n.push(` ${h.toUpperCase()} ${f}`):n.push(f);}),n.length===0?"":` WHERE ${n.join("")}`}function de(e,r,a,s,d,l){let o,n=s??(l?l():null);if(n)o=T(e,n).toString();else switch(a?.idGenerator){case "surreal.ULID":o=`type::record('${e}', rand::ulid())`;break;case "surreal.UUID":o=`type::record('${e}', rand::uuid())`;break;case "surreal.UUIDv4":o=`type::record('${e}', rand::uuid::v4())`;break;case "surreal.UUIDv7":o=`type::record('${e}', rand::uuid::v7())`;break;case "surreal.guid":o=`type::record('${e}', rand::guid())`;break;default:o=`type::record('${e}')`;break}let y=v({returnFields:d}),b=`CREATE ${o} CONTENT $content${y}`;return {query:new BoundQuery(b,{content:r})}}function j(e){let{file:r,tables:a,getModelName:s,getFieldName:d,getReferencedModel:l}=e,o=[],n=new Date,y=`${n.getUTCFullYear()}-${String(n.getUTCMonth()+1).padStart(2,"0")}-${String(n.getUTCDate()).padStart(2,"0")} at ${String(n.getUTCHours()).padStart(2,"0")}:${String(n.getUTCMinutes()).padStart(2,"0")}:${String(n.getUTCSeconds()).padStart(2,"0")} UTC`;o.push("-- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","-- \u2551 SurrealDB Better Auth Schema \u2551","-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 This schema was auto-generated for BetterAuth integration \u2551","-- \u2551 Adapter: surreal-better-auth \u2551","-- \u2551 Repo: https://github.com/oskar-gmerek/surreal-better-auth \u2551","-- \u2551 Author: Oskar Gmerek \u2551","-- \u2551 \u2551",`-- \u2551 Generation Date: ${y.padEnd(53)}\u2551`,"-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 Warning: It is strongly recommended to manually review the schema \u2551","-- \u2551 after each generation to ensure it fully meets your \u2551","-- \u2551 project's specific requirements. \u2551","-- \u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562","-- \u2551 Tip: The easiest way to apply this schema to your db is to copy its \u2551","-- \u2551 contents and paste them directly into the Surrealist. \u2551","-- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","","","");function b(u,R=76){let h=R-8,I=u.padEnd(h," "),m=`-- \u2554${"\u2550".repeat(R-4)}\u2557`,f=`-- \u2551 ${I} \u2551`,t=`-- \u255A${"\u2550".repeat(R-4)}\u255D`;return [m,f,t]}function p(u,R,h){try{let f=s("account"),t=s("user"),i=d({model:"account",field:"accountId"});if(u===f&&R===i)return `record<${t}> | string`}catch{}try{let f=s("oauthAccessToken"),t=s("oauthApplication"),i=d({model:"oauthAccessToken",field:"clientId"});if(u===f&&R===i)return `record<${t}>`}catch{}try{let f=s("oauthConsent"),t=s("oauthApplication"),i=d({model:"oauthConsent",field:"clientId"});if(u===f&&R===i)return `record<${t}>`}catch{}let I=l(u,R);return I?`record<${I}>`:{boolean:"bool",date:"datetime"}[h||""]||h||"any"}for(let[u,R]of Object.entries(a)){let h=s(u);if(!R.disableMigrations){o.push(...b(`TABLE: ${h}`)),o.push(`DEFINE TABLE OVERWRITE ${h} SCHEMAFULL;`);for(let[I,m]of Object.entries(R.fields)){let f=d({model:u,field:I}),t=p(h,f,m.type?.toString()),i=m.required===false?`option<${t}>`:t;o.push(`DEFINE FIELD OVERWRITE ${f} ON TABLE ${h} TYPE ${i};`);}o.push("");for(let[I,m]of Object.entries(R.fields)){let f=d({model:u,field:I}),i={user:"email",account:"userId",session:["userId","token"],verification:"identifier",invitation:["email","organizationId"],member:["userId","organizationId"],organization:"slug",passkey:"userId",twoFactor:"secret"}[u];i&&(Array.isArray(i)&&i.includes(I)||i===I)&&o.push(`DEFINE INDEX OVERWRITE idx_${h}_${f} ON ${h} COLUMNS ${f}${m.unique?" UNIQUE":""};`);}o.push("");}}return {path:r??"schema.surql",code:o.join(`
6
+ `),overwrite:true}}var be=(e,r)=>createAdapter({config:{adapterId:"surrealdb_adapter",adapterName:"surreal-better-auth",usePlural:r?.usePlural??false,debugLogs:r?.debugLogs??false,supportsNumericIds:false,supportsBooleans:true,supportsDates:true,supportsJSON:true,customIdGenerator:r?.idGenerator?.startsWith("sdk.")?({model:a})=>{switch(r?.debugLogs&&logger.info(`[surreal-better-auth]: Generating custom ID for model: ${a} using ${r.idGenerator} `),r.idGenerator){case "sdk.UUIDv4":return Uuid.v4().toString();case "sdk.UUIDv7":return Uuid.v7().toString();default:throw new Error(`Invalid ID generator type: ${r.idGenerator}. Supported types: "sdk.UUIDv4", "sdk.UUIDv7", "surreal", "surreal.ULID", "surreal.UUID", "surreal.UUIDv4", "surreal.UUIDv7", "surreal.guid"`)}}:void 0,disableIdGeneration:r?.idGenerator?.startsWith("surreal")??false,customTransformOutput({data:a}){return a===void 0?null:x(a)}},adapter:({options:a,getModelName:s,getFieldName:d,getDefaultModelName:l,getDefaultFieldName:o,debugLog:n})=>{let y=te(a?.schema?.tables,s,d),b=a?.advanced?.database?.generateId,p=(t,i)=>ne(t,i,y,l,o,s,r),$=()=>oe(s,d,r),u=(t,i)=>se(t,i,p,$,r),R=(t,i)=>ie(t,i,s),h=(t={})=>v(t,d),I=(t,{where:i,model:c})=>ae(t,{where:i,model:c},s,d,p,r),m=(t,i,c,g)=>de(t,i,r,c,g,b);async function f(t){let{method:i,model:c,where:g,baseQuery:S,directRecordQuery:E,content:A,suffix:D="",processResult:C=G=>G,returnCount:O=false,singleRecord:U=false}=t,Y=R(g,c);if(Y&&E){let{recordIds:G,remainingWhere:H}=Y,J=E(G);if(H.length===0){let K={};A!==void 0&&(K.content=A);let Z=new BoundQuery(J+D,K);F(r,n,i,Z);let P=await e.query(Z).collect();return O?P[0]?.length||0:C(P[0])}let _={};A!==void 0&&(_.content=A);let pe=I(_,{where:H,model:c}),fe=J+pe+D,X=new BoundQuery(fe,_);F(r,n,i,X);let B=await e.query(X).collect();return O?B[0]?.length||0:C(B[0])}let Q={};A!==void 0&&(Q.content=A);let ce=I(Q,{where:g||[],model:c}),le=S+ce+D,V=new BoundQuery(le,Q);F(r,n,i,V);let w=await e.query(V).collect();return O?w[0]?.length||0:C(w[0])}return {async create({model:t,data:i,select:c}){let g=s(t),S=u(g,k(i)),E=(r?.allowPassingId||r?.idGenerator?.startsWith("sdk."))&&S.id?S.id:void 0;S.id=void 0;let A;if(c&&Array.isArray(c)&&c.length>0){let O=c.map(U=>d({model:t,field:U}));O.includes("id")||O.unshift("id"),A=O.join(", ");}let{query:D}=m(g,S,E,A);F(r,n,"create",D);let C=await e.query(D).collect();return x(C[0][0])},async findOne({model:t,where:i,select:c}){let g=s(t),S=c?typeof c=="string"?d({model:t,field:c}):c.map(E=>d({model:t,field:E})).join(", "):"*";return f({method:"findOne",model:t,where:i,baseQuery:`SELECT ${S} FROM ONLY ${g}`,directRecordQuery:E=>`SELECT ${S} FROM ONLY ${E[0].toString()}`,suffix:h({limitOne:true}),processResult:E=>x(E)||null,singleRecord:true})},async findMany({model:t,where:i,limit:c,offset:g,sortBy:S}){let E=s(t),A="*";return f({method:"findMany",model:t,where:i,baseQuery:`SELECT ${A} FROM ${E}`,directRecordQuery:D=>`SELECT ${A} FROM [${D.map(C=>C.toString()).join(", ")}]`,suffix:h({sortBy:S,limit:c,offset:g,model:t}),processResult:x})},async count({model:t,where:i}){let c=s(t);return f({method:"count",model:t,where:i,baseQuery:`SELECT count() FROM ${c}`,directRecordQuery:g=>`SELECT count() FROM [${g.map(S=>S.toString()).join(", ")}]`,suffix:h({groupAll:true}),processResult:g=>g[0].count||0,singleRecord:true})},async update({model:t,where:i,update:c}){let g=s(t),S=u(g,k(c));return f({method:"update",model:t,where:i,baseQuery:`UPDATE ONLY ${g} MERGE $content`,directRecordQuery:E=>`UPDATE ONLY ${E[0].toString()} MERGE $content`,content:S,suffix:h({returnAfter:true}),processResult:E=>x(E)||null,singleRecord:true})},async updateMany({model:t,where:i,update:c}){let g=s(t),S=u(g,k(c));return f({method:"updateMany",model:t,where:i,baseQuery:`UPDATE ${g} MERGE $content`,directRecordQuery:E=>`UPDATE [${E.map(A=>A.toString()).join(", ")}] MERGE $content`,content:S,returnCount:true})},async delete({model:t,where:i}){let c=s(t);return f({method:"delete",model:t,where:i,baseQuery:`DELETE ${c}`,directRecordQuery:g=>`DELETE ${g[0].toString()}`,processResult:()=>{}})},async deleteMany({model:t,where:i}){let c=s(t);return f({method:"deleteMany",model:t,where:i,baseQuery:`DELETE ${c}`,directRecordQuery:g=>`DELETE [${g.map(S=>S.toString()).join(", ")}]`,returnCount:true})},async createSchema({file:t,tables:i}){return j({file:t,tables:i,getModelName:s,getFieldName:d,getReferencedModel:p})}}}});export{j as generateSchema,be as surrealdbAdapter};//# sourceMappingURL=index.js.map
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/helpers.ts","../src/schema.ts","../src/surreal-adapter.ts"],"names":["DEFAULT_FIELD_REFERENCES","COMPARISON_OPERATORS","STRING_OPERATORS","FIELD_MAPPING_RULES","data","mapNullToUndefined","out","k","toRecordId","model","id","RecordId","recordIdsToStrings","value","v","buildRecordIdMap","tables","getModelName","getFieldName","map","internalModelName","tableDef","actualTableName","internalFieldName","fieldDef","actualFieldName","referencedActualTableName","logQuery","config","debugLog","method","query","queryTemplate","params","readableQuery","paramName","paramPattern","formattedValue","colors","formatLogLine","lang","transationId","stepString","methodString","preparedString","PADDING","formattedString","ERROR_HANDLERS","modelName","logger","rule","reason","operator","getReferencedModel","tableName","fieldName","recordIdMap","getDefaultModelName","getDefaultFieldName","defaultModel","defaultField","referencedModel","tableSpecificRef","buildSpecialCasesMapping","specialCases","sourceModelName","targetModelName","e","error","serializeRecordIdFields","getReferencedModelFn","buildSpecialCasesFn","specialCase","recordId","extractDirectRecords","where","idEqIndex","w","idEqCondition","remainingWhere","_","index","idInIndex","recordIds","buildQuerySuffix","options","sortBy","limit","offset","groupAll","returnAfter","returnFields","limitOne","suffix","field","direction","buildWhereClauseParts","bindings","conditions","idx","internalField","connector","param","conditionStr","vals","finalVals","referencedModelName","generateCreateQuery","content","customId","selectFields","generateId","targetClause","providedId","queryString","BoundQuery","generateSchema","file","schemaLines","date","formatted","buildTableBox","text","totalWidth","contentWidth","lineContent","top","mid","bot","mapFieldType","type","accountModelName","userModelName","accountIdFieldName","oauthAccessTokenModelName","oauthApplicationModelName","oauthAccessTokenIdFieldName","oauthConsentModelName","oauthConsentIdFieldName","baseType","finalType","fieldsToIndex","surrealdbAdapter","db","createAdapter","Uuid","serializeRecordIdFieldsFn","extractDirectRecordsFn","buildQuerySuffixFn","buildWhereClausePartsFn","generateCreateQueryFn","executeOptimizedQuery","baseQuery","directRecordQuery","processResult","r","returnCount","singleRecord","directRecordInfo","directQuery","result","whereStr","values","select","mappedFields","f","selectClause"],"mappings":"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","file":"index.js","sourcesContent":["import type { AdapterDebugLogs } from \"better-auth/adapters\";\n\n/**\n * ID generation strategies for SurrealDB records.\n */\nexport type IdGenerator =\n | \"sdk.UUIDv4\"\n | \"sdk.UUIDv7\"\n | \"surreal\"\n | \"surreal.ULID\"\n | \"surreal.UUID\"\n | \"surreal.UUIDv4\"\n | \"surreal.UUIDv7\"\n | \"surreal.guid\";\n\n/**\n * Maps table fields to their referenced tables for RecordId conversion.\n */\nexport interface RecordIdMap {\n tableSpecific: Record<string, Record<string, string>>;\n}\n\n/**\n * Configuration options for the SurrealDB adapter.\n */\nexport interface SurrealDBAdapterConfig {\n /** Enable debug logging for adapter operations. */\n debugLogs?: AdapterDebugLogs;\n\n /** Use plural table names (e.g., 'users' instead of 'user'). @default false */\n usePlural?: boolean;\n\n /** ID generation strategy. @default undefined (uses Better Auth default) */\n idGenerator?: IdGenerator;\n\n /** Allow passing custom IDs in data objects. @default false */\n allowPassingId?: boolean;\n}\n\n/**\n * Adapter method names for logging and debugging.\n */\nexport type AdapterMethod =\n | \"create\"\n | \"update\"\n | \"updateMany\"\n | \"findOne\"\n | \"findMany\"\n | \"delete\"\n | \"deleteMany\"\n | \"count\";\n\n/**\n * Rule for special field-to-table mappings with optional conditions.\n */\nexport interface FieldMappingRule {\n sourceModel: string;\n sourceField: string;\n targetModel: string;\n condition?: (data: Record<string, any>) => boolean;\n}\n\n/**\n * Options for building query suffix clauses (ORDER BY, LIMIT, etc.).\n */\nexport interface QuerySuffixOptions {\n sortBy?: { field: string; direction?: \"asc\" | \"desc\" };\n limit?: number;\n offset?: number;\n groupAll?: boolean;\n returnAfter?: boolean;\n returnFields?: string;\n limitOne?: boolean;\n model?: string;\n}\n\n/**\n * Options for optimized query execution with direct record access.\n */\nexport interface ExecuteOptimizedQueryOptions {\n method: AdapterMethod;\n model: string;\n where?: any[];\n baseQuery: string;\n directRecordQuery?: (recordIds: any[]) => string;\n content?: any;\n suffix?: string;\n processResult?: (result: any) => any;\n returnCount?: boolean;\n singleRecord?: boolean;\n}\n\n/**\n * Default field-to-table reference mappings for common Better Auth fields.\n */\nexport const DEFAULT_FIELD_REFERENCES: Record<string, string> = {\n userId: \"user\",\n organizationId: \"organization\",\n teamId: \"team\",\n inviterId: \"user\",\n activeOrganizationId: \"organization\",\n activeTeamId: \"team\",\n};\n\n/**\n * Comparison operator mappings for SurrealDB WHERE clauses.\n */\nexport const COMPARISON_OPERATORS: Record<string, string> = {\n eq: \"=\",\n ne: \"!=\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/**\n * String operator mappings for SurrealDB text operations.\n */\nexport const STRING_OPERATORS: Record<string, string> = {\n contains: \"CONTAINS\",\n starts_with: \"starts_with\",\n ends_with: \"ends_with\",\n};\n\n/**\n * Special field mapping rules with conditional logic.\n */\nexport const FIELD_MAPPING_RULES: FieldMappingRule[] = [\n {\n sourceModel: \"account\",\n sourceField: \"accountId\",\n targetModel: \"user\",\n condition: (data) => data.providerId === \"credential\",\n },\n {\n sourceModel: \"oauthAccessToken\",\n sourceField: \"clientId\",\n targetModel: \"oauthApplication\",\n },\n {\n sourceModel: \"oauthConsent\",\n sourceField: \"clientId\",\n targetModel: \"oauthApplication\",\n },\n];\n\n/**\n * Parameters for schema generation from Better Auth tables.\n */\nexport interface GenerateSchemaParams {\n file?: string;\n tables: Record<string, any>;\n getModelName: (model: string) => string;\n getFieldName: (opts: { model: string; field: string }) => string;\n getReferencedModel: (tableName: string, fieldName: string) => string | null;\n}\n\n/**\n * Result of schema generation with path and content.\n */\nexport interface GenerateSchemaResult {\n path: string;\n code: string;\n overwrite: boolean;\n}\n","/**\n * Helper utilities for SurrealDB Better Auth adapter.\n * Handles ID conversion, data transformation, and schema mapping.\n */\n\nimport { BoundQuery, RecordId } from \"surrealdb\";\nimport type { Where } from \"better-auth/types\";\nimport { logger } from \"better-auth\";\nimport type {\n AdapterMethod,\n RecordIdMap,\n SurrealDBAdapterConfig,\n QuerySuffixOptions,\n // FieldMappingRule\n} from \"./types\";\nimport {\n COMPARISON_OPERATORS,\n STRING_OPERATORS,\n DEFAULT_FIELD_REFERENCES,\n FIELD_MAPPING_RULES,\n} from \"./types\";\n\n/**\n * Converts null values to undefined to prevent SurrealDB errors with option<record<table>> fields.\n */\nexport function mapNullToUndefined(\n data: Record<string, any>,\n): Record<string, any> {\n const out: Record<string, any> = { ...data };\n for (const k of Object.keys(out)) {\n if (out[k] === null) out[k] = undefined;\n }\n return out;\n}\n\n/**\n * Converts various ID formats to SurrealDB RecordId.\n * Handles RecordId instances, \"table:id\" strings, plain IDs, and numbers.\n */\nexport function toRecordId(model: string, id: any): RecordId {\n if (id instanceof RecordId) return id;\n if (typeof id === \"string\") {\n if (id.includes(\":\"))\n return new RecordId(id.split(\":\")[0], id.split(\":\")[1]);\n return new RecordId(model, id);\n }\n return new RecordId(model, id);\n}\n\n/**\n * Recursively converts RecordId objects to \"table:id\" strings throughout data structures.\n */\nexport function recordIdsToStrings<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (value instanceof RecordId)\n return value.toString() as unknown as T;\n if (value instanceof Date) {\n return value;\n }\n if (Array.isArray(value))\n return value.map((v) => recordIdsToStrings(v)) as unknown as T;\n if (typeof value === \"object\") {\n const out: any = {};\n for (const [k, v] of Object.entries(value as any)) {\n out[k] = recordIdsToStrings(v as any);\n }\n return out as T;\n }\n return value;\n}\n\n/**\n * Builds field-to-table reference mappings from Better Auth schema for RecordId conversion.\n */\nexport function buildRecordIdMap(\n tables: any,\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n): RecordIdMap {\n const map: RecordIdMap = { tableSpecific: {} };\n if (!tables) return map;\n\n for (const internalModelName in tables) {\n const tableDef = tables[internalModelName];\n if (!tableDef?.fields) continue;\n\n const actualTableName = getModelName(internalModelName);\n if (!map.tableSpecific[actualTableName]) {\n map.tableSpecific[actualTableName] = {};\n }\n\n for (const internalFieldName in tableDef.fields) {\n const fieldDef = tableDef.fields[internalFieldName];\n if (fieldDef?.references?.model) {\n const actualFieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n const referencedActualTableName = getModelName(\n fieldDef.references.model,\n );\n map.tableSpecific[actualTableName][actualFieldName] =\n referencedActualTableName;\n }\n }\n }\n return map;\n}\n\n/**\n * Logs SurrealDB queries with formatted output when debug logging is enabled.\n */\nexport function logQuery(\n config: SurrealDBAdapterConfig | undefined,\n debugLog: (...args: any[]) => void,\n method: AdapterMethod,\n query: BoundQuery,\n): void {\n if (!config?.debugLogs) return;\n if (\n config.debugLogs &&\n typeof config.debugLogs === \"object\" &&\n !(\"isRunningAdapterTests\" in config.debugLogs)\n ) {\n if (method === \"create\" && !config.debugLogs.create) {\n return;\n }\n if (method === \"update\" && !config.debugLogs.update) {\n return;\n }\n if (method === \"updateMany\" && !config.debugLogs.updateMany) {\n return;\n }\n if (method === \"findOne\" && !config.debugLogs.findOne) {\n return;\n }\n if (method === \"findMany\" && !config.debugLogs.findMany) {\n return;\n }\n if (method === \"delete\" && !config.debugLogs.delete) {\n return;\n }\n if (method === \"deleteMany\" && !config.debugLogs.deleteMany) {\n return;\n }\n if (method === \"count\" && !config.debugLogs.count) {\n return;\n }\n }\n\n const queryTemplate = query.query;\n const params = query.bindings;\n let readableQuery = queryTemplate;\n\n // Replace parameters with actual values\n Object.entries(params).forEach(([paramName, value]) => {\n const paramPattern = new RegExp(`\\\\$${paramName}\\\\b`, \"g\");\n let formattedValue: string;\n\n if (value instanceof RecordId) {\n // RecordId should be displayed without quotes\n formattedValue = value.toString();\n } else if (typeof value === \"string\" && value.includes(\":\")) {\n // String that looks like RecordId should be displayed without quotes\n formattedValue = value;\n } else {\n // Other values should be JSON stringified\n formattedValue = JSON.stringify(value);\n }\n\n readableQuery = readableQuery.replace(paramPattern, formattedValue);\n });\n const colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n fg: {\n surreal_pink: \"\\x1b[38;5;200m\",\n surreal_purple: \"\\x1b[38;5;93m\",\n yellow: \"\\x1b[33m\",\n magenta: \"\\x1b[35m\",\n },\n bg: {\n obsidian_violet: \"\\x1b[48;5;233m\",\n black: \"\\x1b[40m\",\n },\n };\n function formatLogLine(lang: string, query: string) {\n const transationId = `${colors.fg.magenta}###`;\n const stepString = `${colors.bg.black}${colors.fg.yellow}[0/#]${colors.reset}`;\n const methodString = `${colors.bright}${method}`;\n const preparedString = `${colors.dim}(BoundQuery)${colors.reset}`;\n const PADDING = \" \";\n let formattedString = `${colors.bg.obsidian_violet}`;\n formattedString += PADDING;\n formattedString += `${colors.fg.surreal_purple}[${lang}]`;\n formattedString += ` ${colors.fg.surreal_pink}${query}`;\n formattedString += PADDING;\n formattedString += `${colors.reset}`;\n return `${transationId} ${stepString} ${methodString} ${preparedString} \\n\\n${formattedString}\\n\\n`;\n }\n\n debugLog(`${formatLogLine(\"SurrealQL\", readableQuery)}`);\n}\n/**\n * Declarative error handling configuration for adapter operations.\n */\nexport const ERROR_HANDLERS = {\n modelNotFound: (modelName: string, config?: SurrealDBAdapterConfig) => {\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Model '${modelName}' not found in schema, skipping operation `,\n );\n }\n },\n fieldMappingSkipped: (\n rule: string,\n reason: string,\n config?: SurrealDBAdapterConfig,\n ) => {\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Skipping field mapping rule for '${rule}': ${reason} `,\n );\n }\n },\n unsupportedOperator: (operator: string, config?: SurrealDBAdapterConfig) => {\n if (config?.debugLogs) {\n logger.warn(\n `[surreal-better-auth]: Unknown operator '${operator}', falling back to equality comparison `,\n );\n }\n },\n};\n\n/**\n * Gets the referenced table name for a field using default mappings and schema.\n */\nexport function getReferencedModel(\n tableName: string,\n fieldName: string,\n recordIdMap: RecordIdMap,\n getDefaultModelName: (tableName: string) => string,\n getDefaultFieldName: (opts: { model: string; field: string }) => string,\n getModelName: (model: string) => string,\n config?: SurrealDBAdapterConfig,\n): string | null {\n const defaultModel = getDefaultModelName(tableName);\n const defaultField = getDefaultFieldName({\n model: defaultModel,\n field: fieldName,\n });\n\n // Check default references first\n const referencedModel = DEFAULT_FIELD_REFERENCES[defaultField];\n if (referencedModel) {\n try {\n const modelName = getModelName(referencedModel);\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Found default reference: ${tableName}.${fieldName} -> ${modelName} `,\n );\n }\n return modelName;\n } catch (error) {\n ERROR_HANDLERS.modelNotFound(referencedModel, config);\n }\n }\n\n // Fallback to table-specific mappings\n const tableSpecificRef = recordIdMap.tableSpecific[tableName]?.[fieldName];\n if (tableSpecificRef && config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Found table-specific reference: ${tableName}.${fieldName} -> ${tableSpecificRef} `,\n );\n }\n\n return tableSpecificRef || null;\n}\n\n/**\n * Builds special field mapping cases from declarative rules.\n */\nexport function buildSpecialCasesMapping(\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n config?: SurrealDBAdapterConfig,\n): Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n> {\n const specialCases: Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n > = {};\n\n for (const rule of FIELD_MAPPING_RULES) {\n try {\n const sourceModelName = getModelName(rule.sourceModel);\n const targetModelName = getModelName(rule.targetModel);\n const fieldName = getFieldName({\n model: rule.sourceModel,\n field: rule.sourceField,\n });\n\n if (!specialCases[sourceModelName]) {\n specialCases[sourceModelName] = {};\n }\n\n specialCases[sourceModelName][fieldName] = {\n recordTable: targetModelName,\n condition: rule.condition,\n };\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Registered field mapping: ${sourceModelName}.${fieldName} -> to record ${targetModelName} `,\n );\n }\n } catch (e) {\n const error = e as Error;\n ERROR_HANDLERS.fieldMappingSkipped(\n `${rule.sourceModel}.${rule.sourceField}`,\n error.message,\n config,\n );\n }\n }\n\n return specialCases;\n}\n\n/**\n * Converts string IDs to RecordId objects for fields that reference other tables.\n */\nexport function serializeRecordIdFields(\n tableName: string,\n data: Record<string, any>,\n getReferencedModelFn: (tableName: string, fieldName: string) => string | null,\n buildSpecialCasesFn: () => Record<\n string,\n Record<\n string,\n {\n condition?: (data: Record<string, any>) => boolean;\n recordTable: string;\n }\n >\n >,\n config?: SurrealDBAdapterConfig,\n): Record<string, any> {\n const out = { ...data };\n const specialCases = buildSpecialCasesFn();\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Serializing record ID fields for table: ${tableName} `,\n {\n fieldCount: Object.keys(out).length,\n hasSpecialCases: !!specialCases[tableName],\n },\n );\n }\n\n for (const fieldName in out) {\n const value = out[fieldName];\n\n if (typeof value !== \"string\" || !value) {\n continue;\n }\n\n const specialCase = specialCases[tableName]?.[fieldName];\n\n if (specialCase) {\n const shouldApply = !specialCase.condition || specialCase.condition(out);\n\n if (shouldApply) {\n const recordId = toRecordId(specialCase.recordTable, value);\n out[fieldName] = recordId;\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Applied special case mapping: ${tableName}.${fieldName} = \"${value}\" -> \"${recordId}\" `,\n );\n }\n } else if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Special case condition not met for: ${tableName}.${fieldName} `,\n );\n }\n } else {\n const referencedModel = getReferencedModelFn(tableName, fieldName);\n\n if (referencedModel) {\n const recordId = toRecordId(referencedModel, value);\n out[fieldName] = recordId;\n\n if (config?.debugLogs) {\n logger.debug(\n `[surreal-better-auth]: Applied default reference mapping: ${tableName}.${fieldName} = \"${value}\" -> \"${recordId}\" `,\n );\n }\n }\n }\n }\n\n return out;\n}\n\n/**\n * Extracts direct record IDs from WHERE conditions for query optimization.\n */\nexport function extractDirectRecords(\n where: Where[] | undefined,\n model: string,\n getModelName: (model: string) => string,\n): { recordIds: RecordId[]; remainingWhere: Where[] } | null {\n if (!where || where.length === 0) return null;\n\n const tableName = getModelName(model);\n\n // Find id = value condition (single record)\n const idEqIndex = where.findIndex(\n (w) => w.field === \"id\" && w.operator === \"eq\",\n );\n if (idEqIndex !== -1) {\n const idEqCondition = where[idEqIndex];\n const recordId = toRecordId(tableName, idEqCondition.value as any);\n const remainingWhere = where.filter((_, index) => index !== idEqIndex);\n return { recordIds: [recordId], remainingWhere };\n }\n\n // Find id IN [...] condition (multiple records)\n const idInIndex = where.findIndex(\n (w) => w.field === \"id\" && w.operator === \"in\" && Array.isArray(w.value),\n );\n if (idInIndex !== -1) {\n const idInCondition = where[idInIndex];\n const recordIds = (idInCondition.value as any[]).map((id) =>\n toRecordId(tableName, id),\n );\n const remainingWhere = where.filter((_, index) => index !== idInIndex);\n return { recordIds, remainingWhere };\n }\n\n return null;\n}\n\n/**\n * Builds query suffix with ORDER BY, LIMIT, RETURN clauses.\n */\nexport function buildQuerySuffix(\n options: QuerySuffixOptions = {},\n getFieldName?: (opts: { model: string; field: string }) => string,\n): string {\n const {\n sortBy,\n limit,\n offset,\n groupAll,\n returnAfter,\n returnFields,\n limitOne,\n model,\n } = options;\n\n let suffix = \"\";\n\n // ORDER BY clause\n if (sortBy && model && getFieldName) {\n const field = getFieldName({ model, field: sortBy.field });\n const direction = sortBy.direction === \"desc\" ? \"DESC\" : \"ASC\";\n suffix += ` ORDER BY ${field} ${direction}`;\n }\n\n // LIMIT clause\n if (limitOne) {\n suffix += \" LIMIT 1\";\n } else if (typeof limit === \"number\") {\n suffix += ` LIMIT ${limit}`;\n }\n\n // START AT clause (offset)\n if (typeof offset === \"number\") {\n suffix += ` START AT ${offset}`;\n }\n\n // GROUP ALL clause\n if (groupAll) {\n suffix += \" GROUP ALL\";\n }\n\n // RETURN clauses\n if (returnAfter) {\n suffix += \" RETURN AFTER\";\n } else if (returnFields) {\n suffix += ` RETURN ${returnFields}`;\n }\n\n return suffix;\n}\n\n/**\n * Builds WHERE clause with proper parameter binding and RecordId conversion.\n */\nexport function buildWhereClauseParts(\n bindings: Record<string, unknown>,\n { where, model }: { where: Where[]; model: string },\n getModelName: (model: string) => string,\n getFieldName: (opts: { model: string; field: string }) => string,\n getReferencedModelFn: (tableName: string, fieldName: string) => string | null,\n config?: SurrealDBAdapterConfig,\n): string {\n if (!where || where.length === 0) return \"\";\n\n const conditions: string[] = [];\n const tableName = getModelName(model);\n\n where.forEach((w, idx) => {\n const {\n field: internalField,\n value,\n operator = \"eq\",\n connector = \"AND\",\n } = w;\n if (operator === \"in\" && Array.isArray(value) && value.length === 0) return;\n if (operator === \"not_in\" && Array.isArray(value) && value.length === 0) return;\n\n const fieldName = getFieldName({ model, field: internalField });\n\n const param = `where_${idx}`;\n let conditionStr = \"\";\n\n if (operator === \"in\") {\n conditionStr = `${fieldName} IN $${param}`;\n const vals = Array.isArray(value) ? value : [value];\n let finalVals: (RecordId | string | number | boolean | Date | null)[] = vals;\n\n if (internalField === \"id\") {\n finalVals = vals.map((v) => toRecordId(tableName, v));\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName) {\n finalVals = vals.map((v) =>\n typeof v === \"string\" ? toRecordId(referencedModelName, v) : v,\n );\n }\n }\n bindings[param] = finalVals;\n } else if (operator === \"not_in\") {\n conditionStr = `${fieldName} NOT IN $${param}`;\n const vals = Array.isArray(value) ? value : [value];\n let finalVals: (RecordId | string | number | boolean | Date | null)[] = vals;\n\n if (internalField === \"id\") {\n finalVals = vals.map((v) => toRecordId(tableName, v));\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName) {\n finalVals = vals.map((v) =>\n typeof v === \"string\" ? toRecordId(referencedModelName, v) : v,\n );\n }\n }\n bindings[param] = finalVals;\n } else if (operator in COMPARISON_OPERATORS) {\n conditionStr = `${fieldName} ${COMPARISON_OPERATORS[operator]} $${param}`;\n if (internalField === \"id\") {\n bindings[param] = toRecordId(tableName, value);\n } else {\n const referencedModelName = getReferencedModelFn(tableName, fieldName);\n if (referencedModelName && typeof value === \"string\") {\n bindings[param] = toRecordId(referencedModelName, value);\n } else {\n bindings[param] = value;\n }\n }\n } else if (operator in STRING_OPERATORS) {\n if (STRING_OPERATORS[operator] === \"CONTAINS\") {\n conditionStr = `${fieldName} CONTAINS $${param}`;\n } else {\n conditionStr = `string::${STRING_OPERATORS[operator]}(${fieldName}, $${param})`;\n }\n bindings[param] = value;\n } else {\n // Fallback for unknown operators - treat as generic value comparison\n conditionStr = `${fieldName} = $${param}`;\n bindings[param] = value;\n\n ERROR_HANDLERS.unsupportedOperator(operator, config);\n }\n\n if (conditions.length > 0)\n conditions.push(` ${connector.toUpperCase()} ${conditionStr}`);\n else conditions.push(conditionStr);\n });\n\n if (conditions.length === 0) return \"\";\n return ` WHERE ${conditions.join(\"\")}`;\n}\n\n/**\n * Generates CREATE query with appropriate ID generation strategy.\n */\nexport function generateCreateQuery(\n tableName: string,\n content: Record<string, any>,\n config?: SurrealDBAdapterConfig,\n customId?: string,\n selectFields?: string,\n generateId?: () => string,\n): { query: BoundQuery } {\n let targetClause: string;\n const providedId = customId ?? (generateId ? generateId() : null);\n\n if (providedId) {\n targetClause = toRecordId(tableName, providedId).toString();\n } else {\n switch (config?.idGenerator) {\n case \"surreal.ULID\":\n targetClause = `type::record('${tableName}', rand::ulid())`;\n break;\n case \"surreal.UUID\":\n targetClause = `type::record('${tableName}', rand::uuid())`;\n break;\n case \"surreal.UUIDv4\":\n targetClause = `type::record('${tableName}', rand::uuid::v4())`;\n break;\n case \"surreal.UUIDv7\":\n targetClause = `type::record('${tableName}', rand::uuid::v7())`;\n break;\n case \"surreal.guid\":\n targetClause = `type::record('${tableName}', rand::guid())`;\n break;\n default: // Includes `sdk.*` and undefined\n targetClause = `type::record('${tableName}')`;\n break;\n }\n }\n\n const suffix = buildQuerySuffix({ returnFields: selectFields });\n const queryString = `CREATE ${targetClause} CONTENT $content${suffix}`;\n\n return {\n query: new BoundQuery(queryString, { content }),\n };\n}\n","/**\n * Schema generation utilities for SurrealDB Better Auth adapter.\n * Generates SurrealDB schema definitions with proper field types and indexes.\n */\n\nimport type { GenerateSchemaParams, GenerateSchemaResult } from \"./types\";\n\n/**\n * Generates SurrealDB schema from Better Auth table definitions with proper field types and indexes.\n */\nexport function generateSchema(\n params: GenerateSchemaParams,\n): GenerateSchemaResult {\n const { file, tables, getModelName, getFieldName, getReferencedModel } =\n params;\n\n const schemaLines: string[] = [];\n const date = new Date();\n const formatted = `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, \"0\")}-${String(date.getUTCDate()).padStart(2, \"0\")} at ${String(date.getUTCHours()).padStart(2, \"0\")}:${String(date.getUTCMinutes()).padStart(2, \"0\")}:${String(date.getUTCSeconds()).padStart(2, \"0\")} UTC`;\n\n schemaLines.push(\n \"-- ╔════════════════════════════════════════════════════════════════════════╗\",\n \"-- ║ SurrealDB Better Auth Schema ║\",\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ This schema was auto-generated for BetterAuth integration ║\",\n \"-- ║ Adapter: surreal-better-auth ║\",\n \"-- ║ Repo: https://github.com/oskar-gmerek/surreal-better-auth ║\",\n \"-- ║ Author: Oskar Gmerek ║\",\n \"-- ║ ║\",\n `-- ║ Generation Date: ${formatted.padEnd(53)}║`,\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ Warning: It is strongly recommended to manually review the schema ║\",\n \"-- ║ after each generation to ensure it fully meets your ║\",\n `-- ║ project's specific requirements. ║`,\n \"-- ╟────────────────────────────────────────────────────────────────────────╢\",\n \"-- ║ Tip: The easiest way to apply this schema to your db is to copy its ║\",\n \"-- ║ contents and paste them directly into the Surrealist. ║\",\n \"-- ╚════════════════════════════════════════════════════════════════════════╝\",\n \"\",\n \"\",\n \"\",\n );\n\n /**\n * Builds decorative box around table names in schema output.\n */\n function buildTableBox(text: string, totalWidth = 76): string[] {\n const contentWidth = totalWidth - 8;\n const lineContent = text.padEnd(contentWidth, \" \");\n const top = `-- ╔${\"═\".repeat(totalWidth - 4)}╗`;\n const mid = `-- ║ ${lineContent} ║`;\n const bot = `-- ╚${\"═\".repeat(totalWidth - 4)}╝`;\n return [top, mid, bot];\n }\n\n /**\n * Maps Better Auth field types to SurrealDB types with special cases for references.\n */\n function mapFieldType(\n tableName: string,\n fieldName: string,\n type?: string,\n ): string {\n // Special cases for field-to-table mappings in schema generation\n try {\n const accountModelName = getModelName(\"account\");\n const userModelName = getModelName(\"user\");\n const accountIdFieldName = getFieldName({\n model: \"account\",\n field: \"accountId\",\n });\n\n if (tableName === accountModelName && fieldName === accountIdFieldName) {\n return `record<${userModelName}> | string`;\n }\n } catch (e) {\n // account or user model not in schema, skip\n }\n\n try {\n const oauthAccessTokenModelName = getModelName(\"oauthAccessToken\");\n const oauthApplicationModelName = getModelName(\"oauthApplication\");\n const oauthAccessTokenIdFieldName = getFieldName({\n model: \"oauthAccessToken\",\n field: \"clientId\",\n });\n\n if (\n tableName === oauthAccessTokenModelName &&\n fieldName === oauthAccessTokenIdFieldName\n ) {\n return `record<${oauthApplicationModelName}>`;\n }\n } catch (e) {\n // oauthAccessToken or oauthApplication model not in schema, skip\n }\n\n try {\n const oauthConsentModelName = getModelName(\"oauthConsent\");\n const oauthApplicationModelName = getModelName(\"oauthApplication\");\n const oauthConsentIdFieldName = getFieldName({\n model: \"oauthConsent\",\n field: \"clientId\",\n });\n\n if (\n tableName === oauthConsentModelName &&\n fieldName === oauthConsentIdFieldName\n ) {\n return `record<${oauthApplicationModelName}>`;\n }\n } catch (e) {\n // oauthConsent or oauthApplication model not in schema, skip\n }\n\n const referencedModel = getReferencedModel(tableName, fieldName);\n if (referencedModel) {\n return `record<${referencedModel}>`;\n }\n\n const typeMap: Record<string, string> = {\n boolean: \"bool\",\n date: \"datetime\",\n };\n\n return typeMap[type || \"\"] || type || \"any\";\n }\n\n // Generate schema for each table\n for (const [internalModelName, tableDef] of Object.entries(tables)) {\n const tableName = getModelName(internalModelName);\n if ((tableDef as any).disableMigrations) continue;\n\n schemaLines.push(...buildTableBox(`TABLE: ${tableName}`));\n schemaLines.push(`DEFINE TABLE OVERWRITE ${tableName} SCHEMAFULL;`);\n\n // Generate field definitions\n for (const [internalFieldName, field] of Object.entries(\n (tableDef as any).fields,\n )) {\n const fieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n const baseType = mapFieldType(\n tableName,\n fieldName,\n (field as any).type?.toString(),\n );\n const finalType =\n (field as any).required === false ? `option<${baseType}>` : baseType;\n schemaLines.push(\n `DEFINE FIELD OVERWRITE ${fieldName} ON TABLE ${tableName} TYPE ${finalType};`,\n );\n }\n\n schemaLines.push(\"\");\n // Generate indexes for specific fields\n for (const [internalFieldName, field] of Object.entries(\n (tableDef as any).fields,\n )) {\n const fieldName = getFieldName({\n model: internalModelName,\n field: internalFieldName,\n });\n\n const indexedFields: Record<string, string | string[]> = {\n user: \"email\",\n account: \"userId\",\n session: [\"userId\", \"token\"],\n verification: \"identifier\",\n invitation: [\"email\", \"organizationId\"],\n member: [\"userId\", \"organizationId\"],\n organization: \"slug\",\n passkey: \"userId\",\n twoFactor: \"secret\",\n };\n\n const fieldsToIndex = indexedFields[internalModelName];\n const shouldIndex =\n fieldsToIndex &&\n ((Array.isArray(fieldsToIndex) &&\n fieldsToIndex.includes(internalFieldName)) ||\n fieldsToIndex === internalFieldName);\n\n if (shouldIndex) {\n schemaLines.push(\n `DEFINE INDEX OVERWRITE idx_${tableName}_${fieldName} ON ${tableName} COLUMNS ${fieldName}${(field as any).unique ? \" UNIQUE\" : \"\"};`,\n );\n }\n }\n schemaLines.push(\"\");\n }\n\n const path = file ?? \"schema.surql\";\n return {\n path,\n code: schemaLines.join(\"\\n\"),\n overwrite: true,\n };\n}\n","import {\n type RecordId,\n BoundQuery,\n Uuid,\n type Surreal,\n} from \"surrealdb\";\nimport type { Where } from \"better-auth/types\";\nimport { createAdapter } from \"better-auth/adapters\";\nimport { logger } from \"better-auth\";\nimport {\n mapNullToUndefined,\n recordIdsToStrings,\n buildRecordIdMap,\n logQuery,\n getReferencedModel,\n buildSpecialCasesMapping,\n serializeRecordIdFields,\n extractDirectRecords,\n buildQuerySuffix,\n buildWhereClauseParts,\n generateCreateQuery,\n} from \"./helpers\";\nimport { generateSchema } from \"./schema\";\nimport type {\n ExecuteOptimizedQueryOptions,\n SurrealDBAdapterConfig,\n} from \"./types\";\n\nexport const surrealdbAdapter = (\n db: Surreal,\n config?: SurrealDBAdapterConfig,\n) => {\n return createAdapter({\n config: {\n adapterId: \"surrealdb_adapter\",\n adapterName: \"surreal-better-auth\",\n usePlural: config?.usePlural ?? false,\n debugLogs: config?.debugLogs ?? false,\n supportsNumericIds: false,\n supportsBooleans: true,\n supportsDates: true,\n supportsJSON: true,\n customIdGenerator: config?.idGenerator?.startsWith(\"sdk.\")\n ? ({ model }: { model: string }) => {\n if (config?.debugLogs) {\n logger.info(\n `[surreal-better-auth]: Generating custom ID for model: ${model} using ${config.idGenerator} `,\n );\n }\n switch (config.idGenerator) {\n case \"sdk.UUIDv4\":\n return Uuid.v4().toString();\n case \"sdk.UUIDv7\":\n return Uuid.v7().toString();\n default:\n throw new Error(\n `Invalid ID generator type: ${config.idGenerator}. Supported types: \"sdk.UUIDv4\", \"sdk.UUIDv7\", \"surreal\", \"surreal.ULID\", \"surreal.UUID\", \"surreal.UUIDv4\", \"surreal.UUIDv7\", \"surreal.guid\"`,\n );\n }\n }\n : undefined,\n disableIdGeneration: config?.idGenerator?.startsWith(\"surreal\") ?? false,\n customTransformOutput({ data }) {\n if (data === undefined) return null;\n return recordIdsToStrings(data);\n },\n },\n adapter: ({\n options,\n getModelName,\n getFieldName,\n getDefaultModelName,\n getDefaultFieldName,\n debugLog,\n }) => {\n const recordIdMap = buildRecordIdMap(\n (options as any)?.schema?.tables,\n getModelName,\n getFieldName,\n );\n\n // Extract generateId from options if provided by Better Auth\n const generateId = (options as any)?.advanced?.database?.generateId;\n\n // Create helper functions with bound dependencies\n const getReferencedModelFn = (tableName: string, fieldName: string) =>\n getReferencedModel(\n tableName,\n fieldName,\n recordIdMap,\n getDefaultModelName,\n getDefaultFieldName,\n getModelName,\n config,\n );\n\n const buildSpecialCasesFn = () =>\n buildSpecialCasesMapping(getModelName, getFieldName, config);\n\n const serializeRecordIdFieldsFn = (\n tableName: string,\n data: Record<string, any>,\n ) =>\n serializeRecordIdFields(\n tableName,\n data,\n getReferencedModelFn,\n buildSpecialCasesFn,\n config,\n );\n\n const extractDirectRecordsFn = (\n where: Where[] | undefined,\n model: string,\n ) => extractDirectRecords(where, model, getModelName);\n\n const buildQuerySuffixFn = (options: any = {}) =>\n buildQuerySuffix(options, getFieldName);\n\n const buildWhereClausePartsFn = (\n bindings: Record<string, unknown>,\n { where, model }: { where: Where[]; model: string },\n ) =>\n buildWhereClauseParts(\n bindings,\n { where, model },\n getModelName,\n getFieldName,\n getReferencedModelFn,\n config,\n );\n\n const generateCreateQueryFn = (\n tableName: string,\n content: Record<string, any>,\n customId?: string,\n selectFields?: string,\n ) =>\n generateCreateQuery(\n tableName,\n content,\n config,\n customId,\n selectFields,\n generateId,\n );\n\n async function executeOptimizedQuery(\n options: ExecuteOptimizedQueryOptions,\n ): Promise<any> {\n const {\n method,\n model,\n where,\n baseQuery,\n directRecordQuery,\n content,\n suffix = \"\",\n processResult = (r: any) => r,\n returnCount = false,\n singleRecord = false,\n } = options;\n\n // Check for direct record access optimization\n const directRecordInfo = extractDirectRecordsFn(where, model);\n\n if (directRecordInfo && directRecordQuery) {\n const { recordIds, remainingWhere } = directRecordInfo;\n const directQuery = directRecordQuery(recordIds);\n\n if (remainingWhere.length === 0) {\n // Pure direct record operation\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const query = new BoundQuery(directQuery + suffix, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n // Direct record operation with additional WHERE conditions\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const whereStr = buildWhereClausePartsFn(bindings, {\n where: remainingWhere,\n model,\n });\n const queryString = directQuery + whereStr + suffix;\n\n const query = new BoundQuery(queryString, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n\n // Fallback to standard WHERE clause query\n const bindings: Record<string, unknown> = {};\n\n if (content !== undefined) {\n bindings.content = content;\n }\n\n const whereStr = buildWhereClausePartsFn(bindings, {\n where: where || [],\n model,\n });\n const queryString = baseQuery + whereStr + suffix;\n\n const query = new BoundQuery(queryString, bindings);\n logQuery(config, debugLog, method, query);\n const result = await db.query<[any[]]>(query).collect();\n\n if (returnCount) {\n return result[0]?.length || 0;\n }\n\n return processResult(singleRecord ? result[0] : result[0]);\n }\n\n return {\n async create({ model, data: values, select }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n // Extract custom ID if allowed or if using sdk.* generator (Better Auth passes generated ID)\n const customId =\n (config?.allowPassingId ||\n config?.idGenerator?.startsWith(\"sdk.\")) &&\n content.id\n ? content.id\n : undefined;\n // Always remove id field from content\n content.id = undefined;\n\n // Process select parameter\n let selectFields: string | undefined;\n if (select && Array.isArray(select) && select.length > 0) {\n const mappedFields = select.map((field) =>\n getFieldName({ model, field }),\n );\n // Always include id in the return fields\n if (!mappedFields.includes(\"id\")) {\n mappedFields.unshift(\"id\");\n }\n selectFields = mappedFields.join(\", \");\n }\n\n // Generate query\n const { query } = generateCreateQueryFn(\n tableName,\n content,\n customId,\n selectFields,\n );\n\n logQuery(config, debugLog, \"create\", query);\n\n const result = await db.query<[any[]]>(query).collect();\n return recordIdsToStrings(result[0][0]);\n },\n\n async findOne({ model, where, select }) {\n const tableName = getModelName(model);\n const selectFields = select\n ? typeof select === \"string\"\n ? getFieldName({ model, field: select })\n : (select as string[])\n .map((f) => getFieldName({ model, field: f }))\n .join(\", \")\n : \"*\";\n\n return executeOptimizedQuery({\n method: \"findOne\",\n model,\n where,\n baseQuery: `SELECT ${selectFields} FROM ONLY ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT ${selectFields} FROM ONLY ${recordIds[0].toString()}`,\n suffix: buildQuerySuffixFn({ limitOne: true }),\n processResult: (result: any) => recordIdsToStrings(result) || null,\n singleRecord: true,\n });\n },\n\n async findMany({ model, where, limit, offset, sortBy }) {\n const tableName = getModelName(model);\n const selectClause = \"*\";\n\n return executeOptimizedQuery({\n method: \"findMany\",\n model,\n where,\n baseQuery: `SELECT ${selectClause} FROM ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT ${selectClause} FROM [${recordIds.map((id: RecordId) => id.toString()).join(\", \")}]`,\n suffix: buildQuerySuffixFn({ sortBy, limit, offset, model }),\n processResult: recordIdsToStrings,\n });\n },\n\n async count({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"count\",\n model,\n where,\n baseQuery: `SELECT count() FROM ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `SELECT count() FROM [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}]`,\n suffix: buildQuerySuffixFn({ groupAll: true }),\n processResult: (result: any) => result[0].count || 0,\n singleRecord: true,\n });\n },\n\n async update({ model, where, update: values }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n return executeOptimizedQuery({\n method: \"update\",\n model,\n where,\n baseQuery: `UPDATE ONLY ${tableName} MERGE $content`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `UPDATE ONLY ${recordIds[0].toString()} MERGE $content`,\n content,\n suffix: buildQuerySuffixFn({ returnAfter: true }),\n processResult: (result: any) => recordIdsToStrings(result) || null,\n singleRecord: true,\n });\n },\n\n async updateMany({ model, where, update: values }) {\n const tableName = getModelName(model);\n const content = serializeRecordIdFieldsFn(\n tableName,\n mapNullToUndefined(values as Record<string, any>),\n );\n\n return executeOptimizedQuery({\n method: \"updateMany\",\n model,\n where,\n baseQuery: `UPDATE ${tableName} MERGE $content`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `UPDATE [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}] MERGE $content`,\n content,\n returnCount: true,\n });\n },\n\n async delete({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"delete\",\n model,\n where,\n baseQuery: `DELETE ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `DELETE ${recordIds[0].toString()}`,\n processResult: () => undefined,\n });\n },\n\n async deleteMany({ model, where }) {\n const tableName = getModelName(model);\n\n return executeOptimizedQuery({\n method: \"deleteMany\",\n model,\n where,\n baseQuery: `DELETE ${tableName}`,\n directRecordQuery: (recordIds: RecordId[]) =>\n `DELETE [${recordIds.map((r: RecordId) => r.toString()).join(\", \")}]`,\n returnCount: true,\n });\n },\n\n async createSchema({ file, tables }) {\n return generateSchema({\n file,\n tables,\n getModelName,\n getFieldName,\n getReferencedModel: getReferencedModelFn,\n });\n },\n };\n },\n });\n};\n"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@imran3113/surreal-better-auth",
3
+ "description": "SurrealDB adapter for Better Auth",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "cellograph",
7
+ "github": "https://github.com/cellograph"
8
+ },
9
+ "keywords": [
10
+ "adapter",
11
+ "auth",
12
+ "authentication",
13
+ "database",
14
+ "better-auth",
15
+ "better-auth-adapter",
16
+ "surreal-better-auth",
17
+ "surrealdb-better-auth",
18
+ "surrealdb",
19
+ "surrealdb-adapter",
20
+ "surrealdb-auth",
21
+ "javascript",
22
+ "typescript"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/cellograph/surreal-better-auth.git"
27
+ },
28
+ "license": "MIT",
29
+ "main": "./dist/index.cjs",
30
+ "module": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js",
36
+ "require": "./dist/index.cjs"
37
+ }
38
+ },
39
+ "files": [
40
+ "dist"
41
+ ],
42
+ "engines": {
43
+ "node": ">=20.0.0",
44
+ "bun": ">=1.2.0"
45
+ },
46
+ "scripts": {
47
+ "build": "tsup",
48
+ "dev": "tsup --watch",
49
+ "test": "bun run build && vitest run tests/",
50
+ "test:unit": "bun run build && vitest run tests/unit/",
51
+ "test:integration": "bun run build && vitest run tests/integration/",
52
+ "test:plugins": "vitest run tests/plugins/"
53
+ },
54
+ "peerDependencies": {
55
+ "better-auth": "^1.3.7",
56
+ "surrealdb": "2.0.0"
57
+ },
58
+ "devDependencies": {
59
+ "@better-auth/cli": "1.3.7",
60
+ "@types/node": "24.3.0",
61
+ "tsup": "8.5.0",
62
+ "typescript": "5.9.2",
63
+ "vitest": "3.2.4"
64
+ },
65
+ "type": "module"
66
+ }