Uh oh!
There was an error while loading. Please reload this page.
test(plugin-detail): type-check its tests and clear its TEST_DEBT entry (#4040) - #4326
Merged
Conversation
…ry (#4040) Wires `tsconfig.test.json` into the package's `type-check` script and fixes the 11 errors that surfaced (registry declared 5). Two were public shapes that contradicted the code under them: - `RecordRelatedListRendererProps.schema` required `objectName`, rejecting the authoring shape objectstack#6953 added — `ElementDataSourceGate` maps the binding's `object` onto it before the body runs, and the body already read it defensively because it can arrive unbound. - `ObjectDefLike.fieldGroups` restated the spec's authorable group and had drifted off it, omitting `icon`/`description` — the two keys `deriveFieldGroupDetailSections` passes through to section descriptors (#2548). Derived from `ServiceObject['fieldGroups']` now, so it cannot drift again. The rest are test-side: a permissions fixture whose object grants were spelled in two keys `ObjectPermissionConfig` never declared (inert — rewritten to the `actions` channel the evaluator reads, with no assertion moving), two spies typed through the bare `ReturnType<typeof vi.spyOn>` generic that erased their call signatures, two mocks with no parameters whose cases inspect `mock.calls[0][0]`, an unused parameter, and a retired-spelling negative case that now models its untyped source instead of asking the type to admit a key that was deliberately retired. Refs #4040
…gin-detail # Conflicts: # scripts/check-type-check-coverage.mjs
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 17:18
Uh oh!
There was an error while loading. Please reload this page.
yinlianghui pushed a commit
that referenced
this pull request
Aug 11, 2026
…il removal landed in #4326, plugin-list removal is this PR's)
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 freeto 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.
Part of #4040 — one package per PR, per the standing objectstack#4118 ruling.
@object-ui/plugin-detailnow type-checks its 77 test files; itsTEST_DEBTentry is gone.Measured, not trusted
The registry declared 5 errors. At this branch point the package has 11 — 0 config-tier, so 11 real. Tranche 2 established the registry is stale by up to 8x, and the full re-measure of every remaining entry is reported separately to the PM; plugin-detail is 2.2x.
The
tsconfig.test.jsonneeds nolibbump and no@testing-library/jest-domintypes(three files import it explicitly, and a global augmentation reached by an import applies program-wide). It does needtypes: ["node"]for the one parity test that reads spec sources off disk.Two public shapes that contradicted the code under them
RecordRelatedListRendererProps.schemarequiredobjectName. The exportedRecordRelatedListRendereris theElementDataSourceGatewrapper, and the gate maps the per-element binding'sobjectontoobjectNamebeforeRecordRelatedListBodysees the schema. So{ relationshipField, dataSource: { object, view } }— the exact authoring shape objectstack#6953 added — was legal input at runtime and illegal to the type of the component that exists to accept it. The body already reads the key defensively (objectName && …,objectName || '') precisely because it can arrive unbound; the declaration now agrees with that code. Optional on the wrapper's input only; the spec'sRecordRelatedListPropskeeps it required, which is correct — one describes what an author writes, the other what the block reads.ObjectDefLike.fieldGroupsrestated the spec's authorable group, and had drifted off it. The hand-written list carriedkey/label/collapseplus the deprecatedcollapsible/collapsedpair, but noticon,descriptionordefaultExpanded. Two of those three are read by the same file:deriveFieldGroupDetailSectionspassess.icon/s.descriptionthrough to the section descriptors under a comment citing #2548 ("Dropping them here made the spec keys silently inert on detail pages"). So an object definition declaring the group icon the synthesizer honours did not type-check against the synthesizer. It is derived fromServiceObject['fieldGroups']now — the key is a pass-through (deriveFieldGroupLayoutis the real reader), so the members it should admit are by definition the ones the spec declares.Partialis the one shape difference, and it is the reason the type exists: a raw object definition that has not been through a spec parse.The test-side seven
DetailView.permissions.test.tsx— the role config spelled its object grants asobjectPermissions: { read: true, … }beside aroleNameecho of its own map key. Neither key exists onObjectPermissionConfig['roles'][string], so both were inert and the role granted nothing at all. Rewritten to theactionschannelevaluatePermissionactually reads. No assertion moves, and that is worth stating rather than hiding: the field gate runs throughcheckField, which readsfieldPermissionsdirectly and never consultsactions, so these cases were testing what they claim even while the object grant was empty; the write gate readsactionsand stays false either way. TheRoleDefinitionfixture gainslabel+permissions: []following the convention fix(permissions): type-check its tests (#4040 tranche 1) #4287 set (the dormancy itself isRoleDefinition.permissionsis required and read by nothing — every consumer uses onlyname/inherits#4288).ReturnType<typeof vi.spyOn>— the bare generic resolves its type parameters to their constraints, erasing the call signature, so everymock.callsentry was an implicitany. NowMockInstance<typeof console.warn>.record-quick-actions.actionText-i18n.test.tsxhad no parameters while every case readsmock.calls[0][0]to check which string the provider was handed —calls[0]was the empty tuple. Derived fromActionProvider's own props rather than restated.compactLayout, framework#2536) that now models its untyped source instead of asking the type to re-admit a deliberately retired key.RelatedList.longFormColumns.test.tsx's@object-ui/fields/widgets/MarkdownContentpre-load resolves only through the repo vitest alias —fieldspublishes no such subpath. The import is load-bearing (the negative cases assert synchronously against aReact.lazychunk, so without it a wrongly-derived column reads as absent while loading — green for the wrong reason), so it stays, andtsconfig.test.jsonrestates the alias as apathsentry scoped towidgets/*. Packaging gap filed as@object-ui/fieldsdeep subpaths resolve only through the repo vitest alias — itsexportsmap publishes none of them #4325. Its comment also claimed "Same specifier the component uses", which was false — the component imports./widgets/MarkdownContentrelatively from insidefields. Corrected.Discrimination proof
A — the config actually runs. This is objectui#3009's third failure mode (config exists, nothing invokes it). A provably-false line in a file only the new project reads; the first two compilers pass it and the third reports it:
B — the
fieldGroupsderivation is real, not a widening. Paste a key the spec does not declare and it is still rejected — and the message quotes the spec's own member list, which is what proves nothing was hand-copied and no index signature was added:C — exactly one key was made optional. Drop
relationshipFieldfrom the same literal and it is still rejected:Verification
Merged
origin/mainto resolve the expectedcheck-type-check-coverage.mjsconflict (tranche 2's #4297/#4317 plus #4283 landed while this was in flight): took main's registry, removed only this package's line, re-ran the script, re-rantype-checkafter the merge. GitHub silently disables auto-merge on a conflict, so this PR needs it re-armed.Changeset:
patchfor@object-ui/plugin-detail— the two source type corrections are user-visible.Generated by Claude Code