fix(types): declare editable on the rich TableColumnSchema zod mirror so locked columns stay locked through parse - #5854
Merged
Conversation
…or (#5821) The `TableColumn` interface declares `editable?: boolean` (@default true) and `data-table` reads it at three sites, but the zod mirror omitted the key — z.object is non-strict, so a parse silently STRIPPED it, and a column an author locked with `editable: false` came out of validation editable again. - add `editable: z.boolean().optional()` to `TableColumnSchema` - fold `editable` back into the #5474 rich-surface interactive-keys loop - pin survival (`editable: false` retained in parsed OUTPUT — acceptance alone stays green through a strip, so the pin is on the output) - pin the mirror's declared key set against the interface key list (type-level exhaustive via `satisfies` + `Equal`, runtime via zod shape) The narrow `StaticTableColumnSchema` tombstone for `editable` is untouched on purpose — narrow-refuses / rich-honours is the ruled design (#5474). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7snar5mwF7qoXJazqKhys
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5821
Clause-②: yes—@object-ui/types/zodis a published surface and this PR moves it two ways: the mirror's inferred type gains a key (13 → 14), andeditable: falsestops being stripped, so any pipeline parsing through the mirror (including the CLIvalidateroute viaAnyComponentSchema) changes behaviour. Dispatched at contract-review tier by the spec@objectui seat (seat post #5734).What
The rich
TableColumninterface declareseditable?: boolean(@default true) anddata-tablereads it at three sites to gate inline editing (col.editable !== false), but the zod mirrorTableColumnSchemaomitted the key.z.objectis non-strict, so the mirror silently stripped it — and since the renderer treats absence astrue, a column an author locked witheditable: falsecame out of validation editable again.packages/types/src/zod/data-display.zod.ts— addeditable: z.boolean().optional()to the richTableColumnSchema, matching the interface's key order.packages/types/src/__tests__/static-table-narrow-surface.test.ts— the finding(components): the statictablerenderer reads 9 of the 20 keysTableSchema/TableColumndeclare —hoverable,striped,align,sortable,celland 6 more are inert, and the reference page documents two of them as working #5474 close-out plus the pins this card's verification bar demands:editableback into the rich-surface interactive-keys loop (the filter and its drift comment are gone);editable: falseis asserted present in the parsed output. Acceptance alone cannot pin this defect — a non-strict object accepts-and-strips an undeclared key, so the pre-existingsafeParse(...).successloop stayed green even before the fix (measured, see ablation below);RICH_COLUMN_KEYSis typedsatisfies readonly (keyof TableColumn)[]with anEqualexhaustiveness pin, and the runtime test asserts the zod shape declares exactly that list — a key added to the interface without a mirror decision now fails type-check, and a key dropped from the mirror fails the parity test..changeset/issue-5821-table-column-editable-mirror.md— patch bump for@object-ui/types, stating the behaviour change plainly: columns locked witheditable: falsenow stay locked through parse.Scope fence honoured (both directions)
StaticTableColumnSchematombstone foreditable(z.never().optional()) is untouched — narrow-refuses / rich-honours is the ruled design of finding(components): the statictablerenderer reads 9 of the 20 keysTableSchema/TableColumndeclare —hoverable,striped,align,sortable,celland 6 more are inert, and the reference page documents two of them as working #5474, not drift.DashboardComponentSchema.ariadeclares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830 runs in parallel in the same package (packages/types/src/complex.ts). This diff does not touchcomplex.ts; the two surfaces are disjoint and changesets are one file each.Verification (all quoted from runs at
be8fdc8b9, clean tree; the pre-commit runs were on the byte-identical tree the commit captured)Local verification is narrowed to the affected packages — CI runs the full farm; per-package eslint/tsc verdicts elsewhere cannot move on this diff (no other package references
TableColumnSchema: consumer grep found onlypackages/typesitself, its zod barrel, and the narrow-only import intable-declared-equals-enforced.test.tsx; adding an optional key to a non-strict object rejects nothing that parsed before).packages/types/distat baseda8db03a6, the card'snode -eline printseditable in parsed output: false, parsed JSON drops the key. After — rebuilt dist at this HEAD printseditable in parsed output: true — value: false.grep -cof the injected line = 0 — mutation on disk), test file kept. Result:Tests 2 failed | 21 passed— exactly the two finding(types): the richTableColumnSchemazod mirror omitseditable— a keydata-tablereads at three sites is silently stripped by validation, so a column locked witheditable: falsere-opens after parse #5821 pins red (survival + key-set parity), and notably the folded-in acceptance loop stayed green under the strip, proving acceptance alone is not a pin. Restore leg: file checked out from the branch (grep -c= 1 — restoration on disk), rerunTests 23 passed (23). The test imports the mirror by relative src path (../zod/data-display.zod), so no build step sits between the mutation and the reading; the dist reproduce line above covers the built surface separately.pnpm exec vitest run packages/types/(repo root, per AGENTS.md invocation discipline):Test Files 48 passed (48),Tests 543 passed (543)— re-run atbe8fdc8b9after the final commit.pnpm exec vitest run packages/components/:Test Files 181 passed (181),Tests 1656 passed (1656).packages/typestype-check(src + examples + tests projects — the tests project enforces the newEqual/satisfiespins and the existing@ts-expect-errordirectives) exit 0;packages/componentstype-checkexit 0 after building its dependency closure (first run failed withTS2307 Cannot find module '@object-ui/core'— stale worktree missing sibling dists, not this diff; declared here as the one retried gate).check:spec-symbols— its own verdict line: "spec symbol derivation: 1299 files scanned against 4959 spec export names ... ✅";check:phantom-deps✅;check:self-import✅;check-type-check-coverage✅ (41/41);check-changeset-presence✅ (1 changeset detected);check-changeset-fixed✅;check-changeset-no-major✅ (patch bump);packages/typeseslint .— 0 errors (253 pre-existing warnings, untouched by this diff).Type Checkcarriescheck:spec-symbols(ci.yml:238).Build Docsis red onmain(Build Docsis red onmain:fsreaches the browser bundle via@objectstack/spec→pg-connection-string#5668, inherited) and shows implausibly short turbo-cached greens — excluded as evidence here with that cause; this PR makes no docs claims on it.Out of scope, filed unassigned
TableColumn.typedisagrees three ways — interface declares 8 literals, zod mirror accepts any string, renderer's live read set handles values outside the union via anas anycast #5853 —TableColumn.typedisagrees three ways (interface: 8-literal union; mirror: any string; renderer live read set includesint/integer/float/doublevia anas anycast atdata-table.tsx:2152). Found during this card's 13-key correspondence check; needs a canonical-value-set decision first, so it is not absorbed here. finding(types):TableColumn.typedisagrees three ways — interface declares 8 literals, zod mirror accepts any string, renderer's live read set handles values outside the union via anas anycast #5853 is not addressed in this PR and remains open.Generated by Claude Code
Generated by Claude Code