Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/10535-person-name-read-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ are unchanged.
This is defence in depth: ObjectStack's `FieldMasker` already removes the
fields a user may not read from the rows it returns, and on those rows nothing
changes. The change matters for a backend that does not.

⚠️ **Dated note, 2026-09-30 — the cell reads the person's object from `reference` alone — objectui#11070.** "the object the field's `reference_to` (or `reference`) names" above held when this change landed. Later in this same release objectui#11070 (round 4) narrowed `UserCellRenderer` to `reference`, with `sys_user` when it names none. The read gate is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/11070-field-metadata-spec-spellings.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ The formula and summary field widgets read `@objectstack/spec`'s own spellings,
**Breaking, priced as minor under the fixed group's version policy.** A literal annotated as `FormulaFieldMetadata`, `SummaryFieldMetadata` or `PasswordFieldMetadata` that still writes a retired member no longer compiles (an excess-property error naming the key), and at runtime a formula or summary field that carries only `return_type` or `summary_type` renders its value unformatted. `@objectstack/spec`'s `FieldSchema` refuses every retired spelling by name, so no spec-compliant producer writes them. The fix is the spec spelling: `returnType`, and `summaryOperations: { object, field, function }` (with `filter` for the former `summary_filter`).

**Not in this change.** `LookupFieldMetadata.reference_to` and the lookup readers' `reference_to` read stay: in-repo producers still write `reference_to` onto the field definitions those readers are handed, so retiring the spelling is a separate decision on objectui#11070. The strict face keeps refusing `return_type`, `summary_type`, `summary_object` and `summary_field` on a hand-authored form's field, as before.

⚠️ **Dated note, 2026-09-30 — the `reference_to` decision was taken in this same release — objectui#11070.** "Not in this change" above is still true of this change. Round 4 of objectui#11070, later in this same release, retired `LookupFieldMetadata.reference_to` and the lookup readers' `reference_to` read, and moved the in-repo producers to `reference`. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
32 changes: 32 additions & 0 deletions .changeset/11070-reference-to-round4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
'@object-ui/types': minor
'@object-ui/core': minor
'@object-ui/fields': minor
'@object-ui/app-shell': minor
'@object-ui/plugin-detail': minor
'@object-ui/plugin-form': minor
'@object-ui/plugin-grid': minor
'@object-ui/plugin-list': patch
'@object-ui/plugin-dashboard': patch
'@object-ui/data-objectstack': patch
---

`reference` is now the only spelling ObjectUI writes or reads for a relational field's target object (objectui#11070, round 4, under the objectui#6837 ruling: 「objectui不是前端的项目吗?后端的元数据只要对,前端按协议执行就行了呀」).

- **Types.** `LookupFieldMetadata`, `MasterDetailFieldMetadata` and `DetailViewField` (with its zod mirror `DetailViewFieldSchema`) declare `reference` and no longer declare `reference_to`. On the two field metadata types the member is typed by reference to `@objectstack/spec`'s `FieldSchema.reference`. `@object-ui/plugin-form`'s `FieldDefaultsSchemaLike` drops its `reference_to` member the same way.
- **Readers.** `LookupField`, `UserField`, `LookupCellRenderer`, `UserCellRenderer`, the inline editor's reference fallback, the form's `current_user` seeding and the inline-subform parent lookup read `reference` alone.
- **Emitters.** Every in-repo producer that builds a field definition or a widget `field` prop writes `reference`: the action-param dialog (`paramToField`), the bulk-action dialog, the record detail page, drawer, footer, related list and synthesised page, the gallery card, the form's section-field override and the flow designer's reference picker. The grid's and the dashboard's relational copy sets carry `reference` and no longer copy `reference_to`.
- **Ingestion.** `normalizeFieldReferenceKeys` (behind `ObjectStackAdapter.getObjectSchema` and `MetadataProvider`) still folds a legacy `reference_to` / `referenceTo` onto `reference` when `reference` is absent, and still warns in dev. It no longer stamps `reference_to` onto every relational definition, and it still never drops or overwrites a key.

