fix(types): ObjectCalendarSchema declares the record-source ladder its renderer reads (objectui#7313) - #7777
Conversation
…s renderer reads (objectui#7313)
ObjectCalendar resolves its records through the shared ladder in @object-ui/core
(resolveRecordSourceConfig: data, then staticData, then objectName), yet the
published interface REQUIRED objectName and declared neither data nor staticData;
the zod mirror did the same. A node authored on staticData — the route the plugin
page documents twice — rendered correctly, was refused by safeValidateSchema, and
could not be annotated with its own type (TS2741).
Landed in the shape objectui#6939 gave object-map / object-gantt:
- TS face: objectName optional with the gantt docblock (identifiers substituted);
data (ViewData) and staticData (any[]) declared with the gantt docblocks copied.
- zod face: requireRecordSource widened to object-calendar; the member declares
data / staticData exactly as ObjectGanttSchema spells them and ends in
.superRefine(requireRecordSource('object-calendar')).
- Docs: the two static-data blocks on plugin-calendar.mdx are annotated
ObjectCalendarSchema and compile against the built dist.
- Pin: object-calendar-record-source-7313.test.ts — type-level optionality and
Equal pins on both faces, the four-document verdict table on safeParse and
safeValidateSchema, verdict-for-verdict parity with ObjectGanttSchema with a
non-vacuity assertion, a BaseSchema control, the renderer read set off disk,
the doc annotations, and a ts-expect-error control that ObjectKanbanSchema
still requires objectName (the class boundary, untouched).
- Changeset: @object-ui/types minor — a widening toward what already renders.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
…ect-calendar-record-source
✅ 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
|
…ect-calendar-record-source
… objectui#7322 landed objectui#7322 (PR #7774, 669d71b) made groupBy the required lane key on ObjectKanbanSchema and retired groupField as a never-typed tombstone. The ts-expect-error control in object-calendar-record-source-7313.test.ts wrote groupField: 'status', so after the merge the literal would miss two members and carry a tombstone violation — the directive would be satisfied by omissions unrelated to objectName and stop saying anything about it. It now supplies groupBy so objectName is again the one member the literal is missing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
|
Merge round after PR #7774 (objectui#7322) landed: new head
Gates on the merged tree (bytes identical to
Left as draft with Generated by Claude Code |
|
Generated by Claude Code |
✅ 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
|
Fixes #7313
Tier
CONTRACT_REVIEW_TIER(a published validator's accept set moves — clause 2 yes): the seat reviews at tier; left as draft. Session:https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s. Generic type parameters and placeholders below are spelled as words (the GitHub body sanitizer eats angle-bracket shapes).What moved
ObjectCalendarresolves its records through the shared ladderresolveRecordSourceConfig(schema)in@object-ui/core(packages/core/src/utils/record-source.ts, lines 146-171:dataat 151,staticDataat 155,objectNameat 162,nullotherwise), called frompackages/plugin-calendar/src/ObjectCalendar.tsx:242with the memo keyed on the three. The published interface REQUIREDobjectNameand declared neitherdatanorstaticData; the mirror did the same. Landed in the shape objectui#6939 gaveobject-map/object-gantt(PR #7471,77cb489b):packages/types/src/objectql.ts, theObjectCalendarSchemablock only):objectName?: stringwith the gantt docblock (identifiers substituted, see deviations);data?: ViewDataandstaticData?: any[]with the gantt docblocks copied. Every other member and docblock untouched.packages/types/src/zod/objectql.zod.ts):requireRecordSource's type parameter widened to'object-calendar'(its body does not branch on the type); the const declaresobjectNameoptional,dataasViewDataSchema.optional()andstaticDataasz.array(z.any()).optional()— spelled as the gantt const spells them — and ends in.superRefine(requireRecordSource('object-calendar')).content/docs/plugins/plugin-calendar.mdx): the two bareobject-calendarblocks — "With Static Data" and "Value Provider (Static)" — annotatedObjectCalendarSchemawith the type import in the neighbouring blocks' style. No prose rewrite.packages/types/src/__tests__/object-calendar-record-source-7313.test.ts(15 tests): type-levelEqual/IsOptionalKeypins on the three keys and parity with the gantt's types; the two documents as compile-time annotations; the four-document verdict table throughsafeParseandsafeValidateSchemawith the refusal message asserted verbatim; verdict-for-verdict parity withObjectGanttSchemawith a non-vacuity assertion on the vector; aBaseSchemacontrol (accepts all four);data/staticDatarefused AT the key with the base as control;.shapestill exposed; the renderer read and the ladder order off disk; the two doc annotations off disk; ats-expect-errorcontrol thatObjectKanbanSchemastill requiresobjectName..changeset/7313-object-calendar-record-source.md:@object-ui/types: minor.Verdict table (measured, pristine dist at
91f92768for BEFORE; rebuilt dist for AFTER)ObjectGanttSchema(before and after)staticDataonlyobjectName(invalid_type)dataonly ({ provider: 'value', items })objectName(invalid_type)objectName(invalid_type)params.code = RECORD_SOURCE_REQUIRED, messageobject-calendar has no record source: declare one of data, staticData or objectNameobject-ganttobjectNameonlySame verdicts through
safeValidateSchema(pinned).objectName: ''still parses (presence is!== undefined), so the accept set only widens.BaseSchemaaccepts all four (control).Kanban reading (triage boundary 3 — measured only, NOT edited; objectui#7322 holds the block)
ObjectKanbanSchemacarries the same defect class, in a different ladder shape.packages/plugin-kanban/src/ObjectKanban.tsx:283gates the fetch onschema.objectName && !boundData && !schema.dataand:294readsrawData = external || boundData || schema.data || fetchedData—datais read ahead of the fetch and is UNDECLARED onObjectKanbanSchema(it is an inlineany[]on this schema, notViewData; falls on the index signature / passthrough), whileobjectName: stringis REQUIRED on both faces and every read of it is guarded (:185?? '',:205,:247,:283,:601,:630,:723,:768,:976). NostaticDatarung. The plugin's ownKanbanSchema(packages/plugin-kanban/src/types.ts:89) already spellsobjectName?: stringanddata?: any[]. The ladder isexternal, bind, data, fetch, so a card for it is not a copy of this one. Left to the seat to file.Ablation (red-first, both faces reverted to
4dfdcc3c, trap-restored, blob-hash proven)Mutation:
git checkout 4dfdcc3c -- objectql.ts objectql.zod.ts; on-disk proof: marker count 0 in the zod source,objectName: string;back in the calendar block,staticDatacount 0 in it; blobs2714449…/b20e082…differ from HEAD's19b4419…/f0e00a9…. Rebuilt; dist marker count 0 (absent preflight). Results: vitest 9 failed / 6 passed of 15 (the four-document, parity and declared-key groups red; the off-disk reads green as expected);type-check10 errors — 8 x TS2344 on theEqual/IsOptionalKeypins, 2 x TS2741 on the two document annotations; the narrowed doc compile 2 x TS2741 (Property 'objectName' is missing) on both annotated blocks. The kanbants-expect-errorcontrol stayed satisfied (no TS2578) in both states. Restore:git checkout HEAD -- both, blobs equal HEAD's,git diff HEADempty,git status --porcelainempty; rebuilt, dist marker count 1, 15/15 green.Gates on the merged head
c458bfe3(exit codes captured before any pipe)pnpm exec turbo run build --filter="@object-ui/plugin-calendar^..." --filter="@object-ui/types" --concurrency=2— 13/13 successful, exit 0 (under the shared verify lock)pnpm exec vitest run --maxWorkers=2 packages/types/— Test Files 125 passed (125), Tests 2209 passed (2209), exit 0; the new file alone: 15 passed (15) (verbose reporter)pnpm --filter @object-ui/types type-check— exit 0, 0error TS(script name echoed;tsconfig.test.jsoncompiles the new test)pnpm --filter @object-ui/plugin-calendar type-check— exit 0, 0 errors, against the rebuilt dist (read-only package; nothing changed there)pnpm --filter @object-ui/types lint— exit 0, 0 errors; 272 warnings vs 270 before: the two new ones areno-explicit-anyonstaticData?: any[](objectql.ts:2700, the rule the gantt/map lines 2277 / 2662 already carry) and the test'sany[]pinnode scripts/check-changeset-presence.mjs/-fixed/-no-major/-overwrite— all exit 0node scripts/check-control-bytes.mjs— exit 0;pnpm check:doc-fences— exit 0;node scripts/check-doc-links.mjs— exit 0;pnpm check:spec-symbols— exit 0;pnpm check:doc-types— exit 0pnpm check:doc-snippets— NOT MEASURED locally: its--build-filterclosure is 26 packages plus dependencies (app-shell, components and the rest), too heavy for the shared box. Substitute: the two annotated blocks extracted verbatim and compiledtsc --strict --noEmit(moduleResolution Bundler) with@object-ui/typesmapped to the rebuiltpackages/types/dist/index.d.ts(resolution self-check printed that path): 0 diagnostics; a control block withstaticData: 'nope'refused with TS2322. CI'sDoc Snippet Type Checkis the measurement.check-governed-merges.mjs --teston the final five paths) — 0 of 5 governedzod-mirror-parity.test.ts— green with no ledger row: both faces moved togetherDeviations and notes for the reviewer
mainPR fix(types): tree-view mirror stops requiring the limb it reads third (group 2 of objectui#6939) #7533 (777e5c6f) is the tree-view group and the map/gantt shape is PR fix(types): object-map / object-gantt — objectName optional behind a record-source refinement (objectui#6939, group 6 of 8) #7471 (77cb489b). Both pins were read; the member shape follows fix(types): object-map / object-gantt — objectName optional behind a record-source refinement (objectui#6939, group 6 of 8) #7471, the type-level pin form follows fix(types): tree-view mirror stops requiring the limb it reads third (group 2 of objectui#6939) #7533.:160,:210) predate theallowCreatesection: on this tree:160is thecalendar-viewfragment (declared as such), and the two bareobject-calendarblocks are:210and:310— the two sections the issue names. Those two were annotated.objectNamedocblock: copied from the gantt withObjectCalendarSchema, the renderer path,calendarand the card number substituted, and one factual substitution — "refused the two documented static-data examples" in place of "refused three catalog entries" (the calendar has no catalog entries). Thedata/staticDatadocblocks are verbatim with the card number substituted. The contract'sgetDataConfigwording is kept as the gantt/map/core header spell it, although the calendar and gantt now read throughresolveRecordSourceConfig— a wording sweep is a separate card, not this one.minorper the dispatch; the objectui#6939 precedent changeset usedpatchfor the same widening class (its text argues "patch, not minor"). Flagged, not decided here.ts-expect-errorcontrol is the line the card that moves the kanban'sobjectNameto optional deletes.ObjectKanbanSchemablock next to this one on both files.origin/main(16a725f9) was merged before opening (clean); a second merge follows when feat(types): declare ObjectKanbanSchema.groupBy and .limit, retire groupField on both faces (objectui#7322 item 1) #7774 lands, gates re-run on that head — by merge, never rebase.Out of scope
domain:ui) —ObjectCalendarComponentProps.schemais not repointed;packages/plugin-calendar/**untouched.content/docs/plugins/plugin-gantt.mdxstill carries three bareobject-ganttstatic-data blocks (:79,:238,:354) thatObjectGanttSchemahas admitted since PR fix(types): object-map / object-gantt — objectName optional behind a record-source refinement (objectui#6939, group 6 of 8) #7471 — the same completion signal this card demanded for the calendar; reported as a finding, not touched here.🤖 Generated with Claude Code
https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
Generated by Claude Code