Validation
Validation protocol schemas
ObjectStack Validation Protocol
This module defines the validation schema protocol for ObjectStack, providing a comprehensive
type-safe validation system similar to Salesforce's validation rules but with enhanced capabilities.
Overview
Validation rules are applied at the data layer to ensure data integrity and enforce business logic.
The system supports multiple validation types:
-
Script Validation: Formula-based validation using expressions
-
Uniqueness Validation: Enforce unique constraints across fields
-
State Machine Validation: Control allowed state transitions
-
Format Validation: Validate field formats (email, URL, regex, etc.)
-
Cross-Field Validation: Validate relationships between multiple fields
-
Async Validation: Remote validation via API calls
-
Custom Validation: User-defined validation functions
-
Conditional Validation: Apply validations based on conditions
Salesforce Comparison
ObjectStack validation rules are inspired by Salesforce validation rules but enhanced:
-
Salesforce: Formula-based validation with
Error Condition Formula -
ObjectStack: Multiple validation types with composable rules
Example Salesforce validation rule:
Rule Name: Discount_Cannot_Exceed_40_Percent
Error Condition Formula: Discount_Percent__c > 0.40
Error Message: Discount cannot exceed 40%.Equivalent ObjectStack rule:
\{
type: 'script',
name: 'discount_cannot_exceed_40_percent',
condition: 'discount_percent > 0.40',
message: 'Discount cannot exceed 40%',
severity: 'error'
\}Source: packages/spec/src/data/validation.zod.ts
TypeScript Usage
import { AsyncValidation, ConditionalValidation, CrossFieldValidation, CustomValidator, FormatValidation, JSONValidation, ScriptValidation, StateMachineValidation, UniquenessValidation, ValidationRule } from '@objectstack/spec/data';
import type { AsyncValidation, ConditionalValidation, CrossFieldValidation, CustomValidator, FormatValidation, JSONValidation, ScriptValidation, StateMachineValidation, UniquenessValidation, ValidationRule } from '@objectstack/spec/data';
// Validate data
const result = AsyncValidation.parse(data);AsyncValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | Field to validate |
| validatorUrl | string | optional | External API endpoint for validation |
| method | Enum<'GET' | 'POST'> | ✅ | HTTP method for external call |
| headers | Record<string, string> | optional | Custom headers for the request |
| validatorFunction | string | optional | Reference to custom validator function |
| timeout | number | ✅ | Timeout in milliseconds |
| debounce | number | optional | Debounce delay in milliseconds |
| params | Record<string, any> | optional | Additional parameters to pass to validator |
ConditionalValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| when | string | ✅ | Condition formula (e.g. "type = 'enterprise'") |
| then | Object | Object | Object | Object | Object | Object | Object | Object | [#](./#) | ✅ | Validation rule to apply when condition is true |
| otherwise | Object | Object | Object | Object | Object | Object | Object | Object | [#](./#) | optional | Validation rule to apply when condition is false |
CrossFieldValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| condition | string | ✅ | Formula expression comparing fields (e.g. "end_date > start_date") |
| fields | string[] | ✅ | Fields involved in the validation |
CustomValidator
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| handler | string | ✅ | Name of the custom validation function registered in the system |
| params | Record<string, any> | optional | Parameters passed to the custom handler |
FormatValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | |
| regex | string | optional | |
| format | Enum<'email' | 'url' | 'phone' | 'json'> | optional |
JSONValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | JSON field to validate |
| schema | Record<string, any> | ✅ | JSON Schema object definition |
ScriptValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| condition | string | ✅ | Formula expression. If TRUE, validation fails. (e.g. amount < 0) |
StateMachineValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | State field (e.g. status) |
| transitions | Record<string, string[]> | ✅ | Map of { OldState: [AllowedNewStates] } |
UniquenessValidation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| fields | string[] | ✅ | Fields that must be combined unique |
| scope | string | optional | Formula condition for scope (e.g. active = true) |
| caseSensitive | boolean | ✅ |
ValidationRule
Union Options
This schema accepts one of the following structures:
Option 1
Type: script
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| condition | string | ✅ | Formula expression. If TRUE, validation fails. (e.g. amount < 0) |
Option 2
Type: unique
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| fields | string[] | ✅ | Fields that must be combined unique |
| scope | string | optional | Formula condition for scope (e.g. active = true) |
| caseSensitive | boolean | ✅ |
Option 3
Type: state_machine
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | State field (e.g. status) |
| transitions | Record<string, string[]> | ✅ | Map of { OldState: [AllowedNewStates] } |
Option 4
Type: format
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | |
| regex | string | optional | |
| format | Enum<'email' | 'url' | 'phone' | 'json'> | optional |
Option 5
Type: cross_field
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| condition | string | ✅ | Formula expression comparing fields (e.g. "end_date > start_date") |
| fields | string[] | ✅ | Fields involved in the validation |
Option 6
Type: json_schema
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | JSON field to validate |
| schema | Record<string, any> | ✅ | JSON Schema object definition |
Option 7
Type: async
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| field | string | ✅ | Field to validate |
| validatorUrl | string | optional | External API endpoint for validation |
| method | Enum<'GET' | 'POST'> | ✅ | HTTP method for external call |
| headers | Record<string, string> | optional | Custom headers for the request |
| validatorFunction | string | optional | Reference to custom validator function |
| timeout | number | ✅ | Timeout in milliseconds |
| debounce | number | optional | Debounce delay in milliseconds |
| params | Record<string, any> | optional | Additional parameters to pass to validator |
Option 8
Type: custom
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique rule name (snake_case) |
| label | string | optional | Human-readable label for the rule listing |
| description | string | optional | Administrative notes explaining the business reason |
| active | boolean | ✅ | |
| events | Enum<'insert' | 'update' | 'delete'>[] | ✅ | Validation contexts |
| priority | integer | ✅ | Execution priority (lower runs first, default: 100) |
| tags | string[] | optional | Categorization tags (e.g., "compliance", "billing") |
| severity | Enum<'error' | 'warning' | 'info'> | ✅ | |
| message | string | ✅ | Error message to display to the user |
| type | string | ✅ | |
| handler | string | ✅ | Name of the custom validation function registered in the system |
| params | Record<string, any> | optional | Parameters passed to the custom handler |
Option 9
Reference: __schema0