-
Notifications
You must be signed in to change notification settings - Fork 0
Migrate @objectql/types to use @objectstack/spec as protocol constitution #135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
24be696
8c60f19
07b8bce
9ff88f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,7 @@ export function convertIntrospectedSchemaToObjects( | |
| if (foreignKey) { | ||
| // This is a lookup field | ||
| fieldConfig = { | ||
| name: column.name, | ||
| type: 'lookup', | ||
| reference_to: foreignKey.referencedTable, | ||
| label: toTitleCase(column.name), | ||
|
|
@@ -121,6 +122,7 @@ export function convertIntrospectedSchemaToObjects( | |
| const fieldType = mapDatabaseTypeToFieldType(column.type); | ||
|
|
||
| fieldConfig = { | ||
| name: column.name, | ||
|
||
| type: fieldType, | ||
| label: toTitleCase(column.name), | ||
| required: !column.nullable | ||
|
|
@@ -133,7 +135,7 @@ export function convertIntrospectedSchemaToObjects( | |
|
|
||
| // Add max length for text fields | ||
| if (column.maxLength && (fieldType === 'text' || fieldType === 'textarea')) { | ||
| fieldConfig.max_length = column.maxLength; | ||
| fieldConfig.maxLength = column.maxLength; | ||
| } | ||
|
|
||
| // Add default value | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,11 +6,26 @@ | |||||||||||||||||||||||||||
| * LICENSE file in the root directory of this source tree. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import { FieldValidation, ValidationAiContext } from './validation'; | ||||||||||||||||||||||||||||
| // Import types from the Protocol Constitution (@objectstack/spec) | ||||||||||||||||||||||||||||
| import type { FieldType as ProtocolFieldType, Field, SelectOption as SpecSelectOption } from '@objectstack/spec'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Re-export Protocol Types from the Constitution | ||||||||||||||||||||||||||||
| * These are the wire-protocol standard types defined in @objectstack/spec | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export type { Field as SpecField, SpecSelectOption, ProtocolFieldType }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * RUNTIME-SPECIFIC TYPES | ||||||||||||||||||||||||||||
| * The following types extend or complement the Protocol Constitution | ||||||||||||||||||||||||||||
| * with runtime-specific properties that don't belong in the wire protocol. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Attachment field data structure for file and image types. | ||||||||||||||||||||||||||||
| * Stores metadata about uploaded files, with actual file content stored separately. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * This is a RUNTIME type - not part of the wire protocol. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export interface AttachmentData { | ||||||||||||||||||||||||||||
| /** Unique identifier for this file */ | ||||||||||||||||||||||||||||
|
|
@@ -41,6 +56,8 @@ export interface AttachmentData { | |||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Image-specific attachment data with additional metadata. | ||||||||||||||||||||||||||||
| * Extends AttachmentData with image-specific properties. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * This is a RUNTIME type - not part of the wire protocol. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export interface ImageAttachmentData extends AttachmentData { | ||||||||||||||||||||||||||||
| /** Image width in pixels */ | ||||||||||||||||||||||||||||
|
|
@@ -61,111 +78,89 @@ export interface ImageAttachmentData extends AttachmentData { | |||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Represents the supported field data types in the ObjectQL schema. | ||||||||||||||||||||||||||||
| * These types determine how data is stored, validated, and rendered. | ||||||||||||||||||||||||||||
| * Runtime Field Type | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * - `text`: Simple string. | ||||||||||||||||||||||||||||
| * - `textarea`: Long string. | ||||||||||||||||||||||||||||
| * - `select`: Choice from a list. | ||||||||||||||||||||||||||||
| * - `lookup`: Relationship to another object. | ||||||||||||||||||||||||||||
| * - `file`: File attachment. Value stored as AttachmentData (single) or AttachmentData[] (multiple). | ||||||||||||||||||||||||||||
| * - `image`: Image attachment. Value stored as ImageAttachmentData (single) or ImageAttachmentData[] (multiple). | ||||||||||||||||||||||||||||
| * Extends the Protocol FieldType with runtime-specific types. | ||||||||||||||||||||||||||||
| * The Protocol Constitution defines the core field types. | ||||||||||||||||||||||||||||
| * We add runtime-specific types like 'vector', 'grid', 'location', 'object' here. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export type FieldType = | ||||||||||||||||||||||||||||
| | 'text' | ||||||||||||||||||||||||||||
| | 'textarea' | ||||||||||||||||||||||||||||
| | 'markdown' | ||||||||||||||||||||||||||||
| | 'html' | ||||||||||||||||||||||||||||
| | 'select' | ||||||||||||||||||||||||||||
| | 'date' | ||||||||||||||||||||||||||||
| | 'datetime' | ||||||||||||||||||||||||||||
| | 'time' | ||||||||||||||||||||||||||||
| | 'number' | ||||||||||||||||||||||||||||
| | 'currency' | ||||||||||||||||||||||||||||
| | 'percent' | ||||||||||||||||||||||||||||
| | 'boolean' | ||||||||||||||||||||||||||||
| | 'email' | ||||||||||||||||||||||||||||
| | 'phone' | ||||||||||||||||||||||||||||
| | 'url' | ||||||||||||||||||||||||||||
| | 'image' | ||||||||||||||||||||||||||||
| | 'file' | ||||||||||||||||||||||||||||
| | 'location' | ||||||||||||||||||||||||||||
| | 'lookup' | ||||||||||||||||||||||||||||
| | 'master_detail' | ||||||||||||||||||||||||||||
| | 'password' | ||||||||||||||||||||||||||||
| | 'formula' | ||||||||||||||||||||||||||||
| | 'summary' | ||||||||||||||||||||||||||||
| | 'auto_number' | ||||||||||||||||||||||||||||
| | 'object' | ||||||||||||||||||||||||||||
| | 'vector' | ||||||||||||||||||||||||||||
| | 'grid'; | ||||||||||||||||||||||||||||
| | ProtocolFieldType | ||||||||||||||||||||||||||||
| | 'location' // Runtime: Geographic location | ||||||||||||||||||||||||||||
| | 'object' // Runtime: Nested object/JSON | ||||||||||||||||||||||||||||
| | 'vector' // Runtime: Vector embeddings for AI | ||||||||||||||||||||||||||||
| | 'grid'; // Runtime: Inline grid/table | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Defines a single option for select/multiselect fields. | ||||||||||||||||||||||||||||
| * Runtime Field Option | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * Extends the Protocol SelectOption to allow number values (for backwards compatibility). | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export interface FieldOption { | ||||||||||||||||||||||||||||
| /** The display label for the option. */ | ||||||||||||||||||||||||||||
| label: string; | ||||||||||||||||||||||||||||
| /** The actual value stored in the database. */ | ||||||||||||||||||||||||||||
| value: string | number; | ||||||||||||||||||||||||||||
| /** Optional color for visual representation */ | ||||||||||||||||||||||||||||
| color?: string; | ||||||||||||||||||||||||||||
| /** Whether this is the default option */ | ||||||||||||||||||||||||||||
| default?: boolean; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Configuration for a single field on an object. | ||||||||||||||||||||||||||||
| * This defines the schema, validation rules, and UI hints for the attribute. | ||||||||||||||||||||||||||||
| * Runtime Field Configuration | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * Extends the Protocol Field definition with runtime-specific properties. | ||||||||||||||||||||||||||||
| * The Protocol Constitution (SpecField) defines the core field schema. | ||||||||||||||||||||||||||||
| * This adds runtime conveniences and extensions. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * We make certain spec fields optional since Zod applies defaults at parse time. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| export interface FieldConfig { | ||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * The unique API name of the field. | ||||||||||||||||||||||||||||
| * If defined within an object map, this is often automatically populated from the key. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| name?: string; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** The human-readable label used in UIs. */ | ||||||||||||||||||||||||||||
| label?: string; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Description of the field for documentation or tooltip. */ | ||||||||||||||||||||||||||||
| 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'> { | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| /** The data type of the field (extended with runtime types) */ | ||||||||||||||||||||||||||||
| type: FieldType; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Options for select fields (extended to allow number values) */ | ||||||||||||||||||||||||||||
| options?: FieldOption[]; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether the field is mandatory. Defaults to false. */ | ||||||||||||||||||||||||||||
| required?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether the field allows multiple values. */ | ||||||||||||||||||||||||||||
| multiple?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether the field is unique in the table. */ | ||||||||||||||||||||||||||||
| unique?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether to create a database index for this field. */ | ||||||||||||||||||||||||||||
| index?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether the field is read-only in UI. */ | ||||||||||||||||||||||||||||
| readonly?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Delete behavior for relationships */ | ||||||||||||||||||||||||||||
| deleteBehavior?: 'set_null' | 'cascade' | 'restrict'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether the field is hidden from default UI/API response. */ | ||||||||||||||||||||||||||||
| hidden?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** The default value if not provided during creation. */ | ||||||||||||||||||||||||||||
| defaultValue?: any; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Tooltip or help text for the user. */ | ||||||||||||||||||||||||||||
| help_text?: string; | ||||||||||||||||||||||||||||
| /** Whether the field is read-only in UI. */ | ||||||||||||||||||||||||||||
| readonly?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Whether the field allows multiple values. | ||||||||||||||||||||||||||||
| * Supported by 'select', 'lookup', 'file', 'image'. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| multiple?: boolean; | ||||||||||||||||||||||||||||
| /** Whether the field is encrypted */ | ||||||||||||||||||||||||||||
| encryption?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Options for select fields. | ||||||||||||||||||||||||||||
| * List of available choices for select/multiselect fields. | ||||||||||||||||||||||||||||
| /** Whether to create a database index for this field. */ | ||||||||||||||||||||||||||||
| index?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Whether this is an external ID field */ | ||||||||||||||||||||||||||||
| externalId?: boolean; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * RUNTIME EXTENSIONS BELOW | ||||||||||||||||||||||||||||
| * These properties are NOT in the wire protocol but are useful for the runtime. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| options?: FieldOption[]; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** Tooltip or help text for the user. */ | ||||||||||||||||||||||||||||
| help_text?: string; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Reference to another object for lookup/master_detail fields. | ||||||||||||||||||||||||||||
| * Specifies the target object name for relationship fields. | ||||||||||||||||||||||||||||
| * @deprecated Use 'reference' from SpecField instead | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| * @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`. |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
nameproperty 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 explicitnameassignment is now required, or if this is needed for protocol compliance.