@@ -186,13 +186,51 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
186186 }
187187
188188 async findData ( request : { object : string , query ?: any } ) {
189- // TODO: Normalize query from HTTP Query params (string values) to DataEngineQueryOptions (typed)
190- // For now, we assume query is partially compatible or simple enough.
191- // We should parse 'top', 'skip', 'limit' to numbers if they are strings.
192189 const options : any = { ...request . query } ;
193- if ( options . top ) options . top = Number ( options . top ) ;
194- if ( options . skip ) options . skip = Number ( options . skip ) ;
195- if ( options . limit ) options . limit = Number ( options . limit ) ;
190+
191+ // Numeric fields
192+ if ( options . top != null ) options . top = Number ( options . top ) ;
193+ if ( options . skip != null ) options . skip = Number ( options . skip ) ;
194+ if ( options . limit != null ) options . limit = Number ( options . limit ) ;
195+
196+ // Select: comma-separated string → array
197+ if ( typeof options . select === 'string' ) {
198+ options . select = options . select . split ( ',' ) . map ( ( s : string ) => s . trim ( ) ) . filter ( Boolean ) ;
199+ }
200+
201+ // Sort/orderBy: string → sort array (e.g. "name asc,created_at desc" or "name,-created_at")
202+ const sortValue = options . orderBy ?? options . sort ;
203+ if ( typeof sortValue === 'string' ) {
204+ const parsed = sortValue . split ( ',' ) . map ( ( part : string ) => {
205+ const trimmed = part . trim ( ) ;
206+ if ( trimmed . startsWith ( '-' ) ) {
207+ return { field : trimmed . slice ( 1 ) , order : 'desc' as const } ;
208+ }
209+ const [ field , order ] = trimmed . split ( / \s + / ) ;
210+ return { field, order : ( order ?. toLowerCase ( ) === 'desc' ? 'desc' : 'asc' ) as 'asc' | 'desc' } ;
211+ } ) . filter ( ( s : any ) => s . field ) ;
212+ options . sort = parsed ;
213+ delete options . orderBy ;
214+ }
215+
216+ // Filter: JSON string → object
217+ if ( typeof options . filter === 'string' ) {
218+ try { options . filter = JSON . parse ( options . filter ) ; } catch { /* keep as-is */ }
219+ }
220+ if ( typeof options . filters === 'string' ) {
221+ try { options . filter = JSON . parse ( options . filters ) ; delete options . filters ; } catch { /* keep as-is */ }
222+ }
223+
224+ // Populate: comma-separated string → array
225+ if ( typeof options . populate === 'string' ) {
226+ options . populate = options . populate . split ( ',' ) . map ( ( s : string ) => s . trim ( ) ) . filter ( Boolean ) ;
227+ }
228+
229+ // Boolean fields
230+ for ( const key of [ 'distinct' , 'count' ] ) {
231+ if ( options [ key ] === 'true' ) options [ key ] = true ;
232+ else if ( options [ key ] === 'false' ) options [ key ] = false ;
233+ }
196234
197235 // Handle OData style $filter if present, or flat filters
198236 // This is a naive implementation, a real OData parser is needed for complex scenarios.
0 commit comments