structurize 2.16.2__py3-none-any.whl → 2.16.5__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.
Files changed (53) hide show
  1. avrotize/__init__.py +63 -63
  2. avrotize/__main__.py +5 -5
  3. avrotize/_version.py +34 -34
  4. avrotize/asn1toavro.py +160 -160
  5. avrotize/avrotize.py +152 -152
  6. avrotize/avrotocpp.py +483 -483
  7. avrotize/avrotocsharp.py +992 -992
  8. avrotize/avrotocsv.py +121 -121
  9. avrotize/avrotodatapackage.py +173 -173
  10. avrotize/avrotodb.py +1383 -1383
  11. avrotize/avrotogo.py +476 -476
  12. avrotize/avrotographql.py +197 -197
  13. avrotize/avrotoiceberg.py +210 -210
  14. avrotize/avrotojava.py +1023 -1023
  15. avrotize/avrotojs.py +250 -250
  16. avrotize/avrotojsons.py +481 -481
  17. avrotize/avrotojstruct.py +345 -345
  18. avrotize/avrotokusto.py +363 -363
  19. avrotize/avrotomd.py +137 -137
  20. avrotize/avrotools.py +168 -168
  21. avrotize/avrotoparquet.py +208 -208
  22. avrotize/avrotoproto.py +358 -358
  23. avrotize/avrotopython.py +622 -622
  24. avrotize/avrotorust.py +435 -435
  25. avrotize/avrotots.py +598 -598
  26. avrotize/avrotoxsd.py +344 -344
  27. avrotize/commands.json +2493 -2433
  28. avrotize/common.py +828 -828
  29. avrotize/constants.py +4 -4
  30. avrotize/csvtoavro.py +131 -131
  31. avrotize/datapackagetoavro.py +76 -76
  32. avrotize/dependency_resolver.py +348 -348
  33. avrotize/jsonstoavro.py +1698 -1698
  34. avrotize/jsonstostructure.py +2642 -2642
  35. avrotize/jstructtoavro.py +878 -878
  36. avrotize/kstructtoavro.py +93 -93
  37. avrotize/kustotoavro.py +455 -455
  38. avrotize/parquettoavro.py +157 -157
  39. avrotize/proto2parser.py +497 -497
  40. avrotize/proto3parser.py +402 -402
  41. avrotize/prototoavro.py +382 -382
  42. avrotize/structuretocsharp.py +2005 -2005
  43. avrotize/structuretojsons.py +498 -498
  44. avrotize/structuretopython.py +772 -772
  45. avrotize/structuretots.py +653 -0
  46. avrotize/xsdtoavro.py +413 -413
  47. {structurize-2.16.2.dist-info → structurize-2.16.5.dist-info}/METADATA +848 -805
  48. structurize-2.16.5.dist-info/RECORD +52 -0
  49. {structurize-2.16.2.dist-info → structurize-2.16.5.dist-info}/licenses/LICENSE +200 -200
  50. structurize-2.16.2.dist-info/RECORD +0 -51
  51. {structurize-2.16.2.dist-info → structurize-2.16.5.dist-info}/WHEEL +0 -0
  52. {structurize-2.16.2.dist-info → structurize-2.16.5.dist-info}/entry_points.txt +0 -0
  53. {structurize-2.16.2.dist-info → structurize-2.16.5.dist-info}/top_level.txt +0 -0
