Skip to content

Commit 62fbaed

Browse files
committed
fix(spec): keep liveness gate + api-surface green for the view union schema
Two CI gates broke on the #3095 change that maps `view` to a union: - Spec property liveness: `check-liveness.mts` walked each metadata type's top-level OBJECT shape; a union has none, so it threw "view is not an object schema". Teach `shapeOf` to resolve a union to its first object-typed member — the canonical authorable container (list/form/listViews/formViews) the ledger governs. Discriminated-union members (ViewItem) are skipped; their inner config is the same ListView/FormView surface already governed under the container's list/form children. - API-surface snapshot: record the two intended new public exports (`ViewMetadata` type, `ViewMetadataSchema` const) via gen:api-surface. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LFmMsWLC3CVULh3Ke7rUdd
1 parent 046b58d commit 62fbaed

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

packages/spec/api-surface.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,6 +3471,8 @@
34713471
"ViewKeyCollision (interface)",
34723472
"ViewKind (type)",
34733473
"ViewKindSchema (const)",
3474+
"ViewMetadata (type)",
3475+
"ViewMetadataSchema (const)",
34743476
"ViewSchema (const)",
34753477
"ViewScope (type)",
34763478
"ViewScopeSchema (const)",

packages/spec/scripts/liveness/check-liveness.mts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,22 @@ function unwrap(s: any, depth = 0): any {
8787
function shapeOf(s: any): Record<string, any> | null {
8888
const u = unwrap(s);
8989
const def = defOf(u);
90-
if (def?.type !== 'object') return null;
91-
return def.shape ?? u.shape ?? null;
90+
if (def?.type === 'object') return def.shape ?? u.shape ?? null;
91+
// #3095 — a metadata type may register a UNION of shapes rather than a single
92+
// object (e.g. `view`: defineView container | ViewItem record | flattened
93+
// personalization overlay). The liveness ledger governs the canonical
94+
// authorable **container**, which is the first object-typed member of the
95+
// union. Discriminated-union members (ViewItem) are skipped — their inner
96+
// `config` is the same ListView/FormView surface already governed under the
97+
// container's `list` / `form` children — so this walks the container shape.
98+
if (def?.type === 'union' && Array.isArray(def.options)) {
99+
for (const opt of def.options) {
100+
const uo = unwrap(opt);
101+
const od = defOf(uo);
102+
if (od?.type === 'object') return od.shape ?? uo.shape ?? null;
103+
}
104+
}
105+
return null;
92106
}
93107
function descOf(s: any): string {
94108
let cur = s;

0 commit comments

Comments
 (0)