Skip to content

Commit 33a3ab4

Browse files
authored
Merge pull request #983 from objectstack-ai/copilot/unify-architecture-remove-dataenginequeryoptions
2 parents b83fef3 + b942cdd commit 33a3ab4

File tree

19 files changed

+829
-371
lines changed

19 files changed

+829
-371
lines changed

.changeset/queryast-convergence.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
"@objectstack/spec": minor
3+
"@objectstack/core": minor
4+
"@objectstack/objectql": minor
5+
"@objectstack/client": minor
6+
"@objectstack/runtime": patch
7+
"@objectstack/plugin-auth": patch
8+
---
9+
10+
Deprecate DataEngineQueryOptions in favor of QueryAST-aligned EngineQueryOptions.
11+
12+
Engine, Protocol, and Client now use standard QueryAST parameter names:
13+
- `filter``where`
14+
- `select``fields`
15+
- `sort``orderBy`
16+
- `skip``offset`
17+
- `populate``expand`
18+
- `top``limit`
19+
20+
The old DataEngine* schemas and types are preserved with `@deprecated` markers for backward compatibility.

apps/studio/src/lib/create-broker-shim.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function createBrokerShim(kernel: any): BrokerShim {
7575
}
7676

7777
try {
78-
await ql.update(params.object, params.data, { filter: params.id });
78+
await ql.update(params.object, params.data, { where: { id: params.id } });
7979
} catch (err: any) {
8080
console.warn(`[BrokerShim] update failed: ${err.message}`);
8181
throw err;
@@ -87,7 +87,7 @@ export function createBrokerShim(kernel: any): BrokerShim {
8787
}
8888
if (method === 'delete') {
8989
try {
90-
await ql.delete(params.object, { filter: params.id });
90+
await ql.delete(params.object, { where: { id: params.id } });
9191
return { object: params.object, id: params.id, deleted: true };
9292
} catch (err: any) {
9393
console.warn(`[BrokerShim] delete failed: ${err.message}`);

content/docs/references/data/data-engine.mdx

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ The Data Engine acts as the "Driver" layer in the Hexagonal Architecture.
2424
## TypeScript Usage
2525

2626
```typescript
27-
import { BaseEngineOptions, DataEngineAggregateOptions, DataEngineAggregateRequest, DataEngineBatchRequest, DataEngineCountOptions, DataEngineCountRequest, DataEngineDeleteOptions, DataEngineDeleteRequest, DataEngineExecuteRequest, DataEngineFilter, DataEngineFindOneRequest, DataEngineFindRequest, DataEngineInsertOptions, DataEngineInsertRequest, DataEngineQueryOptions, DataEngineRequest, DataEngineSort, DataEngineUpdateOptions, DataEngineUpdateRequest, DataEngineVectorFindRequest } from '@objectstack/spec/data';
28-
import type { BaseEngineOptions, DataEngineAggregateOptions, DataEngineAggregateRequest, DataEngineBatchRequest, DataEngineCountOptions, DataEngineCountRequest, DataEngineDeleteOptions, DataEngineDeleteRequest, DataEngineExecuteRequest, DataEngineFilter, DataEngineFindOneRequest, DataEngineFindRequest, DataEngineInsertOptions, DataEngineInsertRequest, DataEngineQueryOptions, DataEngineRequest, DataEngineSort, DataEngineUpdateOptions, DataEngineUpdateRequest, DataEngineVectorFindRequest } from '@objectstack/spec/data';
27+
import { BaseEngineOptions, DataEngineAggregateOptions, DataEngineAggregateRequest, DataEngineBatchRequest, DataEngineCountOptions, DataEngineCountRequest, DataEngineDeleteOptions, DataEngineDeleteRequest, DataEngineExecuteRequest, DataEngineFilter, DataEngineFindOneRequest, DataEngineFindRequest, DataEngineInsertOptions, DataEngineInsertRequest, DataEngineQueryOptions, DataEngineRequest, DataEngineSort, DataEngineUpdateOptions, DataEngineUpdateRequest, DataEngineVectorFindRequest, EngineAggregateOptions, EngineCountOptions, EngineDeleteOptions, EngineQueryOptions, EngineUpdateOptions } from '@objectstack/spec/data';
28+
import type { BaseEngineOptions, DataEngineAggregateOptions, DataEngineAggregateRequest, DataEngineBatchRequest, DataEngineCountOptions, DataEngineCountRequest, DataEngineDeleteOptions, DataEngineDeleteRequest, DataEngineExecuteRequest, DataEngineFilter, DataEngineFindOneRequest, DataEngineFindRequest, DataEngineInsertOptions, DataEngineInsertRequest, DataEngineQueryOptions, DataEngineRequest, DataEngineSort, DataEngineUpdateOptions, DataEngineUpdateRequest, DataEngineVectorFindRequest, EngineAggregateOptions, EngineCountOptions, EngineDeleteOptions, EngineQueryOptions, EngineUpdateOptions } from '@objectstack/spec/data';
2929

3030
// Validate data
3131
const result = BaseEngineOptions.parse(data);
@@ -68,7 +68,7 @@ Options for DataEngine.aggregate operations
6868
| :--- | :--- | :--- | :--- |
6969
| **method** | `string` || |
7070
| **object** | `string` || |
71-
| **query** | `Object` || Options for DataEngine.aggregate operations |
71+
| **query** | `Object` || |
7272

7373

7474
---
@@ -108,7 +108,7 @@ Options for DataEngine.count operations
108108
| :--- | :--- | :--- | :--- |
109109
| **method** | `string` || |
110110
| **object** | `string` || |
111-
| **query** | `Object` | optional | Options for DataEngine.count operations |
111+
| **query** | `Object` | optional | |
112112

113113

114114
---
@@ -136,8 +136,8 @@ Options for DataEngine.delete operations
136136
| :--- | :--- | :--- | :--- |
137137
| **method** | `string` || |
138138
| **object** | `string` || |
139-
| **id** | `string \| number` | optional | ID for single delete, or use filter in options |
140-
| **options** | `Object` | optional | Options for DataEngine.delete operations |
139+
| **id** | `string \| number` | optional | ID for single delete, or use where in options |
140+
| **options** | `Object` | optional | |
141141

142142

143143
---
@@ -186,7 +186,7 @@ Reference: [__schema0](./__schema0)
186186
| :--- | :--- | :--- | :--- |
187187
| **method** | `string` || |
188188
| **object** | `string` || |
189-
| **query** | `Object` | optional | Query options for IDataEngine.find() operations |
189+
| **query** | `Object` | optional | |
190190

191191

192192
---
@@ -199,7 +199,7 @@ Reference: [__schema0](./__schema0)
199199
| :--- | :--- | :--- | :--- |
200200
| **method** | `string` || |
201201
| **object** | `string` || |
202-
| **query** | `Object` | optional | Query options for IDataEngine.find() operations |
202+
| **query** | `Object` | optional | |
203203

204204

205205
---
@@ -268,7 +268,7 @@ This schema accepts one of the following structures:
268268
| :--- | :--- | :--- | :--- |
269269
| **method** | `string` || |
270270
| **object** | `string` || |
271-
| **query** | `Object` | optional | Query options for IDataEngine.find() operations |
271+
| **query** | `Object` | optional | |
272272

273273
---
274274

@@ -280,7 +280,7 @@ This schema accepts one of the following structures:
280280
| :--- | :--- | :--- | :--- |
281281
| **method** | `string` || |
282282
| **object** | `string` || |
283-
| **query** | `Object` | optional | Query options for IDataEngine.find() operations |
283+
| **query** | `Object` | optional | |
284284

285285
---
286286

@@ -306,8 +306,8 @@ This schema accepts one of the following structures:
306306
| **method** | `string` || |
307307
| **object** | `string` || |
308308
| **data** | `Record<string, any>` || |
309-
| **id** | `string \| number` | optional | ID for single update, or use filter in options |
310-
| **options** | `Object` | optional | Options for DataEngine.update operations |
309+
| **id** | `string \| number` | optional | ID for single update, or use where in options |
310+
| **options** | `Object` | optional | |
311311

312312
---
313313

@@ -319,8 +319,8 @@ This schema accepts one of the following structures:
319319
| :--- | :--- | :--- | :--- |
320320
| **method** | `string` || |
321321
| **object** | `string` || |
322-
| **id** | `string \| number` | optional | ID for single delete, or use filter in options |
323-
| **options** | `Object` | optional | Options for DataEngine.delete operations |
322+
| **id** | `string \| number` | optional | ID for single delete, or use where in options |
323+
| **options** | `Object` | optional | |
324324

325325
---
326326

@@ -332,7 +332,7 @@ This schema accepts one of the following structures:
332332
| :--- | :--- | :--- | :--- |
333333
| **method** | `string` || |
334334
| **object** | `string` || |
335-
| **query** | `Object` | optional | Options for DataEngine.count operations |
335+
| **query** | `Object` | optional | |
336336

337337
---
338338

@@ -344,7 +344,7 @@ This schema accepts one of the following structures:
344344
| :--- | :--- | :--- | :--- |
345345
| **method** | `string` || |
346346
| **object** | `string` || |
347-
| **query** | `Object` || Options for DataEngine.aggregate operations |
347+
| **query** | `Object` || |
348348

349349
---
350350

@@ -381,8 +381,8 @@ This schema accepts one of the following structures:
381381
| **method** | `string` || |
382382
| **object** | `string` || |
383383
| **vector** | `number[]` || |
384-
| **filter** | `Record<string, any> \| [__schema0](./__schema0)` | optional | Data Engine query filter conditions |
385-
| **select** | `string[]` | optional | |
384+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
385+
| **fields** | `string[]` | optional | |
386386
| **limit** | `integer` | optional | |
387387
| **threshold** | `number` | optional | |
388388

@@ -446,8 +446,8 @@ Options for DataEngine.update operations
446446
| **method** | `string` || |
447447
| **object** | `string` || |
448448
| **data** | `Record<string, any>` || |
449-
| **id** | `string \| number` | optional | ID for single update, or use filter in options |
450-
| **options** | `Object` | optional | Options for DataEngine.update operations |
449+
| **id** | `string \| number` | optional | ID for single update, or use where in options |
450+
| **options** | `Object` | optional | |
451451

452452

453453
---
@@ -461,11 +461,96 @@ Options for DataEngine.update operations
461461
| **method** | `string` || |
462462
| **object** | `string` || |
463463
| **vector** | `number[]` || |
464-
| **filter** | `Record<string, any> \| [__schema0](./__schema0)` | optional | Data Engine query filter conditions |
465-
| **select** | `string[]` | optional | |
464+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
465+
| **fields** | `string[]` | optional | |
466466
| **limit** | `integer` | optional | |
467467
| **threshold** | `number` | optional | |
468468

469469

470470
---
471471

472+
## EngineAggregateOptions
473+
474+
QueryAST-aligned options for DataEngine.aggregate operations
475+
476+
### Properties
477+
478+
| Property | Type | Required | Description |
479+
| :--- | :--- | :--- | :--- |
480+
| **context** | `Object` | optional | |
481+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
482+
| **groupBy** | `string[]` | optional | |
483+
| **aggregations** | `Object[]` | optional | |
484+
485+
486+
---
487+
488+
## EngineCountOptions
489+
490+
QueryAST-aligned options for DataEngine.count operations
491+
492+
### Properties
493+
494+
| Property | Type | Required | Description |
495+
| :--- | :--- | :--- | :--- |
496+
| **context** | `Object` | optional | |
497+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
498+
499+
500+
---
501+
502+
## EngineDeleteOptions
503+
504+
QueryAST-aligned options for DataEngine.delete operations
505+
506+
### Properties
507+
508+
| Property | Type | Required | Description |
509+
| :--- | :--- | :--- | :--- |
510+
| **context** | `Object` | optional | |
511+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
512+
| **multi** | `boolean` | optional | |
513+
514+
515+
---
516+
517+
## EngineQueryOptions
518+
519+
QueryAST-aligned query options for IDataEngine.find() operations
520+
521+
### Properties
522+
523+
| Property | Type | Required | Description |
524+
| :--- | :--- | :--- | :--- |
525+
| **context** | `Object` | optional | |
526+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
527+
| **fields** | `[__schema1](./__schema1)[]` | optional | |
528+
| **orderBy** | `Object[]` | optional | |
529+
| **limit** | `number` | optional | |
530+
| **offset** | `number` | optional | |
531+
| **top** | `number` | optional | |
532+
| **cursor** | `Record<string, any>` | optional | |
533+
| **search** | `Object` | optional | |
534+
| **expand** | `Record<string, [__schema2](./__schema2)>` | optional | |
535+
| **distinct** | `boolean` | optional | |
536+
537+
538+
---
539+
540+
## EngineUpdateOptions
541+
542+
QueryAST-aligned options for DataEngine.update operations
543+
544+
### Properties
545+
546+
| Property | Type | Required | Description |
547+
| :--- | :--- | :--- | :--- |
548+
| **context** | `Object` | optional | |
549+
| **where** | `Record<string, any> \| [__schema0](./__schema0)` | optional | |
550+
| **upsert** | `boolean` | optional | |
551+
| **multi** | `boolean` | optional | |
552+
| **returning** | `boolean` | optional | |
553+
554+
555+
---
556+

content/docs/references/data/driver.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const result = DriverCapabilities.parse(data);
5757
| **arrayFields** | `boolean` || Supports array field types |
5858
| **vectorSearch** | `boolean` || Supports vector embeddings and similarity search |
5959
| **schemaSync** | `boolean` || Supports automatic schema synchronization |
60+
| **batchSchemaSync** | `boolean` || Supports batched schema sync to reduce schema DDL round-trips |
6061
| **migrations** | `boolean` || Supports database migrations |
6162
| **indexes** | `boolean` || Supports index creation and management |
6263
| **connectionPooling** | `boolean` || Supports connection pooling |

packages/client/src/client.hono.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ describe('ObjectStackClient (with Hono Server)', () => {
5252
if (protocol) {
5353
return await protocol.findData({ object: params.object, query: params.query || params.filters });
5454
}
55-
const records = await ql.find(params.object, { filter: params.filters });
55+
const records = await ql.find(params.object, { where: params.filters });
5656
return { object: params.object, records, total: records.length };
5757
}
5858
if (method === 'find') {
5959
if (protocol) {
6060
return await protocol.findData({ object: params.object, query: params.query || params.filters });
6161
}
62-
const records = await ql.find(params.object, { filter: params.filters });
62+
const records = await ql.find(params.object, { where: params.filters });
6363
return { object: params.object, records, total: records.length };
6464
}
6565
}

packages/client/src/client.msw.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ describe('ObjectStackClient (with MSW Plugin)', () => {
5757
return await protocol.findData({ object: params.object, query: params.query });
5858
}
5959
const queryOpts = params.query || {};
60-
const records = await ql.find(params.object, { filter: queryOpts.filters || queryOpts.filter });
60+
const records = await ql.find(params.object, { where: queryOpts.filters || queryOpts.filter || queryOpts.where });
6161
return { object: params.object, records, total: records.length };
6262
}
6363
if (method === 'find') {
6464
if (protocol) {
6565
return await protocol.findData({ object: params.object, query: params.query });
6666
}
6767
const queryOpts = params.query || {};
68-
const records = await ql.find(params.object, { filter: queryOpts.filters || queryOpts.filter });
68+
const records = await ql.find(params.object, { where: queryOpts.filters || queryOpts.filter || queryOpts.where });
6969
return { object: params.object, records, total: records.length };
7070
}
7171
}

packages/client/src/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ export interface ClientConfig {
113113
*/
114114
export type DiscoveryResult = GetDiscoveryResponse;
115115

116+
/**
117+
* @deprecated Use `data.query()` with standard QueryAST parameters instead.
118+
* This interface uses legacy parameter names (filter/sort/top/skip) that
119+
* require translation to QueryAST. Prefer QueryAST fields directly:
120+
* - filter → where
121+
* - select → fields
122+
* - sort → orderBy
123+
* - skip → offset
124+
* - top → limit
125+
*/
116126
export interface QueryOptions {
117127
select?: string[]; // Simplified Selection
118128
/** @canonical Preferred filter parameter (singular). */
@@ -1423,6 +1433,10 @@ export class ObjectStackClient {
14231433
return this.unwrapResponse<PaginatedResult<T>>(res);
14241434
},
14251435

1436+
/**
1437+
* @deprecated Use `data.query()` with standard QueryAST parameters instead.
1438+
* This method uses legacy parameter names. Internally adapts to HTTP GET params.
1439+
*/
14261440
find: async <T = any>(object: string, options: QueryOptions = {}): Promise<PaginatedResult<T>> => {
14271441
const route = this.getRoute('data');
14281442
const queryParams = new URLSearchParams();

packages/core/src/contracts/data-engine.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

33
import {
4-
DataEngineQueryOptions,
4+
EngineQueryOptions,
55
DataEngineInsertOptions,
6-
DataEngineUpdateOptions,
7-
DataEngineDeleteOptions,
8-
DataEngineAggregateOptions,
9-
DataEngineCountOptions,
6+
EngineUpdateOptions,
7+
EngineDeleteOptions,
8+
EngineAggregateOptions,
9+
EngineCountOptions,
1010
DataEngineRequest,
1111
} from '@objectstack/spec/data';
1212

@@ -17,22 +17,26 @@ import {
1717
* Following the Dependency Inversion Principle - plugins depend on this interface,
1818
* not on concrete database implementations.
1919
*
20+
* All query methods use standard QueryAST parameter names
21+
* (where/fields/orderBy/limit/offset/expand) to eliminate mechanical translation
22+
* between the Engine and Driver layers.
23+
*
2024
* Aligned with 'src/data/data-engine.zod.ts' in @objectstack/spec.
2125
*/
2226

2327
export interface IDataEngine {
24-
find(objectName: string, query?: DataEngineQueryOptions): Promise<any[]>;
25-
findOne(objectName: string, query?: DataEngineQueryOptions): Promise<any>;
28+
find(objectName: string, query?: EngineQueryOptions): Promise<any[]>;
29+
findOne(objectName: string, query?: EngineQueryOptions): Promise<any>;
2630
insert(objectName: string, data: any | any[], options?: DataEngineInsertOptions): Promise<any>;
27-
update(objectName: string, data: any, options?: DataEngineUpdateOptions): Promise<any>;
28-
delete(objectName: string, options?: DataEngineDeleteOptions): Promise<any>;
29-
count(objectName: string, query?: DataEngineCountOptions): Promise<number>;
30-
aggregate(objectName: string, query: DataEngineAggregateOptions): Promise<any[]>;
31+
update(objectName: string, data: any, options?: EngineUpdateOptions): Promise<any>;
32+
delete(objectName: string, options?: EngineDeleteOptions): Promise<any>;
33+
count(objectName: string, query?: EngineCountOptions): Promise<number>;
34+
aggregate(objectName: string, query: EngineAggregateOptions): Promise<any[]>;
3135

3236
/**
3337
* Vector Search (AI/RAG)
3438
*/
35-
vectorFind?(objectName: string, vector: number[], options?: { filter?: any, limit?: number, select?: string[], threshold?: number }): Promise<any[]>;
39+
vectorFind?(objectName: string, vector: number[], options?: { where?: any, limit?: number, fields?: string[], threshold?: number }): Promise<any[]>;
3640

3741
/**
3842
* Batch Operations (Transactional)

0 commit comments

Comments
 (0)