Field Value
Field Value protocol schemas
Field runtime VALUE-shape contract (ADR-0104 D1).
FieldSchema owns what a field definition looks like; this module owns
what a field's runtime value looks like — the shape the write path
accepts, drivers persist, and an unexpanded API read returns. Before this
module the knowledge lived as private, hand-copied type sets in objectql's
record-validator, rest's import-coerce, driver-sql, and verify; adding one
multi-capable or JSON-shaped type meant updating four lists or silently
corrupting data. Those consumers now derive from the classes below.
Two canonical forms exist per field (ADR-0104 D1):
stored— the storage/wire form (e.g. lookup ⇒ record-id string,date⇒YYYY-MM-DD, select ⇒ option code).expanded— the enriched$expandread form (lookup ⇒ the related record object). For types without an expansion, expanded ≡ stored.
"Reality wins": where the deployed stored shape is coherent, the contract
adopts it — deployed data is a wire contract we don't get to rewrite by
editing Zod. This is why currency is a bare number (not the never-consumed
CurrencyValueSchema object) and location is {lat, lng} (what field-zoo
stores), not the never-consumed {latitude, longitude} shape.
Purity: schemas/constants/derivation only — no runtime logic, no caching
(Prime Directive #2). Consumers cache valueSchemaFor results per field
definition; building a Zod schema per write is the one performance trap
this contract has (ADR-0104 performance budget).
Source: packages/spec/src/data/field-value.zod.ts
TypeScript Usage
import { AddressSchema, AddressValueSchema, CalendarDateValueSchema, ClockTimeValueSchema, FileLikeValueSchema, FileReferenceIdValueSchema, FileValueSchema, InstantValueSchema, LocationValueSchema, ReferenceIdValueSchema } from '@objectstack/spec/data';
import type { Address, AddressValue, CalendarDateValue, ClockTimeValue, FileLikeValue, FileReferenceIdValue, FileValue, InstantValue, LocationValue, ReferenceIdValue } from '@objectstack/spec/data';
// Validate data
const result = AddressSchema.parse(data);Address
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| street | string | optional | Street address |
| city | string | optional | City name |
| state | string | optional | State/Province |
| postalCode | string | optional | Postal/ZIP code |
| country | string | optional | Country name or code |
| countryCode | string | optional | ISO country code (e.g., US, GB) |
| formatted | string | optional | Formatted address string |
AddressValue
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| street | string | optional | Street address |
| city | string | optional | City name |
| state | string | optional | State/Province |
| postalCode | string | optional | Postal/ZIP code |
| country | string | optional | Country name or code |
| countryCode | string | optional | ISO country code (e.g., US, GB) |
| formatted | string | optional | Formatted address string |
CalendarDateValue
Type: string
ClockTimeValue
Type: string
FileLikeValue
Union Options
This schema accepts one of the following structures:
Option 1
Type: string
Option 2
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| url | string | ✅ | |
| name | string | optional | |
| size | number | optional | |
| mimeType | string | optional | |
| alt | string | optional | |
| duration | number | optional |
FileReferenceIdValue
Type: string
FileValue
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| url | string | ✅ | |
| name | string | optional | |
| size | number | optional | |
| mimeType | string | optional | |
| alt | string | optional | |
| duration | number | optional |
InstantValue
Type: string
LocationValue
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| lat | number | ✅ | Latitude |
| lng | number | ✅ | Longitude |
| altitude | number | optional | Altitude in meters |
| accuracy | number | optional | Accuracy in meters |
ReferenceIdValue
Type: string