# `Chronicle.Discovery.EventSchemaShape`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle/discovery/event_schema_shape.ex#L4)

Extracts a canonical, coarse shape from an event's JSON schema for identity comparison.

A faithful port of the .NET client's `EventSchemaShape` normalization
(`Source/Clients/DotNET/Discovery/EventSchemaShape.cs`): property names, nesting and
primitive type categories, with `$ref`/`anyOf`/`oneOf` resolved and nullability stripped —
so renaming a property is a shape change but reordering keys, widening `integer` to
`number`, or `["string", "null"]` versus `"string"` is not. Used by
`Chronicle.Discovery.DriftDetector` to notice a generation whose struct changed without a
bumped `:generation`.

# `of`

```elixir
@spec of(String.t()) :: map() | nil
```

Normalizes a nonempty JSON schema string for identity comparison.

Returns the canonical shape as a normalized map (comparable with `==`), or `nil` when the
schema isn't a JSON object, has no properties, or normalization is unsafe (an unresolved or
cyclic `$ref`).

---

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