diff --git a/net_api_generator/middleware_generator/MiddlewareLoader.py b/net_api_generator/middleware_generator/MiddlewareLoader.py index 3d64efc3fe804b3be2c2040dc59a58330e3d9a74..41c9bdf4c474a91a6809f138059baa56eac413ef 100644 --- a/net_api_generator/middleware_generator/MiddlewareLoader.py +++ b/net_api_generator/middleware_generator/MiddlewareLoader.py @@ -72,14 +72,14 @@ class MiddlewareLoader: elif "type" in object_property: if object_property['type'] == "array" and "items" in object_property: if len(object_property['items']) > 0: - array_item_type = self.load_object_property(property_key, object_property['items']) + array_item_type = FunctionParameterArrayType(self.load_object_property(property_key, object_property['items'])) else: array_item_type = FunctionParameterArrayType(FunctionParameterSimpleType("any", property_key)) parameter_type = FunctionParameterSimpleType(array_item_type, property_key) return parameter_type else: - parameter_type = FunctionParameterSimpleType(object_property['title'], object_property['type']) + parameter_type = FunctionParameterSimpleType(object_property['type'], object_property['title']) # todo: handle default values + description return parameter_type diff --git a/net_api_generator/middleware_generator/MiddlewareModel.py b/net_api_generator/middleware_generator/MiddlewareModel.py index 7ed1141773c91a6870a147d365c180945bd19734..a0a92c2ae50d165cf8c40d84ca8a5c135f7431af 100644 --- a/net_api_generator/middleware_generator/MiddlewareModel.py +++ b/net_api_generator/middleware_generator/MiddlewareModel.py @@ -1,15 +1,19 @@ -from abc import ABC +from abc import ABC, abstractmethod from dataclasses import dataclass from enum import Enum from typing import TypeVar, Optional -from net_api_generator.bootstrap_model import APIObject - class TypeConnector(Enum): anyOf = "anyOf" allOf = "allOf" oneOf = "oneOf" +def map_json_data_type_to_typescript(data_type: str): + if data_type == "integer": + return "number" + else: + return data_type + @dataclass() class FunctionParameterBaseType(ABC): title: Optional[str] @@ -17,6 +21,10 @@ class FunctionParameterBaseType(ABC): def __init__(self, title: Optional[str]=None): self.title = title + @abstractmethod + def resolve_data_type(self, array: bool=False): + pass + @dataclass() class FunctionParameterComposedType(FunctionParameterBaseType): type_connector: TypeConnector @@ -27,14 +35,16 @@ class FunctionParameterComposedType(FunctionParameterBaseType): self.type_connector = type_connector self.connected_types = connected_types -T = TypeVar("T", str, APIObject, FunctionParameterComposedType) -@dataclass() -class FunctionParameterSimpleType[T](FunctionParameterBaseType): - data_type: T - - def __init__(self, data_type: T, title: Optional[str]=None, ): - super().__init__(title) - self.data_type = data_type + def resolve_data_type(self, array: bool=False): + data_type_name = "" + for i, connected_type in enumerate(self.connected_types): + if array: + data_type_name += connected_type.resolve_data_type() + "[]" + else: + data_type_name += connected_type.resolve_data_type() + if i < len(self.connected_types) - 1: + data_type_name += " | " + return data_type_name class FunctionParameterArrayType(FunctionParameterBaseType): item_type: FunctionParameterBaseType @@ -43,6 +53,39 @@ class FunctionParameterArrayType(FunctionParameterBaseType): super().__init__(title) self.item_type = item_type + def resolve_data_type(self, array: bool=False): + return self.item_type.resolve_data_type(True) + +@dataclass() +class FunctionParameter: + title: str + data_type: FunctionParameterBaseType + +@dataclass() +class ApiObject: + name: str + parameters: list[FunctionParameter] + +T = TypeVar("T", str, ApiObject, FunctionParameterComposedType, FunctionParameterArrayType) +@dataclass() +class FunctionParameterSimpleType[T](FunctionParameterBaseType): + data_type: T + default_value: Optional[str] + + def __init__(self, data_type: T, title: Optional[str]=None, default_value: Optional[str]=None): + super().__init__(title) + self.data_type = data_type + self.default_value = default_value + + def resolve_data_type(self, array: bool=False): + if isinstance(self.data_type, str): + return map_json_data_type_to_typescript(self.data_type) + "[]" if array else map_json_data_type_to_typescript(self.data_type) + elif isinstance(self.data_type, ApiObject): + return self.data_type.name + "[]" if array else self.data_type.name + else: + resolved_data_type = self.data_type.resolve_data_type() + return resolved_data_type + "[]" if array else resolved_data_type + EnumString = TypeVar("EnumString", str, int) @dataclass() @@ -55,15 +98,10 @@ class FunctionParameterEnumType[EnumString](FunctionParameterBaseType): self.data_type = data_type self.enum = enum + def resolve_data_type(self, array: bool=False): + return self.data_type + "[]" if array else self.data_type + -@dataclass() -class FunctionParameter: - title: str - data_type: FunctionParameterBaseType -@dataclass() -class ApiObject: - name: str - parameters: list[FunctionParameter] diff --git a/net_api_generator/middleware_generator/generator.py b/net_api_generator/middleware_generator/generator.py index b9378bf878a1a5cf118f7f333acb77330cab068e..7e3859422927f234b94960bf3c9560e7452123ae 100644 --- a/net_api_generator/middleware_generator/generator.py +++ b/net_api_generator/middleware_generator/generator.py @@ -9,14 +9,43 @@ from net_api_generator.middleware_generator.MiddlewareModel import FunctionParam def typescript(open_api_file): def generate_object_class(api_object: ApiObject): - api_object_code = ("export class ${API_OBJECT_NAME} {\n" + code_template = ("export class ${API_OBJECT_NAME} {\n" "\t${API_ATTRIBUTE}\n" "\tconstructor(${CONSTRUCTOR_PARAMETER}) {\n" "\t\t${ATTRIBUTE_ASSIGNMENT}\n" - "\t}" + "\t}\n" "}") - def generate_integer_enum(enum_parameter: FunctionParameter): - pass + + code_template = code_template.replace("${API_OBJECT_NAME}", api_object.name) + for i, parameter in enumerate(api_object.parameters): + parameter_name = parameter.title.lower().replace(" ", "_") + api_attribute_str = "" + constructor_parameter_str = "" + attribute_assignment_str = "" + if isinstance(parameter.data_type, FunctionParameterSimpleType): + api_attribute_str = f"{parameter_name}: {parameter.data_type.resolve_data_type()}" + if parameter.data_type.default_value is None: + constructor_parameter_str = api_attribute_str + else : + constructor_parameter_str = f"{parameter_name}: {parameter.data_type.resolve_data_type()} = {parameter.data_type.default_value}" + else: + api_attribute_str = f"{parameter_name}: {parameter.data_type.resolve_data_type()}" + constructor_parameter_str = api_attribute_str + + attribute_assignment_str = f"this.{parameter_name} = {parameter_name}" + + + if i < len(api_object.parameters) - 1: + code_template = code_template.replace("${API_ATTRIBUTE}", api_attribute_str + "\n\t${API_ATTRIBUTE}") + code_template = code_template.replace("${CONSTRUCTOR_PARAMETER}", constructor_parameter_str + ", ${CONSTRUCTOR_PARAMETER}") + code_template = code_template.replace("${ATTRIBUTE_ASSIGNMENT}", attribute_assignment_str +"\n\t\t${ATTRIBUTE_ASSIGNMENT}") + else: + code_template = code_template.replace("${API_ATTRIBUTE}", api_attribute_str + "\n") + code_template = code_template.replace("${CONSTRUCTOR_PARAMETER}", constructor_parameter_str) + code_template = code_template.replace("${ATTRIBUTE_ASSIGNMENT}", attribute_assignment_str) + + print(code_template) + return code_template def generate_object_enum(api_object: ApiObject, enum_parameter: FunctionParameter): if isinstance(enum_parameter.data_type, FunctionParameterEnumType): @@ -39,7 +68,6 @@ def typescript(open_api_file): code_template = code_template.replace("${ENUM_VALUE}", enum_value_str + ",\n\t${ENUM_VALUE}") else: code_template = code_template.replace("${ENUM_VALUE}", enum_value_str) - print(code_template) return code_template else: raise ValueError("Passed Parameter is not an enum!") @@ -52,3 +80,5 @@ def typescript(open_api_file): for api_object in api_objects: if len(api_object.parameters) == 1 and isinstance(api_object.parameters[0].data_type, FunctionParameterEnumType): generate_object_enum(api_object, api_object.parameters[0]) + else: + generate_object_class(api_object)