`@objectstack/spec`'s `FieldSchema` refuses `reference_to` by name, and objectstack#13847 rewrites stored ones on the serve path and in `os migrate meta`, so a definition served by an ObjectStack backend is unaffected.

## ⚠️ BREAKING for a host that hands `reference_to` to the widgets directly

The type change is a compile error for TypeScript that writes `reference_to` on `LookupFieldMetadata`, `MasterDetailFieldMetadata` or `DetailViewField`: rename it to `reference`.

At runtime the break reaches exactly one kind of host: one that serves object definitions spelling the target only as `reference_to` through a `DataSource` other than `ObjectStackAdapter`, or that passes such a definition straight into `LookupField`, `UserField` or a cell renderer. Those definitions never pass the ingestion fold. Measured with an object-bound lookup field on `ObjectForm` and a lookup column on `ObjectGrid`, both fed by a hand-written `DataSource` whose `getObjectSchema` returns `{ type: 'lookup', reference_to: 'account' }`:

- before this change, opening the picker queried `account` and the cell resolved the record's name;
- after it, the picker has no object to query (no `find` call is made) and the cell shows the raw id beside the unresolved-reference marker.

The same definition served through `ObjectStackAdapter.getObjectSchema` still works, before and after: the fold adds `reference`, the picker queries `account`, the cell resolves the name, and the dev warning names the field. **Fix:** spell the target `reference` in the definition your `DataSource` serves.
2 changes: 2 additions & 0 deletions .changeset/6528-resolve-reference-to-census.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ already head of the old chain, so any document carrying both is unaffected.

The string / array / `{ object }` carriers are untouched: the carrier is a
separate axis from the spelling and narrowing it needs its own census.

⚠️ **Dated note, 2026-09-30 — `reference_to` is no longer live on ObjectUI's own view/field schema — objectui#11070.** The table's `reference_to` row said the spelling was "live only on ObjectUI's own view/field schema". Later in this same release objectui#11070 (round 4) moved that schema (`DetailViewField` / `DetailViewFieldSchema`) and the field metadata types to `reference`. The narrowing this change made is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6597-retire-fieldmeta-referenceto.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ than assumed: `FieldMeta`, `AuthoredColumnOverrides`, `EnrichedColumn` and
barrel re-exports only the `ObjectDataTable` component, and the package's `exports` map
publishes only `"."`. No downstream type moves; this is a package-internal contract change
plus a README correction, not a removal from a published type surface.

⚠️ **Dated note, 2026-09-30 — `reference_to` has since left the cell and the grid's copy — objectui#11070.** The measurement above read `LookupCellRenderer` resolving its target from `field.reference_to` / `field.reference`, and `applyRelationalMeta` copying `reference_to`. Later in this same release objectui#11070 (round 4) narrowed the cell to `reference` alone and dropped `reference_to` from both copy sets. The verdict on `referenceTo` is unchanged. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6694-dashboard-lookup-reference-meta.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ Behaviour note for existing dashboards: a lookup cell whose referenced object de
`nameField` other than `name` / `title` will now show that declared name instead of the
heuristic's pick, and valued lookup cells become links wherever the host publishes
`recordHref`.

⚠️ **Dated note, 2026-09-30 — the cell's reads and the copy set have since moved — objectui#11070.** Later in this same release objectui#11070 (round 4) narrowed `LookupCellRenderer` to `reference` alone, so "reads exactly `reference_to`, `reference` and `display_field`" and `useRefObjectSchema(reference_to)` above no longer describe what ships: the cell reads `reference`, and `buildFieldMeta` no longer copies `reference_to` (its `FieldMeta` member is retired, and `ObjectDataTable` refuses it by a hand-written tombstone). `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6711-retire-reference-to-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ correct, so the absence is pinned directly instead
(`__tests__/relationalMetaCopySet-6711.test.tsx`): all three call sites, each with a
presence assertion on the eight surviving keys as the control against a fixture that
passes by never reaching the copy path.

