diff --git a/content/docs/references/api/protocol.mdx b/content/docs/references/api/protocol.mdx index 697a5499f..8cbbe19fb 100644 --- a/content/docs/references/api/protocol.mdx +++ b/content/docs/references/api/protocol.mdx @@ -522,6 +522,7 @@ const result = AiInsightsRequest.parse(data); | :--- | :--- | :--- | :--- | | **type** | `string` | ✅ | Metadata type name | | **name** | `string` | ✅ | Item name (snake_case identifier) | +| **packageId** | `string` | optional | Optional package ID to filter items by | --- @@ -546,6 +547,7 @@ const result = AiInsightsRequest.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **type** | `string` | ✅ | Metadata type name (e.g., "object", "plugin") | +| **packageId** | `string` | optional | Optional package ID to filter items by | --- diff --git a/content/docs/references/system/metadata-persistence.mdx b/content/docs/references/system/metadata-persistence.mdx index 055a78206..52fd095d7 100644 --- a/content/docs/references/system/metadata-persistence.mdx +++ b/content/docs/references/system/metadata-persistence.mdx @@ -16,8 +16,8 @@ Defines the lifecycle and mutability of a metadata item. ## TypeScript Usage ```typescript -import { MetadataCollectionInfo, MetadataExportOptions, MetadataFallbackStrategy, MetadataFormat, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system'; -import type { MetadataCollectionInfo, MetadataExportOptions, MetadataFallbackStrategy, MetadataFormat, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system'; +import { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFallbackStrategy, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system'; +import type { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFallbackStrategy, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system'; // Validate data const result = MetadataCollectionInfo.parse(data); @@ -36,6 +36,25 @@ const result = MetadataCollectionInfo.parse(data); | **namespaces** | `string[]` | ✅ | | +--- + +## MetadataDiffResult + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | | +| **name** | `string` | ✅ | | +| **version1** | `number` | ✅ | | +| **version2** | `number` | ✅ | | +| **checksum1** | `string` | ✅ | | +| **checksum2** | `string` | ✅ | | +| **identical** | `boolean` | ✅ | | +| **patch** | `any[]` | optional | JSON patch operations | +| **summary** | `string` | optional | Human-readable summary of changes | + + --- ## MetadataExportOptions @@ -76,6 +95,72 @@ const result = MetadataCollectionInfo.parse(data); * `javascript` +--- + +## MetadataHistoryQueryOptions + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **limit** | `integer` | optional | Maximum number of history records to return | +| **offset** | `integer` | optional | Number of records to skip | +| **since** | `string` | optional | Only return history after this timestamp | +| **until** | `string` | optional | Only return history before this timestamp | +| **operationType** | `Enum<'create' \| 'update' \| 'publish' \| 'revert' \| 'delete'>` | optional | Filter by operation type | +| **includeMetadata** | `boolean` | ✅ | Include full metadata payload | + + +--- + +## MetadataHistoryQueryResult + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **records** | `Object[]` | ✅ | | +| **total** | `integer` | ✅ | | +| **hasMore** | `boolean` | ✅ | | + + +--- + +## MetadataHistoryRecord + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **id** | `string` | ✅ | | +| **metadataId** | `string` | ✅ | Foreign key to sys_metadata.id | +| **name** | `string` | ✅ | | +| **type** | `string` | ✅ | | +| **version** | `number` | ✅ | Version number at this snapshot | +| **operationType** | `Enum<'create' \| 'update' \| 'publish' \| 'revert' \| 'delete'>` | ✅ | Type of operation that created this history entry | +| **metadata** | `string \| Record \| null` | optional | Snapshot of metadata definition at this version (raw JSON string or parsed object) | +| **checksum** | `string` | ✅ | SHA-256 checksum of metadata content | +| **previousChecksum** | `string` | optional | Checksum of the previous version | +| **changeNote** | `string` | optional | Description of changes made in this version | +| **tenantId** | `string` | optional | Tenant identifier for multi-tenant isolation | +| **recordedBy** | `string` | optional | User who made this change | +| **recordedAt** | `string` | ✅ | Timestamp when this version was recorded | + + +--- + +## MetadataHistoryRetentionPolicy + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **maxVersions** | `integer` | optional | Maximum number of versions to retain | +| **maxAgeDays** | `integer` | optional | Maximum age of history records in days | +| **autoCleanup** | `boolean` | ✅ | Enable automatic cleanup of old history | +| **cleanupIntervalHours** | `integer` | ✅ | How often to run cleanup (in hours) | + + --- ## MetadataImportOptions diff --git a/content/docs/references/ui/action.mdx b/content/docs/references/ui/action.mdx index 0bb8be6e4..10a0780e4 100644 --- a/content/docs/references/ui/action.mdx +++ b/content/docs/references/ui/action.mdx @@ -32,7 +32,7 @@ const result = ActionParam.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | | -| **label** | `string \| Object` | ✅ | Display label: plain string or i18n translation object | +| **label** | `string` | ✅ | Display label (plain string; i18n keys are auto-generated by the framework) | | **type** | `Enum<'text' \| 'textarea' \| 'email' \| 'url' \| 'phone' \| 'password' \| 'markdown' \| 'html' \| 'richtext' \| 'number' \| 'currency' \| 'percent' \| 'date' \| 'datetime' \| 'time' \| 'boolean' \| 'toggle' \| 'select' \| 'multiselect' \| 'radio' \| 'checkboxes' \| 'lookup' \| 'master_detail' \| 'tree' \| 'image' \| 'file' \| 'avatar' \| 'video' \| 'audio' \| 'formula' \| 'summary' \| 'autonumber' \| 'location' \| 'address' \| 'code' \| 'json' \| 'color' \| 'rating' \| 'slider' \| 'signature' \| 'qrcode' \| 'progress' \| 'tags' \| 'vector'>` | ✅ | | | **required** | `boolean` | ✅ | | | **options** | `Object[]` | optional | | diff --git a/content/docs/references/ui/animation.mdx b/content/docs/references/ui/animation.mdx index eef8e8163..d01dd2a66 100644 --- a/content/docs/references/ui/animation.mdx +++ b/content/docs/references/ui/animation.mdx @@ -50,13 +50,13 @@ Component-level animation configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | optional | Descriptive label for this animation configuration | +| **label** | `string` | optional | Descriptive label for this animation configuration | | **enter** | `Object` | optional | Enter/mount animation | | **exit** | `Object` | optional | Exit/unmount animation | | **hover** | `Object` | optional | Hover state animation | | **trigger** | `Enum<'on_mount' \| 'on_unmount' \| 'on_hover' \| 'on_focus' \| 'on_click' \| 'on_scroll' \| 'on_visible'>` | optional | When to trigger the animation | | **reducedMotion** | `Enum<'respect' \| 'disable' \| 'alternative'>` | ✅ | Accessibility: how to handle prefers-reduced-motion | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | @@ -87,7 +87,7 @@ Top-level motion and animation design configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | optional | Descriptive label for the motion configuration | +| **label** | `string` | optional | Descriptive label for the motion configuration | | **defaultTransition** | `Object` | optional | Default transition applied to all animations | | **pageTransitions** | `Object` | optional | Page navigation transition settings | | **componentAnimations** | `Record` | optional | Component name to animation configuration mapping | diff --git a/content/docs/references/ui/app.mdx b/content/docs/references/ui/app.mdx index 45819407d..ee54dfd61 100644 --- a/content/docs/references/ui/app.mdx +++ b/content/docs/references/ui/app.mdx @@ -50,7 +50,7 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -69,9 +69,9 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | App unique machine name (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | App display label | +| **label** | `string` | ✅ | App display label | | **version** | `string` | optional | App version | -| **description** | `string \| Object` | optional | App description | +| **description** | `string` | optional | App description | | **icon** | `string` | optional | App icon used in the App Launcher | | **branding** | `Object` | optional | App-specific branding | | **active** | `boolean` | ✅ | Whether the app is enabled | @@ -110,7 +110,7 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -129,7 +129,7 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -148,10 +148,10 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique area identifier (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Area display label | +| **label** | `string` | ✅ | Area display label | | **icon** | `string` | optional | Area icon name | | **order** | `number` | optional | Sort order among areas (lower = first) | -| **description** | `string \| Object` | optional | Area description | +| **description** | `string` | optional | Area description | | **visible** | `string` | optional | Visibility formula condition for this area | | **requiredPermissions** | `string[]` | optional | Permissions required to access this area | | **navigation** | `[__schema0](./__schema0)[]` | ✅ | Navigation items within this area | @@ -174,7 +174,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -196,7 +196,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -216,7 +216,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -237,7 +237,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -258,7 +258,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -278,7 +278,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -298,7 +298,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -320,7 +320,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -340,7 +340,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -360,7 +360,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | @@ -379,7 +379,7 @@ This schema accepts one of the following structures: | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique identifier for this navigation item (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display proper label | +| **label** | `string` | ✅ | Display proper label | | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | diff --git a/content/docs/references/ui/chart.mdx b/content/docs/references/ui/chart.mdx index 272ad3e33..04377e53f 100644 --- a/content/docs/references/ui/chart.mdx +++ b/content/docs/references/ui/chart.mdx @@ -38,7 +38,7 @@ const result = ChartAnnotation.parse(data); | **value** | `number \| string` | ✅ | Start value | | **endValue** | `number \| string` | optional | End value for regions | | **color** | `string` | optional | | -| **label** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **label** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **style** | `Enum<'solid' \| 'dashed' \| 'dotted'>` | ✅ | | @@ -51,7 +51,7 @@ const result = ChartAnnotation.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **field** | `string` | ✅ | Data field key | -| **title** | `string \| Object` | optional | Axis display title | +| **title** | `string` | optional | Axis display title | | **format** | `string` | optional | Value format string (e.g., "$0,0.00") | | **min** | `number` | optional | Minimum value | | **max** | `number` | optional | Maximum value | @@ -70,9 +70,9 @@ const result = ChartAnnotation.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **type** | `Enum<'bar' \| 'horizontal-bar' \| 'column' \| 'grouped-bar' \| 'stacked-bar' \| 'bi-polar-bar' \| 'line' \| 'area' \| 'stacked-area' \| 'step-line' \| 'spline' \| 'pie' \| 'donut' \| 'funnel' \| 'pyramid' \| 'scatter' \| 'bubble' \| 'treemap' \| 'sunburst' \| 'sankey' \| 'word-cloud' \| 'gauge' \| 'solid-gauge' \| 'metric' \| 'kpi' \| 'bullet' \| 'choropleth' \| 'bubble-map' \| 'gl-map' \| 'heatmap' \| 'radar' \| 'waterfall' \| 'box-plot' \| 'violin' \| 'candlestick' \| 'stock' \| 'table' \| 'pivot'>` | ✅ | | -| **title** | `string \| Object` | optional | Chart title | -| **subtitle** | `string \| Object` | optional | Chart subtitle | -| **description** | `string \| Object` | optional | Accessibility description | +| **title** | `string` | optional | Chart title | +| **subtitle** | `string` | optional | Chart subtitle | +| **description** | `string` | optional | Accessibility description | | **xAxis** | `Object` | optional | X-Axis configuration | | **yAxis** | `Object[]` | optional | Y-Axis configuration (support dual axis) | | **series** | `Object[]` | optional | Defined series configuration | @@ -108,7 +108,7 @@ const result = ChartAnnotation.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Field name or series identifier | -| **label** | `string \| Object` | optional | Series display label | +| **label** | `string` | optional | Series display label | | **type** | `Enum<'bar' \| 'horizontal-bar' \| 'column' \| 'grouped-bar' \| 'stacked-bar' \| 'bi-polar-bar' \| 'line' \| 'area' \| 'stacked-area' \| 'step-line' \| 'spline' \| 'pie' \| 'donut' \| 'funnel' \| 'pyramid' \| 'scatter' \| 'bubble' \| 'treemap' \| 'sunburst' \| 'sankey' \| 'word-cloud' \| 'gauge' \| 'solid-gauge' \| 'metric' \| 'kpi' \| 'bullet' \| 'choropleth' \| 'bubble-map' \| 'gl-map' \| 'heatmap' \| 'radar' \| 'waterfall' \| 'box-plot' \| 'violin' \| 'candlestick' \| 'stock' \| 'table' \| 'pivot'>` | optional | Override chart type for this series | | **color** | `string` | optional | Series color (hex/rgb/token) | | **stack** | `string` | optional | Stack identifier to group series | diff --git a/content/docs/references/ui/component.mdx b/content/docs/references/ui/component.mdx index d785162b8..1056d3cc1 100644 --- a/content/docs/references/ui/component.mdx +++ b/content/docs/references/ui/component.mdx @@ -43,7 +43,7 @@ const result = AIChatWindowProps.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | ✅ | Button display label | +| **label** | `string` | ✅ | Button display label | | **variant** | `Enum<'primary' \| 'secondary' \| 'danger' \| 'ghost' \| 'link'>` | ✅ | Button visual variant | | **size** | `Enum<'small' \| 'medium' \| 'large'>` | ✅ | Button size | | **icon** | `string` | optional | Icon name (Lucide icon) | @@ -79,7 +79,7 @@ const result = AIChatWindowProps.parse(data); | **object** | `string` | ✅ | Object for the form | | **fields** | `string[]` | optional | Fields to display (defaults to all editable fields) | | **mode** | `Enum<'create' \| 'edit'>` | ✅ | Form mode | -| **submitLabel** | `string \| Object` | optional | Submit button label | +| **submitLabel** | `string` | optional | Submit button label | | **onSubmit** | `string` | optional | Action expression on form submit | | **aria** | `Object` | optional | ARIA accessibility attributes | @@ -131,7 +131,7 @@ const result = AIChatWindowProps.parse(data); | **filter** | `[__schema0](./__schema0)` | optional | Filter criteria for available records | | **multiple** | `boolean` | ✅ | Allow multiple record selection | | **targetVariable** | `string` | optional | Page variable to bind selected record ID(s) | -| **placeholder** | `string \| Object` | optional | Placeholder text | +| **placeholder** | `string` | optional | Placeholder text | | **aria** | `Object` | optional | ARIA accessibility attributes | @@ -170,7 +170,7 @@ const result = AIChatWindowProps.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **title** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **title** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **bordered** | `boolean` | ✅ | | | **actions** | `string[]` | optional | | | **body** | `any[]` | optional | Card content components (slot) | @@ -186,8 +186,8 @@ const result = AIChatWindowProps.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **title** | `string \| Object` | ✅ | Page title | -| **subtitle** | `string \| Object` | optional | Page subtitle | +| **title** | `string` | ✅ | Page title | +| **subtitle** | `string` | optional | Page subtitle | | **icon** | `string` | optional | Icon name | | **breadcrumb** | `boolean` | ✅ | Show breadcrumb | | **actions** | `string[]` | optional | Action IDs to show in header | @@ -301,7 +301,7 @@ const result = AIChatWindowProps.parse(data); | **sort** | `string \| Object[]` | optional | Sort order for related records | | **limit** | `integer` | ✅ | Number of records to display initially | | **filter** | `Object[]` | optional | Additional filter criteria for related records | -| **title** | `string \| Object` | optional | Custom title for the related list | +| **title** | `string` | optional | Custom title for the related list | | **showViewAll** | `boolean` | ✅ | Show "View All" link to see all related records | | **actions** | `string[]` | optional | Action IDs available for related records | | **aria** | `Object` | optional | ARIA accessibility attributes | diff --git a/content/docs/references/ui/dashboard.mdx b/content/docs/references/ui/dashboard.mdx index 48f555e6e..af0961925 100644 --- a/content/docs/references/ui/dashboard.mdx +++ b/content/docs/references/ui/dashboard.mdx @@ -30,8 +30,8 @@ const result = Dashboard.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Dashboard unique name | -| **label** | `string \| Object` | ✅ | Dashboard label | -| **description** | `string \| Object` | optional | Dashboard description | +| **label** | `string` | ✅ | Dashboard label | +| **description** | `string` | optional | Dashboard description | | **header** | `Object` | optional | Dashboard header configuration | | **widgets** | `Object[]` | ✅ | Widgets to display | | **refreshInterval** | `number` | optional | Auto-refresh interval in seconds | @@ -66,7 +66,7 @@ Dashboard header action | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | ✅ | Action button label | +| **label** | `string` | ✅ | Action button label | | **actionUrl** | `string` | ✅ | URL or target for the action | | **actionType** | `Enum<'script' \| 'url' \| 'modal' \| 'flow' \| 'api'>` | optional | Type of action | | **icon** | `string` | optional | Icon identifier for the action button | @@ -81,8 +81,8 @@ Dashboard header action | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **id** | `string` | ✅ | Unique widget identifier (snake_case) | -| **title** | `string \| Object` | optional | Widget title | -| **description** | `string \| Object` | optional | Widget description text below the header | +| **title** | `string` | optional | Widget title | +| **description** | `string` | optional | Widget description text below the header | | **type** | `Enum<'bar' \| 'horizontal-bar' \| 'column' \| 'grouped-bar' \| 'stacked-bar' \| 'bi-polar-bar' \| 'line' \| 'area' \| 'stacked-area' \| 'step-line' \| 'spline' \| 'pie' \| 'donut' \| 'funnel' \| 'pyramid' \| 'scatter' \| 'bubble' \| 'treemap' \| 'sunburst' \| 'sankey' \| 'word-cloud' \| 'gauge' \| 'solid-gauge' \| 'metric' \| 'kpi' \| 'bullet' \| 'choropleth' \| 'bubble-map' \| 'gl-map' \| 'heatmap' \| 'radar' \| 'waterfall' \| 'box-plot' \| 'violin' \| 'candlestick' \| 'stock' \| 'table' \| 'pivot'>` | ✅ | Visualization type | | **chartConfig** | `Object` | optional | Chart visualization configuration | | **colorVariant** | `Enum<'default' \| 'blue' \| 'teal' \| 'orange' \| 'purple' \| 'success' \| 'warning' \| 'danger'>` | optional | Widget color variant for theming | @@ -110,7 +110,7 @@ Dashboard header action | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **field** | `string` | ✅ | Field name to filter on | -| **label** | `string \| Object` | optional | Display label for the filter | +| **label** | `string` | optional | Display label for the filter | | **type** | `Enum<'text' \| 'select' \| 'date' \| 'number' \| 'lookup'>` | optional | Filter input type | | **options** | `Object[]` | optional | Static filter options | | **optionsFrom** | `Object` | optional | Dynamic filter options from object | @@ -180,7 +180,7 @@ Widget measure definition | :--- | :--- | :--- | :--- | | **valueField** | `string` | ✅ | Field to aggregate | | **aggregate** | `Enum<'count' \| 'sum' \| 'avg' \| 'min' \| 'max'>` | ✅ | Aggregate function | -| **label** | `string \| Object` | optional | Measure display label | +| **label** | `string` | optional | Measure display label | | **format** | `string` | optional | Number format string | diff --git a/content/docs/references/ui/dnd.mdx b/content/docs/references/ui/dnd.mdx index 5a0fb7ca6..4869e2001 100644 --- a/content/docs/references/ui/dnd.mdx +++ b/content/docs/references/ui/dnd.mdx @@ -80,12 +80,12 @@ Draggable item configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **type** | `string` | ✅ | Drag item type identifier for matching with drop zones | -| **label** | `string \| Object` | optional | Accessible label describing the draggable item | +| **label** | `string` | optional | Accessible label describing the draggable item | | **handle** | `Enum<'element' \| 'handle' \| 'grip_icon'>` | ✅ | How to initiate drag | | **constraint** | `Object` | optional | Drag movement constraints | | **preview** | `Enum<'element' \| 'custom' \| 'none'>` | ✅ | Drag preview type | | **disabled** | `boolean` | ✅ | Disable dragging | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | @@ -114,12 +114,12 @@ Drop zone configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | optional | Accessible label for the drop zone | +| **label** | `string` | optional | Accessible label for the drop zone | | **accept** | `string[]` | ✅ | Accepted drag item types | | **maxItems** | `number` | optional | Maximum items allowed in drop zone | | **highlightOnDragOver** | `boolean` | ✅ | Highlight drop zone when dragging over | | **dropEffect** | `Enum<'move' \| 'copy' \| 'link' \| 'none'>` | ✅ | Visual effect on drop | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | diff --git a/content/docs/references/ui/i18n.mdx b/content/docs/references/ui/i18n.mdx index a65ea9d5f..9c3748c85 100644 --- a/content/docs/references/ui/i18n.mdx +++ b/content/docs/references/ui/i18n.mdx @@ -49,7 +49,7 @@ ARIA accessibility attributes | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | @@ -70,32 +70,6 @@ Date/time formatting rules | **hour12** | `boolean` | optional | Use 12-hour format | ---- - -## I18nLabel - -Display label: plain string or i18n translation object - -### Union Options - -This schema accepts one of the following structures: - -#### Option 1 - -Type: `string` - ---- - -#### Option 2 - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **key** | `string` | ✅ | Translation key (e.g., "views.task_list.label") | -| **defaultValue** | `string` | optional | Fallback value when translation key is not found | -| **params** | `Record` | optional | Interpolation parameters (e.g., `{ count: 5 }`) | - --- diff --git a/content/docs/references/ui/keyboard.mdx b/content/docs/references/ui/keyboard.mdx index bb1a26e16..497e42a0d 100644 --- a/content/docs/references/ui/keyboard.mdx +++ b/content/docs/references/ui/keyboard.mdx @@ -69,7 +69,7 @@ Keyboard navigation and shortcut configuration | **shortcuts** | `Object[]` | optional | Registered keyboard shortcuts | | **focusManagement** | `Object` | optional | Focus and tab order management | | **rovingTabindex** | `boolean` | ✅ | Enable roving tabindex pattern for composite widgets | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | @@ -86,7 +86,7 @@ Keyboard shortcut binding | :--- | :--- | :--- | :--- | | **key** | `string` | ✅ | Key combination (e.g., "Ctrl+S", "Alt+N", "Escape") | | **action** | `string` | ✅ | Action identifier to invoke when shortcut is triggered | -| **description** | `string \| Object` | optional | Human-readable description of what the shortcut does | +| **description** | `string` | optional | Human-readable description of what the shortcut does | | **scope** | `Enum<'global' \| 'view' \| 'form' \| 'modal' \| 'list'>` | ✅ | Scope in which this shortcut is active | diff --git a/content/docs/references/ui/notification.mdx b/content/docs/references/ui/notification.mdx index 80c276a7f..3ad62625a 100644 --- a/content/docs/references/ui/notification.mdx +++ b/content/docs/references/ui/notification.mdx @@ -35,14 +35,14 @@ Notification instance definition | :--- | :--- | :--- | :--- | | **type** | `Enum<'toast' \| 'snackbar' \| 'banner' \| 'alert' \| 'inline'>` | ✅ | Notification presentation style | | **severity** | `Enum<'info' \| 'success' \| 'warning' \| 'error'>` | ✅ | Notification severity level | -| **title** | `string \| Object` | optional | Notification title | -| **message** | `string \| Object` | ✅ | Notification message body | +| **title** | `string` | optional | Notification title | +| **message** | `string` | ✅ | Notification message body | | **icon** | `string` | optional | Icon name override | | **duration** | `number` | optional | Auto-dismiss duration in ms, omit for persistent | | **dismissible** | `boolean` | ✅ | Allow user to dismiss the notification | | **actions** | `Object[]` | optional | Action buttons | | **position** | `Enum<'top_left' \| 'top_center' \| 'top_right' \| 'bottom_left' \| 'bottom_center' \| 'bottom_right'>` | optional | Override default position | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | @@ -57,7 +57,7 @@ Notification action button | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **label** | `string \| Object` | ✅ | Action button label | +| **label** | `string` | ✅ | Action button label | | **action** | `string` | ✅ | Action identifier to execute | | **variant** | `Enum<'primary' \| 'secondary' \| 'link'>` | ✅ | Button variant style | diff --git a/content/docs/references/ui/offline.mdx b/content/docs/references/ui/offline.mdx index 18634ca22..833db7a31 100644 --- a/content/docs/references/ui/offline.mdx +++ b/content/docs/references/ui/offline.mdx @@ -81,7 +81,7 @@ Offline support configuration | **cache** | `Object` | optional | Cache settings for offline data | | **sync** | `Object` | optional | Sync settings for offline mutations | | **offlineIndicator** | `boolean` | ✅ | Show a visual indicator when offline | -| **offlineMessage** | `string \| Object` | optional | Customizable offline status message shown to users | +| **offlineMessage** | `string` | optional | Customizable offline status message shown to users | | **queueMaxSize** | `number` | optional | Maximum number of queued offline mutations | diff --git a/content/docs/references/ui/page.mdx b/content/docs/references/ui/page.mdx index 23a888a33..7b17c755e 100644 --- a/content/docs/references/ui/page.mdx +++ b/content/docs/references/ui/page.mdx @@ -97,8 +97,8 @@ Interface-level page configuration (Airtable parity) | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Page unique name (lowercase snake_case) | -| **label** | `string \| Object` | ✅ | Display label: plain string or i18n translation object | -| **description** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **label** | `string` | ✅ | Display label (plain string; i18n keys are auto-generated by the framework) | +| **description** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **icon** | `string` | optional | Page icon name | | **type** | `Enum<'record' \| 'home' \| 'app' \| 'utility' \| 'dashboard' \| 'grid' \| 'list' \| 'gallery' \| 'kanban' \| 'calendar' \| 'timeline' \| 'form' \| 'record_detail' \| 'record_review' \| 'overview' \| 'blank'>` | ✅ | Page type | | **variables** | `Object[]` | optional | Local page state variables | @@ -123,7 +123,7 @@ Interface-level page configuration (Airtable parity) | :--- | :--- | :--- | :--- | | **type** | `Enum<'page:header' \| 'page:footer' \| 'page:sidebar' \| 'page:tabs' \| 'page:accordion' \| 'page:card' \| 'page:section' \| 'record:details' \| 'record:highlights' \| 'record:related_list' \| 'record:activity' \| 'record:chatter' \| 'record:path' \| 'app:launcher' \| 'nav:menu' \| 'nav:breadcrumb' \| 'global:search' \| 'global:notifications' \| 'user:profile' \| 'ai:chat_window' \| 'ai:suggestion' \| 'element:text' \| 'element:number' \| 'element:image' \| 'element:divider' \| 'element:button' \| 'element:filter' \| 'element:form' \| 'element:record_picker'> \| string` | ✅ | Component Type (Standard enum or custom string) | | **id** | `string` | optional | Unique instance ID | -| **label** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **label** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **properties** | `Record` | ✅ | Component props passed to the widget. See component.zod.ts for schemas. | | **events** | `Record` | optional | Event handlers map | | **style** | `Record` | optional | Inline styles or utility classes | diff --git a/content/docs/references/ui/report.mdx b/content/docs/references/ui/report.mdx index f86f1e414..5345a7759 100644 --- a/content/docs/references/ui/report.mdx +++ b/content/docs/references/ui/report.mdx @@ -30,8 +30,8 @@ const result = Report.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Report unique name | -| **label** | `string \| Object` | ✅ | Report label | -| **description** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **label** | `string` | ✅ | Report label | +| **description** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **objectName** | `string` | ✅ | Primary object | | **type** | `Enum<'tabular' \| 'summary' \| 'matrix' \| 'joined'>` | ✅ | Report format type | | **columns** | `Object[]` | ✅ | Columns to display | @@ -52,9 +52,9 @@ const result = Report.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **type** | `Enum<'bar' \| 'horizontal-bar' \| 'column' \| 'grouped-bar' \| 'stacked-bar' \| 'bi-polar-bar' \| 'line' \| 'area' \| 'stacked-area' \| 'step-line' \| 'spline' \| 'pie' \| 'donut' \| 'funnel' \| 'pyramid' \| 'scatter' \| 'bubble' \| 'treemap' \| 'sunburst' \| 'sankey' \| 'word-cloud' \| 'gauge' \| 'solid-gauge' \| 'metric' \| 'kpi' \| 'bullet' \| 'choropleth' \| 'bubble-map' \| 'gl-map' \| 'heatmap' \| 'radar' \| 'waterfall' \| 'box-plot' \| 'violin' \| 'candlestick' \| 'stock' \| 'table' \| 'pivot'>` | ✅ | | -| **title** | `string \| Object` | optional | Chart title | -| **subtitle** | `string \| Object` | optional | Chart subtitle | -| **description** | `string \| Object` | optional | Accessibility description | +| **title** | `string` | optional | Chart title | +| **subtitle** | `string` | optional | Chart subtitle | +| **description** | `string` | optional | Accessibility description | | **xAxis** | `string` | ✅ | Grouping field for X-Axis | | **yAxis** | `string` | ✅ | Summary field for Y-Axis | | **series** | `Object[]` | optional | Defined series configuration | @@ -77,7 +77,7 @@ const result = Report.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **field** | `string` | ✅ | Field name | -| **label** | `string \| Object` | optional | Override label | +| **label** | `string` | optional | Override label | | **aggregate** | `Enum<'sum' \| 'avg' \| 'max' \| 'min' \| 'count' \| 'unique'>` | optional | Aggregation function | | **responsive** | `Object` | optional | Responsive visibility for this column | diff --git a/content/docs/references/ui/touch.mdx b/content/docs/references/ui/touch.mdx index 73b291306..d787cd858 100644 --- a/content/docs/references/ui/touch.mdx +++ b/content/docs/references/ui/touch.mdx @@ -34,7 +34,7 @@ Per-gesture configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **type** | `Enum<'swipe' \| 'pinch' \| 'long_press' \| 'double_tap' \| 'drag' \| 'rotate' \| 'pan'>` | ✅ | Gesture type to configure | -| **label** | `string \| Object` | optional | Descriptive label for the gesture action | +| **label** | `string` | optional | Descriptive label for the gesture action | | **enabled** | `boolean` | ✅ | Whether this gesture is active | | **swipe** | `Object` | optional | Swipe gesture settings (when type is swipe) | | **pinch** | `Object` | optional | Pinch gesture settings (when type is pinch) | @@ -126,7 +126,7 @@ Touch and gesture interaction configuration | **gestures** | `Object[]` | optional | Configured gesture recognizers | | **touchTarget** | `Object` | optional | Touch target sizing and hit area | | **hapticFeedback** | `boolean` | optional | Enable haptic feedback on touch interactions | -| **ariaLabel** | `string \| Object` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | +| **ariaLabel** | `string` | optional | Accessible label for screen readers (WAI-ARIA aria-label) | | **ariaDescribedBy** | `string` | optional | ID of element providing additional description (WAI-ARIA aria-describedby) | | **role** | `string` | optional | WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert") | diff --git a/content/docs/references/ui/view.mdx b/content/docs/references/ui/view.mdx index 76d52478f..6eaa3d381 100644 --- a/content/docs/references/ui/view.mdx +++ b/content/docs/references/ui/view.mdx @@ -97,9 +97,9 @@ Aggregation function for column footer summary | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **field** | `string` | ✅ | Field name (snake_case) | -| **label** | `string \| Object` | optional | Display label override | -| **placeholder** | `string \| Object` | optional | Placeholder text | -| **helpText** | `string \| Object` | optional | Help/hint text | +| **label** | `string` | optional | Display label override | +| **placeholder** | `string` | optional | Placeholder text | +| **helpText** | `string` | optional | Help/hint text | | **readonly** | `boolean` | optional | Read-only override | | **required** | `boolean` | optional | Required override | | **hidden** | `boolean` | optional | Hidden override | @@ -189,7 +189,7 @@ Record grouping configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **field** | `string` | ✅ | Field name (snake_case) | -| **label** | `string \| Object` | optional | Display label override | +| **label** | `string` | optional | Display label override | | **width** | `number` | optional | Column width in pixels | | **align** | `Enum<'left' \| 'center' \| 'right'>` | optional | Text alignment | | **hidden** | `boolean` | optional | Hide column by default | @@ -212,7 +212,7 @@ Record grouping configuration | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | optional | Internal view name (lowercase snake_case) | -| **label** | `string \| Object` | optional | Display label: plain string or i18n translation object | +| **label** | `string` | optional | Display label (plain string; i18n keys are auto-generated by the framework) | | **type** | `Enum<'grid' \| 'kanban' \| 'gallery' \| 'calendar' \| 'timeline' \| 'gantt' \| 'map'>` | ✅ | | | **data** | `Object \| Object \| Object` | optional | Data source configuration (defaults to "object" provider) | | **columns** | `string[] \| Object[]` | ✅ | Fields to display as columns | @@ -232,7 +232,7 @@ Record grouping configuration | **gantt** | `Object` | optional | | | **gallery** | `Object` | optional | Gallery/card view configuration | | **timeline** | `Object` | optional | Timeline view configuration | -| **description** | `string \| Object` | optional | View description for documentation/tooltips | +| **description** | `string` | optional | View description for documentation/tooltips | | **sharing** | `Object` | optional | View sharing and access configuration | | **rowHeight** | `Enum<'compact' \| 'short' \| 'medium' \| 'tall' \| 'extra_tall'>` | optional | Row height / density setting | | **grouping** | `Object` | optional | Group records by one or more fields | @@ -458,7 +458,7 @@ Tab configuration for multi-tab view interface | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Tab identifier (snake_case) | -| **label** | `string \| Object` | optional | Display label | +| **label** | `string` | optional | Display label | | **icon** | `string` | optional | Tab icon name | | **view** | `string` | optional | Referenced list view name from listViews | | **filter** | `Object[]` | optional | Tab-specific filter criteria | diff --git a/content/docs/references/ui/widget.mdx b/content/docs/references/ui/widget.mdx index a093fb6ca..1c96e0fee 100644 --- a/content/docs/references/ui/widget.mdx +++ b/content/docs/references/ui/widget.mdx @@ -60,8 +60,8 @@ const result = WidgetEvent.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Event name | -| **label** | `string \| Object` | optional | Human-readable event label | -| **description** | `string \| Object` | optional | Event description and usage | +| **label** | `string` | optional | Human-readable event label | +| **description** | `string` | optional | Event description and usage | | **bubbles** | `boolean` | ✅ | Whether event bubbles | | **cancelable** | `boolean` | ✅ | Whether event is cancelable | | **payload** | `Record` | optional | Event payload schema | @@ -93,8 +93,8 @@ const result = WidgetEvent.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Widget identifier (snake_case) | -| **label** | `string \| Object` | ✅ | Widget display name | -| **description** | `string \| Object` | optional | Widget description | +| **label** | `string` | ✅ | Widget display name | +| **description** | `string` | optional | Widget description | | **version** | `string` | optional | Widget version (semver) | | **author** | `string` | optional | Widget author | | **icon** | `string` | optional | Widget icon | @@ -122,11 +122,11 @@ const result = WidgetEvent.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **name** | `string` | ✅ | Property name (camelCase) | -| **label** | `string \| Object` | optional | Human-readable label | +| **label** | `string` | optional | Human-readable label | | **type** | `Enum<'string' \| 'number' \| 'boolean' \| 'array' \| 'object' \| 'function' \| 'any'>` | ✅ | TypeScript type | | **required** | `boolean` | ✅ | Whether property is required | | **default** | `any` | optional | Default value | -| **description** | `string \| Object` | optional | Property description | +| **description** | `string` | optional | Property description | | **validation** | `Record` | optional | Validation rules | | **category** | `string` | optional | Property category | diff --git a/packages/plugins/plugin-security/src/security-plugin.test.ts b/packages/plugins/plugin-security/src/security-plugin.test.ts index 1d9f8722f..01caa43b1 100644 --- a/packages/plugins/plugin-security/src/security-plugin.test.ts +++ b/packages/plugins/plugin-security/src/security-plugin.test.ts @@ -21,23 +21,32 @@ describe('SecurityPlugin', () => { it('should register services during init', async () => { const plugin = new SecurityPlugin(); + const manifestService = { register: vi.fn() }; const ctx: any = { logger: { info: vi.fn(), warn: vi.fn() }, registerService: vi.fn(), - getService: vi.fn(), + getService: vi.fn().mockImplementation((name: string) => { + if (name === 'manifest') return manifestService; + return undefined; + }), }; await plugin.init(ctx); expect(ctx.registerService).toHaveBeenCalledWith('security.permissions', expect.any(PermissionEvaluator)); expect(ctx.registerService).toHaveBeenCalledWith('security.rls', expect.any(RLSCompiler)); expect(ctx.registerService).toHaveBeenCalledWith('security.fieldMasker', expect.any(FieldMasker)); + expect(manifestService.register).toHaveBeenCalled(); }); it('should warn and return when objectql service is missing', async () => { const plugin = new SecurityPlugin(); + const manifestService = { register: vi.fn() }; const ctx: any = { logger: { info: vi.fn(), warn: vi.fn() }, registerService: vi.fn(), - getService: vi.fn().mockImplementation(() => { throw new Error('not found'); }), + getService: vi.fn().mockImplementation((name: string) => { + if (name === 'manifest') return manifestService; + throw new Error('not found'); + }), }; await plugin.init(ctx); await plugin.start(ctx); @@ -46,10 +55,14 @@ describe('SecurityPlugin', () => { it('should warn when objectql does not support middleware', async () => { const plugin = new SecurityPlugin(); + const manifestService = { register: vi.fn() }; const ctx: any = { logger: { info: vi.fn(), warn: vi.fn() }, registerService: vi.fn(), - getService: vi.fn().mockReturnValue({}), // no registerMiddleware + getService: vi.fn().mockImplementation((name: string) => { + if (name === 'manifest') return manifestService; + return {}; // objectql without registerMiddleware + }), }; await plugin.init(ctx); await plugin.start(ctx); @@ -59,10 +72,14 @@ describe('SecurityPlugin', () => { it('should register middleware when objectql supports it', async () => { const plugin = new SecurityPlugin(); const registerMiddleware = vi.fn(); + const manifestService = { register: vi.fn() }; const ctx: any = { logger: { info: vi.fn(), warn: vi.fn() }, registerService: vi.fn(), - getService: vi.fn().mockReturnValue({ registerMiddleware }), + getService: vi.fn().mockImplementation((name: string) => { + if (name === 'manifest') return manifestService; + return { registerMiddleware }; + }), }; await plugin.init(ctx); await plugin.start(ctx); diff --git a/packages/plugins/plugin-setup/src/setup-plugin.test.ts b/packages/plugins/plugin-setup/src/setup-plugin.test.ts index 997d4f4c9..7a2c1dc9b 100644 --- a/packages/plugins/plugin-setup/src/setup-plugin.test.ts +++ b/packages/plugins/plugin-setup/src/setup-plugin.test.ts @@ -11,6 +11,13 @@ import type { SetupNavContribution } from './setup-app.js'; // --------------------------------------------------------------------------- function createMockContext() { const services = new Map(); + + // Pre-register the manifest service + const manifestService = { + register: vi.fn(), + }; + services.set('manifest', manifestService); + return { logger: { info: vi.fn(), @@ -23,6 +30,7 @@ function createMockContext() { }), getService: vi.fn((name: string) => services.get(name)), services, + manifestService, // Expose for test assertions } as any; } @@ -55,11 +63,10 @@ describe('SETUP_AREAS', () => { } }); - it('each area should have i18n labels', () => { + it('each area should have string labels', () => { for (const area of SETUP_AREAS) { - expect(typeof area.label).toBe('object'); - expect((area.label as any).key).toBeDefined(); - expect((area.label as any).defaultValue).toBeDefined(); + expect(typeof area.label).toBe('string'); + expect(area.label).toBeTruthy(); } }); }); @@ -72,9 +79,9 @@ describe('SETUP_APP_DEFAULTS', () => { expect(SETUP_APP_DEFAULTS.name).toBe('setup'); }); - it('should have i18n label', () => { - expect(typeof SETUP_APP_DEFAULTS.label).toBe('object'); - expect((SETUP_APP_DEFAULTS.label as any).defaultValue).toBe('Setup'); + it('should have string label', () => { + expect(typeof SETUP_APP_DEFAULTS.label).toBe('string'); + expect(SETUP_APP_DEFAULTS.label).toBe('Setup'); }); it('should require setup.access permission', () => { @@ -121,8 +128,8 @@ describe('SetupPlugin', () => { await plugin.init(ctx); await plugin.start(ctx); - expect(ctx.registerService).toHaveBeenCalledWith( - 'app.com.objectstack.setup', + // Verify manifest.register was called + expect(ctx.manifestService.register).toHaveBeenCalledWith( expect.objectContaining({ id: 'com.objectstack.setup', apps: expect.arrayContaining([ @@ -132,10 +139,8 @@ describe('SetupPlugin', () => { ); // No areas should be present — all areas are empty. - const call = ctx.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; expect(app.areas).toBeUndefined(); }); @@ -161,10 +166,8 @@ describe('SetupPlugin', () => { await plugin.start(ctx); - const call = ctx.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; // Only non-empty areas should be present. expect(app.areas).toHaveLength(2); @@ -187,10 +190,8 @@ describe('SetupPlugin', () => { await plugin.start(ctx); - const call = ctx.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; expect(app.areas).toHaveLength(1); expect(app.areas[0].id).toBe('area_custom_billing'); expect(app.areas[0].navigation).toHaveLength(1); @@ -212,10 +213,8 @@ describe('SetupPlugin', () => { await plugin.start(ctx); - const call = ctx.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; // Administration (order 10) should come before System (order 30). expect(app.areas[0].id).toBe(SETUP_AREA_IDS.administration); expect(app.areas[1].id).toBe(SETUP_AREA_IDS.system); @@ -236,10 +235,8 @@ describe('SetupPlugin', () => { await plugin.start(ctx); - const call = ctx.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; const platformArea = app.areas.find((a: any) => a.id === SETUP_AREA_IDS.platform); expect(platformArea).toBeDefined(); expect(platformArea!.navigation).toHaveLength(2); @@ -263,10 +260,8 @@ describe('SetupPlugin', () => { await plugin.init(ctx2); await plugin.start(ctx2); - const call = ctx2.registerService.mock.calls.find( - (c: any[]) => c[0] === 'app.com.objectstack.setup', - ); - const app = call[1].apps[0]; + const call = ctx2.manifestService.register.mock.calls[0]; + const app = call[0].apps[0]; expect(app.areas).toBeUndefined(); }); }); diff --git a/packages/services/service-ai/src/__tests__/ai-service.test.ts b/packages/services/service-ai/src/__tests__/ai-service.test.ts index ba721741d..05e0694b8 100644 --- a/packages/services/service-ai/src/__tests__/ai-service.test.ts +++ b/packages/services/service-ai/src/__tests__/ai-service.test.ts @@ -739,6 +739,9 @@ describe('AIServicePlugin', () => { const services = new Map(); const hooks = new Map(); + // Pre-register manifest service + services.set('manifest', { register: vi.fn() }); + return { registerService: vi.fn((name: string, service: unknown) => services.set(name, service)), replaceService: vi.fn((name: string, service: unknown) => services.set(name, service)),