fix: address Copilot review round 11 — recurse constants into nested objects

applySchemaConstants only corrected top-level pinned fields, but the deep
link's overlay replaces a nested object wholesale rather than merging into it —
so `{ config: { kind: "sms" } }` slipped past a nested read-only
`kind: { const: "email" }` the form was displaying. It now recurses into
object-valued properties, resolving each one's own root union the same way.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 04:36:13 -04:00
commit a69cb58451

View file

@ -445,6 +445,27 @@ describe("root composition (#2123)", () => {
});
});
it("re-applies a nested object's constants", () => {
// The overlay replaces the whole nested object rather than merging into it,
// so a link naming `{ config: { kind: "sms" } }` would otherwise slip past
// the pinned `kind` the nested form displays.
const schema: InspectorFormSchema = {
type: "object",
properties: {
config: {
type: "object",
properties: {
kind: { type: "string", const: "email" },
to: { type: "string" },
},
},
},
};
expect(
applySchemaConstants(schema, { config: { kind: "sms", to: "a@b.c" } }),
).toEqual({ config: { kind: "email", to: "a@b.c" } });
});
it("leaves values alone when nothing is pinned", () => {
const values = { a: 1 };
expect(