avrotize 2.21.1__py3-none-any.whl
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.
- avrotize/__init__.py +66 -0
- avrotize/__main__.py +6 -0
- avrotize/_version.py +34 -0
- avrotize/asn1toavro.py +160 -0
- avrotize/avrotize.py +152 -0
- avrotize/avrotocpp/CMakeLists.txt.jinja +77 -0
- avrotize/avrotocpp/build.bat.jinja +7 -0
- avrotize/avrotocpp/build.sh.jinja +7 -0
- avrotize/avrotocpp/dataclass_body.jinja +108 -0
- avrotize/avrotocpp/vcpkg.json.jinja +21 -0
- avrotize/avrotocpp.py +483 -0
- avrotize/avrotocsharp/README.md.jinja +166 -0
- avrotize/avrotocsharp/class_test.cs.jinja +266 -0
- avrotize/avrotocsharp/dataclass_core.jinja +293 -0
- avrotize/avrotocsharp/enum_test.cs.jinja +20 -0
- avrotize/avrotocsharp/project.csproj.jinja +30 -0
- avrotize/avrotocsharp/project.sln.jinja +34 -0
- avrotize/avrotocsharp/run_coverage.ps1.jinja +98 -0
- avrotize/avrotocsharp/run_coverage.sh.jinja +149 -0
- avrotize/avrotocsharp/testproject.csproj.jinja +19 -0
- avrotize/avrotocsharp.py +1180 -0
- avrotize/avrotocsv.py +121 -0
- avrotize/avrotodatapackage.py +173 -0
- avrotize/avrotodb.py +1383 -0
- avrotize/avrotogo/go_enum.jinja +12 -0
- avrotize/avrotogo/go_helpers.jinja +31 -0
- avrotize/avrotogo/go_struct.jinja +151 -0
- avrotize/avrotogo/go_test.jinja +47 -0
- avrotize/avrotogo/go_union.jinja +38 -0
- avrotize/avrotogo.py +476 -0
- avrotize/avrotographql.py +197 -0
- avrotize/avrotoiceberg.py +210 -0
- avrotize/avrotojava/class_test.java.jinja +212 -0
- avrotize/avrotojava/enum_test.java.jinja +21 -0
- avrotize/avrotojava/testproject.pom.jinja +54 -0
- avrotize/avrotojava.py +2156 -0
- avrotize/avrotojs.py +250 -0
- avrotize/avrotojsons.py +481 -0
- avrotize/avrotojstruct.py +345 -0
- avrotize/avrotokusto.py +364 -0
- avrotize/avrotomd/README.md.jinja +49 -0
- avrotize/avrotomd.py +137 -0
- avrotize/avrotools.py +168 -0
- avrotize/avrotoparquet.py +208 -0
- avrotize/avrotoproto.py +359 -0
- avrotize/avrotopython/dataclass_core.jinja +241 -0
- avrotize/avrotopython/enum_core.jinja +87 -0
- avrotize/avrotopython/pyproject_toml.jinja +18 -0
- avrotize/avrotopython/test_class.jinja +97 -0
- avrotize/avrotopython/test_enum.jinja +23 -0
- avrotize/avrotopython.py +626 -0
- avrotize/avrotorust/dataclass_enum.rs.jinja +74 -0
- avrotize/avrotorust/dataclass_struct.rs.jinja +204 -0
- avrotize/avrotorust/dataclass_union.rs.jinja +105 -0
- avrotize/avrotorust.py +435 -0
- avrotize/avrotots/class_core.ts.jinja +140 -0
- avrotize/avrotots/class_test.ts.jinja +77 -0
- avrotize/avrotots/enum_core.ts.jinja +46 -0
- avrotize/avrotots/gitignore.jinja +34 -0
- avrotize/avrotots/index.ts.jinja +0 -0
- avrotize/avrotots/package.json.jinja +23 -0
- avrotize/avrotots/tsconfig.json.jinja +21 -0
- avrotize/avrotots.py +687 -0
- avrotize/avrotoxsd.py +344 -0
- avrotize/cddltostructure.py +1841 -0
- avrotize/commands.json +3496 -0
- avrotize/common.py +834 -0
- avrotize/constants.py +87 -0
- avrotize/csvtoavro.py +132 -0
- avrotize/datapackagetoavro.py +76 -0
- avrotize/dependencies/cpp/vcpkg/vcpkg.json +19 -0
- avrotize/dependencies/cs/net90/dependencies.csproj +29 -0
- avrotize/dependencies/go/go121/go.mod +6 -0
- avrotize/dependencies/java/jdk21/pom.xml +91 -0
- avrotize/dependencies/python/py312/requirements.txt +13 -0
- avrotize/dependencies/rust/stable/Cargo.toml +17 -0
- avrotize/dependencies/typescript/node22/package.json +16 -0
- avrotize/dependency_resolver.py +348 -0
- avrotize/dependency_version.py +432 -0
- avrotize/generic/generic.avsc +57 -0
- avrotize/jsonstoavro.py +2167 -0
- avrotize/jsonstostructure.py +2864 -0
- avrotize/jstructtoavro.py +878 -0
- avrotize/kstructtoavro.py +93 -0
- avrotize/kustotoavro.py +455 -0
- avrotize/openapitostructure.py +717 -0
- avrotize/parquettoavro.py +157 -0
- avrotize/proto2parser.py +498 -0
- avrotize/proto3parser.py +403 -0
- avrotize/prototoavro.py +382 -0
- avrotize/prototypes/any.avsc +19 -0
- avrotize/prototypes/api.avsc +106 -0
- avrotize/prototypes/duration.avsc +20 -0
- avrotize/prototypes/field_mask.avsc +18 -0
- avrotize/prototypes/struct.avsc +60 -0
- avrotize/prototypes/timestamp.avsc +20 -0
- avrotize/prototypes/type.avsc +253 -0
- avrotize/prototypes/wrappers.avsc +117 -0
- avrotize/structuretocddl.py +597 -0
- avrotize/structuretocpp/CMakeLists.txt.jinja +76 -0
- avrotize/structuretocpp/build.bat.jinja +3 -0
- avrotize/structuretocpp/build.sh.jinja +3 -0
- avrotize/structuretocpp/dataclass_body.jinja +50 -0
- avrotize/structuretocpp/vcpkg.json.jinja +11 -0
- avrotize/structuretocpp.py +697 -0
- avrotize/structuretocsharp/class_test.cs.jinja +180 -0
- avrotize/structuretocsharp/dataclass_core.jinja +156 -0
- avrotize/structuretocsharp/enum_test.cs.jinja +36 -0
- avrotize/structuretocsharp/json_structure_converters.cs.jinja +399 -0
- avrotize/structuretocsharp/program.cs.jinja +49 -0
- avrotize/structuretocsharp/project.csproj.jinja +17 -0
- avrotize/structuretocsharp/project.sln.jinja +34 -0
- avrotize/structuretocsharp/testproject.csproj.jinja +18 -0
- avrotize/structuretocsharp/tuple_converter.cs.jinja +121 -0
- avrotize/structuretocsharp.py +2295 -0
- avrotize/structuretocsv.py +365 -0
- avrotize/structuretodatapackage.py +659 -0
- avrotize/structuretodb.py +1125 -0
- avrotize/structuretogo/go_enum.jinja +12 -0
- avrotize/structuretogo/go_helpers.jinja +26 -0
- avrotize/structuretogo/go_interface.jinja +18 -0
- avrotize/structuretogo/go_struct.jinja +187 -0
- avrotize/structuretogo/go_test.jinja +70 -0
- avrotize/structuretogo.py +729 -0
- avrotize/structuretographql.py +502 -0
- avrotize/structuretoiceberg.py +355 -0
- avrotize/structuretojava/choice_core.jinja +34 -0
- avrotize/structuretojava/class_core.jinja +23 -0
- avrotize/structuretojava/enum_core.jinja +18 -0
- avrotize/structuretojava/equals_hashcode.jinja +30 -0
- avrotize/structuretojava/pom.xml.jinja +26 -0
- avrotize/structuretojava/tuple_core.jinja +49 -0
- avrotize/structuretojava.py +938 -0
- avrotize/structuretojs/class_core.js.jinja +33 -0
- avrotize/structuretojs/enum_core.js.jinja +10 -0
- avrotize/structuretojs/package.json.jinja +12 -0
- avrotize/structuretojs/test_class.js.jinja +84 -0
- avrotize/structuretojs/test_enum.js.jinja +58 -0
- avrotize/structuretojs/test_runner.js.jinja +45 -0
- avrotize/structuretojs.py +657 -0
- avrotize/structuretojsons.py +498 -0
- avrotize/structuretokusto.py +639 -0
- avrotize/structuretomd/README.md.jinja +204 -0
- avrotize/structuretomd.py +322 -0
- avrotize/structuretoproto.py +764 -0
- avrotize/structuretopython/dataclass_core.jinja +363 -0
- avrotize/structuretopython/enum_core.jinja +45 -0
- avrotize/structuretopython/map_alias.jinja +21 -0
- avrotize/structuretopython/pyproject_toml.jinja +23 -0
- avrotize/structuretopython/test_class.jinja +103 -0
- avrotize/structuretopython/test_enum.jinja +34 -0
- avrotize/structuretopython.py +799 -0
- avrotize/structuretorust/dataclass_enum.rs.jinja +63 -0
- avrotize/structuretorust/dataclass_struct.rs.jinja +121 -0
- avrotize/structuretorust/dataclass_union.rs.jinja +81 -0
- avrotize/structuretorust.py +714 -0
- avrotize/structuretots/class_core.ts.jinja +78 -0
- avrotize/structuretots/enum_core.ts.jinja +6 -0
- avrotize/structuretots/gitignore.jinja +8 -0
- avrotize/structuretots/index.ts.jinja +1 -0
- avrotize/structuretots/package.json.jinja +39 -0
- avrotize/structuretots/test_class.ts.jinja +35 -0
- avrotize/structuretots/tsconfig.json.jinja +21 -0
- avrotize/structuretots.py +740 -0
- avrotize/structuretoxsd.py +679 -0
- avrotize/xsdtoavro.py +413 -0
- avrotize-2.21.1.dist-info/METADATA +1319 -0
- avrotize-2.21.1.dist-info/RECORD +171 -0
- avrotize-2.21.1.dist-info/WHEEL +4 -0
- avrotize-2.21.1.dist-info/entry_points.txt +3 -0
- avrotize-2.21.1.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# {{ schema_name }}
|
|
2
|
+
|
|
3
|
+
{%- if schema_description %}
|
|
4
|
+
{{ schema_description }}
|
|
5
|
+
{%- endif %}
|
|
6
|
+
|
|
7
|
+
{%- if schema_id %}
|
|
8
|
+
**Schema ID:** `{{ schema_id }}`
|
|
9
|
+
{%- endif %}
|
|
10
|
+
|
|
11
|
+
{%- if schema_uses %}
|
|
12
|
+
**Uses Extensions:** {{ schema_uses | join(', ') }}
|
|
13
|
+
{%- endif %}
|
|
14
|
+
|
|
15
|
+
{%- if schema_offers %}
|
|
16
|
+
## Add-in System ($offers)
|
|
17
|
+
|
|
18
|
+
This schema offers the following add-ins:
|
|
19
|
+
|
|
20
|
+
{%- for addin_name, addin_def in schema_offers.items() %}
|
|
21
|
+
### {{ addin_name }}
|
|
22
|
+
{%- if addin_def.description %}
|
|
23
|
+
|
|
24
|
+
{{ addin_def.description }}
|
|
25
|
+
{%- endif %}
|
|
26
|
+
|
|
27
|
+
{%- if addin_def.properties %}
|
|
28
|
+
**Properties:**
|
|
29
|
+
|
|
30
|
+
{%- set required_fields = addin_def.required if addin_def.required else [] %}
|
|
31
|
+
{%- for prop_name, prop_schema in addin_def.properties.items() %}
|
|
32
|
+
{{ generate_property_markdown(prop_name, prop_schema, prop_name in required_fields) }}
|
|
33
|
+
{%- endfor %}
|
|
34
|
+
{%- endif %}
|
|
35
|
+
|
|
36
|
+
{%- endfor %}
|
|
37
|
+
{%- endif %}
|
|
38
|
+
|
|
39
|
+
{%- if objects %}
|
|
40
|
+
## Objects
|
|
41
|
+
{%- for namespace, object_list in objects.items() %}
|
|
42
|
+
{%- if namespace %}
|
|
43
|
+
### Namespace: {{ namespace }}
|
|
44
|
+
{%- endif %}
|
|
45
|
+
{%- for obj in object_list %}
|
|
46
|
+
|
|
47
|
+
### {{ obj.name }}
|
|
48
|
+
{%- if obj.description %}
|
|
49
|
+
|
|
50
|
+
{{ obj.description }}
|
|
51
|
+
{%- endif %}
|
|
52
|
+
|
|
53
|
+
{%- if obj.abstract %}
|
|
54
|
+
**Abstract:** Yes
|
|
55
|
+
{%- endif %}
|
|
56
|
+
|
|
57
|
+
{%- if obj['$extends'] %}
|
|
58
|
+
**Extends:** {{ obj['$extends'] }}
|
|
59
|
+
{%- endif %}
|
|
60
|
+
|
|
61
|
+
{%- if obj['$uses'] %}
|
|
62
|
+
**Uses Extensions:** {{ obj['$uses'] | join(', ') }}
|
|
63
|
+
{%- endif %}
|
|
64
|
+
|
|
65
|
+
{%- if obj.properties %}
|
|
66
|
+
**Properties:**
|
|
67
|
+
|
|
68
|
+
{%- set required_fields = obj.required if obj.required else [] %}
|
|
69
|
+
{%- for prop_name, prop_schema in obj.properties.items() %}
|
|
70
|
+
{{ generate_property_markdown(prop_name, prop_schema, prop_name in required_fields) }}
|
|
71
|
+
{%- endfor %}
|
|
72
|
+
{%- endif %}
|
|
73
|
+
|
|
74
|
+
{%- endfor %}
|
|
75
|
+
{%- endfor %}
|
|
76
|
+
{%- endif %}
|
|
77
|
+
|
|
78
|
+
{%- if choices %}
|
|
79
|
+
## Choice Types (Unions)
|
|
80
|
+
{%- for namespace, choice_list in choices.items() %}
|
|
81
|
+
{%- if namespace %}
|
|
82
|
+
### Namespace: {{ namespace }}
|
|
83
|
+
{%- endif %}
|
|
84
|
+
{%- for choice in choice_list %}
|
|
85
|
+
|
|
86
|
+
### {{ choice.name }}
|
|
87
|
+
{%- if choice.description %}
|
|
88
|
+
|
|
89
|
+
{{ choice.description }}
|
|
90
|
+
{%- endif %}
|
|
91
|
+
|
|
92
|
+
{%- if choice['$extends'] %}
|
|
93
|
+
**Extends:** {{ choice['$extends'] }}
|
|
94
|
+
{%- endif %}
|
|
95
|
+
|
|
96
|
+
{%- if choice['$uses'] %}
|
|
97
|
+
**Uses Extensions:** {{ choice['$uses'] | join(', ') }}
|
|
98
|
+
{%- endif %}
|
|
99
|
+
|
|
100
|
+
{%- if choice.selector %}
|
|
101
|
+
**Selector:** `{{ choice.selector }}`
|
|
102
|
+
{%- endif %}
|
|
103
|
+
|
|
104
|
+
**Choices:**
|
|
105
|
+
|
|
106
|
+
{%- if choice.choices is mapping %}
|
|
107
|
+
{%- for choice_name, choice_schema in choice.choices.items() %}
|
|
108
|
+
- **{{ choice_name }}**: {{ get_type_string(choice_schema) }}
|
|
109
|
+
{%- if choice_schema is mapping and choice_schema.description %}
|
|
110
|
+
- Description: {{ choice_schema.description }}
|
|
111
|
+
{%- endif %}
|
|
112
|
+
{%- endfor %}
|
|
113
|
+
{%- elif choice.choices is iterable %}
|
|
114
|
+
{%- for choice_schema in choice.choices %}
|
|
115
|
+
- {{ get_type_string(choice_schema) }}
|
|
116
|
+
{%- if choice_schema is mapping and choice_schema.description %}
|
|
117
|
+
- Description: {{ choice_schema.description }}
|
|
118
|
+
{%- endif %}
|
|
119
|
+
{%- endfor %}
|
|
120
|
+
{%- endif %}
|
|
121
|
+
|
|
122
|
+
{%- endfor %}
|
|
123
|
+
{%- endfor %}
|
|
124
|
+
{%- endif %}
|
|
125
|
+
|
|
126
|
+
{%- if definitions %}
|
|
127
|
+
## Definitions
|
|
128
|
+
{%- for def_name, def_schema in definitions.items() %}
|
|
129
|
+
|
|
130
|
+
### {{ def_name }}
|
|
131
|
+
{%- if def_schema.description %}
|
|
132
|
+
|
|
133
|
+
{{ def_schema.description }}
|
|
134
|
+
{%- endif %}
|
|
135
|
+
|
|
136
|
+
{%- if def_schema.abstract %}
|
|
137
|
+
**Abstract:** Yes
|
|
138
|
+
{%- endif %}
|
|
139
|
+
|
|
140
|
+
{%- if def_schema['$extends'] %}
|
|
141
|
+
**Extends:** {{ def_schema['$extends'] }}
|
|
142
|
+
{%- endif %}
|
|
143
|
+
|
|
144
|
+
{%- if def_schema['$uses'] %}
|
|
145
|
+
**Uses Extensions:** {{ def_schema['$uses'] | join(', ') }}
|
|
146
|
+
{%- endif %}
|
|
147
|
+
|
|
148
|
+
{%- if def_schema.type == 'object' and def_schema.properties %}
|
|
149
|
+
**Properties:**
|
|
150
|
+
|
|
151
|
+
{%- set required_fields = def_schema.required if def_schema.required else [] %}
|
|
152
|
+
{%- for prop_name, prop_schema in def_schema.properties.items() %}
|
|
153
|
+
{{ generate_property_markdown(prop_name, prop_schema, prop_name in required_fields) }}
|
|
154
|
+
{%- endfor %}
|
|
155
|
+
{%- elif def_schema.type == 'choice' %}
|
|
156
|
+
{%- if def_schema.selector %}
|
|
157
|
+
**Selector:** `{{ def_schema.selector }}`
|
|
158
|
+
{%- endif %}
|
|
159
|
+
|
|
160
|
+
**Choices:**
|
|
161
|
+
|
|
162
|
+
{%- if def_schema.choices is mapping %}
|
|
163
|
+
{%- for choice_name, choice_schema in def_schema.choices.items() %}
|
|
164
|
+
- **{{ choice_name }}**: {{ get_type_string(choice_schema) }}
|
|
165
|
+
{%- if choice_schema is mapping and choice_schema.description %}
|
|
166
|
+
- Description: {{ choice_schema.description }}
|
|
167
|
+
{%- endif %}
|
|
168
|
+
{%- endfor %}
|
|
169
|
+
{%- elif def_schema.choices is iterable %}
|
|
170
|
+
{%- for choice_schema in def_schema.choices %}
|
|
171
|
+
- {{ get_type_string(choice_schema) }}
|
|
172
|
+
{%- if choice_schema is mapping and choice_schema.description %}
|
|
173
|
+
- Description: {{ choice_schema.description }}
|
|
174
|
+
{%- endif %}
|
|
175
|
+
{%- endfor %}
|
|
176
|
+
{%- endif %}
|
|
177
|
+
{%- elif def_schema.enum %}
|
|
178
|
+
**Enum values:** {{ def_schema.enum | join(', ') }}
|
|
179
|
+
{%- else %}
|
|
180
|
+
**Type:** {{ get_type_string(def_schema) }}
|
|
181
|
+
{%- endif %}
|
|
182
|
+
|
|
183
|
+
{%- endfor %}
|
|
184
|
+
{%- endif %}
|
|
185
|
+
|
|
186
|
+
{%- if enums %}
|
|
187
|
+
## Enumerations
|
|
188
|
+
{%- for namespace, enum_list in enums.items() %}
|
|
189
|
+
{%- if namespace %}
|
|
190
|
+
### Namespace: {{ namespace }}
|
|
191
|
+
{%- endif %}
|
|
192
|
+
{%- for enum in enum_list %}
|
|
193
|
+
|
|
194
|
+
### {{ enum.name }}
|
|
195
|
+
{%- if enum.doc %}
|
|
196
|
+
|
|
197
|
+
{{ enum.doc }}
|
|
198
|
+
{%- endif %}
|
|
199
|
+
|
|
200
|
+
**Values:** {{ enum['values'] | join(', ') }}
|
|
201
|
+
|
|
202
|
+
{%- endfor %}
|
|
203
|
+
{%- endfor %}
|
|
204
|
+
{%- endif %}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
"""
|
|
3
|
+
Module to convert JSON Structure schema to Markdown documentation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from typing import Any, Dict, List, Union
|
|
9
|
+
|
|
10
|
+
from avrotize.common import render_template
|
|
11
|
+
|
|
12
|
+
class StructureToMarkdownConverter:
|
|
13
|
+
"""
|
|
14
|
+
Class to convert JSON Structure schema to Markdown documentation.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, structure_schema_path: str, markdown_path: str):
|
|
18
|
+
"""
|
|
19
|
+
Initialize the converter with file paths.
|
|
20
|
+
|
|
21
|
+
:param structure_schema_path: Path to the JSON Structure schema file.
|
|
22
|
+
:param markdown_path: Path to save the Markdown file.
|
|
23
|
+
"""
|
|
24
|
+
self.structure_schema_path = structure_schema_path
|
|
25
|
+
self.markdown_path = markdown_path
|
|
26
|
+
self.objects = {}
|
|
27
|
+
self.choices = {}
|
|
28
|
+
self.enums = {}
|
|
29
|
+
self.definitions = {}
|
|
30
|
+
|
|
31
|
+
def convert(self):
|
|
32
|
+
"""
|
|
33
|
+
Convert JSON Structure schema to Markdown and save to file.
|
|
34
|
+
"""
|
|
35
|
+
with open(self.structure_schema_path, 'r', encoding='utf-8') as file:
|
|
36
|
+
structure_schema = json.load(file)
|
|
37
|
+
|
|
38
|
+
schema_name = os.path.splitext(os.path.basename(self.structure_schema_path))[0]
|
|
39
|
+
|
|
40
|
+
# Process the schema
|
|
41
|
+
self.process_schema(structure_schema)
|
|
42
|
+
|
|
43
|
+
# Generate markdown
|
|
44
|
+
self.generate_markdown(schema_name, structure_schema)
|
|
45
|
+
|
|
46
|
+
def process_schema(self, schema: Dict[str, Any], parent_namespace: str = ''):
|
|
47
|
+
"""
|
|
48
|
+
Process the schema to extract all named types.
|
|
49
|
+
|
|
50
|
+
:param schema: The schema or sub-schema to process
|
|
51
|
+
:param parent_namespace: The parent namespace
|
|
52
|
+
"""
|
|
53
|
+
# Store definitions separately
|
|
54
|
+
if 'definitions' in schema:
|
|
55
|
+
self.definitions = schema['definitions']
|
|
56
|
+
|
|
57
|
+
# Process root schema (but not definitions)
|
|
58
|
+
if 'type' in schema:
|
|
59
|
+
name = schema.get('name', 'Root')
|
|
60
|
+
self.extract_named_types(schema, parent_namespace, name, skip_definitions=True)
|
|
61
|
+
|
|
62
|
+
def extract_named_types(self, schema: Union[Dict, List, str], parent_namespace: str = '', type_name: str = '', skip_definitions: bool = False):
|
|
63
|
+
"""
|
|
64
|
+
Extract all named types (objects, choices, enums) from the schema.
|
|
65
|
+
|
|
66
|
+
:param schema: Schema element to process
|
|
67
|
+
:param parent_namespace: Parent namespace
|
|
68
|
+
:param type_name: Name of this type
|
|
69
|
+
:param skip_definitions: Skip processing definitions (they're handled separately)
|
|
70
|
+
"""
|
|
71
|
+
if isinstance(schema, dict):
|
|
72
|
+
# Skip definitions section when processing root schema
|
|
73
|
+
if skip_definitions and 'definitions' in schema:
|
|
74
|
+
# Create a copy without definitions for processing
|
|
75
|
+
schema = {k: v for k, v in schema.items() if k != 'definitions'}
|
|
76
|
+
|
|
77
|
+
schema_type = schema.get('type')
|
|
78
|
+
ns = schema.get('namespace', parent_namespace)
|
|
79
|
+
name = schema.get('name', type_name)
|
|
80
|
+
|
|
81
|
+
# Only add named objects and choices to the respective lists
|
|
82
|
+
# Inline/anonymous objects should not be listed separately
|
|
83
|
+
if schema_type == 'object' and 'name' in schema:
|
|
84
|
+
self.objects.setdefault(ns, []).append(schema)
|
|
85
|
+
elif schema_type == 'choice' and 'name' in schema:
|
|
86
|
+
self.choices.setdefault(ns, []).append(schema)
|
|
87
|
+
elif 'enum' in schema:
|
|
88
|
+
# Handle enum constraint
|
|
89
|
+
self.enums.setdefault(ns, []).append({
|
|
90
|
+
'name': name,
|
|
91
|
+
'values': schema['enum'],
|
|
92
|
+
'doc': schema.get('description', '')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
# Recursively process properties
|
|
96
|
+
if 'properties' in schema:
|
|
97
|
+
for prop_name, prop_schema in schema['properties'].items():
|
|
98
|
+
self.extract_named_types(prop_schema, ns, prop_name)
|
|
99
|
+
|
|
100
|
+
# Process items in arrays/sets
|
|
101
|
+
if 'items' in schema:
|
|
102
|
+
self.extract_named_types(schema['items'], ns)
|
|
103
|
+
|
|
104
|
+
# Process values in maps
|
|
105
|
+
if 'values' in schema:
|
|
106
|
+
self.extract_named_types(schema['values'], ns)
|
|
107
|
+
|
|
108
|
+
# Process choice alternatives
|
|
109
|
+
if 'choices' in schema:
|
|
110
|
+
choices = schema['choices']
|
|
111
|
+
if isinstance(choices, dict):
|
|
112
|
+
for choice_name, choice_schema in choices.items():
|
|
113
|
+
self.extract_named_types(choice_schema, ns, choice_name)
|
|
114
|
+
elif isinstance(choices, list):
|
|
115
|
+
for choice_schema in choices:
|
|
116
|
+
self.extract_named_types(choice_schema, ns)
|
|
117
|
+
|
|
118
|
+
elif isinstance(schema, list):
|
|
119
|
+
# Union type
|
|
120
|
+
for sub_schema in schema:
|
|
121
|
+
self.extract_named_types(sub_schema, parent_namespace)
|
|
122
|
+
|
|
123
|
+
def generate_markdown(self, schema_name: str, root_schema: Dict[str, Any]):
|
|
124
|
+
"""
|
|
125
|
+
Generate markdown content from the extracted types using Jinja2 template.
|
|
126
|
+
|
|
127
|
+
:param schema_name: The name of the schema file.
|
|
128
|
+
:param root_schema: The root schema object
|
|
129
|
+
"""
|
|
130
|
+
render_template("structuretomd/README.md.jinja", self.markdown_path,
|
|
131
|
+
schema_name=schema_name,
|
|
132
|
+
schema_description=root_schema.get('description', ''),
|
|
133
|
+
schema_id=root_schema.get('$id', ''),
|
|
134
|
+
schema_uses=root_schema.get('$uses', []),
|
|
135
|
+
schema_offers=root_schema.get('$offers', {}),
|
|
136
|
+
objects=self.objects,
|
|
137
|
+
choices=self.choices,
|
|
138
|
+
enums=self.enums,
|
|
139
|
+
definitions=self.definitions,
|
|
140
|
+
generate_property_markdown=self.generate_property_markdown,
|
|
141
|
+
get_type_string=self.get_type_string
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def generate_property_markdown(self, prop_name: str, prop_schema: Union[Dict, List, str], required: bool = False) -> str:
|
|
145
|
+
"""
|
|
146
|
+
Generate markdown content for a single property.
|
|
147
|
+
|
|
148
|
+
:param prop_name: Property name
|
|
149
|
+
:param prop_schema: Property schema
|
|
150
|
+
:param required: Whether the property is required
|
|
151
|
+
:return: Markdown content as a string
|
|
152
|
+
"""
|
|
153
|
+
lines = []
|
|
154
|
+
type_str = self.get_type_string(prop_schema)
|
|
155
|
+
required_str = " (required)" if required else ""
|
|
156
|
+
|
|
157
|
+
lines.append(f"- **{prop_name}**{required_str}: {type_str}")
|
|
158
|
+
|
|
159
|
+
# Add description if present
|
|
160
|
+
if isinstance(prop_schema, dict):
|
|
161
|
+
if 'description' in prop_schema:
|
|
162
|
+
lines.append(f" - Description: {prop_schema['description']}")
|
|
163
|
+
|
|
164
|
+
# Add extension properties (from various JSON Structure extension specs)
|
|
165
|
+
extensions = []
|
|
166
|
+
|
|
167
|
+
# Alternate names (JSONStructureAlternateNames extension)
|
|
168
|
+
if 'altnames' in prop_schema:
|
|
169
|
+
altnames = prop_schema['altnames']
|
|
170
|
+
if isinstance(altnames, dict):
|
|
171
|
+
altnames_list = [f"{k}: {v}" for k, v in altnames.items()]
|
|
172
|
+
extensions.append(f"altnames: {{{', '.join(altnames_list)}}}")
|
|
173
|
+
|
|
174
|
+
# Units (JSONStructureUnits extension)
|
|
175
|
+
if 'unit' in prop_schema:
|
|
176
|
+
extensions.append(f"unit: {prop_schema['unit']}")
|
|
177
|
+
|
|
178
|
+
# Currency (for decimal types)
|
|
179
|
+
if 'currency' in prop_schema:
|
|
180
|
+
extensions.append(f"currency: {prop_schema['currency']}")
|
|
181
|
+
|
|
182
|
+
# Symbol (from JSONStructureSymbol extension)
|
|
183
|
+
if 'symbol' in prop_schema:
|
|
184
|
+
extensions.append(f"symbol: {prop_schema['symbol']}")
|
|
185
|
+
|
|
186
|
+
# Content encoding/media type (JSONStructureContent extension)
|
|
187
|
+
if 'contentEncoding' in prop_schema:
|
|
188
|
+
extensions.append(f"contentEncoding: {prop_schema['contentEncoding']}")
|
|
189
|
+
if 'contentMediaType' in prop_schema:
|
|
190
|
+
extensions.append(f"contentMediaType: {prop_schema['contentMediaType']}")
|
|
191
|
+
|
|
192
|
+
# Format
|
|
193
|
+
if 'format' in prop_schema:
|
|
194
|
+
extensions.append(f"format: {prop_schema['format']}")
|
|
195
|
+
|
|
196
|
+
# Examples
|
|
197
|
+
if 'examples' in prop_schema:
|
|
198
|
+
examples_str = ', '.join(str(ex) for ex in prop_schema['examples'])
|
|
199
|
+
extensions.append(f"examples: [{examples_str}]")
|
|
200
|
+
|
|
201
|
+
# Default value
|
|
202
|
+
if 'default' in prop_schema:
|
|
203
|
+
extensions.append(f"default: {prop_schema['default']}")
|
|
204
|
+
|
|
205
|
+
if extensions:
|
|
206
|
+
lines.append(f" - Extensions: {', '.join(extensions)}")
|
|
207
|
+
|
|
208
|
+
# Add constraints
|
|
209
|
+
constraints = []
|
|
210
|
+
if 'minLength' in prop_schema:
|
|
211
|
+
constraints.append(f"minLength: {prop_schema['minLength']}")
|
|
212
|
+
if 'maxLength' in prop_schema:
|
|
213
|
+
constraints.append(f"maxLength: {prop_schema['maxLength']}")
|
|
214
|
+
if 'minimum' in prop_schema:
|
|
215
|
+
constraints.append(f"minimum: {prop_schema['minimum']}")
|
|
216
|
+
if 'maximum' in prop_schema:
|
|
217
|
+
constraints.append(f"maximum: {prop_schema['maximum']}")
|
|
218
|
+
if 'exclusiveMinimum' in prop_schema:
|
|
219
|
+
constraints.append(f"exclusiveMinimum: {prop_schema['exclusiveMinimum']}")
|
|
220
|
+
if 'exclusiveMaximum' in prop_schema:
|
|
221
|
+
constraints.append(f"exclusiveMaximum: {prop_schema['exclusiveMaximum']}")
|
|
222
|
+
if 'multipleOf' in prop_schema:
|
|
223
|
+
constraints.append(f"multipleOf: {prop_schema['multipleOf']}")
|
|
224
|
+
if 'pattern' in prop_schema:
|
|
225
|
+
constraints.append(f"pattern: `{prop_schema['pattern']}`")
|
|
226
|
+
if 'minItems' in prop_schema:
|
|
227
|
+
constraints.append(f"minItems: {prop_schema['minItems']}")
|
|
228
|
+
if 'maxItems' in prop_schema:
|
|
229
|
+
constraints.append(f"maxItems: {prop_schema['maxItems']}")
|
|
230
|
+
if 'precision' in prop_schema:
|
|
231
|
+
constraints.append(f"precision: {prop_schema['precision']}")
|
|
232
|
+
if 'scale' in prop_schema:
|
|
233
|
+
constraints.append(f"scale: {prop_schema['scale']}")
|
|
234
|
+
if 'enum' in prop_schema:
|
|
235
|
+
constraints.append(f"enum: {', '.join(str(v) for v in prop_schema['enum'])}")
|
|
236
|
+
if 'const' in prop_schema:
|
|
237
|
+
constraints.append(f"const: {prop_schema['const']}")
|
|
238
|
+
|
|
239
|
+
if constraints:
|
|
240
|
+
lines.append(f" - Constraints: {', '.join(constraints)}")
|
|
241
|
+
|
|
242
|
+
return '\n'.join(lines)
|
|
243
|
+
|
|
244
|
+
def get_type_string(self, schema: Union[Dict, List, str]) -> str:
|
|
245
|
+
"""
|
|
246
|
+
Get a string representation of a type.
|
|
247
|
+
|
|
248
|
+
:param schema: Type schema
|
|
249
|
+
:return: Type string
|
|
250
|
+
"""
|
|
251
|
+
if isinstance(schema, str):
|
|
252
|
+
# Simple type reference or primitive
|
|
253
|
+
if schema.startswith('#/'):
|
|
254
|
+
# Reference
|
|
255
|
+
ref_parts = schema.split('/')
|
|
256
|
+
return f"[{ref_parts[-1]}](#{ref_parts[-1].lower()})"
|
|
257
|
+
return f"`{schema}`"
|
|
258
|
+
|
|
259
|
+
elif isinstance(schema, list):
|
|
260
|
+
# Union type
|
|
261
|
+
type_strs = [self.get_type_string(t) for t in schema]
|
|
262
|
+
return ' | '.join(type_strs)
|
|
263
|
+
|
|
264
|
+
elif isinstance(schema, dict):
|
|
265
|
+
schema_type = schema.get('type')
|
|
266
|
+
|
|
267
|
+
if '$ref' in schema:
|
|
268
|
+
# Reference
|
|
269
|
+
ref = schema['$ref']
|
|
270
|
+
ref_parts = ref.split('/')
|
|
271
|
+
ref_name = ref_parts[-1]
|
|
272
|
+
return f"[{ref_name}](#{ref_name.lower()})"
|
|
273
|
+
|
|
274
|
+
if schema_type == 'array':
|
|
275
|
+
items_type = self.get_type_string(schema.get('items', 'any'))
|
|
276
|
+
return f"array<{items_type}>"
|
|
277
|
+
|
|
278
|
+
elif schema_type == 'set':
|
|
279
|
+
items_type = self.get_type_string(schema.get('items', 'any'))
|
|
280
|
+
return f"set<{items_type}>"
|
|
281
|
+
|
|
282
|
+
elif schema_type == 'map':
|
|
283
|
+
keys_type = self.get_type_string(schema.get('keys', 'string'))
|
|
284
|
+
values_type = self.get_type_string(schema.get('values', 'any'))
|
|
285
|
+
return f"map<{keys_type}, {values_type}>"
|
|
286
|
+
|
|
287
|
+
elif schema_type == 'tuple':
|
|
288
|
+
items = schema.get('items', [])
|
|
289
|
+
if isinstance(items, list):
|
|
290
|
+
item_types = [self.get_type_string(item) for item in items]
|
|
291
|
+
return f"tuple<{', '.join(item_types)}>"
|
|
292
|
+
return "tuple"
|
|
293
|
+
|
|
294
|
+
elif schema_type == 'choice':
|
|
295
|
+
name = schema.get('name', 'Choice')
|
|
296
|
+
return f"[{name}](#{name.lower()})"
|
|
297
|
+
|
|
298
|
+
elif schema_type == 'object':
|
|
299
|
+
name = schema.get('name', 'object')
|
|
300
|
+
if name != 'object':
|
|
301
|
+
return f"[{name}](#{name.lower()})"
|
|
302
|
+
return "`object`"
|
|
303
|
+
|
|
304
|
+
elif schema_type:
|
|
305
|
+
return f"`{schema_type}`"
|
|
306
|
+
|
|
307
|
+
# If no type specified but has properties, it's an inline object
|
|
308
|
+
if 'properties' in schema:
|
|
309
|
+
return "`object` (inline)"
|
|
310
|
+
|
|
311
|
+
return "`any`"
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def convert_structure_to_markdown(structure_schema_path: str, markdown_path: str):
|
|
315
|
+
"""
|
|
316
|
+
Convert a JSON Structure schema file to a Markdown file.
|
|
317
|
+
|
|
318
|
+
:param structure_schema_path: Path to the JSON Structure schema file.
|
|
319
|
+
:param markdown_path: Path to save the Markdown file.
|
|
320
|
+
"""
|
|
321
|
+
converter = StructureToMarkdownConverter(structure_schema_path, markdown_path)
|
|
322
|
+
converter.convert()
|