Summary
DynamicValueSchema rejects shapes that resolveActionParam resolves correctly at runtime. This causes false positives for tools that schema-validate emitted specs against ActionBindingSchema.
Repro
import {
ActionBindingSchema,
DynamicValueSchema,
resolveActionParam,
} from "@json-render/core"; // 0.19.0
const ctx = {
stateModel: { form: { text: "hi" } },
repeatBasePath: "/todos/2",
repeatIndex: 2,
};
// Runtime accepts each shape:
resolveActionParam({ $index: true }, ctx); // → 2
resolveActionParam(["a", "b"], ctx); // → ["a", "b"]
resolveActionParam({ id: { $state: "/form/text" } }, ctx); // → { id: "hi" }
// Schema rejects each:
DynamicValueSchema.safeParse({ $index: true }).success; // false
DynamicValueSchema.safeParse(["a", "b"]).success; // false
DynamicValueSchema.safeParse({ id: { $state: "/x" } }).success; // false
// Same rejection cascades into ActionBindingSchema:
ActionBindingSchema.safeParse({
action: "setState",
params: { value: ["a", "b"] },
}).success; // false
Why this matters
resolveActionParam is documented to:
- Resolve
{ $item: "field" } to an absolute state path.
- Resolve
{ $index: true } to a numeric index.
- Delegate everything else to
resolvePropValue, which recurses into objects/arrays and handles the full PropExpression grammar.
But DynamicValueSchema is union(string, number, boolean, null, { $state: string }) — anything else fails validation even though the runtime resolves it correctly.
Concrete impact: external tooling that validates an emitted Spec against ActionBindingSchema gets false positives on legitimate emissions like params: { value: ["a", "b"] } (literal array) or params: { value: { id: { \$state: "/x" } } } (object with state refs).
Context
Surfaced while building a parity test suite for a DSL → json-render compiler against @json-render/core@0.19.0. Happy to PR if alignment on the approach is reached.
Summary
DynamicValueSchemarejects shapes thatresolveActionParamresolves correctly at runtime. This causes false positives for tools that schema-validate emitted specs againstActionBindingSchema.Repro
Why this matters
resolveActionParamis documented to:{ $item: "field" }to an absolute state path.{ $index: true }to a numeric index.resolvePropValue, which recurses into objects/arrays and handles the fullPropExpressiongrammar.But
DynamicValueSchemaisunion(string, number, boolean, null, { $state: string })— anything else fails validation even though the runtime resolves it correctly.Concrete impact: external tooling that validates an emitted
SpecagainstActionBindingSchemagets false positives on legitimate emissions likeparams: { value: ["a", "b"] }(literal array) orparams: { value: { id: { \$state: "/x" } } }(object with state refs).Context
Surfaced while building a parity test suite for a DSL → json-render compiler against
@json-render/core@0.19.0. Happy to PR if alignment on the approach is reached.