@@ -3,9 +3,10 @@ import {
33 createAdapter ,
44 type AdapterDebugLogs ,
55} from "better-auth/adapters" ;
6- import { createFmOdataFetch , type FmOdataConfig } from "./odata" ;
6+ import { createRawFetch , type FmOdataConfig } from "./odata" ;
77import { prettifyError , z } from "zod/v4" ;
88import { logger } from "better-auth" ;
9+ import buildQuery from "odata-query" ;
910
1011const configSchema = z . object ( {
1112 debugLogs : z . unknown ( ) . optional ( ) ,
@@ -153,7 +154,7 @@ export const FileMakerAdapter = (
153154 }
154155 const config = parsed . data ;
155156
156- const fetch = createFmOdataFetch ( {
157+ const { fetch, baseURL } = createRawFetch ( {
157158 ...config . odata ,
158159 logging : config . debugLogs ? "verbose" : "none" ,
159160 } ) ;
@@ -192,114 +193,177 @@ export const FileMakerAdapter = (
192193 count : async ( { model, where } ) => {
193194 const filter = parseWhere ( where ) ;
194195 logger . debug ( "$filter" , filter ) ;
195- const result = await fetch ( `/${ model } /$count` , {
196+
197+ const query = buildQuery ( {
198+ filter : filter . length > 0 ? filter : undefined ,
199+ } ) ;
200+
201+ const result = await fetch ( `/${ model } /$count${ query } ` , {
196202 method : "GET" ,
197- query : {
198- $filter : filter ,
199- } ,
200203 output : z . object ( { value : z . number ( ) } ) ,
201204 } ) ;
202205 if ( ! result . data ) {
203206 throw new Error ( "Failed to count records" ) ;
204207 }
205- return result . data ?. value ?? 0 ;
208+ return ( result . data ?. value as any ) ?? 0 ;
206209 } ,
207210 findOne : async ( { model, where } ) => {
208211 const filter = parseWhere ( where ) ;
209212 logger . debug ( "$filter" , filter ) ;
210- const result = await fetch ( `/${ model } ` , {
213+
214+ const query = buildQuery ( {
215+ top : 1 ,
216+ filter : filter . length > 0 ? filter : undefined ,
217+ } ) ;
218+
219+ const result = await fetch ( `/${ model } ${ query } ` , {
211220 method : "GET" ,
212- query : {
213- ...( filter . length > 0 ? { $filter : filter } : { } ) ,
214- $top : 1 ,
215- } ,
216221 output : z . object ( { value : z . array ( z . any ( ) ) } ) ,
217222 } ) ;
218223 if ( result . error ) {
219224 throw new Error ( "Failed to find record" ) ;
220225 }
221- return result . data ?. value ?. [ 0 ] ?? null ;
226+ return ( result . data ?. value ?. [ 0 ] as any ) ?? null ;
222227 } ,
223228 findMany : async ( { model, where, limit, offset, sortBy } ) => {
224229 const filter = parseWhere ( where ) ;
225- logger . debug ( "$filter" , filter ) ;
230+ logger . debug ( "FIND MANY" , { where, filter } ) ;
231+
232+ const query = buildQuery ( {
233+ top : limit ,
234+ skip : offset ,
235+ orderBy : sortBy
236+ ? `${ sortBy . field } ${ sortBy . direction ?? "asc" } `
237+ : undefined ,
238+ filter : filter . length > 0 ? filter : undefined ,
239+ } ) ;
240+ logger . debug ( "QUERY" , query ) ;
226241
227- const rows = await fetch ( `/${ model } ` , {
242+ const result = await fetch ( `/${ model } ${ query } ` , {
228243 method : "GET" ,
229- query : {
230- ...( filter . length > 0 ? { $filter : filter } : { } ) ,
231- $top : limit ,
232- $skip : offset ,
233- ...( sortBy
234- ? { $orderby : `"${ sortBy . field } " ${ sortBy . direction ?? "asc" } ` }
235- : { } ) ,
236- } ,
237244 output : z . object ( { value : z . array ( z . any ( ) ) } ) ,
238245 } ) ;
239- if ( rows . error ) {
246+ logger . debug ( "RESULT" , result ) ;
247+
248+ if ( result . error ) {
240249 throw new Error ( "Failed to find records" ) ;
241250 }
242- return rows . data ?. value ?? [ ] ;
251+
252+ return ( result . data ?. value as any ) ?? [ ] ;
243253 } ,
244254 delete : async ( { model, where } ) => {
245255 const filter = parseWhere ( where ) ;
256+ console . log ( "DELETE" , { model, where, filter } ) ;
246257 logger . debug ( "$filter" , filter ) ;
247- console . log ( "delete" , model , where , filter ) ;
248- const result = await fetch ( `/${ model } ` , {
258+
259+ // Find a single id matching the filter
260+ const query = buildQuery ( {
261+ top : 1 ,
262+ select : [ `"id"` ] ,
263+ filter : filter . length > 0 ? filter : undefined ,
264+ } ) ;
265+
266+ const toDelete = await fetch ( `/${ model } ${ query } ` , {
267+ method : "GET" ,
268+ output : z . object ( { value : z . array ( z . object ( { id : z . string ( ) } ) ) } ) ,
269+ } ) ;
270+
271+ const id = toDelete . data ?. value ?. [ 0 ] ?. id ;
272+ if ( ! id ) {
273+ // Nothing to delete
274+ return ;
275+ }
276+
277+ const result = await fetch ( `/${ model } ('${ id } ')` , {
249278 method : "DELETE" ,
250- query : {
251- ...( where . length > 0 ? { $filter : filter } : { } ) ,
252- $top : 1 ,
253- } ,
254279 } ) ;
255280 if ( result . error ) {
281+ console . log ( "DELETE ERROR" , result . error ) ;
256282 throw new Error ( "Failed to delete record" ) ;
257283 }
258284 } ,
259285 deleteMany : async ( { model, where } ) => {
260286 const filter = parseWhere ( where ) ;
261- logger . debug (
262- where
263- . map ( ( o ) => `typeof ${ o . value } is ${ typeof o . value } ` )
264- . join ( "\n" ) ,
265- ) ;
266- logger . debug ( "$filter" , filter ) ;
287+ console . log ( "DELETE MANY" , { model, where, filter } ) ;
267288
268- const result = await fetch ( `/${ model } /$count` , {
269- method : "DELETE" ,
270- query : {
271- ...( where . length > 0 ? { $filter : filter } : { } ) ,
272- } ,
273- output : z . coerce . number ( ) ,
289+ // Find all ids matching the filter
290+ const query = buildQuery ( {
291+ select : [ `"id"` ] ,
292+ filter : filter . length > 0 ? filter : undefined ,
274293 } ) ;
275- if ( result . error ) {
276- throw new Error ( "Failed to delete record" ) ;
294+
295+ const rows = await fetch ( `/${ model } ${ query } ` , {
296+ method : "GET" ,
297+ output : z . object ( { value : z . array ( z . object ( { id : z . string ( ) } ) ) } ) ,
298+ } ) ;
299+
300+ const ids = rows . data ?. value ?. map ( ( r : any ) => r . id ) ?? [ ] ;
301+ let deleted = 0 ;
302+ for ( const id of ids ) {
303+ const res = await fetch ( `/${ model } ('${ id } ')` , {
304+ method : "DELETE" ,
305+ } ) ;
306+ if ( ! res . error ) deleted ++ ;
277307 }
278- return result . data ?? 0 ;
308+ return deleted ;
279309 } ,
280310 update : async ( { model, where, update } ) => {
281- const result = await fetch ( `/${ model } ` , {
311+ const filter = parseWhere ( where ) ;
312+ logger . debug ( "UPDATE" , { model, where, update } ) ;
313+ logger . debug ( "$filter" , filter ) ;
314+ // Find one id to update
315+ const query = buildQuery ( {
316+ select : [ `"id"` ] ,
317+ filter : filter . length > 0 ? filter : undefined ,
318+ } ) ;
319+
320+ const existing = await fetch ( `/${ model } ${ query } ` , {
321+ method : "GET" ,
322+ output : z . object ( { value : z . array ( z . object ( { id : z . string ( ) } ) ) } ) ,
323+ } ) ;
324+ logger . debug ( "EXISTING" , existing . data ) ;
325+
326+ const id = existing . data ?. value ?. [ 0 ] ?. id ;
327+ if ( ! id ) return null ;
328+
329+ const patchRes = await fetch ( `/${ model } ('${ id } ')` , {
282330 method : "PATCH" ,
283- query : {
284- ...( where . length > 0 ? { $filter : parseWhere ( where ) } : { } ) ,
285- $top : 1 ,
286- $select : [ `"id"` ] ,
287- } ,
288331 body : update ,
289- output : z . object ( { value : z . array ( z . any ( ) ) } ) ,
290332 } ) ;
291- return result . data ?. value ?. [ 0 ] ?? null ;
333+ logger . debug ( "PATCH RES" , patchRes . data ) ;
334+ if ( patchRes . error ) return null ;
335+
336+ // Read back the updated record
337+ const readBack = await fetch ( `/${ model } ('${ id } ')` , {
338+ method : "GET" ,
339+ output : z . record ( z . string ( ) , z . unknown ( ) ) ,
340+ } ) ;
341+ logger . debug ( "READ BACK" , readBack . data ) ;
342+ return ( readBack . data as any ) ?? null ;
292343 } ,
293344 updateMany : async ( { model, where, update } ) => {
294345 const filter = parseWhere ( where ) ;
295- const result = await fetch ( `/${ model } ` , {
296- method : "PATCH" ,
297- query : {
298- ...( where . length > 0 ? { $filter : filter } : { } ) ,
299- } ,
300- body : update ,
346+ // Find all ids matching the filter
347+ const query = buildQuery ( {
348+ select : [ `"id"` ] ,
349+ filter : filter . length > 0 ? filter : undefined ,
301350 } ) ;
302- return result . data as any ;
351+
352+ const rows = await fetch ( `/${ model } ${ query } ` , {
353+ method : "GET" ,
354+ output : z . object ( { value : z . array ( z . object ( { id : z . string ( ) } ) ) } ) ,
355+ } ) ;
356+
357+ const ids = rows . data ?. value ?. map ( ( r : any ) => r . id ) ?? [ ] ;
358+ let updated = 0 ;
359+ for ( const id of ids ) {
360+ const res = await fetch ( `/${ model } ('${ id } ')` , {
361+ method : "PATCH" ,
362+ body : update ,
363+ } ) ;
364+ if ( ! res . error ) updated ++ ;
365+ }
366+ return updated as any ;
303367 } ,
304368 } ;
305369 } ,
0 commit comments