Module validate

Source
Expand description

Checking attribute values against a file’s schemas.

The rules follow upstream’s Validate in src/ifcx-core/schema/schema-validation.ts of the ifcx_alpha draft, with two differences: every failure is collected into a ValidationReport instead of stopping at the first, and a few cases upstream leaves open are decided here.

§Rules

Every attribute id on a node must name a schema; ids starting with __internal are skipped, as upstream does. The value is then checked against the schema’s IfcxValueDescription:

dataTypeAccepted value
BooleanJSON true or false
String, Referenceany JSON string; a reference is not resolved
DateTimeany JSON string; the ISO 8601 format is not checked, as upstream
Enuma string equal to one of enumRestrictions.options
Realany JSON number
Integera JSON number without a fractional part (3 and 3.0, not 3.5)
Objecta JSON object with every non-optional key of objectRestrictions.values, each checked recursively; other keys are allowed
Arraya JSON array whose length is within arrayRestrictions.min and max, each element checked against arrayRestrictions.value
Blobany value, unchecked
anything elsenothing; reported as FailureKind::UnknownDataType

A value description with inherits is first checked against the value description of every inherited schema, then against its own dataType. A schema reached through several inherits paths (a diamond) is checked once per value, so its failures are reported once. Inheritance is walked without recursion, so chains of any length are checked. optional only lets an object key be absent; a JSON null is never accepted where a value is present. quantityKind is not checked.

§Where this is stricter or more defined than upstream

  • Integer rejects numbers with a fractional part; upstream accepts any number for both Integer and Real.
  • Array checks min and max; upstream ignores them.
  • Object requires a JSON object; upstream’s typeof value === "object" also lets arrays and null through.
  • Blob accepts any value. The draft does not say how a blob is encoded, and upstream rejects every blob as an unexpected data type.
  • An Enum without enumRestrictions and an inheritance cycle are reported; upstream crashes or recurses without end.
  • quantityKind is an annotation for numbers. Neither upstream nor this module checks it against the value or against the list of known kinds.

§Flattened and raw nodes

Upstream validates flattened nodes, after all opinions on a path have been merged. validate_flat checks the output of flatten or flatten_owned. IfcxFile::validate merges the attributes of nodes sharing a path, later opinions winning, as flattening does, before validating them; it does not copy any value. validate_attributes takes any (path, attributes) pairs, and validate_nodes raw nodes as they are.

§Imports

A file’s own schemas often do not describe its attributes: most upstream examples take them from imported files. LayerStack::validate checks a layer stack built with its imports: the schemas of every layer, merged as federate does, against the attributes of every layer, merged per path as flattening does.

Structs§

ValidationFailure
One attribute value that does not match its schema.
ValidationReport
Every failure found in one validation run, in node and attribute order.

Enums§

FailureKind
What is wrong with one attribute value.
JsonType
The JSON type of a value, for failure messages.

Constants§

INTERNAL_ATTRIBUTE_PREFIX
Attribute ids with this prefix are not validated, as upstream.

Functions§

validate_attributes
Checks the attributes of nodes, given as (path, attributes) pairs, against schemas and collects every failure.
validate_flat
Checks flattened nodes, as flatten or flatten_owned return them, against schemas. This is what upstream validates: one merged node per path, in the flattened order.
validate_nodes
Checks the attributes of each node as it is, without merging nodes that share a path. Nodes without attributes are skipped.