fix: address Copilot review round 10 — structural const match, deep-link constants
- selectBranchIndex compares a discriminator structurally: a `const` may be an object or array, and deep-link arguments arrive as freshly parsed instances that could never be reference-equal to the schema's own. - New applySchemaConstants, applied by InspectorView AFTER the deep link's `appArgs` are spread over the seeded defaults. The form renders a pinned field read-only, so a link disagreeing with one would otherwise auto-open an App with a hidden value contradicting the shape on screen. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
246ee1c262
commit
775fec0f6a
1 changed files with 91 additions and 8 deletions
|
|
@ -174,6 +174,36 @@ export function collectSchemaDefaults(
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite every `const`-pinned field with the value its schema fixes.
|
||||
*
|
||||
* The form renders such a field read-only, so a value disagreeing with it can
|
||||
* only have come from outside the form — an App deep link's `appArgs`, which
|
||||
* are spread over the seeded defaults and would otherwise leave the arguments
|
||||
* claiming a shape the user is being shown the opposite of (#2123). Apply this
|
||||
* *after* any such overlay.
|
||||
*
|
||||
* The branch is chosen the same way {@link collectSchemaDefaults} chooses it,
|
||||
* from the values themselves, so the constants applied belong to the shape the
|
||||
* form will display.
|
||||
*/
|
||||
export function applySchemaConstants(
|
||||
schema: InspectorFormSchema,
|
||||
values: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
const { base, branches } = resolveRootUnion(schema);
|
||||
const selected = selectBranchIndex(branches, values) ?? 0;
|
||||
const properties = (branches[selected]?.schema ?? base).properties ?? {};
|
||||
const pinned = Object.entries(properties).filter(
|
||||
([, fieldSchema]) => fieldSchema.const !== undefined,
|
||||
);
|
||||
if (pinned.length === 0) return values;
|
||||
return Object.fromEntries([
|
||||
...Object.entries(values),
|
||||
...pinned.map(([name, fieldSchema]) => [name, fieldSchema.const]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether any of the schema's required top-level fields is missing a value in
|
||||
* `values` (absent, null, or empty string). Used to gate a form's submit
|
||||
|
|
|
|||
Loading…
Reference in a new issue