lutaml-asyncapi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop_todo.yml +1 -0
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.md +33 -0
- data/PLAN.md +86 -0
- data/README.md +1 -0
- data/Rakefile +12 -0
- data/lib/lutaml/asyncapi/document.rb +50 -0
- data/lib/lutaml/asyncapi/version.rb +7 -0
- data/lib/lutaml/asyncapi.rb +27 -0
- metadata +110 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b75c05f01f5016b7deba173f61e368b03928246dffb6f33fd5a7a097fbd4f960
|
|
4
|
+
data.tar.gz: eafbc41e37f96e3f5298782b3fe9a9c63a031bd7b0bea907f9cea25da67a5d30
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 883f8c505425be9ad9425614ccc796c4afd64a59b8f93fe2aebba5ed15725ea4567feb9458f59d95ba94ec12ee544dff82a47dd23076f90e3e0b3d139ef13819
|
|
7
|
+
data.tar.gz: f95b27f78433d007a170fdfef17f77f05e34dbdc7719cf2bfd76272e5d26ea17acbe85db67a2b21132788b10f35640cb7a6756e822b4f32cddf14bc10c827154
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Auto-generated by Cimas; offenses baselined at scaffold time.
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
"lutaml-jsonschema" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
+
|
|
5
|
+
* Participants will be tolerant of opposing views.
|
|
6
|
+
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
+
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
+
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
+
|
|
10
|
+
If you have any concerns about behaviour within this project, please contact us at ["ronald.tse@ribose.com"](mailto:"ronald.tse@ribose.com").
|
data/LICENSE.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Licenses & Copyright
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
This license file adheres to the formatting guidelines of
|
|
5
|
+
[readable-licenses](https://github.com/nevir/readable-licenses).
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Ribose's BSD 2-Clause License
|
|
9
|
+
-----------------------------
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026, [Ribose Inc](https://www.ribose.com).
|
|
12
|
+
All rights reserved.
|
|
13
|
+
|
|
14
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
15
|
+
are permitted provided that the following conditions are met:
|
|
16
|
+
|
|
17
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
18
|
+
this list of conditions and the following disclaimer.
|
|
19
|
+
|
|
20
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
21
|
+
this list of conditions and the following disclaimer in the documentation
|
|
22
|
+
and/or other materials provided with the distribution.
|
|
23
|
+
|
|
24
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
25
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
26
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
27
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
28
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
29
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
31
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
32
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
33
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/PLAN.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# PLAN.md — lutaml-asyncapi: AsyncAPI as a model-based standard
|
|
2
|
+
|
|
3
|
+
The event-driven counterpart of the OpenAPI program
|
|
4
|
+
([metanorma/metanorma-ogc#153](https://github.com/metanorma/metanorma-ogc/issues/153),
|
|
5
|
+
`lutaml/lutaml-openapi`): make the AsyncAPI definition the **primary
|
|
6
|
+
publication** of event-driven / pub-sub API standards, with normative
|
|
7
|
+
documentation driven by the AsyncAPI model.
|
|
8
|
+
|
|
9
|
+
## Mission
|
|
10
|
+
|
|
11
|
+
Parse **AsyncAPI 2.6, 3.0 and 3.1** documents into a lossless lutaml-model
|
|
12
|
+
object graph (raw-hash fidelity first, typed views on demand), and feed them
|
|
13
|
+
to documentation renderers the way `lutaml-openapi` feeds
|
|
14
|
+
`metanorma-plugin-openapi`.
|
|
15
|
+
|
|
16
|
+
## Audit basis (2026-10-25)
|
|
17
|
+
|
|
18
|
+
Full spec read: `asyncapi/spec` `spec/asyncapi.md` (v3.1.0, 39 objects),
|
|
19
|
+
meta-schemas `asyncapi/spec-json-schemas` (definitions 1.0.0–3.1.0).
|
|
20
|
+
Corpus: 17 documents in `spec/fixtures` — 15 official 3.1.0 examples,
|
|
21
|
+
`asyncapi-connectedsystems-2.yaml` (2.6.0, 9 embedded publish/subscribe
|
|
22
|
+
operations), `edr-pubsub-asyncapi.yaml` (3.0.0). **All parse; 15/17 round-trip
|
|
23
|
+
losslessly** — `gitter-streaming` and `slack-rtm` are blocked upstream by
|
|
24
|
+
[lutaml/lutaml-model#1013](https://github.com/lutaml/lutaml-model/issues/1013)
|
|
25
|
+
(nested `:hash` attributes silently rename key `text` → `type` and drop
|
|
26
|
+
sibling `description`); they are vendored but excluded from goldens until
|
|
27
|
+
that ships.
|
|
28
|
+
|
|
29
|
+
Corpus facts shaping the model: no `schemaFormat` (Multi Format Schema)
|
|
30
|
+
usage in the wild corpus; bindings sparse (kafka/mqtt/websocket); components
|
|
31
|
+
sections seen in the wild: schemas, messages, parameters, securitySchemes,
|
|
32
|
+
correlationIds, messageTraits, operationTraits (the model must still cover
|
|
33
|
+
the full Components Object inventory: servers, channels, operations, replies,
|
|
34
|
+
replyAddresses, externalDocs, tags, serverBindings, channelBindings,
|
|
35
|
+
operationBindings, messageBindings, serverVariables).
|
|
36
|
+
|
|
37
|
+
## Repos and org parity
|
|
38
|
+
|
|
39
|
+
| Repo | Org | Role | Setup cloned from |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| `lutaml/lutaml-asyncapi` | lutaml | the model gem (this repo) | lutaml-openapi (generic-rake CI, cimas release train, rubocop baseline, BSD-2-Clause) |
|
|
42
|
+
| `metanorma/metanorma-plugin-asyncapi` | metanorma | the Metanorma plugin (M3) | metanorma-plugin-openapi (preprocessor splice, real sections) |
|
|
43
|
+
|
|
44
|
+
Team access mirrors siblings: staff:admin, developers:push, ci:push,
|
|
45
|
+
express:push, editors:push.
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
AsyncAPI 2.6 / 3.0 / 3.1 (YAML/JSON)
|
|
51
|
+
│ parse (2.x/3.0 normalized into the 3.x-shaped model; source version kept)
|
|
52
|
+
▼
|
|
53
|
+
Lutaml::Asyncapi::Document (lossless: mapped roots + map_unmapped)
|
|
54
|
+
│ round-trip goes through to_json —
|
|
55
|
+
│ Serializable#to_hash emits attribute names
|
|
56
|
+
├─► typed views (channels, operations, messages) on demand
|
|
57
|
+
└─► metanorma-plugin-asyncapi (M3): preprocessor splice — block
|
|
58
|
+
processors can never yield sections (Parser.parse_blocks limit)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Milestones
|
|
62
|
+
|
|
63
|
+
- **M0 — model seed (this repo)**: `Lutaml::Asyncapi.parse` (Yeptris
|
|
64
|
+
YAML/JSON by sniffing, version detect), `Document` (3.x shape,
|
|
65
|
+
`map_unmapped` extensions), lossless round-trip goldens from the corpus.
|
|
66
|
+
Done-when: 15/17 goldens green, rubocop clean, CI green.
|
|
67
|
+
- **M1 — full typed model**: typed views for channels/operations/messages/
|
|
68
|
+
components incl. Multi Format Schema, bindings, security schemes; 2.6
|
|
69
|
+
frontend (embedded publish/subscribe → operation view, like Oas30).
|
|
70
|
+
Done-when: every spec object has a typed accessor and a spec.
|
|
71
|
+
- **M2 — validation**: offline meta-schema checks against the vendored
|
|
72
|
+
asyncapi/spec-json-schemas (lutaml-jsonschema precedent, JSON Pointer
|
|
73
|
+
error paths).
|
|
74
|
+
- **M3 — metanorma-plugin-asyncapi**: renderer + preprocessor; OGC
|
|
75
|
+
connected-systems part 2 and EDR pubsub as the acceptance corpus.
|
|
76
|
+
- **M4 — SPA frontend**: single-file human documentation (lutaml-xsd /
|
|
77
|
+
lutaml-jsonschema precedent).
|
|
78
|
+
|
|
79
|
+
## Standing laws
|
|
80
|
+
|
|
81
|
+
- Losslessness lives on the raw hash; typed views are on-demand.
|
|
82
|
+
- No hand-rolled serialization — lutaml-model mappings only
|
|
83
|
+
(`map`/`map_unmapped`/attribute serializers).
|
|
84
|
+
- No doubles in specs — real documents from the corpus.
|
|
85
|
+
- Round-trip assertions go through `to_json` (see the `to_hash` gotcha).
|
|
86
|
+
- Versions are the owner's decision; releases only on explicit instruction.
|
data/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# lutaml-asyncapi
|
data/Rakefile
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module Asyncapi
|
|
5
|
+
# The root AsyncAPI document object, in the 3.x shape.
|
|
6
|
+
#
|
|
7
|
+
# Losslessness lives on the raw mapping: every section is kept verbatim
|
|
8
|
+
# and unmodeled keywords re-emit on serialization (map_unmapped).
|
|
9
|
+
# Round-trip assertions go through to_json — Serializable#to_hash emits
|
|
10
|
+
# attribute names, not mapped wire names.
|
|
11
|
+
class Document < Lutaml::Model::Serializable
|
|
12
|
+
attribute :asyncapi, :string
|
|
13
|
+
attribute :id, :string
|
|
14
|
+
attribute :info, :hash
|
|
15
|
+
attribute :servers, :hash
|
|
16
|
+
attribute :default_content_type, :string
|
|
17
|
+
attribute :channels, :hash
|
|
18
|
+
attribute :operations, :hash
|
|
19
|
+
attribute :components, :hash
|
|
20
|
+
attribute :tags, :hash, collection: true
|
|
21
|
+
attribute :external_docs, :hash
|
|
22
|
+
attribute :extensions, :hash, default: -> { {} }
|
|
23
|
+
|
|
24
|
+
json do
|
|
25
|
+
map "asyncapi", to: :asyncapi
|
|
26
|
+
map "id", to: :id
|
|
27
|
+
map "info", to: :info
|
|
28
|
+
map "servers", to: :servers
|
|
29
|
+
map "defaultContentType", to: :default_content_type
|
|
30
|
+
map "channels", to: :channels
|
|
31
|
+
map "operations", to: :operations
|
|
32
|
+
map "components", to: :components
|
|
33
|
+
map "tags", to: :tags
|
|
34
|
+
map "externalDocs", to: :external_docs
|
|
35
|
+
map_unmapped to: :extensions
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The 2.x dialects embed publish/subscribe in channels and carry
|
|
39
|
+
# root tags/externalDocs; the 3.x model holds them verbatim until
|
|
40
|
+
# the 2.x frontend (PLAN.md M1) normalizes the operation view.
|
|
41
|
+
def dialect
|
|
42
|
+
version = asyncapi.to_s
|
|
43
|
+
case version
|
|
44
|
+
when /\A2\./ then "2.x"
|
|
45
|
+
when /\A3\./ then "3.x"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "yeptris/yaml"
|
|
5
|
+
require "lutaml/model"
|
|
6
|
+
|
|
7
|
+
module Lutaml
|
|
8
|
+
# AsyncAPI 2.6/3.0/3.1 as a lossless lutaml-model.
|
|
9
|
+
module Asyncapi
|
|
10
|
+
autoload :Document, "lutaml/asyncapi/document"
|
|
11
|
+
|
|
12
|
+
# Parses an AsyncAPI document (YAML or JSON) into a Document.
|
|
13
|
+
def self.parse(string)
|
|
14
|
+
data = parse_raw(string)
|
|
15
|
+
Document.from_json(JSON.generate(data))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.parse_raw(string)
|
|
19
|
+
case string
|
|
20
|
+
when /\A\s*{/
|
|
21
|
+
JSON.parse(string)
|
|
22
|
+
else
|
|
23
|
+
Yeptris::YAML.load(string)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lutaml-asyncapi
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ribose Inc.
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: json
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: lutaml-model
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.8.122
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.8.122
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: nokogiri
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: yeptris
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 0.6.34
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 0.6.34
|
|
68
|
+
description: Parse AsyncAPI 2.6/3.0/3.1 documents into lossless LutaML model objects;
|
|
69
|
+
the model layer for model-based AsyncAPI standards
|
|
70
|
+
email:
|
|
71
|
+
- open.source@ribose.com
|
|
72
|
+
executables: []
|
|
73
|
+
extensions: []
|
|
74
|
+
extra_rdoc_files: []
|
|
75
|
+
files:
|
|
76
|
+
- ".rubocop_todo.yml"
|
|
77
|
+
- CHANGELOG.md
|
|
78
|
+
- CODE_OF_CONDUCT.md
|
|
79
|
+
- LICENSE.md
|
|
80
|
+
- PLAN.md
|
|
81
|
+
- README.md
|
|
82
|
+
- Rakefile
|
|
83
|
+
- lib/lutaml/asyncapi.rb
|
|
84
|
+
- lib/lutaml/asyncapi/document.rb
|
|
85
|
+
- lib/lutaml/asyncapi/version.rb
|
|
86
|
+
homepage: https://github.com/lutaml/lutaml-asyncapi
|
|
87
|
+
licenses:
|
|
88
|
+
- BSD-2-Clause
|
|
89
|
+
metadata:
|
|
90
|
+
homepage_uri: https://github.com/lutaml/lutaml-asyncapi
|
|
91
|
+
source_code_uri: https://github.com/lutaml/lutaml-asyncapi
|
|
92
|
+
changelog_uri: https://github.com/lutaml/lutaml-asyncapi/blob/main/CHANGELOG.md
|
|
93
|
+
rdoc_options: []
|
|
94
|
+
require_paths:
|
|
95
|
+
- lib
|
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: 3.2.0
|
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '0'
|
|
106
|
+
requirements: []
|
|
107
|
+
rubygems_version: 3.6.9
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: AsyncAPI 2.6/3.0/3.1 as a lossless lutaml-model
|
|
110
|
+
test_files: []
|