⬡ FRAMEWERK
Core

Validation

validate() returns errors for structural problems and warnings for things that render fine and are probably still wrong.

View as Markdown

Validation

validate() returns { valid, errors, warnings }: errors are things the renderer cannot make sense of, warnings are things that render fine and are probably still wrong.

Examples

Validating a good spec:

A spec that validates clean
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Hello
Order
Edit the JSON to update the rendered screen.Edits stay in this preview

The same shape with a dangling navigate — structurally valid, warning on the button:

A dangling navigate warns
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Hello
Order
Edit the JSON to update the rendered screen.Edits stay in this preview

Anatomy

import { validate } from "@framewerk/spec";

const result = validate(spec);
result.valid;     // boolean
result.errors;    // structural problems — the spec is wrong
result.warnings;  // suspicious but renderable

Errors are things the renderer cannot make sense of: an unknown node type, a malformed layout tree, an invalid enum value ("variant": "zzz" on a button).

Warnings are things that render fine and are probably still wrong:

navigate(nope) targets an unknown screen "nope"
Unrecognized action "frobnicate(9)" — expected navigate(screenId), back(),
  setState(key, value), toggleState(key), scrollTo(anchor), or openUrl(address)
Screen "home" has an empty layout with no children

Note where the line falls. A dangling navigate() and an unparseable action are warnings, not errors — the spec is structurally valid and the screen draws correctly; the button just does nothing when clicked. That is the most expensive class of bug in a wireframe and the easiest to miss by eye, so treat warnings as failures in CI unless you have a specific reason not to. validate() reports them; it does not rank them for you.

The package also exports the pieces the validator is built from — parseAction, evaluateExpression, normalizeLayoutTree, resolveId, lintActionStrings, collectReachableScreenIds — so you can build your own tooling on the format without reimplementing its semantics. See the API reference.

Stability

The format versions with @framewerk/spec under semver. A change that invalidates a previously-valid document is breaking, even when the TypeScript surface is untouched. The checked-in api-report.md in each package is the machine-checked record of the exported surface.

Adding a node type or an optional prop is additive. Removing one, or narrowing what an existing field accepts, is not.