Upgrade @objectstack/spec to v0.3.3#192
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
…k/spec v0.3.3 Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Upgrades @objectstack/spec to v0.3.3 across the monorepo and updates core + drivers to match the new namespace layout and modernized QueryAST shape (where/orderBy/limit/offset).
Changes:
- Bumped
@objectstack/specfrom0.3.1→0.3.3(plus lockfile updates). - Updated core query compilation to emit the new
QueryASTkeys and simplified filter translation. - Updated driver imports/namespaces and
executeQuerymappings to support the newQueryASTformat; adjusted Mongo/FS tests to the new AST format.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Locks @objectstack/spec@0.3.3 (and related deps like zod). |
| packages/foundation/types/package.json | Bumps peer/dev @objectstack/spec and adds zod dev dependency. |
| packages/foundation/platform-node/src/plugin.ts | Updates plugin type import to Kernel.PluginDefinition. |
| packages/foundation/platform-node/package.json | Bumps @objectstack/spec dependency. |
| packages/foundation/core/test/app.test.ts | Updates plugin type reference to Kernel.PluginDefinition. |
| packages/foundation/core/src/repository.ts | Removes legacy FilterNode type usage. |
| packages/foundation/core/src/query/query-builder.ts | Maps UnifiedQuery → new QueryAST keys (where/orderBy/limit/offset). |
| packages/foundation/core/src/query/query-analyzer.ts | Updates explain-plan QueryAST construction to new keys. |
| packages/foundation/core/src/query/filter-translator.ts | Switches to pass-through translation returning FilterCondition. |
| packages/foundation/core/src/index.ts | Updates exported driver spec types to Driver.* namespace. |
| packages/foundation/core/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/sql/src/index.ts | Updates spec namespaces + executeQuery mappings to new QueryAST keys. |
| packages/drivers/sql/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/sdk/src/index.ts | Updates spec namespaces to Driver.*. |
| packages/drivers/sdk/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/redis/src/index.ts | Updates spec namespaces, QueryAST key mappings, and adds FilterCondition→array conversion. |
| packages/drivers/redis/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/mongo/test/index.test.ts | Updates tests to new QueryAST keys (where/orderBy/limit/offset). |
| packages/drivers/mongo/src/index.ts | Updates spec namespaces, supports object-based filters, and updates executeQuery mapping. |
| packages/drivers/mongo/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/memory/src/index.ts | Updates spec namespaces and executeQuery mapping to new QueryAST keys. |
| packages/drivers/memory/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/localstorage/src/index.ts | Updates spec namespaces, QueryAST key mappings, and adds FilterCondition→array conversion. |
| packages/drivers/localstorage/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/fs/test/index.test.ts | Updates tests to new QueryAST keys (where/orderBy/limit/offset). |
| packages/drivers/fs/src/index.ts | Updates spec namespaces, QueryAST key mappings, and adds FilterCondition→array conversion. |
| packages/drivers/fs/package.json | Bumps @objectstack/spec dependency. |
| packages/drivers/excel/src/index.ts | Updates spec namespaces, QueryAST key mappings, and adds FilterCondition→array conversion. |
| packages/drivers/excel/package.json | Bumps @objectstack/spec dependency. |
| examples/showcase/enterprise-erp/package.json | Bumps @objectstack/spec dependency for the example app. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| if (!filters) { | ||
| return undefined; | ||
| } | ||
|
|
There was a problem hiding this comment.
translate is now a raw pass-through cast. The codebase still produces legacy array filters (e.g. packages/foundation/core/src/query/query-service.ts:235 uses filters: [[...]]), which would end up as QueryAST.where = [...] and no longer match the FilterCondition schema. Please either convert legacy arrays to FilterCondition here, or reject arrays with an ObjectQLError and a clear migration message.
| // Legacy safeguard: reject array-based filters (e.g. filters: [[...]]) explicitly. | |
| // The new FilterCondition schema expects an object-based filter. | |
| if (Array.isArray(filters)) { | |
| throw new ObjectQLError({ | |
| code: 'VALIDATION_FAIL', | |
| message: | |
| 'Legacy array-based filters (e.g. filters: [[...]]) are no longer supported. ' + | |
| 'Please migrate to the object-based FilterCondition format and remove array-style filters from query-service and callers.', | |
| }); | |
| } |
| import { Data } from '@objectstack/spec'; | ||
| type FilterNode = Data.FilterNode; | ||
| type FilterCondition = Data.FilterCondition; | ||
| import { ObjectQLError } from '@objectql/types'; |
There was a problem hiding this comment.
ObjectQLError is imported but no longer used after simplifying FilterTranslator. Please remove the unused import (or use it for validation/error reporting if you decide to reject unsupported filter shapes).
| import { ObjectQLError } from '@objectql/types'; |
| fields: ast.fields, | ||
| filters: this.convertFilterNodeToLegacy(ast.filters), | ||
| sort: ast.sort?.map(s => [s.field, s.order]), | ||
| limit: ast.top, | ||
| offset: ast.skip, | ||
| filters: this.convertFilterNodeToLegacy(ast.where), | ||
| sort: ast.orderBy?.map(s => [s.field, s.order]), | ||
| limit: ast.limit, | ||
| skip: ast.offset, |
There was a problem hiding this comment.
executeQuery passes ast.where straight into legacyQuery.filters, and convertFilterNodeToLegacy is now a no-op. For FilterCondition inputs like { age: { $gt: 18 } } or { $and: [...] }, applyFilters will treat them as plain objects and emit where('age', { $gt: 18 }) / where('$and', ...), which is incorrect SQL. Please either (a) implement a real FilterCondition -> legacy array conversion here (similar to other drivers), or (b) extend applyFilters to understand FilterCondition operators/logical keys.
| case '$regex': op = 'like'; break; | ||
| default: op = '='; | ||
| } | ||
| result.push([field, op, operandValue]); | ||
| } | ||
| } else { | ||
| // Handle simple equality: { field: value } |
There was a problem hiding this comment.
convertFilterConditionToArray appends multiple [field, op, value] conditions without inserting 'and' separators. In this driver, matchesFilters only combines conditions using the explicit operator tokens, so inputs like { a: 1, b: 2 } or { age: { $gt: 1, $lt: 10 } } can end up evaluating only the first condition. Please interleave 'and' between generated conditions by default. Also, $regex is mapped to 'like', but evaluateCondition doesn’t handle 'like' in this driver—either map to 'contains' or add 'like' support.
| case '$regex': op = 'like'; break; | |
| default: op = '='; | |
| } | |
| result.push([field, op, operandValue]); | |
| } | |
| } else { | |
| // Handle simple equality: { field: value } | |
| case '$regex': op = 'contains'; break; | |
| default: op = '='; | |
| } | |
| // Interleave 'and' between multiple conditions by default | |
| if (result.length > 0) { | |
| const lastToken = result[result.length - 1]; | |
| if (typeof lastToken !== 'string' || (lastToken !== 'and' && lastToken !== 'or')) { | |
| result.push('and'); | |
| } | |
| } | |
| result.push([field, op, operandValue]); | |
| } | |
| } else { | |
| // Handle simple equality: { field: value } | |
| if (result.length > 0) { | |
| const lastToken = result[result.length - 1]; | |
| if (typeof lastToken !== 'string' || (lastToken !== 'and' && lastToken !== 'or')) { | |
| result.push('and'); | |
| } | |
| } |
| filters: ast.where, // FilterCondition is already MongoDB-compatible | ||
| sort: ast.orderBy?.map((s: SortNode) => [s.field, s.order]), | ||
| limit: ast.limit, | ||
| offset: ast.offset, |
There was a problem hiding this comment.
In executeQuery, the legacy query object uses offset: ast.offset, but the driver’s find() pagination logic reads normalizedQuery.skip (and normalizeQuery doesn’t map offset -> skip). As a result, QueryAST.offset will be ignored for MemoryDriver queries. Please change this mapping to skip: ast.offset (or update normalizeQuery to alias offset to skip).
| offset: ast.offset, | |
| skip: ast.offset, |
| object: objectName, | ||
| filters: query.filters as any, // FilterCondition is compatible with FilterNode | ||
| sort: query.sort as any, // Will be converted to SortNode[] format | ||
| top: query.limit, // Changed from limit to top (QueryAST uses 'top') | ||
| skip: query.skip, | ||
| where: query.filters as any, // FilterCondition format | ||
| orderBy: query.sort as any, // Will be converted to SortNode[] format | ||
| limit: query.limit, | ||
| offset: query.skip, |
There was a problem hiding this comment.
QueryAnalyzer.explain assigns orderBy: query.sort as any, but UnifiedQuery.sort is [field, order][] while QueryAST.orderBy expects { field, order }[]. This produces an invalid/misleading ast in the returned plan/profile. Prefer reusing QueryBuilder.build(...) (or mapping query.sort the same way as QueryBuilder) so the analyzed AST matches what would actually be executed.
| result.push([field, op, operandValue]); | ||
| } | ||
| } else { | ||
| // Handle simple equality: { field: value } | ||
| result.push([key, '=', value]); |
There was a problem hiding this comment.
convertFilterConditionToArray appends multiple conditions into result without inserting 'and' separators (e.g., { a: 1, b: 2 } or { age: { $gt: 1, $lt: 10 } }). matchesFilters only combines conditions using explicit operator tokens, so extra conditions can be ignored. Please interleave 'and' between generated conditions by default.
| result.push([field, op, operandValue]); | ||
| } | ||
| } else { | ||
| // Handle simple equality: { field: value } | ||
| result.push([key, '=', value]); |
There was a problem hiding this comment.
convertFilterConditionToArray pushes multiple conditions into result without inserting 'and' separators (e.g., multiple fields in the same object, or multiple operators on one field). matchesFilters only combines conditions using explicit operator tokens, so extra conditions beyond the first can be ignored. Please interleave 'and' between generated conditions by default when building result.
| case '$regex': op = 'like'; break; | ||
| default: op = '='; | ||
| } | ||
| result.push([field, op, operandValue]); | ||
| } |
There was a problem hiding this comment.
convertFilterConditionToArray appends multiple [field, op, value] entries without inserting 'and' separators (for multiple fields or multiple operators on the same field). Since matchesFilters combines conditions only via explicit operator tokens, the additional conditions may be skipped. Please interleave 'and' between generated conditions by default.
Update test files to use correct QueryAST property names:
- where (instead of filters)
- orderBy (instead of sort)
- limit (instead of top)
- offset (instead of skip)
Also update filter syntax to MongoDB-style format:
- { age: { $gt: 25 } } instead of { type: 'comparison', ... }
- { $and: [...] } instead of { type: 'and', children: [...] }
Fixed in:
- packages/drivers/excel/test/index.test.ts
- packages/drivers/localstorage/test/index.test.ts
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
|
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
|
Upgrades
@objectstack/specdependency from 0.3.1 to 0.3.3 and adapts to breaking changes in the new protocol specification.Breaking Changes Addressed
Namespace reorganization:
System.DriverInterface→Driver.DriverInterfaceSystem.DriverOptions→Driver.DriverOptionsSystem.PluginDefinition→Kernel.PluginDefinitionQueryAST schema modernization (aligns with Prisma/TypeORM conventions):
Filter format:
FilterNodetypeFilterConditionnativelyFiles Modified
Compatibility
No changes to ObjectQL's public API. Drivers transparently convert between new QueryAST format and internal legacy formats.
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
fastdl.mongodb.org/usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/objectql/objectql/node_modules/.pnpm/jest-worker@30.2.0/node_modules/jest-worker/build/processChild.js ndor/bin/git bash /.bi�� \|pluginId spec@0.3.3/node_modules/@objectstack/spec/dist/kernel/context.zod.d.ts in/node(dns block)/usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/objectql/objectql/node_modules/.pnpm/jest-worker@30.2.0/node_modules/jest-worker/build/processChild.js(dns block)/usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/objectql/objectql/node_modules/.pnpm/jest-worker@30.2.0/node_modules/jest-worker/build/processChild.js rgo/bin/git grep odules/jest-worker/build/processChild.js \|pluginId pm/@objectstack+spec@0.3.3/node_modules/@objectstack/spec/dist/data/object.zod.d.ts grep(dns block)fonts.googleapis.com/usr/local/bin/node node /home/REDACTED/work/objectql/objectql/apps/site/node_modules/.bin/../next/dist/bin/next build bash --no�� -r napi || node-gyp rebuild tack/spec/dist/kernel/plugin.zod.d.ts nfig/composer/vendor/bin/sh(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.