#378

fix(core): multi-component catalogs accept invalid concrete props

Opencoygeekopened 1mo ago

Summary

With two component definitions, catalog.validate() accepts concrete props that the selected component's Zod schema rejects. Adding an unrelated component changes validation of the same numeric prop.

Steps to reproduce

  1. Install @json-render/core@0.21.0, @json-render/react@0.21.0, and zod@4.3.6 in a fresh consumer.
  2. Run this script.
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
import { z } from "zod";

const components = {
  Number: { props: z.object({ value: z.number() }), slots: [] },
  Text: { props: z.object({ text: z.string() }), slots: [] },
};
const catalog = defineCatalog(schema, { components });
const spec = {
  root: "n",
  elements: {
    n: { type: "Number", props: { value: "wrong" }, children: [] },
  },
};
console.log(catalog.validate(spec).success);
console.log(components.Number.props.safeParse(spec.elements.n.props).success);
const single = defineCatalog(schema, { components: { Number: components.Number } });
console.log(single.validate(spec).success);

Expected behavior

All three results are false for the invalid concrete string. Changing value to a number should make validation succeed. Adding Text should not disable validation of the numeric props for Number.

Actual behavior

The multi-component catalog returns true while the selected component schema returns false. The source builds a permissive record for propsOf when more than one component props schema exists; a single-component catalog uses the actual props schema.

Affected area

defineCatalog().validate() and zodSchema() for the flat element schema and multiple catalog components.

Runtime or environment

Fresh published-package reproduction on Node v22.23.2, @json-render/core and @json-render/react 0.21.0, and zod 4.3.6. Preserved independent source probes at fc2a696a50a30cb30c878ab1eb65e102487eea0f show the same multi-component result.

Evidence

The catalog API documentation presents validation as a way to check an AI spec before rendering. The propsOf schema branch returns z.record(z.string(), z.unknown()) for multiple props schemas, while using the declared schema for one component.

Impact

Consumers can receive a successful catalog validation result for a component instance whose concrete props violate their declared schema. This reproduction contains no dynamic expressions and does not request evaluation of $state or other directives.

Activity

0

No activity yet.