Modernize query filter syntax to object-based DSL#162
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Replace FilterExpression array syntax with FilterCondition object syntax - Update UnifiedQuery to use Filter (FilterCondition) type - Implement filter translation from new object syntax to legacy array format - Update all API types to use new Filter type - Add operator mapping: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $contains, etc. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Detect when filters are already in legacy array format - Pass through array filters without conversion - All core tests passing (276 tests) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Add 14 tests for new object-based filter syntax - Test all operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin - Test logical operators: $and, $or, nested combinations - Test implicit equality and mixed syntax - Test backward compatibility with legacy array syntax - All 290 core tests passing Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Complete reference for new object-based filter syntax - Migration guide from legacy array-based syntax - Real-world examples for common use cases - Operator reference table - TypeScript support examples - Best practices and performance considerations Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Remove incomplete $not operator implementation - Throw clear error if $not is used - Update documentation to reflect limitation - Recommend using $ne for field-level negation instead - All 290 tests still passing Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Fix multiple operators on same field (always AND them together) - Remove $not from type documentation - Clarify range operators use $gte/$lte not $between - All 290 tests passing Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
There was a problem hiding this comment.
Pull request overview
This PR modernizes ObjectQL's query filter syntax from array-based to object-based DSL, following the @objectstack/spec FilterCondition specification while maintaining backward compatibility.
Changes:
- Type system updated to use FilterCondition from spec instead of array-based FilterExpression
- Core translation layer converts modern object syntax to legacy FilterNode format for drivers
- Comprehensive test suite added with 14 new tests covering operator combinations
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/foundation/types/src/query.ts | Replaces FilterExpression with Filter (FilterCondition) type and adds comprehensive documentation |
| packages/foundation/types/src/api.ts | Updates API interfaces to use new Filter type |
| packages/foundation/core/test/filter-syntax.test.ts | Adds test coverage for modern filter syntax translation |
| packages/foundation/core/src/repository.ts | Implements translateFilters() and convertFilterToNode() for syntax conversion |
| packages/drivers/sdk/src/index.ts | Updates SDK to use Filter type |
| docs/filter-syntax.md | Complete documentation of new syntax with migration guide |
| const [op, opValue] = entries[i]; | ||
|
|
||
| // Add 'and' before each operator (except the very first node) | ||
| if (nodes.length > 0 || i > 0) { |
There was a problem hiding this comment.
The condition nodes.length > 0 || i > 0 could be simplified. Since we're adding 'and' before each operator except the very first node, consider restructuring to check if this is not the first overall node. The current logic may add an extra 'and' operator when processing the first field operator if nodes already contains logical operators.
ObjectQL's filter syntax required comprehensive modernization from array-based to object-based DSL per @objectstack/spec FilterCondition.
Changes
Type System (
@objectql/types)FilterExpressionarray type withFilterConditionobject type from specUnifiedQuery.filterssignature and all dependent API typesCore Translation (
@objectql/core)translateFilters()converting FilterCondition → FilterNode arraysconvertFilterToNode()handling nested logical operators$eq,$ne,$gt,$gte,$lt,$lte,$in,$nin,$contains,$startsWith,$endsWith,$null,$exist$and,$orlogical compositionTesting
Documentation
Example
Architecture
Translation happens in core repository layer - drivers receive legacy FilterNode format unchanged. Zero driver modifications required.
Limitation:
$notoperator throws error (legacy format incompatible). Use$nefor field negation.Security: CodeQL scan clean, type-safe implementation.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.