Migrate @objectql/types to use @objectstack/spec as protocol constitution#135
Migrate @objectql/types to use @objectstack/spec as protocol constitution#135huangyiirene merged 8 commits intomainfrom
Conversation
…ql/types Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…minLength, maxLength) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
There was a problem hiding this comment.
Pull request overview
This PR migrates the type system to use @objectstack/spec v0.1.1 as the single source of truth for protocol definitions, eliminating duplicate type definitions and establishing a clean separation between protocol (wire format) and runtime (implementation) types.
Changes:
- Refactored
@objectql/typesto import and extend protocol types from@objectstack/specrather than duplicating definitions - Standardized field type and property naming to match protocol conventions (
auto_number→autonumber,max_length→maxLength) - Updated core utilities, GraphQL adapter, metadata endpoints, and CLI tools to use protocol-compliant naming
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/foundation/types/package.json | Added @objectstack/spec dependency and temporarily disabled JSON schema generation |
| packages/foundation/types/src/index.ts | Added documentation explaining the protocol/runtime type relationship |
| packages/foundation/types/src/field.ts | Refactored to import protocol types and extend with runtime-specific properties |
| packages/foundation/types/src/object.ts | Refactored to import ServiceObject from spec and extend with runtime features |
| packages/foundation/types/src/action.ts | Refactored to import Action from spec and extend with runtime execution capabilities |
| packages/foundation/core/src/util.ts | Updated to use protocol-compliant property names (maxLength) |
| packages/foundation/core/test/util.test.ts | Updated test assertions to match new property names |
| packages/runtime/server/src/metadata.ts | Updated metadata serialization to use protocol-compliant names |
| packages/runtime/server/src/adapters/graphql.ts | Updated field type mapping from auto_number to autonumber |
| packages/tools/cli/src/commands/generate.ts | Updated TypeScript mapping from auto_number to autonumber |
| packages/tools/cli/src/commands/sync.ts | Updated database introspection to use maxLength property |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| description?: string; | ||
|
|
||
| /** The data type of the field. */ | ||
| export interface FieldConfig extends Omit<Field, 'type' | 'options' | 'required' | 'multiple' | 'unique' | 'deleteBehavior' | 'hidden' | 'readonly' | 'encryption' | 'index' | 'externalId'> { |
There was a problem hiding this comment.
The Omit list contains 11 properties being excluded from the base Field type. This creates a tight coupling to the protocol definition and makes the interface fragile - any changes to the protocol's Field interface could silently break this contract. Consider using a Pick approach to explicitly declare which protocol properties are inherited, or document why each property needs to be re-declared.
There was a problem hiding this comment.
Added detailed documentation explaining each omitted property and why it needs to be re-declared (optionality differences, type extensions). This documents the contract explicitly rather than leaving it implicit. See commit 9f1b180.
| /** | ||
| * Reference to another object for lookup/master_detail fields. | ||
| * Specifies the target object name for relationship fields. | ||
| * @deprecated Use 'reference' from SpecField instead |
There was a problem hiding this comment.
This property is marked as deprecated in favor of the protocol's reference field, but there's no migration path or guidance provided. Consider adding a comment explaining how to migrate from reference_to to reference, or implement a getter/setter that maps between the two to ease the transition.
| * @deprecated Use 'reference' from SpecField instead | |
| * | |
| * @deprecated Legacy alias for the protocol-level {@link SpecField.reference} field. | |
| * | |
| * Migration guidance: | |
| * - New schemas MUST use the `reference` field defined on SpecField (wire protocol) instead of `reference_to`. | |
| * - During migration, engines and tooling SHOULD: | |
| * - Treat `reference_to` as a fallback alias for `reference` (i.e., if `reference` is undefined and `reference_to` | |
| * is defined, behave as though `reference` were set to the same value). | |
| * - Prefer the protocol `reference` value when both are present. | |
| * | |
| * This property is retained only for backward compatibility with older *.object.yml definitions and may be removed | |
| * in a future major version once all callers have migrated to `reference`. |
There was a problem hiding this comment.
Added comprehensive migration guide with YAML examples showing the old (deprecated) pattern vs. the new protocol-compliant pattern. The guide explains the fallback behavior and timeline for removal. See commit 9f1b180.
| * Regular expression pattern for validation. | ||
| * @deprecated Use validation.pattern instead | ||
| */ | ||
| regex?: string; |
There was a problem hiding this comment.
This property is marked as deprecated in favor of validation.pattern, but it's also included again inside the validation object (line 230 has regex as an alias for pattern). This creates ambiguity about which property should be used. Consider removing the deprecated top-level property entirely or providing a clear migration timeline.
There was a problem hiding this comment.
Removed both the top-level deprecated regex property and the validation.regex alias to eliminate ambiguity. Now only validation.pattern is supported. Updated validator.ts and metadata.ts accordingly. See commit 9f1b180.
| if (foreignKey) { | ||
| // This is a lookup field | ||
| fieldConfig = { | ||
| name: column.name, |
There was a problem hiding this comment.
The name property is now explicitly set in both lookup and regular field configurations. This is redundant since the comment on line 114 in the original code states 'If defined within an object map, this is often automatically populated from the key.' Consider documenting why explicit name assignment is now required, or if this is needed for protocol compliance.
There was a problem hiding this comment.
Added clarifying comments explaining that explicit name assignment is required when creating FieldConfig programmatically (as in database introspection). The auto-population behavior applies only to YAML definitions where the Record key becomes the field name. See commit 9f1b180.
| const fieldType = mapDatabaseTypeToFieldType(column.type); | ||
|
|
||
| fieldConfig = { | ||
| name: column.name, |
There was a problem hiding this comment.
The name property is now explicitly set in both lookup and regular field configurations. This is redundant since the comment on line 114 in the original code states 'If defined within an object map, this is often automatically populated from the key.' Consider documenting why explicit name assignment is now required, or if this is needed for protocol compliance.
There was a problem hiding this comment.
Added clarifying comments explaining that explicit name assignment is required when creating FieldConfig programmatically (as in database introspection). The auto-population behavior applies only to YAML definitions where the Record key becomes the field name. See commit 9f1b180.
…mpilation errors The @objectstack/spec package requires name and label fields on the Field type, but when fields are defined in ObjectConfig.fields as a Record<string, FieldConfig>, the name is inferred from the record key. This change makes name and label optional in FieldConfig to match this usage pattern. Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
|
@copilot fix |
…ve ambiguous deprecated properties Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
Migration to @objectstack/spec as Protocol Constitution
✅ Implementation Complete
This PR successfully migrates
@objectql/typesto use@objectstack/spec(v0.1.1) as the single source of truth for all metadata/AST interfaces.Implementation Checklist
@objectstack/specexports and identify overlaps with@objectql/typespackages/foundation/types/package.jsonto add@objectstack/specdependencypackages/foundation/types/src/object.tspackages/foundation/types/src/field.tspackages/foundation/types/src/action.tspackages/foundation/types/src/index.tsto re-export typespackages/foundation/coreresulting from the migrationChanges Summary
Phase 1: Core Type Integration
packages/foundation/types/package.jsonField,FieldTypeandSelectOptionfrom specServiceObjectandIndexSchemafrom specActionfrom specPhase 2: Protocol Alignment
auto_number→autonumber(aligned with spec)min_length/max_length→minLength/maxLength(aligned with spec camelCase)namefield to generated FieldConfig objectsmax_lengthtomaxLengthautonumberautonumbermaxLengthmaxLengthinstead ofmax_lengthPhase 3: PR Review Feedback (Latest)
reference_to→referencemigrationregexproperty (deprecated in favor ofvalidation.pattern)validation.regexalias to eliminate ambiguityvalidation.patternnameproperty usage:namemust be set explicitly (programmatic creation)Key Principles Applied
@objectstack/specTest Results
Architecture Notes
The migration establishes a clean separation:
This architecture ensures:
Original prompt
@objectstack/spec(v0.1.1) is now the "Constitution" for all Metadata/AST interfaces. #134💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.