diff --git a/content/docs/ai/coding-assistant.mdx b/content/docs/ai/coding-assistant.mdx index 42c03dcf..99383092 100644 --- a/content/docs/ai/coding-assistant.mdx +++ b/content/docs/ai/coding-assistant.mdx @@ -21,7 +21,7 @@ Without this prompt, Copilot assumes you are using a generic ORM (like TypeORM) With the System Prompt, it understands the **Context + Repository** pattern: > ✅ **Good AI Output:** -> `await ctx.object('todo').find({ filters: [['priority', '=', 'high']] })` +> `await ctx.object('todo').find({ filters: { priority: 'high' } })` ### 2. Prompting Strategy @@ -103,10 +103,10 @@ Use the standard generic CRUD API via a context. const ctx = app.createContext({}); const todos = await ctx.object('todo').find({ - filters: [ - ['completed', '=', false], - ['priority', '=', 'high'] - ], + filters: { + completed: false, + priority: 'high' + }, fields: ['title', 'owner.name'], // Select specific fields & relations sort: [['created_at', 'desc']], skip: 0, diff --git a/content/docs/data-access/best-practices.mdx b/content/docs/data-access/best-practices.mdx index e4261fbd..f7ce05ad 100644 --- a/content/docs/data-access/best-practices.mdx +++ b/content/docs/data-access/best-practices.mdx @@ -40,11 +40,10 @@ The **JSON-DSL** is ObjectQL's core query language - a structured JSON represent ```typescript const tasks = await app.object('task').find({ fields: ['name', 'status', 'due_date'], - filters: [ - ['status', '=', 'active'], - 'and', - ['priority', '>=', 3] - ], + filters: { + status: 'active', + priority: { $gte: 3 } + }, sort: [['due_date', 'asc']], skip: 0, limit: 20 @@ -59,7 +58,7 @@ const tasks = await app.object('task').find({ ```typescript // Returns ALL fields (inefficient) await app.object('user').find({ - filters: [['status', '=', 'active']] + filters: { status: 'active' } }); ``` @@ -68,7 +67,7 @@ await app.object('user').find({ // Returns only needed fields (efficient) await app.object('user').find({ fields: ['id', 'name', 'email'], - filters: [['status', '=', 'active']] + filters: { status: 'active' } }); ``` @@ -79,17 +78,16 @@ await app.object('user').find({ **Bad:** ```typescript // Filters on non-indexed field -filters: [['description', 'contains', 'urgent']] +filters: { description: { $contains: 'urgent' } } ``` **Good:** ```typescript // Filters on indexed field first, then post-filter if needed -filters: [ - ['status', '=', 'open'], // Indexed - 'and', - ['priority', '=', 'high'] // Indexed -] +filters: { + status: 'open', // Indexed + priority: 'high' // Indexed +} ``` **Impact:** Can improve query speed by 10-100x depending on dataset size. @@ -100,7 +98,7 @@ filters: [ ```typescript // Returns all records (dangerous) await app.object('order').find({ - filters: [['year', '=', 2024]] + filters: { year: 2024 } }); ``` @@ -108,7 +106,7 @@ await app.object('order').find({ ```typescript // Paginated results (safe and fast) await app.object('order').find({ - filters: [['year', '=', 2024]], + filters: { year: 2024 }, limit: 50, skip: page * 50, sort: [['created_at', 'desc']] @@ -431,7 +429,7 @@ const tasksWithAssignee = await Promise.all( const tasks = await taskRepo.find(); const userIds = tasks.map(t => t.assignee_id); const users = await userRepo.find({ - filters: [['id', 'in', userIds]] + filters: { id: { $in: userIds } } }); const userMap = new Map(users.map(u => [u.id, u])); const tasksWithAssigneeBatched = tasks.map((task) => ({ @@ -516,7 +514,7 @@ query Dashboard { // Hook: Automatically assign to least-busy team member async function autoAssign(task: any) { const members = await app.object('user').aggregate({ - filters: [['team_id', '=', task.team_id]], + filters: { team_id: task.team_id }, groupBy: ['id', 'name'], aggregate: [ { func: 'count', field: 'tasks.id', alias: 'task_count' } @@ -581,7 +579,7 @@ AND priority = 'high' AND invalid_function(status); **Bad (Application-level aggregation):** ```typescript const orders = await app.object('order').find({ - filters: [['status', '=', 'paid']] + filters: { status: 'paid' } }); // Slow: Iterating in application code @@ -594,7 +592,7 @@ for (const order of orders) { **Good (Database-level aggregation):** ```typescript const stats = await app.object('order').aggregate({ - filters: [['status', '=', 'paid']], + filters: { status: 'paid' }, groupBy: ['customer_id'], aggregate: [ { func: 'sum', field: 'amount', alias: 'total_revenue' }, @@ -620,7 +618,7 @@ const uniqueCustomers = [...new Set(orders.map(o => o.customer_id))]; **Good:** ```typescript const uniqueCustomers = await app.object('order').distinct('customer_id', { - filters: [['year', '=', 2024]] + filters: { year: 2024 } }); ``` @@ -661,18 +659,19 @@ indexes: **Bad (OR requires multiple index scans):** ```typescript -filters: [ - ['status', '=', 'pending'], - 'or', - ['status', '=', 'active'] -] +filters: { + $or: [ + { status: 'pending' }, + { status: 'active' } + ] +} ``` **Good (IN uses single index scan):** ```typescript -filters: [ - ['status', 'in', ['pending', 'active']] -] +filters: { + status: { $in: ['pending', 'active'] } +} ``` **Impact:** 2-5x faster for large tables. @@ -693,7 +692,7 @@ await app.object('order').find({ **Good (Cursor pagination using last ID):** ```typescript await app.object('order').find({ - filters: [['id', '>', lastSeenId]], + filters: { id: { $gt: lastSeenId } }, limit: 50, sort: [['id', 'asc']] }); @@ -754,7 +753,7 @@ GET /api/data/tasks?status=active&limit=20 **After:** ```typescript await app.object('task').find({ - filters: [['status', '=', 'active']], + filters: { status: 'active' }, limit: 20 }); ``` @@ -764,7 +763,7 @@ await app.object('task').find({ **Before:** ```typescript const tasks = await app.object('task').find({ - filters: [['status', '=', 'active']], + filters: { status: 'active' }, expand: { assignee: { fields: ['name', 'email'] } } diff --git a/content/docs/data-access/index.mdx b/content/docs/data-access/index.mdx index 7c95dacb..d9003fd3 100644 --- a/content/docs/data-access/index.mdx +++ b/content/docs/data-access/index.mdx @@ -61,11 +61,10 @@ const ctx = app.createContext({ isSystem: true }); // Query data with filters const products = await ctx.object('product').find({ fields: ['name', 'price', 'category'], - filters: [ - ['category', '=', 'electronics'], - 'and', - ['price', '<', 1000] - ], + filters: { + category: 'electronics', + price: { $lt: 1000 } + }, sort: [['price', 'asc']], top: 10 }); diff --git a/content/docs/data-access/querying.mdx b/content/docs/data-access/querying.mdx index 834064f4..34bcef70 100644 --- a/content/docs/data-access/querying.mdx +++ b/content/docs/data-access/querying.mdx @@ -15,10 +15,10 @@ The `find` method recovers a list of records matching specific criteria. ```typescript const products = await app.object('product').find({ - filters: [ - ['category', '=', 'electronics'], - ['price', '>', 500] - ], + filters: { + category: 'electronics', + price: { $gt: 500 } + }, fields: ['name', 'price', 'category'], sort: ['-price'], // Descending skip: 0, @@ -28,19 +28,26 @@ const products = await app.object('product').find({ ### Filters -Filters are defined as a 2D array: `[[ field, operator, value ]]`. +Filters use an object-based syntax with implicit equality and operator objects. **Implicit AND**: ```typescript -filters: [ - ['status', '=', 'active'], - ['stock', '>', 0] -] +filters: { + status: 'active', + stock: { $gt: 0 } +} // SQL: WHERE status = 'active' AND stock > 0 ``` **Explicit OR**: -Use the `_or` special operator in complex filters (see advanced docs). +```typescript +filters: { + $or: [ + { status: 'active' }, + { featured: true } + ] +} +``` ### Sorting @@ -66,13 +73,13 @@ Updates are always bulk operations targeted by `filters`. To update a single rec ```typescript // Update specific record await app.object('user').update( - { filters: [['_id', '=', '123']] }, // Target + { filters: { _id: '123' } }, // Target { doc: { status: 'active' } } // Change ); // Bulk update await app.object('product').update( - { filters: [['stock', '=', 0]] }, + { filters: { stock: 0 } }, { doc: { status: 'out_of_stock' } } ); ``` @@ -82,7 +89,7 @@ await app.object('product').update( ```typescript // Delete specific record await app.object('user').delete({ - filters: [['_id', '=', '123']] + filters: { _id: '123' } }); ``` @@ -141,9 +148,9 @@ There are two ways to filter based on relationships: Find tasks where the *project's status* is active. *(Note: Requires a driver that supports SQL Joins)* ```typescript -filters: [ - ['project.status', '=', 'active'] -] +filters: { + 'project.status': 'active' +} ``` **B. Filter the Expanded List** @@ -152,7 +159,7 @@ Find projects, but only include *completed* tasks in the expansion. app.object('project').find({ expand: { tasks: { - filters: [['status', '=', 'completed']] + filters: { status: 'completed' } } } }) @@ -165,7 +172,7 @@ ObjectQL supports SQL-like aggregation via the `aggregate()` method on the repos ```typescript const stats = await app.object('order').aggregate({ // 1. Filter first - filters: [['status', '=', 'paid']], + filters: { status: 'paid' }, // 2. Group by specific fields groupBy: ['customer_id'], diff --git a/content/docs/data-access/sdk.mdx b/content/docs/data-access/sdk.mdx index c9d2921c..bb20c9bb 100644 --- a/content/docs/data-access/sdk.mdx +++ b/content/docs/data-access/sdk.mdx @@ -45,7 +45,7 @@ console.log(response.meta); // Pagination metadata // With filters and pagination const activeUsers = await dataClient.list('users', { - filter: [['status', '=', 'active']], + filter: { status: 'active' }, sort: [['created_at', 'desc']], limit: 20, skip: 0, @@ -62,7 +62,7 @@ interface User { } const users = await dataClient.list('users', { - filter: [['status', '=', 'active']] + filter: { status: 'active' } }); users.items?.forEach(user => { @@ -127,7 +127,7 @@ console.log(updated.updated_at); // New timestamp ```typescript const result = await dataClient.updateMany('users', { - filters: [['status', '=', 'pending']], + filters: { status: 'pending' }, data: { status: 'active' } }); ``` @@ -143,7 +143,7 @@ console.log(result.success); ```typescript const result = await dataClient.deleteMany('users', { - filters: [['created_at', '<', '2023-01-01']] + filters: { created_at: { $lt: '2023-01-01' } } }); console.log(result.deleted_count); @@ -152,9 +152,9 @@ console.log(result.deleted_count); ### Count Records ```typescript -const countResult = await dataClient.count('users', [ - ['status', '=', 'active'] -]); +const countResult = await dataClient.count('users', { + status: 'active' +}); console.log(countResult.count); ``` @@ -336,7 +336,7 @@ interface User { function UserList() { const { data: users, loading, error } = useObjectData('users', { - filter: [['status', '=', 'active']], + filter: { status: 'active' }, sort: [['name', 'asc']] }); @@ -478,35 +478,33 @@ export function useObjectData(objectName: string, params?: any) { ### Complex Filter Expressions ```typescript -// AND condition +// AND condition (implicit) const result = await dataClient.list('orders', { - filter: [ - 'and', - ['status', '=', 'pending'], - ['total', '>', 100] - ] + filter: { + status: 'pending', + total: { $gt: 100 } + } }); // OR condition const result = await dataClient.list('users', { - filter: [ - 'or', - ['role', '=', 'admin'], - ['role', '=', 'manager'] - ] + filter: { + $or: [ + { role: 'admin' }, + { role: 'manager' } + ] + } }); // Nested conditions const result = await dataClient.list('orders', { - filter: [ - 'and', - ['status', '=', 'pending'], - [ - 'or', - ['priority', '=', 'high'], - ['total', '>', 1000] + filter: { + status: 'pending', + $or: [ + { priority: 'high' }, + { total: { $gt: 1000 } } ] - ] + } }); ``` diff --git a/content/docs/getting-started/index.mdx b/content/docs/getting-started/index.mdx index 5aa796f7..a6d2ccdf 100644 --- a/content/docs/getting-started/index.mdx +++ b/content/docs/getting-started/index.mdx @@ -156,7 +156,7 @@ async function main() { // 4. Query Data const tasks = await todoRepo.find({ - filters: [['completed', '=', false]] + filters: { completed: false } }); console.log('Pending Tasks:', tasks); } diff --git a/content/docs/logic/formulas.mdx b/content/docs/logic/formulas.mdx index 6b36d934..06e9f430 100644 --- a/content/docs/logic/formulas.mdx +++ b/content/docs/logic/formulas.mdx @@ -385,10 +385,10 @@ rules: validator: | async function validate(record, context) { const customer = await context.api.findOne('customers', record.customer_id); - const totalOrders = await context.api.sum('orders', 'amount', [ - ['customer_id', '=', record.customer_id], - ['status', 'in', ['pending', 'processing']] - ]); + const totalOrders = await context.api.sum('orders', 'amount', { + customer_id: record.customer_id, + status: { $in: ['pending', 'processing'] } + }); return (totalOrders + record.amount) <= customer.credit_limit; } @@ -546,33 +546,31 @@ condition: Used in query language for filtering records: ```javascript -// Basic filter - [field, operator, value] -["status", "=", "active"] +// Basic filter - object with implicit equality +{ status: 'active' } -// Multiple filters with AND -[ - ["status", "=", "active"], - "and", - ["amount", ">", 1000] -] +// Multiple filters with AND (implicit) +{ + status: 'active', + amount: { $gt: 1000 } +} // Multiple filters with OR -[ - ["priority", "=", "high"], - "or", - ["amount", ">", 50000] -] +{ + $or: [ + { priority: 'high' }, + { amount: { $gt: 50000 } } + ] +} // Complex nested conditions -[ - ["status", "=", "active"], - "and", - [ - ["priority", "=", "high"], - "or", - ["amount", ">", 10000] +{ + status: 'active', + $or: [ + { priority: 'high' }, + { amount: { $gt: 10000 } } ] -] +} ``` ## Best Practices @@ -665,7 +663,7 @@ rules: async function validateBatch(records, context) { const skus = records.map(r => r.sku); const inventory = await context.api.find('inventory', { - filters: [['sku', 'in', skus]] + filters: { sku: { $in: skus } } }); return records.map(record => { diff --git a/content/docs/modeling/migrations.mdx b/content/docs/modeling/migrations.mdx index 240b14a1..5f85cb8c 100644 --- a/content/docs/modeling/migrations.mdx +++ b/content/docs/modeling/migrations.mdx @@ -28,7 +28,7 @@ The MongoDB driver now automatically maps between `id` (API) and `_id` (database ```typescript // MongoDB-specific code const query = { - filters: [['_id', '=', 'user-123']] + filters: { _id: 'user-123' } }; ``` @@ -36,7 +36,7 @@ const query = { ```typescript // Works with both MongoDB and SQL const query = { - filters: [['id', '=', 'user-123']] + filters: { id: 'user-123' } }; ``` @@ -147,7 +147,7 @@ The MongoDB driver maintains **full backward compatibility** for `_id` usage: ```typescript // Legacy code - fully supported for backward compatibility const query = { - filters: [['_id', '=', 'user-123']], + filters: { _id: 'user-123' }, sort: [['_id', 'desc']], fields: ['_id', 'name', 'email'] }; @@ -196,7 +196,7 @@ assert(user._id === undefined); // Should not have _id ### 2. Find Operations ```typescript const users = await app.find('users', { - filters: [['id', '=', 'test-123']] + filters: { id: 'test-123' } }); assert(users[0].id === 'test-123'); ``` diff --git a/content/docs/reference/api/client-sdk.mdx b/content/docs/reference/api/client-sdk.mdx index c9d2921c..dbe2e89e 100644 --- a/content/docs/reference/api/client-sdk.mdx +++ b/content/docs/reference/api/client-sdk.mdx @@ -127,7 +127,7 @@ console.log(updated.updated_at); // New timestamp ```typescript const result = await dataClient.updateMany('users', { - filters: [['status', '=', 'pending']], + filters: { status: 'pending' }, data: { status: 'active' } }); ``` @@ -143,7 +143,7 @@ console.log(result.success); ```typescript const result = await dataClient.deleteMany('users', { - filters: [['created_at', '<', '2023-01-01']] + filters: { created_at: { $lt: '2023-01-01' } } }); console.log(result.deleted_count); @@ -152,9 +152,9 @@ console.log(result.deleted_count); ### Count Records ```typescript -const countResult = await dataClient.count('users', [ - ['status', '=', 'active'] -]); +const countResult = await dataClient.count('users', { + status: 'active' +}); console.log(countResult.count); ``` diff --git a/content/docs/reference/api/examples.mdx b/content/docs/reference/api/examples.mdx index d07cb436..47335792 100644 --- a/content/docs/reference/api/examples.mdx +++ b/content/docs/reference/api/examples.mdx @@ -66,11 +66,10 @@ const response = await fetch('/api/objectql', { { func: 'count', field: 'id', alias: 'order_count' }, { func: 'avg', field: 'amount', alias: 'avg_order_value' } ], - filters: [ - ['status', '=', 'paid'], - 'and', - ['created_at', '>=', '2024-01-01'] - ], + filters: { + status: 'paid', + created_at: { $gte: '2024-01-01' } + }, sort: [['month', 'asc'], ['revenue', 'desc']] } }) @@ -99,19 +98,17 @@ const response = await fetch('/api/objectql', { object: 'customers', args: { fields: ['name', 'email', 'vip_level', 'total_spent'], - filters: [ - ['vip_level', '>=', 'gold'], - 'and', - ['is_active', '=', true] - ], + filters: { + vip_level: { $gte: 'gold' }, + is_active: true + }, expand: { orders: { fields: ['order_no', 'amount', 'status'], - filters: [ - ['created_at', '>', '2024-01-01'], - 'and', - ['amount', '>', 1000] - ], + filters: { + created_at: { $gt: '2024-01-01' }, + amount: { $gt: 1000 } + }, sort: [['created_at', 'desc']], top: 5 } diff --git a/content/docs/reference/api/websocket.mdx b/content/docs/reference/api/websocket.mdx index 94cb3b0d..07d949b0 100644 --- a/content/docs/reference/api/websocket.mdx +++ b/content/docs/reference/api/websocket.mdx @@ -22,7 +22,7 @@ ws.onopen = () => { ws.send(JSON.stringify({ type: 'subscribe', object: 'orders', - filters: [["status", "=", "pending"]] + filters: { status: 'pending' } })); }; diff --git a/content/docs/reference/spec/validation.mdx b/content/docs/reference/spec/validation.mdx index 61e3f50e..07914160 100644 --- a/content/docs/reference/spec/validation.mdx +++ b/content/docs/reference/spec/validation.mdx @@ -698,7 +698,7 @@ rules: validator: | async function validate(record, context) { const inventory = await context.api.findOne('inventory', { - filters: [['sku', '=', record.sku]] + filters: { sku: record.sku } }); return inventory.available_quantity >= record.quantity; @@ -822,7 +822,7 @@ rules: // Validate multiple records in one query const skus = records.map(r => r.sku); const inventory = await context.api.find('inventory', { - filters: [['sku', 'in', skus]] + filters: { sku: { $in: skus } } }); // Return validation result for each record diff --git a/content/docs/server/microservices.mdx b/content/docs/server/microservices.mdx index 730def27..98ca33d3 100644 --- a/content/docs/server/microservices.mdx +++ b/content/docs/server/microservices.mdx @@ -52,7 +52,7 @@ Once initialized, the Gateway behaves exactly like a monolith. // Code running on Gateway // Transparently forwards request to User Service via HTTP const users = await app.object('user').find({ - filters: [['status', '=', 'active']] + filters: { status: 'active' } }); ``` diff --git a/examples/drivers/excel-demo/src/index.ts b/examples/drivers/excel-demo/src/index.ts index 5bf59fb1..da551106 100644 --- a/examples/drivers/excel-demo/src/index.ts +++ b/examples/drivers/excel-demo/src/index.ts @@ -138,25 +138,25 @@ async function demoSingleFileMode() { // Filter by role const admins = await driver.find('users', { - filters: [['role', '=', 'admin']] + filters: { role: 'admin' } }); console.log(`✓ Found ${admins.length} admin(s):`, admins.map(u => u.name).join(', ')); // Filter by age const youngUsers = await driver.find('users', { - filters: [['age', '<', 30]] + filters: { age: { $lt: 30 } } }); console.log(`✓ Found ${youngUsers.length} user(s) under 30:`, youngUsers.map(u => u.name).join(', ')); // Filter by department const engineers = await driver.find('users', { - filters: [['department', '=', 'Engineering']] + filters: { department: 'Engineering' } }); console.log(`✓ Found ${engineers.length} engineer(s):`, engineers.map(u => u.name).join(', ')); // Search by name const searchResults = await driver.find('users', { - filters: [['name', 'contains', 'li']] + filters: { name: { $contains: 'li' } } }); console.log(`✓ Search "li" found ${searchResults.length} user(s):`, searchResults.map(u => u.name).join(', ')); @@ -193,7 +193,7 @@ async function demoSingleFileMode() { // Update many const updateResult = await driver.updateMany( 'users', - [['department', '=', 'Engineering']], + { department: 'Engineering' }, { department: 'Tech' } ); console.log(`✓ Updated ${updateResult.modifiedCount} user(s) department to Tech`); @@ -204,7 +204,7 @@ async function demoSingleFileMode() { console.log(`✓ ${updatedUser1.name}: age=${updatedUser1.age}, email=${updatedUser1.email}`); const techUsers = await driver.find('users', { - filters: [['department', '=', 'Tech']] + filters: { department: 'Tech' } }); console.log(`✓ Users in Tech: ${techUsers.map(u => u.name).join(', ')}`); diff --git a/examples/drivers/fs-demo/src/index.ts b/examples/drivers/fs-demo/src/index.ts index 22b5cbf0..66c466ad 100644 --- a/examples/drivers/fs-demo/src/index.ts +++ b/examples/drivers/fs-demo/src/index.ts @@ -127,21 +127,21 @@ async function main() { // Find high priority projects const highPriority = await projects.find({ - filters: [['priority', '=', 'high']] + filters: { priority: 'high' } }); console.log(`🔥 High priority projects: ${highPriority.length}`); highPriority.forEach(p => console.log(` - ${p.name}`)); // Find in-progress projects const inProgress = await projects.find({ - filters: [['status', '=', 'in_progress']] + filters: { status: 'in_progress' } }); console.log(`\n⚡ In-progress projects: ${inProgress.length}`); inProgress.forEach(p => console.log(` - ${p.name}`)); // Find projects with budget > 40000 const largeBudget = await projects.find({ - filters: [['budget', '>', 40000]] + filters: { budget: { $gt: 40000 } } }); console.log(`\n💰 Projects with budget > $40,000: ${largeBudget.length}`); largeBudget.forEach(p => console.log(` - ${p.name}: $${p.budget.toLocaleString()}`)); @@ -163,7 +163,7 @@ async function main() { console.log(`\n📊 Aggregate Operations:\n`); const statusCount = await projects.count({ - filters: [['status', '=', 'in_progress']] + filters: { status: 'in_progress' } }); console.log(`In-progress projects: ${statusCount}`); diff --git a/examples/integrations/express-server/__tests__/data-api.test.ts b/examples/integrations/express-server/__tests__/data-api.test.ts index 696bae09..a1c6f716 100644 --- a/examples/integrations/express-server/__tests__/data-api.test.ts +++ b/examples/integrations/express-server/__tests__/data-api.test.ts @@ -213,7 +213,7 @@ describe('Data API', () => { op: 'find', object: 'task', args: { - filters: [['status', '=', 'pending']] + filters: { status: 'pending' } } }) .set('Accept', 'application/json'); diff --git a/examples/showcase/project-tracker/src/seed.ts b/examples/showcase/project-tracker/src/seed.ts index 6cc3a92b..2eee683b 100644 --- a/examples/showcase/project-tracker/src/seed.ts +++ b/examples/showcase/project-tracker/src/seed.ts @@ -50,7 +50,7 @@ async function main() { console.log("Querying Tasks..."); const tasks = await ctx.object('tasks').find({ - filters: [['project', '=', projectId]] + filters: { project: projectId } }); console.log("📊 Project Report:", JSON.stringify({ project, tasks }, null, 2)); diff --git a/packages/drivers/mongo/src/index.ts b/packages/drivers/mongo/src/index.ts index f4b84d98..8b1b463e 100644 --- a/packages/drivers/mongo/src/index.ts +++ b/packages/drivers/mongo/src/index.ts @@ -43,7 +43,7 @@ export interface CommandResult { * * The driver internally converts QueryAST format to MongoDB query format. */ -export class MongoDriver implements Driver, DriverInterface { +export class MongoDriver implements Driver { // Driver metadata (ObjectStack-compatible) public readonly name = 'MongoDriver'; public readonly version = '3.0.1'; @@ -52,7 +52,13 @@ export class MongoDriver implements Driver, DriverInterface { joins: false, fullTextSearch: true, jsonFields: true, - arrayFields: true + arrayFields: true, + queryFilters: true, + queryAggregations: true, + querySorting: true, + queryPagination: true, + queryWindowFunctions: false, + querySubqueries: false }; private client: MongoClient; diff --git a/packages/drivers/sdk/src/index.ts b/packages/drivers/sdk/src/index.ts index abb2d911..166b8378 100644 --- a/packages/drivers/sdk/src/index.ts +++ b/packages/drivers/sdk/src/index.ts @@ -142,7 +142,7 @@ function createTimeoutSignal(ms: number): AbortSignal { * * @version 4.0.0 - DriverInterface compliant */ -export class RemoteDriver implements Driver, DriverInterface { +export class RemoteDriver implements Driver { // Driver metadata (ObjectStack-compatible) public readonly name = 'RemoteDriver'; public readonly version = '4.0.0'; @@ -151,7 +151,13 @@ export class RemoteDriver implements Driver, DriverInterface { joins: false, fullTextSearch: false, jsonFields: true, - arrayFields: true + arrayFields: true, + queryFilters: true, + queryAggregations: true, + querySorting: true, + queryPagination: true, + queryWindowFunctions: false, + querySubqueries: false }; private rpcPath: string; diff --git a/packages/drivers/sql/src/index.ts b/packages/drivers/sql/src/index.ts index 9f172a8d..26328f55 100644 --- a/packages/drivers/sql/src/index.ts +++ b/packages/drivers/sql/src/index.ts @@ -46,7 +46,7 @@ export interface CommandResult { * * @version 4.0.0 - DriverInterface compliant */ -export class SqlDriver implements Driver, DriverInterface { +export class SqlDriver implements Driver { // Driver metadata (ObjectStack-compatible) public readonly name = 'SqlDriver'; public readonly version = '4.0.0'; @@ -55,7 +55,13 @@ export class SqlDriver implements Driver, DriverInterface { joins: true, fullTextSearch: false, jsonFields: true, - arrayFields: true + arrayFields: true, + queryFilters: true, + queryAggregations: true, + querySorting: true, + queryPagination: true, + queryWindowFunctions: true, + querySubqueries: true }; private knex: Knex; diff --git a/packages/foundation/types/src/driver.ts b/packages/foundation/types/src/driver.ts index 44dcf8e8..614c4b10 100644 --- a/packages/foundation/types/src/driver.ts +++ b/packages/foundation/types/src/driver.ts @@ -72,6 +72,12 @@ export interface Driver { fullTextSearch?: boolean; jsonFields?: boolean; arrayFields?: boolean; + queryFilters?: boolean; + queryAggregations?: boolean; + querySorting?: boolean; + queryPagination?: boolean; + queryWindowFunctions?: boolean; + querySubqueries?: boolean; }; // Core CRUD methods (existing) diff --git a/packages/objectstack/spec/src/index.ts b/packages/objectstack/spec/src/index.ts index 7582b83c..2a87d55d 100644 --- a/packages/objectstack/spec/src/index.ts +++ b/packages/objectstack/spec/src/index.ts @@ -287,6 +287,12 @@ export interface DriverInterface { fullTextSearch?: boolean; jsonFields?: boolean; arrayFields?: boolean; + queryFilters?: boolean; + queryAggregations?: boolean; + querySorting?: boolean; + queryPagination?: boolean; + queryWindowFunctions?: boolean; + querySubqueries?: boolean; }; /** Connect to the database */ connect?(): Promise;