⚠️ **Dated note, 2026-09-30 — `reference_to` has since left `LookupCellRenderer` and the copy set — objectui#11070.** The control above names `reference_to` among the keys `LookupCellRenderer` read. Later in this same release objectui#11070 (round 4) narrowed the cell to `reference` and removed `reference_to` from `RELATIONAL_META_KEYS`; the retirement of `reference_to_field` is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6837-gantt-tree-referenceto-arms.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ surviving spellings.
Pinned by `ObjectGantt.referenceArms-6837.test.tsx` and
`ObjectTree.referenceArms-6837.test.tsx`, which keep the live arms green beside a
named refusal for the deleted key.

⚠️ **Dated note, 2026-09-30 — the choke point folds, it no longer stamps both keys — objectui#11070.** "`normalizeSchemaReferenceKeys` ... stamps both snake_case keys" above held when this change landed. Later in this same release objectui#11070 (round 4) made that pass fold a legacy spelling onto `reference` without stamping `reference_to`; a def that entered through it still carries `reference`, the one arm both components keep. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6837-recorddrawer-invented-target-arms.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ pass over the same cells.

Pinned by `RecordDetailDrawer.referenceArms-6837.test.tsx`, which keeps the live
arms green beside a named refusal per deleted key.

⚠️ **Dated note, 2026-09-30 — the choke point folds, and the drawer emits `reference` — objectui#11070.** "`normalizeSchemaReferenceKeys` ... stamps both snake_case keys" above held when this change landed. Later in this same release objectui#11070 (round 4) made that pass fold a legacy spelling onto `reference` without stamping `reference_to`, and the drawer's field list now carries the target as `reference`. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6837-reference-to-arm-deletion.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,5 @@ narrowing them would break in-repo producers, and `plugin-grid`'s
`relationalMetaCopySet.derivation.test.ts` re-derives its read set from exactly
those three sources — where `reference_to` is recorded with verdict
`adapter-stamped`. `DetailViewFieldSchema` is likewise untouched.

⚠️ **Dated note, 2026-09-30 — the stamp, the three readers and the emitted key have since moved — objectui#11070.** Later in this same release objectui#11070 (round 4) retired `reference_to` inside ObjectUI as well. `normalizeFieldReferenceKeys` now FOLDS a legacy `reference_to` / `referenceTo` onto `reference` and no longer stamps `reference_to`, so "Stamping is deliberately unchanged" and "stamp both snake_case keys" above no longer describe what ships. `LookupCellRenderer`, `LookupField` and `UserField` read `reference` only; `LookupFieldMetadata`, `MasterDetailFieldMetadata` and `DetailViewField` (with `DetailViewFieldSchema`) declare `reference`; and the emitters listed under "What did NOT change" write `reference`. A hand-written schema served through a `DataSource` other than `ObjectStackAdapter` that spells only `reference_to` therefore also loses the lookup picker's target and the read cell's name. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6874-retire-titleformat.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ removal is correct, so the absence is pinned directly instead
(`__tests__/relationalMetaCopySet-6874.test.tsx`): all three call sites, each with a
presence assertion on the seven surviving keys as the control against a fixture that passes
by never reaching the copy path.

⚠️ **Dated note, 2026-09-30 — the copied target key is now `reference` — objectui#11070.** "Copying `reference_to` is what makes `titleFormat` work" above held when this change landed. Later in this same release objectui#11070 (round 4) removed `reference_to` from `RELATIONAL_META_KEYS`; the target reaches the cell as `reference`, which is what the referenced schema is fetched by now. The `titleFormat` retirement is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/6875-grid-relational-meta-derive.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ got a grid cell showing the referenced record's generic `.name` instead.
in prose.
- `plugin-dashboard`'s `CELL_RELATIONAL_META_KEYS` had the same omission in the
same fallback chain and gains `displayField` too.

⚠️ **Dated note, 2026-09-30 — the choke point's one reference rewrite is now one-way — objectui#11070.** "rewrites only the `reference` ⇄ `reference_to` pair" above held when this change landed. Later in this same release objectui#11070 (round 4) made that rewrite a fold onto `reference` that never stamps `reference_to`. Nothing else is rewritten on the way in, so the reasoning above is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/7155-converge-lookup-dialect-camelcase.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ inline-edit enrichment allow-list in `@object-ui/plugin-detail`. `plugin-grid`'s
`relationalMetaKeys.ts` drops the four `legacy-alias` verdicts and retires that verdict
class; its gate is restated to assert the class no longer exists rather than passing
vacuously.

