Class: AsyncapiCable::Generator::AsyncapiWriter
- Inherits:
-
Object
- Object
- AsyncapiCable::Generator::AsyncapiWriter
- Defined in:
- lib/asyncapi_cable/generator/asyncapi_writer.rb
Class Method Summary collapse
- .build_document(schema_name, schema_config) ⇒ Object
-
.declared_messages(contexts) ⇒ Object
Every declared message becomes a
components/messagesentry pointing at a schema of the same name, so these are referenced by construction — whatever scope they carry. - .generate_all!(output_dir: nil, format: nil) ⇒ Object
-
.load_cable_components(scope, declared: []) ⇒ Object
Bypass OpenapiRuby::Components::Loader#to_openapi_hash and read raw schema definitions directly.
- .write(document, schema_name, output_dir:, format:) ⇒ Object
Class Method Details
.build_document(schema_name, schema_config) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/asyncapi_cable/generator/asyncapi_writer.rb', line 21 def build_document(schema_name, schema_config) scope = (schema_config[:component_scope] || schema_config["component_scope"] || :cable).to_sym contexts = Dsl::MetadataStore.contexts_for(schema_name) components = load_cable_components(scope, declared: (contexts)) document = Core::Document.new( info: schema_config[:info] || schema_config["info"] || {}, servers: schema_config[:servers] || schema_config["servers"] || {}, cable_components: components ) contexts.each do |context| document.add_channel(context) end document end |
.declared_messages(contexts) ⇒ Object
Every declared message becomes a components/messages entry pointing
at a schema of the same name, so these are referenced by construction
— whatever scope they carry. A contract that reuses an existing REST
component as its payload declares one that the document's own scope
does not select.
44 45 46 |
# File 'lib/asyncapi_cable/generator/asyncapi_writer.rb', line 44 def (contexts) contexts.flat_map { |context| context.operations.flat_map(&:messages) }.uniq end |
.generate_all!(output_dir: nil, format: nil) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/asyncapi_cable/generator/asyncapi_writer.rb', line 7 def generate_all!(output_dir: nil, format: nil) configuration = AsyncapiCable.configuration output_dir ||= configuration.schema_output_dir format ||= configuration.schema_output_format raise Error, "AsyncapiCable.configuration.schemas is empty" if configuration.schemas.empty? configuration.schemas.map do |schema_name, schema_config| document = build_document(schema_name, schema_config) path = write(document, schema_name, output_dir: output_dir, format: format) [schema_name, path] end.to_h end |
.load_cable_components(scope, declared: []) ⇒ Object
Bypass OpenapiRuby::Components::Loader#to_openapi_hash and read raw
schema definitions directly. The host's openapi-ruby is configured
with camelize_keys = true which is correct for REST API docs but
wrong for cable AsyncAPI docs whose payloads are the snake_case
wire format BroadcastingConcern actually emits. The runtime
PayloadValidator already does the same bypass for the same reason.
We still need the Loader's eager-load side effect though: component
classes reachable only via $ref strings (e.g. an enum a message
schema refs) aren't autoloaded by Ruby, so a raw registry scan
would miss them. Loader#load! is idempotent.
Scope and the declared messages select the entry points; ReferenceClosure adds what those components reference, whatever scope the referee carries.
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/asyncapi_cable/generator/asyncapi_writer.rb', line 63 def load_cable_components(scope, declared: []) OpenapiRuby::Components::Loader.new.load! scoped = OpenapiRuby::Components::Registry.instance.all_registered_classes.select do |klass| klass._component_scopes.include?(scope) end entry_points = (scoped + declared).uniq schemas = Components::ReferenceClosure.(entry_points, scope: scope) .each_with_object({}) do |klass, acc| acc[klass.component_name] = klass._schema_definition end {"schemas" => schemas} end |
.write(document, schema_name, output_dir:, format:) ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/asyncapi_cable/generator/asyncapi_writer.rb', line 77 def write(document, schema_name, output_dir:, format:) ext = (format.to_sym == :json) ? "json" : "yaml" path = File.join(output_dir, "#{schema_name}.#{ext}") FileUtils.mkdir_p(File.dirname(path)) contents = (ext == "json") ? document.to_json : document.to_yaml File.write(path, contents) path end |