# `A2UICore.Catalog.ValidationSchema`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_core/lib/a2ui_core/catalog/validation_schema.ex#L1)

Builds a catalog's validation schema: the self-contained JSON Schema
messages are validated against (the reference's
`Catalog.validation_schema`).

From the catalog's resolved schemas (references into its own `$defs`
and peers written inline, references to common types kept):

  1. the components, functions, own `$defs` and theme are assembled,
     with `anyComponent` / `anyFunction` listing the entries, and
     cleaned (`A2UICore.Catalog.SchemaCleaner`);
  2. each component is flattened: its `allOf` mixins (`ComponentCommon`,
     `Checkable`, local `$defs` mixins) are merged into one
     `properties` / `required` object, its own properties winning,
     inside the canonical envelope (`id`, `component`); local mixins
     nothing references any more leave `$defs`;
  3. a `$ref` to a common type without a `description` takes the
     type's description;
  4. the common types the schema references, transitively, are bundled
     into `$defs` from the published `common_types.json` (a catalog
     without functions gets `anyFunction: {"not": {}}`);
  5. the declared `protocolVersion` is written in its bare form, and
     before v1.0 every function call schema is closed.

# `input`
*since 0.1.0* 

```elixir
@type input() :: %{
  :catalog_id =&gt; String.t(),
  :protocol_version =&gt; String.t(),
  :instructions =&gt; String.t() | nil,
  :declared_protocol_version =&gt; String.t() | nil,
  :defs =&gt; map(),
  :components =&gt; map(),
  :functions =&gt; map(),
  :resolved =&gt; map(),
  :component_order =&gt; [String.t()],
  :function_order =&gt; [String.t()],
  optional(atom()) =&gt; term()
}
```

What the build needs from a catalog.

# `build`
*since 0.1.0* 

```elixir
@spec build(input()) :: map()
```

The validation schema of a catalog.

# `common_names`
*since 0.1.0* 

```elixir
@spec common_names() :: MapSet.t(String.t())
```

The names of the common types of every supported protocol version:
the references a catalog keeps when it writes its own references
inline.

# `component_union`
*since 0.1.0* 

```elixir
@spec component_union([String.t()]) :: map()
```

The `anyComponent` union of `names`: `{"not": {}}` when there are
none.

# `function_union`
*since 0.1.0* 

```elixir
@spec function_union([String.t()]) :: map()
```

The `anyFunction` union of `names`: `{"not": {}}` when there are none.

# `published_defs`
*since 0.1.0* 

```elixir
@spec published_defs(String.t()) :: map()
```

The published common types `$defs` of a protocol version, with
cross-document references made local. Empty for an unsupported
version.

# `system_names`
*since 0.1.0* 

```elixir
@spec system_names(String.t()) :: [String.t()]
```

The names of the system functions a protocol version supplies to every
catalog (`@index` from v1.0 on).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
