|
| 1 | +--- |
| 2 | +'@objectstack/spec': minor |
| 3 | +--- |
| 4 | + |
| 5 | +feat(spec): `Field.valueDomain` — one closed standard-domain vocabulary and one membership predicate shared by settings specifiers and object fields (maintainer ruling 2026-09-02 on #14168, spec half) |
| 6 | + |
| 7 | +<!-- adr-0087: not-required (accept-set expansion) One new CLOSED optional key |
| 8 | +on an existing shape (`FieldSchema.valueDomain`) and one new member of the |
| 9 | +closed field-level error catalog (`value_domain`); nothing authorable is |
| 10 | +renamed, retired or tombstoned, so there is no conversion to register. |
| 11 | +`SpecifierValueDomainSchema` keeps its export name and its exact three |
| 12 | +members — it is now an alias of the shared schema, not a second declaration. --> |
| 13 | + |
| 14 | +An object field can now declare that its written value must be a member of a |
| 15 | +published standard, with the SAME closed vocabulary a settings specifier's |
| 16 | +`valueDomain` already uses — `iana_time_zone` · `iso_4217_currency` · |
| 17 | +`iso_3166_alpha2` — and the same definition of membership. The vocabulary does |
| 18 | +not widen. |
| 19 | + |
| 20 | +- `Field.valueDomain` (`@objectstack/spec/data`): authorable on `text` only — |
| 21 | + the one type whose stored value is a single plain string naming the member. |
| 22 | + On any other type the declaration is refused at parse with a located issue |
| 23 | + naming the type (the same applicability door `maxLength` / `minLength` use). |
| 24 | + A domain outside the vocabulary (`iso_8601_date`) is refused by name. |
| 25 | +- `ValueDomainSchema` / `ValueDomain` / `isValueDomainMember(domain, value)` / |
| 26 | + `ISO_3166_ALPHA2_CODES` (`@objectstack/spec/shared`): the vocabulary and its |
| 27 | + ONE membership predicate, declared once. `iana_time_zone` is the |
| 28 | + `Intl.DateTimeFormat` probe (`UTC`, `Asia/Kolkata`, `Europe/Kyiv` are |
| 29 | + members; `Europe/Munich` is not — never the `Intl.supportedValuesOf` |
| 30 | + enumeration, which omits `UTC`); `iso_4217_currency` is the key set of the |
| 31 | + package's checked-in CLDR snapshot (162 codes, exact uppercase); |
| 32 | + `iso_3166_alpha2` is the explicit list of the 249 officially assigned |
| 33 | + codes (exact uppercase). |
| 34 | +- `SpecifierValueDomainSchema` / `SpecifierValueDomain` |
| 35 | + (`@objectstack/spec/system`): unchanged name, unchanged members, now an |
| 36 | + alias of `ValueDomainSchema` — nothing that imports them moves. |
| 37 | +- `FieldErrorCode` gains `value_domain` (ADR-0114 D1: the code is the |
| 38 | + property's own name, like `max_length`), with message templates in the |
| 39 | + four platform locales (`value_domain`, plus one finer variant per domain). |
| 40 | + |
| 41 | +What this release does NOT yet do: refuse a non-member on the record write |
| 42 | +path. The record validator does not read `Field.valueDomain` yet; that |
| 43 | +enforcement and the settings door's re-point onto the shared predicate are the |
| 44 | +engine and services halves of the same ruling and ship in their own releases. |
| 45 | +Until the engine half lands, a domain declared on a `text` field is accepted |
| 46 | +at parse and describes the contract the write path will enforce. |
0 commit comments