Skip to content

SchemaController

The Schema is the central hub for all data invariants, and metaData associated with the data-model itself. Outside of the types defined in the JSON payload, it doesn’t manage or keep any state. It simply serves as an orchestrator for other modules to interface w/ the schema.

Despite that role, SchemaController lives in schema/, not controllers/ — a naming quirk worth calling out, since it plays the same per-flow orchestrator role as DataController, ValidationController, and friends.

  • core/player/src/schema/schema.tsSchemaController class and the parse() function that expands an authored schema
  • core/player/src/schema/types.tsFormatDefinition, FormatOptions, FormatType
constructor(schema?: SchemaType.Schema)

SchemaController is constructed once per player.start(flow) call from userFlow.schema, before the DataController or ValidationController (both of which depend on it). See Start to Render for exactly where it’s wired up. Player calls this.hooks.schema.call(schema) right after construction so plugins can register data types and formatters via addDataTypes/addFormatters.

The authored schema block is a graph of named nodes (ROOT plus any referenced types). The module-level parse() function walks that graph breadth-first and flattens it into a Map<string, DataType> keyed by dotted path (arrays get a trailing [] segment, records get {}) — this becomes schema.schema, the controller’s read-only lookup table. It throws if it detects a cycle, since a self-referencing schema would recurse forever.

  • getType(binding) — normalizes a BindingInstance (numeric array indices become [], matching how parse() recorded them) and looks up the flattened map, then runs the result through the resolveTypeForBinding hook.
  • getApparentType(binding) — calls getType, then merges in the base type definition registered via addDataTypes (if the schema type references one via type), concatenating validation arrays from both. This is the “effective” type authors think of when they add validation, format, or default.
  • getValidationsForBinding(binding) — reads getApparentType(binding)?.validation, filling in defaults (severity: "error", trigger: "change") for any validation reference that omits them. This is the method that makes SchemaController implement the ValidationProvider interface that ValidationController consumes as one of its two validation sources (schema-level, alongside cross-field/view validations).
  • getFormatter(binding) — resolves the apparent type’s format reference against the formatters registered via addFormatters, returning { format, deformat } functions (or undefined if none is registered). DataController calls this from its format/deformat hook taps.
HookTypeGives youUse it when…
resolveTypeForBindingSyncWaterfallHook<[SchemaType.DataTypes | undefined, BindingInstance]>The schema type looked up for a binding (possibly undefined), plus the binding itselfYou want to override or synthesize a type for bindings that aren’t explicitly in the authored schema