11import { QueryAST , HookContext } from '@objectstack/spec/data' ;
22import { ObjectStackManifest } from '@objectstack/spec/system' ;
33import { DriverInterface , DriverOptions } from '@objectstack/spec/system' ;
4+ import { IDataEngine , QueryOptions } from '@objectstack/spec/system' ;
45import { SchemaRegistry } from './registry' ;
56
67// Export Registry for consumers
@@ -20,8 +21,10 @@ export interface PluginContext {
2021
2122/**
2223 * ObjectQL Engine
24+ *
25+ * Implements the IDataEngine interface for data persistence.
2326 */
24- export class ObjectQL {
27+ export class ObjectQL implements IDataEngine {
2528 private drivers = new Map < string , DriverInterface > ( ) ;
2629 private defaultDriver : string | null = null ;
2730
@@ -211,27 +214,52 @@ export class ObjectQL {
211214 }
212215
213216 // ============================================
214- // Data Access Methods
217+ // Data Access Methods (IDataEngine Interface)
215218 // ============================================
216219
217- async find ( object : string , query : any = { } , options ?: DriverOptions ) {
220+ /**
221+ * Find records matching a query (IDataEngine interface)
222+ *
223+ * @param object - Object name
224+ * @param query - Query options (IDataEngine format)
225+ * @returns Promise resolving to array of records
226+ */
227+ async find ( object : string , query ?: QueryOptions ) : Promise < any [ ] > {
218228 const driver = this . getDriver ( object ) ;
219229
220- // Normalize QueryAST
221- let ast : QueryAST ;
222- if ( query . where || query . fields || query . orderBy || query . limit ) {
223- ast = { object, ...query } as QueryAST ;
224- } else {
225- ast = { object, where : query } as QueryAST ;
230+ // Convert QueryOptions to QueryAST
231+ let ast : QueryAST = { object } ;
232+
233+ if ( query ) {
234+ // Map QueryOptions to QueryAST
235+ if ( query . filter ) {
236+ ast . where = query . filter ;
237+ }
238+ if ( query . select ) {
239+ ast . fields = query . select ;
240+ }
241+ if ( query . sort ) {
242+ ast . orderBy = query . sort ;
243+ }
244+ // Handle both limit and top (top takes precedence)
245+ if ( query . top !== undefined ) {
246+ ast . limit = query . top ;
247+ } else if ( query . limit !== undefined ) {
248+ ast . limit = query . limit ;
249+ }
250+ if ( query . skip !== undefined ) {
251+ ast . offset = query . skip ;
252+ }
226253 }
227254
255+ // Set default limit if not specified
228256 if ( ast . limit === undefined ) ast . limit = 100 ;
229257
230258 // Trigger Before Hook
231259 const hookContext : HookContext = {
232260 object,
233261 event : 'beforeFind' ,
234- input : { ast, options } , // Hooks can modify AST here
262+ input : { ast, options : undefined } ,
235263 ql : this
236264 } ;
237265 await this . triggerHooks ( 'beforeFind' , hookContext ) ;
@@ -275,7 +303,14 @@ export class ObjectQL {
275303 return driver . findOne ( object , ast , options ) ;
276304 }
277305
278- async insert ( object : string , data : Record < string , any > , options ?: DriverOptions ) {
306+ /**
307+ * Insert a new record (IDataEngine interface)
308+ *
309+ * @param object - Object name
310+ * @param data - Data to insert
311+ * @returns Promise resolving to the created record
312+ */
313+ async insert ( object : string , data : any ) : Promise < any > {
279314 const driver = this . getDriver ( object ) ;
280315
281316 // 1. Get Schema
@@ -290,7 +325,7 @@ export class ObjectQL {
290325 const hookContext : HookContext = {
291326 object,
292327 event : 'beforeInsert' ,
293- input : { data, options } ,
328+ input : { data, options : undefined } ,
294329 ql : this
295330 } ;
296331 await this . triggerHooks ( 'beforeInsert' , hookContext ) ;
@@ -306,13 +341,21 @@ export class ObjectQL {
306341 return hookContext . result ;
307342 }
308343
309- async update ( object : string , id : string | number , data : Record < string , any > , options ?: DriverOptions ) {
344+ /**
345+ * Update a record by ID (IDataEngine interface)
346+ *
347+ * @param object - Object name
348+ * @param id - Record ID
349+ * @param data - Updated data
350+ * @returns Promise resolving to the updated record
351+ */
352+ async update ( object : string , id : any , data : any ) : Promise < any > {
310353 const driver = this . getDriver ( object ) ;
311354
312355 const hookContext : HookContext = {
313356 object,
314357 event : 'beforeUpdate' ,
315- input : { id, data, options } ,
358+ input : { id, data, options : undefined } ,
316359 ql : this
317360 } ;
318361 await this . triggerHooks ( 'beforeUpdate' , hookContext ) ;
@@ -326,13 +369,20 @@ export class ObjectQL {
326369 return hookContext . result ;
327370 }
328371
329- async delete ( object : string , id : string | number , options ?: DriverOptions ) {
372+ /**
373+ * Delete a record by ID (IDataEngine interface)
374+ *
375+ * @param object - Object name
376+ * @param id - Record ID
377+ * @returns Promise resolving to true if deleted, false otherwise
378+ */
379+ async delete ( object : string , id : any ) : Promise < boolean > {
330380 const driver = this . getDriver ( object ) ;
331381
332382 const hookContext : HookContext = {
333383 object,
334384 event : 'beforeDelete' ,
335- input : { id, options } ,
385+ input : { id, options : undefined } ,
336386 ql : this
337387 } ;
338388 await this . triggerHooks ( 'beforeDelete' , hookContext ) ;
@@ -343,6 +393,8 @@ export class ObjectQL {
343393 hookContext . result = result ;
344394 await this . triggerHooks ( 'afterDelete' , hookContext ) ;
345395
346- return hookContext . result ;
396+ // Return boolean - true if deletion was successful
397+ // The driver.delete should return the deleted record or null
398+ return hookContext . result !== null && hookContext . result !== undefined ;
347399 }
348400}
0 commit comments