⚠️ **Dated note, 2026-09-30 — `reference_to` did not stay — objectui#11070.** "`reference_to` in particular **stays**" above held when this change landed. Later in this same release objectui#11070 (round 4) retired it: the ingestion pass no longer stamps it, the widgets and read cells read `reference` only, and `LookupFieldMetadata` declares `reference`. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/7166-retire-inert-fieldmeta-copies.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ a consumer READS a key; it does not establish that a given BAG is how the consum
spec-declared against the installed `FieldSchema`, and the sibling pins
(`relationalMetaCopySet-6711` / `-6874`) turn the retired `lookupFilters` into a live
negative assertion on a fixture that still declares it.

⚠️ **Dated note, 2026-09-30 — the lookup and user cells read `reference` alone — objectui#11070.** Later in this same release objectui#11070 (round 4) retired `reference_to` from `LookupCellRenderer` and `UserCellRenderer`, so the sets of keys those cells read, as listed above, no longer include it. The retirement of the three keys this change removed is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
2 changes: 2 additions & 0 deletions .changeset/7324-plugin-form-nameable-parameter-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ requires a `type` on every field, and has no `reference_to` member — while
`isCurrentUserSeedField` honours both `reference` and `reference_to` on purpose. Adopting
it would have narrowed what these functions accept and dropped one of the two honoured
spellings, not widened anything.

⚠️ **Dated note, 2026-09-30 — `FieldDefaultsSchemaLike` pins three members now — objectui#11070.** "the four field members its rule reads (`defaultValue`, `type`, `reference`, `reference_to`)" and "honours both `reference` and `reference_to`" above held when this change landed. Later in this same release objectui#11070 (round 4) retired `reference_to` there: `isCurrentUserSeedField` reads the target as `reference` alone, and the published type no longer carries a `reference_to` member. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ so the two shared nothing and no gate could report a split; and the two member
sets already differed, by `tree`. Lockstep now holds mechanically — the pin is
on object identity (a spy on core's `has`), so a member-identical private copy
fails where a value check would pass.

⚠️ **Dated note, 2026-09-30 — the target key `paramToField` hands the widget is now `reference` — objectui#11070.** Later in this same release objectui#11070 (round 4) moved that key from `reference_to` to `reference`, the only spelling `LookupField` and `UserField` read. The rule this change converged is unaffected. `.changeset/11070-reference-to-round4.md` states what ships; the text above is kept as the reading of this change.
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ describe('ARITY axis — `select` + `multiple: true` is the multiselect widget',
});

it('CONTROL — a multi-value lookup keeps the lookup widget, which handles both arities itself', async () => {
renderForm({ refs: { type: 'lookup', label: 'Refs', multiple: true, reference_to: 'x' } }, ['refs']);
renderForm({ refs: { type: 'lookup', label: 'Refs', multiple: true, reference: 'x' } }, ['refs']);
expect(await widgetOf('refs')).toBe('lookup');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const OBJECT_SCHEMA = {
{ value: 'gift', label: 'Gift' },
],
},
account: { type: 'lookup', label: 'Account', reference_to: 'showcase_account' },
account: { type: 'lookup', label: 'Account', reference: 'showcase_account' },
agree: { type: 'boolean', label: 'Agree', required: true },
priority: {
type: 'radio',
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/components/FormPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ interface RenderableField {
/**
* The object field exactly as the server served it — every key, not only the
* ones {@link ObjectFieldDef} names — so the widget handed this row finds
* what it reads off its metadata (a lookup's `reference_to`, a currency's
* what it reads off its metadata (a lookup's `reference`, a currency's
* `currency`, a code editor's `language`). See {@link widgetFieldOf}.
* Absent on a row built without an object field behind it. Typed as the
* slice this file names; at runtime it is the whole served object.
Expand Down
Loading
Loading