Class: Async::Matrix::Schema::Registry
- Inherits:
-
Object
- Object
- Async::Matrix::Schema::Registry
- Defined in:
- lib/async/matrix/schema/registry.rb
Overview
Loads and indexes Matrix event schemas from the official matrix-org/matrix-spec YAML files bundled in data/matrix-spec/event-schemas/schema/.
Schemas are loaded lazily on first access and cached for the lifetime of the process. Each schema is a JSONSchemer::Schema instance that resolves relative $ref paths (e.g. core-event-schema/room_event.yaml) via a file-based resolver.
registry = Async::Matrix::Schema::Registry.instance
registry["m.room.message"] # => JSONSchemer::Schema
registry.variant("m.room.message", "m.text") # => JSONSchemer::Schema
registry.event_types # => ["m.accepted_terms", ...]
Constant Summary collapse
- MATRIX_FORMATS =
Custom format validators for Matrix-specific format hints.
{ "mx-user-id" => ->(value, _schema) { value.is_a?(String) && value.match?(/\A@[^:]+:.+\z/) }, "mx-room-id" => ->(value, _schema) { value.is_a?(String) && value.match?(/\A![^:]+:.+\z/) }, "mx-event-id" => ->(value, _schema) { value.is_a?(String) && value.match?(/\A\$/) }, "mx-room-alias" => ->(value, _schema) { value.is_a?(String) && value.match?(/\A#[^:]+:.+\z/) }, "mx-server-name" => ->(value, _schema) { value.is_a?(String) && !value.empty? }, "mx-unpadded-base64" => ->(value, _schema) { value.is_a?(String) && value.match?(/\A[A-Za-z0-9+\/]*\z/) }, }.freeze
- GEM_ROOT =
File.("../../../..", __dir__)
- SCHEMA_DIR =
File.join(GEM_ROOT, "data", "matrix-spec", "event-schemas", "schema")
Class Method Summary collapse
-
.instance ⇒ Object
Returns the singleton Registry instance, creating it on first access.
-
.reset! ⇒ Object
Reset the singleton (useful for testing).
Instance Method Summary collapse
-
#[](event_type) ⇒ Object
Look up a schema by Matrix event type (e.g. “m.room.message”).
-
#content_properties(event_type) ⇒ Object
Content properties defined by the schema for a given event type.
-
#event_types ⇒ Array<String>
All known base event types (excludes variant subtypes).
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
-
#size ⇒ Object
Total number of schemas loaded (base + variants).
-
#valid?(event_hash) ⇒ Boolean
Boolean validation.
-
#validate(event_hash) ⇒ Object
Validate an event hash against its schema.
-
#variant(event_type, subtype) ⇒ Object
Look up a variant schema (e.g. variant(“m.room.message”, “m.text”)).
-
#variant_types ⇒ Array<Array(String, String)>
All known variant keys as [event_type, subtype] pairs.
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
54 55 56 57 58 |
# File 'lib/async/matrix/schema/registry.rb', line 54 def initialize @schemas = {} @variants = {} @loaded = false end |
Class Method Details
.instance ⇒ Object
Returns the singleton Registry instance, creating it on first access.
44 45 46 |
# File 'lib/async/matrix/schema/registry.rb', line 44 def instance @instance ||= new end |
.reset! ⇒ Object
Reset the singleton (useful for testing).
49 50 51 |
# File 'lib/async/matrix/schema/registry.rb', line 49 def reset! @instance = nil end |
Instance Method Details
#[](event_type) ⇒ Object
Look up a schema by Matrix event type (e.g. “m.room.message”). Returns a JSONSchemer::Schema or nil if no schema exists for that type.
62 63 64 65 |
# File 'lib/async/matrix/schema/registry.rb', line 62 def [](event_type) load_schemas! unless @loaded @schemas[event_type] end |
#content_properties(event_type) ⇒ Object
Content properties defined by the schema for a given event type. Returns an array of property name strings, or empty array if unknown.
125 126 127 128 129 130 |
# File 'lib/async/matrix/schema/registry.rb', line 125 def content_properties(event_type) schema = self[event_type] return [] unless schema extract_content_properties(schema.value) end |
#event_types ⇒ Array<String>
All known base event types (excludes variant subtypes).
76 77 78 79 |
# File 'lib/async/matrix/schema/registry.rb', line 76 def event_types load_schemas! unless @loaded @schemas.keys.sort end |
#size ⇒ Object
Total number of schemas loaded (base + variants).
89 90 91 92 |
# File 'lib/async/matrix/schema/registry.rb', line 89 def size load_schemas! unless @loaded @schemas.size + @variants.size end |
#valid?(event_hash) ⇒ Boolean
Boolean validation.
119 120 121 |
# File 'lib/async/matrix/schema/registry.rb', line 119 def valid?(event_hash) validate(event_hash).empty? end |
#validate(event_hash) ⇒ Object
Validate an event hash against its schema. Returns an array of error hashes (empty if valid). If no schema exists for the event type, returns empty (lenient).
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/async/matrix/schema/registry.rb', line 97 def validate(event_hash) event_type = event_hash["type"] return [] unless event_type base = self[event_type] return [] unless base errors = base.validate(event_hash).to_a # Also validate against variant if applicable variant_key = detect_variant_key(event_type, event_hash) if variant_key variant_schema = variant(event_type, variant_key) if variant_schema errors.concat(variant_schema.validate(event_hash).to_a) end end errors end |
#variant(event_type, subtype) ⇒ Object
Look up a variant schema (e.g. variant(“m.room.message”, “m.text”)). Returns a JSONSchemer::Schema or nil.
69 70 71 72 |
# File 'lib/async/matrix/schema/registry.rb', line 69 def variant(event_type, subtype) load_schemas! unless @loaded @variants[[event_type, subtype]] end |
#variant_types ⇒ Array<Array(String, String)>
All known variant keys as [event_type, subtype] pairs.
83 84 85 86 |
# File 'lib/async/matrix/schema/registry.rb', line 83 def variant_types load_schemas! unless @loaded @variants.keys.sort end |