avrotize/avrotojs.py CHANGED
@@ -1,250 +1,250 @@
1
- """ Convert Avro schema to TypeScript classes """
2
-
3
- import json
4
- import os
5
- from typing import Any, Dict, List, Set, Union
6
-
7
- from avrotize.common import pascal
8
-
9
- INDENT = ' ' * 4
10
-
11
- def is_javascript_reserved_word(word: str) -> bool:
12
- """ Check if word is a TypeScript reserved word """
13
- reserved_words = [
14
- 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
15
- 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally',
16
- 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'return',
17
- 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void',
18
- 'while', 'with', 'yield'
19
- ]
20
- return word in reserved_words
21
-
22
- def is_javascript_primitive(word: str) -> bool:
23
- """ Check if word is a TypeScript primitive """
24
- primitives = ['null', 'boolean', 'number', 'string', 'Date']
25
- return word in primitives
26
-
27
- class AvroToJavaScript:
28
- """ Convert Avro schema to TypeScript classes """
29
-
30
- def __init__(self, base_package: str = '', avro_annotation=False) -> None:
31
- self.base_package = base_package
32
- self.avro_annotation = avro_annotation
33
- self.output_dir = os.getcwd()
34
-
35
- def map_primitive_to_javascript(self, avro_type: str) -> str:
36
- """ Map Avro primitive type to TypeScript type """
37
- mapping = {
38
- 'null': 'null',
39
- 'boolean': 'boolean',
40
- 'int': 'number',
41
- 'long': 'number',
42
- 'float': 'number',
43
- 'double': 'number',
44
- 'bytes': 'string',
45
- 'string': 'string',
46
- }
47
- return mapping.get(avro_type, avro_type)
48
-
49
- def convert_logical_type_to_javascript(self, avro_type: Dict) -> str:
50
- """ Convert Avro logical type to TypeScript type """
51
- if 'logicalType' in avro_type:
52
- if avro_type['logicalType'] in ['decimal', 'uuid']:
53
- return 'string'
54
- if avro_type['logicalType'] in ['date', 'time-millis', 'time-micros', 'timestamp-millis', 'timestamp-micros']:
55
- return 'Date'
56
- if avro_type['logicalType'] == 'duration':
57
- return 'string'
58
- return 'any'
59
-
60
- def is_javascript_primitive(self, avro_type: str) -> bool:
61
- """ Check if Avro type is a TypeScript primitive """
62
- return avro_type in ['null', 'boolean', 'number', 'string', 'Date']
63
-
64
- def convert_avro_type_to_javascript(self, avro_type: Union[str, Dict, List], parent_namespace: str, import_types: set) -> str | List[Any]:
65
- """ Convert Avro type to TypeScript type """
66
- if isinstance(avro_type, str):
67
- mapped_type = self.map_primitive_to_javascript(avro_type)
68
- if mapped_type == avro_type and not self.is_javascript_primitive(mapped_type):
69
- import_types.add(mapped_type)
70
- return pascal(mapped_type.split('.')[-1])
71
- return mapped_type
72
- elif isinstance(avro_type, list):
73
- return [self.convert_avro_type_to_javascript(t, parent_namespace, import_types) for t in avro_type]
74
- elif isinstance(avro_type, dict):
75
- if 'type' in avro_type and avro_type['type'] == 'record':
76
- class_ref = self.generate_class(avro_type, parent_namespace)
77
- import_types.add(class_ref)
78
- return class_ref.split('.')[-1]
79
- elif 'type' in avro_type and avro_type['type'] == 'enum':
80
- enum_ref = self.generate_enum(avro_type, parent_namespace)
81
- import_types.add(enum_ref)
82
- return enum_ref.split('.')[-1]
83
- elif 'type' in avro_type and avro_type['type'] == 'array':
84
- return [self.convert_avro_type_to_javascript(avro_type["items"], parent_namespace, import_types)]
85
- if 'type' in avro_type and avro_type['type'] == 'map':
86
- return [self.convert_avro_type_to_javascript(avro_type["values"], parent_namespace, import_types)]
87
- if 'logicalType' in avro_type:
88
- return self.convert_logical_type_to_javascript(avro_type)
89
- return self.convert_avro_type_to_javascript(avro_type['type'], parent_namespace, import_types)
90
- return 'any'
91
-
92
- def generate_class(self, avro_schema: Dict, parent_namespace: str) -> str:
93
- """ Generate TypeScript class from Avro record """
94
-
95
- def add_check(arr_check, ft):
96
- if isinstance(ft, list):
97
- for ft2 in ft:
98
- add_check(arr_check, ft2)
99
- elif ft == 'null':
100
- arr_check.append('v !== null')
101
- elif is_javascript_primitive(ft):
102
- arr_check.append(f'typeof v !== "{ft}"')
103
- else:
104
- arr_check.append(f'!(v instanceof {ft})')
105
-
106
- import_types: Set[str] = set()
107
- class_name = pascal(avro_schema['name'])
108
- namespace = avro_schema.get('namespace', '')
109
- if not namespace and parent_namespace:
110
- namespace = parent_namespace
111
- if self.base_package:
112
- namespace = f'{self.base_package}.{namespace}'
113
- fields = avro_schema.get('fields', [])
114
- doc = avro_schema.get('doc', '')
115
-
116
- constructor_body = ''
117
- class_body = ''
118
- if self.avro_annotation:
119
- avro_schema_json = json.dumps(avro_schema)
120
- avro_schema_json = avro_schema_json.replace('"', '§')
121
- avro_schema_json = f"\"+\n{' '*8}\"".join([avro_schema_json[i:i+80] for i in range(0, len(avro_schema_json), 80)])
122
- avro_schema_json = avro_schema_json.replace('§', '\\"')
123
- class_body += f'{class_name}.AvroType = avro.parse("{avro_schema_json}");\n'
124
- for field in fields:
125
- field_name = field['name']
126
- field_doc = field.get('doc', '')
127
- field_avro_type = field['type']
128
- if is_javascript_reserved_word(field_name):
129
- field_name += '_'
130
- field_type = self.convert_avro_type_to_javascript(field['type'], namespace, import_types)
131
- if field_doc:
132
- constructor_body += f'{INDENT}/** {field_doc} */\n'
133
- constructor_body += f'{INDENT}_{field_name} = null;\n'
134
- class_body += f'Object.defineProperty({class_name}.prototype, "{field_name}", {{\n'
135
- class_body += f'{INDENT}get: function() {{'+'\n'
136
- class_body += f'{INDENT}{INDENT}return this._{field_name};\n'
137
- class_body += f'{INDENT}}},\n'
138
- class_body += f'{INDENT}set: function(value) {{'+'\n'
139
- type_check = []
140
- if field_avro_type == 'array':
141
- arr = '!Array.isArray(value) || value.some(v => '
142
- arr_check: List[str] = []
143
- for ft in field_type if isinstance(field_type, list) else [field_type]:
144
- add_check(arr_check, ft)
145
- arr += ' || '.join(arr_check) + ')'
146
- type_check.append(arr)
147
- elif field_avro_type == 'map':
148
- map = '!Object.entries(value).every(([k, v]) => typeof k === "string" && '
149
- map_check: List[str] = []
150
- for ft in field_type if isinstance(field_type, list) else [field_type]:
151
- add_check(map_check, ft)
152
- map += ' && '.join(map_check) + ')'
153
- type_check.append(map)
154
- else:
155
- for ft in field_type if isinstance(field_type, list) else [field_type]:
156
- add_check(type_check, ft)
157
- class_body += f'{INDENT}{INDENT}if ( {" && ".join(type_check)} ) throw new Error(`Invalid type for {field_name}. Expected {field_type}, got ${{value}}`);\n'
158
- class_body += f'{INDENT}{INDENT}this._{field_name} = value;\n'
159
- class_body += f'{INDENT}}}'+'\n'
160
- class_body += '});\n\n'
161
-
162
- imports = ''
163
- if self.avro_annotation:
164
- imports += "var avro = require('avro-js');\n"
165
- for import_type in import_types:
166
- import_type_package = import_type.rsplit('.',1)[0]
167
- import_type_type = pascal(import_type.split('.')[-1])
168
- import_type_package = import_type_package.replace('.', '/')
169
- namespace_path = namespace.replace('.', '/')
170
-
171
- if import_type_package:# get the relative path from the namespace to the import_type_package
172
- import_type_package = os.path.relpath(import_type_package, namespace_path).replace(os.sep, '/')
173
- if not import_type_package.startswith('.'):
174
- import_type_package = f'./{import_type_package}'
175
- imports += f"var {import_type_type} = require('{import_type_package}/{import_type_type}').{import_type_type};\n"
176
- else:
177
- imports += f"var {import_type_type} = require('{import_type_type}'){import_type_type};\n"
178
-
179
- class_definition = imports + '\n'
180
- if doc:
181
- class_definition += f'/** {doc} */\n'
182
- class_definition += f"function {class_name}() {{\n{constructor_body}}}\n\n{class_body}\nmodule.exports = {class_name};\n"
183
- self.write_to_file(namespace, class_name, class_definition)
184
- return f'{namespace}.{class_name}'
185
-
186
- def generate_enum(self, avro_schema: Dict, parent_namespace: str) -> str:
187
- """ Generate TypeScript enum from Avro enum """
188
- enum_name = pascal(avro_schema['name'])
189
- namespace = avro_schema.get('namespace', '')
190
- if not namespace and parent_namespace:
191
- namespace = parent_namespace
192
- if self.base_package:
193
- namespace = f'{self.base_package}.{namespace}'
194
- symbols = avro_schema.get('symbols', [])
195
-
196
- enum_body = ''
197
- for symbol in symbols:
198
- if is_javascript_reserved_word(symbol):
199
- symbol += '_'
200
- enum_body += f'{INDENT}{symbol}: "{symbol}",\n'
201
-
202
- enum_definition = ''
203
- if 'doc' in avro_schema:
204
- enum_definition += f"/** {avro_schema['doc']} */\n"
205
- enum_definition += f"const {enum_name} = Object.freeze({{\n{enum_body}}});\n\n"
206
- enum_definition += f"module.exports = {enum_name};\n"
207
- self.write_to_file(namespace, enum_name, enum_definition)
208
- return f'{namespace}.{enum_name}'
209
-
210
- def write_to_file(self, namespace: str, name: str, content: str):
211
- """ Write TypeScript class to file """
212
- directory_path = os.path.join(self.output_dir, namespace.replace('.', os.sep))
213
- if not os.path.exists(directory_path):
214
- os.makedirs(directory_path, exist_ok=True)
215
-
216
- file_path = os.path.join(directory_path, f"{name}.js")
217
- with open(file_path, 'w', encoding='utf-8') as file:
218
- file.write(content)
219
-
220
- def convert_schema(self, schema: List|Dict, output_dir: str):
221
- """ Convert Avro schema to TypeScript classes """
222
- self.output_dir = output_dir
223
- if isinstance(schema, dict):
224
- schema = [schema]
225
-
226
- for avro_schema in schema:
227
- if avro_schema['type'] == 'record':
228
- self.generate_class(avro_schema, self.base_package)
229
- elif avro_schema['type'] == 'enum':
230
- self.generate_enum(avro_schema, self.base_package)
231
-
232
- def convert(self, avro_schema_path: str, output_dir: str):
233
- """ Convert Avro schema to TypeScript classes """
234
- with open(avro_schema_path, 'r', encoding='utf-8') as file:
235
- schema = json.load(file)
236
- self.convert_schema(schema, output_dir)
237
-
238
- def convert_avro_to_javascript(avro_schema_path, js_dir_path, package_name='', avro_annotation=False):
239
- """ Convert Avro schema to TypeScript classes """
240
-
241
- if not package_name:
242
- package_name = os.path.splitext(os.path.basename(avro_schema_path))[0].replace('-', '_')
243
-
244
- converter = AvroToJavaScript(package_name, avro_annotation=avro_annotation)
245
- converter.convert(avro_schema_path, js_dir_path)
246
-
247
- def convert_avro_schema_to_javascript(avro_schema, js_dir_path, package_name='', avro_annotation=False):
248
- """ Convert Avro schema to TypeScript classes """
249
- converter = AvroToJavaScript(package_name, avro_annotation=avro_annotation)
250
- converter.convert_schema(avro_schema, js_dir_path)
1
+ """ Convert Avro schema to TypeScript classes """
2
+
3
+ import json
4
+ import os
5
+ from typing import Any, Dict, List, Set, Union
6
+
7
+ from avrotize.common import pascal
8
+
9
+ INDENT = ' ' * 4
10
+
11
+ def is_javascript_reserved_word(word: str) -> bool:
12
+ """ Check if word is a TypeScript reserved word """
13
+ reserved_words = [
14
+ 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
15
+ 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally',
16
+ 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'return',
17
+ 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void',
18
+ 'while', 'with', 'yield'
19
+ ]
20
+ return word in reserved_words
21
+
22
+ def is_javascript_primitive(word: str) -> bool:
23
+ """ Check if word is a TypeScript primitive """
24
+ primitives = ['null', 'boolean', 'number', 'string', 'Date']
25
+ return word in primitives
26
+
27
+ class AvroToJavaScript:
28
+ """ Convert Avro schema to TypeScript classes """
29
+
30
+ def __init__(self, base_package: str = '', avro_annotation=False) -> None:
31
+ self.base_package = base_package
32
+ self.avro_annotation = avro_annotation
33
+ self.output_dir = os.getcwd()
34
+
35
+ def map_primitive_to_javascript(self, avro_type: str) -> str:
36
+ """ Map Avro primitive type to TypeScript type """
37
+ mapping = {
38
+ 'null': 'null',
39
+ 'boolean': 'boolean',
40
+ 'int': 'number',
41
+ 'long': 'number',
42
+ 'float': 'number',
43
+ 'double': 'number',
44
+ 'bytes': 'string',
45
+ 'string': 'string',
46
+ }
47
+ return mapping.get(avro_type, avro_type)
48
+
49
+ def convert_logical_type_to_javascript(self, avro_type: Dict) -> str:
50
+ """ Convert Avro logical type to TypeScript type """
51
+ if 'logicalType' in avro_type:
52
+ if avro_type['logicalType'] in ['decimal', 'uuid']:
53
+ return 'string'
54
+ if avro_type['logicalType'] in ['date', 'time-millis', 'time-micros', 'timestamp-millis', 'timestamp-micros']:
55
+ return 'Date'
56
+ if avro_type['logicalType'] == 'duration':
57
+ return 'string'
58
+ return 'any'
59
+
60
+ def is_javascript_primitive(self, avro_type: str) -> bool:
61
+ """ Check if Avro type is a TypeScript primitive """
62
+ return avro_type in ['null', 'boolean', 'number', 'string', 'Date']
63
+
64
+ def convert_avro_type_to_javascript(self, avro_type: Union[str, Dict, List], parent_namespace: str, import_types: set) -> str | List[Any]:
65
+ """ Convert Avro type to TypeScript type """
66
+ if isinstance(avro_type, str):
67
+ mapped_type = self.map_primitive_to_javascript(avro_type)
68
+ if mapped_type == avro_type and not self.is_javascript_primitive(mapped_type):
69
+ import_types.add(mapped_type)
70
+ return pascal(mapped_type.split('.')[-1])
71
+ return mapped_type
72
+ elif isinstance(avro_type, list):
73
+ return [self.convert_avro_type_to_javascript(t, parent_namespace, import_types) for t in avro_type]
74
+ elif isinstance(avro_type, dict):
75
+ if 'type' in avro_type and avro_type['type'] == 'record':
76
+ class_ref = self.generate_class(avro_type, parent_namespace)
77
+ import_types.add(class_ref)
78
+ return class_ref.split('.')[-1]
79
+ elif 'type' in avro_type and avro_type['type'] == 'enum':
80
+ enum_ref = self.generate_enum(avro_type, parent_namespace)
81
+ import_types.add(enum_ref)
82
+ return enum_ref.split('.')[-1]
83
+ elif 'type' in avro_type and avro_type['type'] == 'array':
84
+ return [self.convert_avro_type_to_javascript(avro_type["items"], parent_namespace, import_types)]
85
+ if 'type' in avro_type and avro_type['type'] == 'map':
86
+ return [self.convert_avro_type_to_javascript(avro_type["values"], parent_namespace, import_types)]
87
+ if 'logicalType' in avro_type:
88
+ return self.convert_logical_type_to_javascript(avro_type)
89
+ return self.convert_avro_type_to_javascript(avro_type['type'], parent_namespace, import_types)
90
+ return 'any'
91
+
92
+ def generate_class(self, avro_schema: Dict, parent_namespace: str) -> str:
93
+ """ Generate TypeScript class from Avro record """
94
+
95
+ def add_check(arr_check, ft):
96
+ if isinstance(ft, list):
97
+ for ft2 in ft:
98
+ add_check(arr_check, ft2)
99
+ elif ft == 'null':
100
+ arr_check.append('v !== null')
101
+ elif is_javascript_primitive(ft):
102
+ arr_check.append(f'typeof v !== "{ft}"')
103
+ else:
104
+ arr_check.append(f'!(v instanceof {ft})')
105
+
106
+ import_types: Set[str] = set()
107
+ class_name = pascal(avro_schema['name'])
108
+ namespace = avro_schema.get('namespace', '')
109
+ if not namespace and parent_namespace:
110
+ namespace = parent_namespace
111
+ if self.base_package:
112
+ namespace = f'{self.base_package}.{namespace}'
113
+ fields = avro_schema.get('fields', [])
114
+ doc = avro_schema.get('doc', '')
115
+
116
+ constructor_body = ''
117
+ class_body = ''
118
+ if self.avro_annotation:
119
+ avro_schema_json = json.dumps(avro_schema)
120
+ avro_schema_json = avro_schema_json.replace('"', '§')
121
+ avro_schema_json = f"\"+\n{' '*8}\"".join([avro_schema_json[i:i+80] for i in range(0, len(avro_schema_json), 80)])
122
+ avro_schema_json = avro_schema_json.replace('§', '\\"')
123
+ class_body += f'{class_name}.AvroType = avro.parse("{avro_schema_json}");\n'
124
+ for field in fields:
125
+ field_name = field['name']
126
+ field_doc = field.get('doc', '')
127
+ field_avro_type = field['type']
128
+ if is_javascript_reserved_word(field_name):
129
+ field_name += '_'
130
+ field_type = self.convert_avro_type_to_javascript(field['type'], namespace, import_types)
131
+ if field_doc:
132
+ constructor_body += f'{INDENT}/** {field_doc} */\n'
133
+ constructor_body += f'{INDENT}_{field_name} = null;\n'
134
+ class_body += f'Object.defineProperty({class_name}.prototype, "{field_name}", {{\n'
135
+ class_body += f'{INDENT}get: function() {{'+'\n'
136
+ class_body += f'{INDENT}{INDENT}return this._{field_name};\n'
137
+ class_body += f'{INDENT}}},\n'
138
+ class_body += f'{INDENT}set: function(value) {{'+'\n'
139
+ type_check = []
140
+ if field_avro_type == 'array':
141
+ arr = '!Array.isArray(value) || value.some(v => '
142
+ arr_check: List[str] = []
143
+ for ft in field_type if isinstance(field_type, list) else [field_type]:
144
+ add_check(arr_check, ft)
145
+ arr += ' || '.join(arr_check) + ')'
146
+ type_check.append(arr)
147
+ elif field_avro_type == 'map':
148
+ map = '!Object.entries(value).every(([k, v]) => typeof k === "string" && '
149
+ map_check: List[str] = []
150
+ for ft in field_type if isinstance(field_type, list) else [field_type]:
151
+ add_check(map_check, ft)
152
+ map += ' && '.join(map_check) + ')'
153
+ type_check.append(map)
154
+ else:
155
+ for ft in field_type if isinstance(field_type, list) else [field_type]:
156
+ add_check(type_check, ft)
157
+ class_body += f'{INDENT}{INDENT}if ( {" && ".join(type_check)} ) throw new Error(`Invalid type for {field_name}. Expected {field_type}, got ${{value}}`);\n'
158
+ class_body += f'{INDENT}{INDENT}this._{field_name} = value;\n'
159
+ class_body += f'{INDENT}}}'+'\n'
160
+ class_body += '});\n\n'
161
+
162
+ imports = ''
163
+ if self.avro_annotation:
164
+ imports += "var avro = require('avro-js');\n"
165
+ for import_type in import_types:
166
+ import_type_package = import_type.rsplit('.',1)[0]
167
+ import_type_type = pascal(import_type.split('.')[-1])
168
+ import_type_package = import_type_package.replace('.', '/')
169
+ namespace_path = namespace.replace('.', '/')
170
+
171
+ if import_type_package:# get the relative path from the namespace to the import_type_package
172
+ import_type_package = os.path.relpath(import_type_package, namespace_path).replace(os.sep, '/')
173
+ if not import_type_package.startswith('.'):
174
+ import_type_package = f'./{import_type_package}'
175
+ imports += f"var {import_type_type} = require('{import_type_package}/{import_type_type}').{import_type_type};\n"
176
+ else:
177
+ imports += f"var {import_type_type} = require('{import_type_type}'){import_type_type};\n"
178
+
179
+ class_definition = imports + '\n'
180
+ if doc:
181
+ class_definition += f'/** {doc} */\n'
182
+ class_definition += f"function {class_name}() {{\n{constructor_body}}}\n\n{class_body}\nmodule.exports = {class_name};\n"
183
+ self.write_to_file(namespace, class_name, class_definition)
184
+ return f'{namespace}.{class_name}'
185
+
186
+ def generate_enum(self, avro_schema: Dict, parent_namespace: str) -> str:
187
+ """ Generate TypeScript enum from Avro enum """
188
+ enum_name = pascal(avro_schema['name'])
189
+ namespace = avro_schema.get('namespace', '')
190
+ if not namespace and parent_namespace:
191
+ namespace = parent_namespace
192
+ if self.base_package:
193
+ namespace = f'{self.base_package}.{namespace}'
194
+ symbols = avro_schema.get('symbols', [])
195
+
196
+ enum_body = ''
197
+ for symbol in symbols:
198
+ if is_javascript_reserved_word(symbol):
199
+ symbol += '_'
200
+ enum_body += f'{INDENT}{symbol}: "{symbol}",\n'
201
+
202
+ enum_definition = ''
203
+ if 'doc' in avro_schema:
204
+ enum_definition += f"/** {avro_schema['doc']} */\n"
205
+ enum_definition += f"const {enum_name} = Object.freeze({{\n{enum_body}}});\n\n"
206
+ enum_definition += f"module.exports = {enum_name};\n"
207
+ self.write_to_file(namespace, enum_name, enum_definition)
208
+ return f'{namespace}.{enum_name}'
209
+
210
+ def write_to_file(self, namespace: str, name: str, content: str):
211
+ """ Write TypeScript class to file """
212
+ directory_path = os.path.join(self.output_dir, namespace.replace('.', os.sep))
213
+ if not os.path.exists(directory_path):
214
+ os.makedirs(directory_path, exist_ok=True)
215
+
216
+ file_path = os.path.join(directory_path, f"{name}.js")
217
+ with open(file_path, 'w', encoding='utf-8') as file:
218
+ file.write(content)
219
+
220
+ def convert_schema(self, schema: List|Dict, output_dir: str):
221
+ """ Convert Avro schema to TypeScript classes """
222
+ self.output_dir = output_dir
223
+ if isinstance(schema, dict):
224
+ schema = [schema]
225
+
226
+ for avro_schema in schema:
227
+ if avro_schema['type'] == 'record':
228
+ self.generate_class(avro_schema, self.base_package)
229
+ elif avro_schema['type'] == 'enum':
230
+ self.generate_enum(avro_schema, self.base_package)
231
+
232
+ def convert(self, avro_schema_path: str, output_dir: str):
233
+ """ Convert Avro schema to TypeScript classes """
234
+ with open(avro_schema_path, 'r', encoding='utf-8') as file:
235
+ schema = json.load(file)
236
+ self.convert_schema(schema, output_dir)
237
+
238
+ def convert_avro_to_javascript(avro_schema_path, js_dir_path, package_name='', avro_annotation=False):
239
+ """ Convert Avro schema to TypeScript classes """
240
+
241
+ if not package_name:
242
+ package_name = os.path.splitext(os.path.basename(avro_schema_path))[0].replace('-', '_')
243
+
244
+ converter = AvroToJavaScript(package_name, avro_annotation=avro_annotation)
245
+ converter.convert(avro_schema_path, js_dir_path)
246
+
247
+ def convert_avro_schema_to_javascript(avro_schema, js_dir_path, package_name='', avro_annotation=False):
248
+ """ Convert Avro schema to TypeScript classes """
249
+ converter = AvroToJavaScript(package_name, avro_annotation=avro_annotation)
250
+ converter.convert_schema(avro_schema, js_dir_path)