@@ -10,51 +10,21 @@ import type { CleanedWhere } from 'better-auth/adapters';
1010 * This allows better-auth to use ObjectQL for data persistence instead of
1111 * third-party ORMs like drizzle-orm.
1212 *
13+ * Uses better-auth's native naming conventions (camelCase) for seamless migration.
14+ *
1315 * @param dataEngine - ObjectQL data engine instance
1416 * @returns better-auth CustomAdapter
1517 */
1618export function createObjectQLAdapter ( dataEngine : IDataEngine ) {
17- /**
18- * Convert better-auth table names to ObjectQL object names
19- * better-auth uses camelCase, ObjectQL uses snake_case
20- */
21- function toObjectName ( tableName : string ) : string {
22- // Map better-auth table names to our object names
23- const tableMap : Record < string , string > = {
24- 'user' : 'auth_user' ,
25- 'session' : 'auth_session' ,
26- 'account' : 'auth_account' ,
27- 'verification' : 'auth_verification' ,
28- } ;
29- return tableMap [ tableName ] || `auth_${ tableName } ` ;
30- }
31-
32- /**
33- * Convert better-auth field names to ObjectQL field names
34- * better-auth uses camelCase, ObjectQL uses snake_case
35- */
36- function toFieldName ( fieldName : string ) : string {
37- // Convert camelCase to snake_case
38- return fieldName . replace ( / ( [ A - Z ] ) / g, '_$1' ) . toLowerCase ( ) ;
39- }
40-
41- /**
42- * Convert ObjectQL field names back to better-auth field names
43- * ObjectQL uses snake_case, better-auth uses camelCase
44- */
45- function fromFieldName ( fieldName : string ) : string {
46- // Convert snake_case to camelCase
47- return fieldName . replace ( / _ ( [ a - z ] ) / g, ( _ , letter ) => letter . toUpperCase ( ) ) ;
48- }
49-
5019 /**
5120 * Convert better-auth where clause to ObjectQL query format
5221 */
5322 function convertWhere ( where : CleanedWhere [ ] ) : Record < string , any > {
5423 const filter : Record < string , any > = { } ;
5524
5625 for ( const condition of where ) {
57- const fieldName = toFieldName ( condition . field ) ;
26+ // Use field names as-is (no conversion needed)
27+ const fieldName = condition . field ;
5828
5929 if ( condition . operator === 'eq' ) {
6030 filter [ fieldName ] = condition . value ;
@@ -78,41 +48,19 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
7848 return filter ;
7949 }
8050
81- /**
82- * Convert data from better-auth format to ObjectQL format
83- */
84- function convertDataToObjectQL ( data : Record < string , any > ) : Record < string , any > {
85- const converted : Record < string , any > = { } ;
86- for ( const [ key , value ] of Object . entries ( data ) ) {
87- converted [ toFieldName ( key ) ] = value ;
88- }
89- return converted ;
90- }
91-
92- /**
93- * Convert data from ObjectQL format to better-auth format
94- */
95- function convertDataFromObjectQL ( data : Record < string , any > ) : Record < string , any > {
96- const converted : Record < string , any > = { } ;
97- for ( const [ key , value ] of Object . entries ( data ) ) {
98- converted [ fromFieldName ( key ) ] = value ;
99- }
100- return converted ;
101- }
102-
10351 return {
10452 create : async < T extends Record < string , any > > ( { model, data, select : _select } : { model : string ; data : T ; select ?: string [ ] } ) : Promise < T > => {
105- const objectName = toObjectName ( model ) ;
106- const objectData = convertDataToObjectQL ( data ) ;
53+ // Use model name as-is (no conversion needed)
54+ const objectName = model ;
10755
10856 // Note: select parameter is currently not supported by ObjectQL's insert operation
10957 // The full record is always returned after insertion
110- const result = await dataEngine . insert ( objectName , objectData ) ;
111- return convertDataFromObjectQL ( result ) as T ;
58+ const result = await dataEngine . insert ( objectName , data ) ;
59+ return result as T ;
11260 } ,
11361
11462 findOne : async < T > ( { model, where, select, join : _join } : { model : string ; where : CleanedWhere [ ] ; select ?: string [ ] ; join ?: any } ) : Promise < T | null > => {
115- const objectName = toObjectName ( model ) ;
63+ const objectName = model ;
11664 const filter = convertWhere ( where ) ;
11765
11866 // Note: join parameter is not currently supported by ObjectQL's findOne operation
@@ -121,21 +69,21 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
12169
12270 const result = await dataEngine . findOne ( objectName , {
12371 filter,
124- select : select ?. map ( toFieldName ) ,
72+ select,
12573 } ) ;
12674
127- return result ? convertDataFromObjectQL ( result ) as T : null ;
75+ return result ? result as T : null ;
12876 } ,
12977
13078 findMany : async < T > ( { model, where, limit, offset, sortBy, join : _join } : { model : string ; where ?: CleanedWhere [ ] ; limit : number ; offset ?: number ; sortBy ?: { field : string ; direction : 'asc' | 'desc' } ; join ?: any } ) : Promise < T [ ] > => {
131- const objectName = toObjectName ( model ) ;
79+ const objectName = model ;
13280 const filter = where ? convertWhere ( where ) : { } ;
13381
13482 // Note: join parameter is not currently supported by ObjectQL's find operation
13583 // Joins/populate functionality is planned for future ObjectQL releases
13684
13785 const sort = sortBy ? [ {
138- field : toFieldName ( sortBy . field ) ,
86+ field : sortBy . field ,
13987 order : sortBy . direction as 'asc' | 'desc' ,
14088 } ] : undefined ;
14189
@@ -146,20 +94,19 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
14694 sort,
14795 } ) ;
14896
149- return results . map ( r => convertDataFromObjectQL ( r ) ) as T [ ] ;
97+ return results as T [ ] ;
15098 } ,
15199
152100 count : async ( { model, where } : { model : string ; where ?: CleanedWhere [ ] } ) : Promise < number > => {
153- const objectName = toObjectName ( model ) ;
101+ const objectName = model ;
154102 const filter = where ? convertWhere ( where ) : { } ;
155103
156104 return await dataEngine . count ( objectName , { filter } ) ;
157105 } ,
158106
159107 update : async < T > ( { model, where, update } : { model : string ; where : CleanedWhere [ ] ; update : Record < string , any > } ) : Promise < T | null > => {
160- const objectName = toObjectName ( model ) ;
108+ const objectName = model ;
161109 const filter = convertWhere ( where ) ;
162- const updateData = convertDataToObjectQL ( update ) ;
163110
164111 // Find the record first to get its ID
165112 const record = await dataEngine . findOne ( objectName , { filter } ) ;
@@ -168,17 +115,16 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
168115 }
169116
170117 const result = await dataEngine . update ( objectName , {
171- ...updateData ,
118+ ...update ,
172119 id : record . id ,
173120 } ) ;
174121
175- return result ? convertDataFromObjectQL ( result ) as T : null ;
122+ return result ? result as T : null ;
176123 } ,
177124
178125 updateMany : async ( { model, where, update } : { model : string ; where : CleanedWhere [ ] ; update : Record < string , any > } ) : Promise < number > => {
179- const objectName = toObjectName ( model ) ;
126+ const objectName = model ;
180127 const filter = convertWhere ( where ) ;
181- const updateData = convertDataToObjectQL ( update ) ;
182128
183129 // Note: Sequential updates are used here because ObjectQL's IDataEngine interface
184130 // requires an ID for updates. A future optimization could use a bulk update
@@ -190,7 +136,7 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
190136 // Update each record
191137 for ( const record of records ) {
192138 await dataEngine . update ( objectName , {
193- ...updateData ,
139+ ...update ,
194140 id : record . id ,
195141 } ) ;
196142 }
@@ -199,7 +145,7 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
199145 } ,
200146
201147 delete : async ( { model, where } : { model : string ; where : CleanedWhere [ ] } ) : Promise < void > => {
202- const objectName = toObjectName ( model ) ;
148+ const objectName = model ;
203149 const filter = convertWhere ( where ) ;
204150
205151 // Note: We need to find the record first to get its ID because ObjectQL's
@@ -214,7 +160,7 @@ export function createObjectQLAdapter(dataEngine: IDataEngine) {
214160 } ,
215161
216162 deleteMany : async ( { model, where } : { model : string ; where : CleanedWhere [ ] } ) : Promise < number > => {
217- const objectName = toObjectName ( model ) ;
163+ const objectName = model ;
218164 const filter = convertWhere ( where ) ;
219165
220166 // Note: Sequential deletes are used here because ObjectQL's delete operation
0 commit comments