feat(json-render): add typed specs and custom validation - #273
feat(json-render): add typed specs and custom validation#273dvcolomban wants to merge 2 commits into
Conversation
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR strengthens @devframes/json-render’s public API by introducing catalog-derived, typed JSON-render specs and a generic JsonRenderView/createJsonRenderView surface, plus optional (default-off) synchronous Standard Schema validation for spec creation and updates. It also adds structured diagnostics + docs pages for schema failures and updates API snapshots accordingly.
Changes:
- Add
CatalogUIElement+ genericDevframeJsonRenderSpec<Element>and propagate generics throughJsonRenderView, refs, andcreateJsonRenderView. - Add optional Standard Schema validation (
schema?: StandardSchemaV1 | false) with new diagnosticsDF0073(schema mismatch) andDF0074(async schema rejected). - Add/extend vitest coverage for custom schema behavior and update
tsnapipublic API snapshots + error reference docs.
Reviewed changes
Copilot reviewed 11 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/snapshots/tsnapi/@devframes/json-render/node.snapshot.d.ts | Public API snapshot updates for generic createJsonRenderView options/return type and new diagnostics codes. |
| tests/snapshots/tsnapi/@devframes/json-render/index.snapshot.d.ts | Snapshot updates for generic view/spec types and new catalog-derived element typing exports. |
| pnpm-lock.yaml | Locks @standard-schema/spec addition. |
| packages/json-render/test/create-view.test.ts | Adds tests for custom Standard Schema validation, rejection behavior, permissive mode, and async schema rejection. |
| packages/json-render/test/catalog.test.ts | Adds type-level tests for catalog-derived element narrowing. |
| packages/json-render/src/view-ref.ts | Makes inline view refs/spec refs generic over spec type. |
| packages/json-render/src/types.ts | Introduces generic DevframeJsonRenderSpec/JsonRenderView and CatalogUIElement. |
| packages/json-render/src/node/diagnostics.ts | Adds DF0073/DF0074 diagnostics for schema mismatch and async schema usage. |
| packages/json-render/src/node/create-view.ts | Implements optional synchronous Standard Schema validation and schema-disable behavior. |
| packages/json-render/src/index.ts | Re-exports CatalogUIElement from the public surface. |
| packages/json-render/package.json | Adds @standard-schema/spec dependency to support the exported public types. |
| docs/errors/index.md | Adds DF0073/DF0074 entries to the error reference table. |
| docs/errors/DF0073.md | New error page documenting schema mismatch diagnostic. |
| docs/errors/DF0074.md | New error page documenting async schema diagnostic. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (1)
packages/json-render/src/types.ts:58
JsonRenderViewnow uses function-typed properties forupdate/patchState/value/dispose. Withstrictenabled, this makesSpecTypeeffectively invariant/contravariant (becauseupdate: (spec: SpecType) => voidis a function property), so aJsonRenderView<MySpec>won’t be assignable to APIs expectingJsonRenderView(e.g.packages/json-render/src/hub.ts:51toJsonRenderDockEntry(view: JsonRenderView, ...)). Switching these to method signatures keeps the generic useful without breaking assignability for downstream helpers.
update: (spec: SpecType) => void
/**
* Apply JSON-Pointer patches to the view's `state`. Travels as a
* shared-state patch (not a whole-spec snapshot), so only the changed
* paths cross the wire.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
What changed
Why it changed
This gives downstream renderers a type-safe way to narrow a permissive upstream spec to their own catalog, without making Devframe aware of any particular consumer. The optional validator provides a runtime boundary while retaining the existing permissive use case.
Related to #267.
Validation
pnpm --filter @devframes/json-render typecheckpnpm exec vitest run --project @devframes/json-render test/catalog.test.ts test/create-view.test.ts