66 * LICENSE file in the root directory of this source tree.
77 */
88
9- import { ObjectQLContext , IObjectQL , ObjectConfig , Driver , UnifiedQuery , ActionContext , HookAPI , RetrievalHookContext , MutationHookContext , UpdateHookContext , ValidationContext , ValidationError , ValidationRuleResult , FormulaContext } from '@objectql/types' ;
9+ import { ObjectQLContext , IObjectQL , ObjectConfig , Driver , UnifiedQuery , ActionContext , HookAPI , RetrievalHookContext , MutationHookContext , UpdateHookContext , ValidationContext , ValidationError , ValidationRuleResult , FormulaContext , FilterExpression } from '@objectql/types' ;
10+ import type { ObjectStackKernel } from '@objectstack/runtime' ;
11+ import type { QueryAST , FilterNode , SortNode } from '@objectstack/spec' ;
1012import { Validator } from './validator' ;
1113import { FormulaEngine } from './formula-engine' ;
1214
@@ -29,13 +31,81 @@ export class ObjectRepository {
2931 return this . app . datasource ( datasourceName ) ;
3032 }
3133
34+ private getKernel ( ) : ObjectStackKernel {
35+ return this . app . getKernel ( ) ;
36+ }
37+
3238 private getOptions ( extra : any = { } ) {
3339 return {
3440 transaction : this . context . transactionHandle ,
3541 ...extra
3642 } ;
3743 }
3844
45+ /**
46+ * Translates ObjectQL FilterExpression to ObjectStack FilterNode format
47+ */
48+ private translateFilters ( filters ?: FilterExpression [ ] ) : FilterNode | undefined {
49+ if ( ! filters || filters . length === 0 ) {
50+ return undefined ;
51+ }
52+
53+ // FilterExpression[] is already compatible with FilterNode format
54+ // Just pass through as-is
55+ return filters as FilterNode ;
56+ }
57+
58+ /**
59+ * Translates ObjectQL UnifiedQuery to ObjectStack QueryAST format
60+ */
61+ private buildQueryAST ( query : UnifiedQuery ) : QueryAST {
62+ const ast : QueryAST = {
63+ object : this . objectName ,
64+ } ;
65+
66+ // Map fields
67+ if ( query . fields ) {
68+ ast . fields = query . fields ;
69+ }
70+
71+ // Map filters
72+ if ( query . filters ) {
73+ ast . filters = this . translateFilters ( query . filters ) ;
74+ }
75+
76+ // Map sort
77+ if ( query . sort ) {
78+ ast . sort = query . sort . map ( ( [ field , order ] ) => ( {
79+ field,
80+ order : order as 'asc' | 'desc'
81+ } ) ) ;
82+ }
83+
84+ // Map pagination
85+ if ( query . limit !== undefined ) {
86+ ast . top = query . limit ;
87+ }
88+ if ( query . skip !== undefined ) {
89+ ast . skip = query . skip ;
90+ }
91+
92+ // Map aggregations
93+ if ( query . aggregate ) {
94+ ast . aggregations = query . aggregate . map ( agg => ( {
95+ function : agg . func as any ,
96+ field : agg . field ,
97+ alias : agg . alias || `${ agg . func } _${ agg . field } `
98+ } ) ) ;
99+ }
100+
101+ // Map groupBy
102+ if ( query . groupBy ) {
103+ ast . groupBy = query . groupBy ;
104+ }
105+
106+ return ast ;
107+ }
108+
39109 getSchema ( ) : ObjectConfig {
40110 const obj = this . app . getObject ( this . objectName ) ;
41111 if ( ! obj ) {
@@ -221,8 +291,10 @@ export class ObjectRepository {
221291 } ;
222292 await this . app . triggerHook ( 'beforeFind' , this . objectName , hookCtx ) ;
223293
224- // TODO: Apply basic filters like spaceId
225- const results = await this . getDriver ( ) . find ( this . objectName , hookCtx . query || { } , this . getOptions ( ) ) ;
294+ // Build QueryAST and execute via kernel
295+ const ast = this . buildQueryAST ( hookCtx . query || { } ) ;
296+ const kernelResult = await this . getKernel ( ) . find ( this . objectName , ast ) ;
297+ const results = kernelResult . value ;
226298
227299 // Evaluate formulas for each result
228300 const resultsWithFormulas = results . map ( record => this . evaluateFormulas ( record ) ) ;
@@ -246,7 +318,8 @@ export class ObjectRepository {
246318 } ;
247319 await this . app . triggerHook ( 'beforeFind' , this . objectName , hookCtx ) ;
248320
249- const result = await this . getDriver ( ) . findOne ( this . objectName , idOrQuery , hookCtx . query , this . getOptions ( ) ) ;
321+ // Use kernel.get() for direct ID lookup
322+ const result = await this . getKernel ( ) . get ( this . objectName , String ( idOrQuery ) ) ;
250323
251324 // Evaluate formulas if result exists
252325 const resultWithFormulas = result ? this . evaluateFormulas ( result ) : result ;
@@ -272,7 +345,10 @@ export class ObjectRepository {
272345 } ;
273346 await this . app . triggerHook ( 'beforeCount' , this . objectName , hookCtx ) ;
274347
275- const result = await this . getDriver ( ) . count ( this . objectName , hookCtx . query , this . getOptions ( ) ) ;
348+ // Build QueryAST and execute via kernel to get count
349+ const ast = this . buildQueryAST ( hookCtx . query || { } ) ;
350+ const kernelResult = await this . getKernel ( ) . find ( this . objectName , ast ) ;
351+ const result = kernelResult . count ;
276352
277353 hookCtx . result = result ;
278354 await this . app . triggerHook ( 'afterCount' , this . objectName , hookCtx ) ;
@@ -298,7 +374,8 @@ export class ObjectRepository {
298374 // Validate the record before creating
299375 await this . validateRecord ( 'create' , finalDoc ) ;
300376
301- const result = await this . getDriver ( ) . create ( this . objectName , finalDoc , this . getOptions ( ) ) ;
377+ // Execute via kernel
378+ const result = await this . getKernel ( ) . create ( this . objectName , finalDoc ) ;
302379
303380 hookCtx . result = result ;
304381 await this . app . triggerHook ( 'afterCreate' , this . objectName , hookCtx ) ;
@@ -324,7 +401,8 @@ export class ObjectRepository {
324401 // Validate the update
325402 await this . validateRecord ( 'update' , hookCtx . data , previousData ) ;
326403
327- const result = await this . getDriver ( ) . update ( this . objectName , id , hookCtx . data , this . getOptions ( options ) ) ;
404+ // Execute via kernel
405+ const result = await this . getKernel ( ) . update ( this . objectName , String ( id ) , hookCtx . data ) ;
328406
329407 hookCtx . result = result ;
330408 await this . app . triggerHook ( 'afterUpdate' , this . objectName , hookCtx ) ;
@@ -345,7 +423,8 @@ export class ObjectRepository {
345423 } ;
346424 await this . app . triggerHook ( 'beforeDelete' , this . objectName , hookCtx ) ;
347425
348- const result = await this . getDriver ( ) . delete ( this . objectName , id , this . getOptions ( ) ) ;
426+ // Execute via kernel
427+ const result = await this . getKernel ( ) . delete ( this . objectName , String ( id ) ) ;
349428
350429 hookCtx . result = result ;
351430 await this . app . triggerHook ( 'afterDelete' , this . objectName , hookCtx ) ;
0 commit comments