nsj-rest-lib2 0.0.12__tar.gz → 0.0.14__tar.gz

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 (41) hide show
  1. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/PKG-INFO +1 -1
  2. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/compiler.py +91 -13
  3. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/compiler_structures.py +6 -0
  4. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/dto_compiler.py +4 -3
  5. nsj_rest_lib2-0.0.14/nsj_rest_lib2/compiler/edl_model/entity_model.py +23 -0
  6. nsj_rest_lib2-0.0.12/nsj_rest_lib2/compiler/edl_model/entity_model.py → nsj_rest_lib2-0.0.14/nsj_rest_lib2/compiler/edl_model/entity_model_base.py +10 -15
  7. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/primitives.py +1 -1
  8. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/entity_compiler.py +9 -4
  9. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/property_compiler.py +222 -59
  10. nsj_rest_lib2-0.0.14/nsj_rest_lib2/compiler/util/type_naming_util.py +21 -0
  11. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/PKG-INFO +1 -1
  12. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/SOURCES.txt +2 -0
  13. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/setup.cfg +1 -1
  14. nsj_rest_lib2-0.0.12/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -21
  15. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/README.md +0 -0
  16. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/__init__.py +0 -0
  17. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/__init__.py +0 -0
  18. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/ai_compiler.py +0 -0
  19. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
  20. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
  21. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
  22. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
  23. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
  24. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
  25. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
  26. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py +0 -0
  27. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/model.py +0 -0
  28. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
  29. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
  30. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
  31. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/controller/__init__.py +0 -0
  32. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/controller/dynamic_controller.py +0 -0
  33. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/exception.py +0 -0
  34. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/redis_config.py +0 -0
  35. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/service/__init__.py +0 -0
  36. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/service/entity_loader.py +1 -1
  37. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/settings.py +0 -0
  38. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
  39. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/requires.txt +0 -0
  40. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
  41. {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.12
3
+ Version: 0.0.14
4
4
  Summary: Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
5
5
  Home-page: https://github.com/Nasajon/nsj_rest_lib2
6
6
  Author: Nasajon Sistemas
@@ -3,10 +3,12 @@ import re
3
3
  from typing import Any
4
4
 
5
5
  from nsj_rest_lib2.compiler.compiler_structures import (
6
+ ComponentsCompilerStructure,
6
7
  IndexCompilerStructure,
7
8
  PropertiesCompilerStructure,
8
9
  )
9
10
  from nsj_rest_lib2.compiler.dto_compiler import DTOCompiler
11
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
10
12
  from nsj_rest_lib2.compiler.edl_model.primitives import REGEX_EXTERNAL_REF
11
13
  from nsj_rest_lib2.compiler.entity_compiler import EntityCompiler
12
14
  from nsj_rest_lib2.compiler.model import CompilerResult
@@ -16,16 +18,18 @@ from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
16
18
 
17
19
  from nsj_rest_lib2.settings import get_logger
18
20
 
21
+ # TODO Revisar compilação de valores default (sensível a tipos)
22
+ # TODO Implementar suporte a conjuntos
19
23
  # TODO Autenticação nas rotas
20
- # TODO Carregar, dinamicamente, em memória, o código compilado das dependÊncias por relacionamento
21
24
  # TODO Atualizar o status da entidade pelo worker de compilação (e talvez parar uma compilação, quando se delete uma entidade)
22
- # TODO Relacionamentos
25
+ # TODO Mixins
23
26
  # TODO Classes Abstratas
24
27
  # TODO Partial Classes
25
28
  # TODO Migrations
26
- # TODO Adicionar autenticação aos endpoints dinâmicos
27
29
  # TODO Criar imagem docker base para as aplicações, usando venv (para poderem atualizar o pydantic)
28
30
 
31
+ # TODO Suporte ao "min_items" dos relacionamentos no RestLib1
32
+
29
33
 
30
34
  class EDLCompiler:
31
35
  def __init__(self) -> None:
@@ -76,10 +80,18 @@ class EDLCompiler:
76
80
 
77
81
  def _compile_model(
78
82
  self,
79
- entity_model: EntityModel,
83
+ entity_model: EntityModelBase,
80
84
  entity_models: dict[str, EntityModel],
85
+ escopo: str | None = None,
86
+ prefx_class_name: str = "",
81
87
  ) -> CompilerResult:
82
88
 
89
+ if escopo is None and isinstance(entity_model, EntityModel):
90
+ escopo = entity_model.escopo
91
+
92
+ if not escopo:
93
+ raise Exception(f"Escopo não definido para a entidade: {entity_model.id}.")
94
+
83
95
  # Criando um mapa de índices por nome de property
84
96
  # TODO Implementar tratamento dos índices de apoio às query (não de unicidade)
85
97
  map_indexes_by_property: dict[str, list[IndexCompilerStructure]] = {}
@@ -109,10 +121,43 @@ class EDLCompiler:
109
121
  ) = self._properties_compiler.compile(
110
122
  properties_structure,
111
123
  map_unique_by_property,
124
+ escopo,
112
125
  entity_model,
113
126
  entity_models,
127
+ prefx_class_name,
114
128
  )
115
129
 
130
+ # Gerando o buffer para os códigos de DTO e Entity
131
+ dto_code = ""
132
+ entity_code = ""
133
+ relations_dependencies_complete = []
134
+
135
+ # Carregando a estrutura de compilação dos components
136
+ components_structure = ComponentsCompilerStructure()
137
+ self._make_components_structures(
138
+ components_structure, entity_model, entity_models
139
+ )
140
+
141
+ # Gerando o código das entidades filhas (components)
142
+ for component_key in components_structure.components:
143
+ component = components_structure.components[component_key]
144
+ component_compiled = self._compile_model(
145
+ component,
146
+ entity_models,
147
+ escopo,
148
+ prefx_class_name=f"{prefx_class_name}_{entity_model.id}",
149
+ )
150
+
151
+ # Guardando o código gerado no buffer
152
+ if component_compiled.dto_code:
153
+ dto_code += component_compiled.dto_code + "\n\n"
154
+ if component_compiled.entity_code:
155
+ entity_code += component_compiled.entity_code + "\n\n"
156
+ if component_compiled.relations_dependencies:
157
+ relations_dependencies_complete.extend(
158
+ component_compiled.relations_dependencies
159
+ )
160
+
116
161
  # Gerando o código do DTO
117
162
  dto_class_name, code_dto = self._dto_compiler.compile(
118
163
  entity_model,
@@ -120,32 +165,65 @@ class EDLCompiler:
120
165
  enum_classes,
121
166
  related_imports,
122
167
  fixed_filters,
168
+ prefx_class_name,
123
169
  )
124
170
 
125
171
  # Gerando o código da Entity
126
172
  entity_class_name, code_entity = self._entity_compiler.compile(
127
- entity_model, ast_entity_attributes, props_pk
173
+ entity_model,
174
+ ast_entity_attributes,
175
+ props_pk,
176
+ prefx_class_name,
128
177
  )
129
178
 
179
+ # Extendendo os buffers com os códigos gerados
180
+ dto_code += code_dto
181
+ entity_code += code_entity
182
+ relations_dependencies_complete.extend(relations_dependencies)
183
+
130
184
  # Construindo o resultado
131
185
  compiler_result = CompilerResult()
132
186
  compiler_result.entity_class_name = entity_class_name
133
- compiler_result.entity_code = code_entity
187
+ compiler_result.entity_code = entity_code
134
188
  compiler_result.dto_class_name = dto_class_name
135
- compiler_result.dto_code = code_dto
189
+ compiler_result.dto_code = dto_code
136
190
 
137
191
  # Compilando questões das APIs
138
- compiler_result.api_expose = entity_model.api.expose
139
- compiler_result.api_resource = entity_model.api.resource
140
- compiler_result.api_verbs = entity_model.api.verbs
141
- compiler_result.relations_dependencies = relations_dependencies
192
+ if isinstance(entity_model, EntityModel):
193
+ compiler_result.api_expose = entity_model.api.expose
194
+ compiler_result.api_resource = entity_model.api.resource
195
+ compiler_result.api_verbs = entity_model.api.verbs
196
+ compiler_result.relations_dependencies = relations_dependencies_complete
142
197
 
143
198
  return compiler_result
144
199
 
200
+ def _make_components_structures(
201
+ self,
202
+ components_structure: ComponentsCompilerStructure,
203
+ entity_model: EntityModelBase,
204
+ entity_models: dict[str, EntityModel],
205
+ ):
206
+ if not entity_model:
207
+ return
208
+
209
+ # Populando com os components do trait
210
+ if entity_model.trait_from:
211
+ trait_model = entity_models[entity_model.trait_from]
212
+
213
+ self._make_components_structures(
214
+ components_structure,
215
+ trait_model,
216
+ entity_models,
217
+ )
218
+
219
+ # Populando com os components da entidade atual
220
+ if entity_model.components:
221
+ components_structure.components.update(entity_model.components)
222
+
145
223
  def _make_properties_structures(
146
224
  self,
147
225
  properties_structure: PropertiesCompilerStructure,
148
- entity_model: EntityModel,
226
+ entity_model: EntityModelBase,
149
227
  entity_models: dict[str, EntityModel],
150
228
  ):
151
229
  if not entity_model:
@@ -188,7 +266,7 @@ class EDLCompiler:
188
266
  self,
189
267
  map_indexes_by_property: dict[str, list[IndexCompilerStructure]],
190
268
  map_unique_by_property: dict[str, IndexCompilerStructure],
191
- entity_model: EntityModel,
269
+ entity_model: EntityModelBase,
192
270
  entity_models: dict[str, EntityModel],
193
271
  deep: int = 1,
194
272
  ):
@@ -1,4 +1,5 @@
1
1
  from nsj_rest_lib2.compiler.edl_model.column_meta_model import ColumnMetaModel
2
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
2
3
  from nsj_rest_lib2.compiler.edl_model.index_model import IndexModel
3
4
  from nsj_rest_lib2.compiler.edl_model.property_meta_model import PropertyMetaModel
4
5
  from nsj_rest_lib2.compiler.edl_model.trait_property_meta_model import (
@@ -22,3 +23,8 @@ class PropertiesCompilerStructure:
22
23
  self.metric_label: list[str] = []
23
24
  self.entity_properties: dict[str, ColumnMetaModel] = {}
24
25
  self.trait_properties: dict[str, TraitPropertyMetaModel] = {}
26
+
27
+
28
+ class ComponentsCompilerStructure:
29
+ def __init__(self) -> None:
30
+ self.components: dict[str, EntityModelBase] = {}
@@ -3,8 +3,8 @@ import ast
3
3
  import black
4
4
 
5
5
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
6
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
6
7
  from nsj_rest_lib2.compiler.edl_model.primitives import BasicTypes
7
- from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
8
8
  from nsj_rest_lib2.compiler.util.type_naming_util import compile_dto_class_name
9
9
 
10
10
 
@@ -14,11 +14,12 @@ class DTOCompiler:
14
14
 
15
15
  def compile(
16
16
  self,
17
- entity_model: EntityModel,
17
+ entity_model: EntityModelBase,
18
18
  ast_dto_attributes: list[ast.stmt],
19
19
  enum_classes: list[ast.stmt],
20
20
  related_imports: list[tuple[str, str, str]],
21
21
  fixed_filters: list[tuple[str, BasicTypes]],
22
+ prefx_class_name: str,
22
23
  ) -> tuple[str, str]:
23
24
  """
24
25
  Compila o código do DTO a partir do AST e retorna o código compilado.
@@ -117,7 +118,7 @@ class DTOCompiler:
117
118
  )
118
119
 
119
120
  # Criando o ast da classe
120
- class_name = compile_dto_class_name(entity_model.id)
121
+ class_name = compile_dto_class_name(entity_model.id, prefx_class_name)
121
122
  ast_class = ast.ClassDef(
122
123
  name=class_name,
123
124
  bases=[ast.Name(id="DTOBase", ctx=ast.Load())],
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import Field
4
+ from typing import Optional
5
+
6
+ from nsj_rest_lib2.compiler.edl_model.api_model import APIModel
7
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
8
+
9
+
10
+ class EntityModel(EntityModelBase):
11
+ edl_version: Optional[str] = Field(default="1.0", description="Versão do EDL")
12
+ escopo: str = Field(..., description="Escopo do EDL (define a aplicação).")
13
+ version: Optional[str] = Field(
14
+ default="1.0", description="Versão da entidade (padrão: 1.0)."
15
+ )
16
+ abstract: Optional[bool] = Field(
17
+ default=False,
18
+ description="Indica se a entidade é abstrata (padrão: False). Caso positivo, não gera código, mas pode ser usada na geração de código de outras entidades.",
19
+ )
20
+ api: APIModel = Field(
21
+ ...,
22
+ description="Definição da API REST associada ao modelo, com todos os seus endpoints.",
23
+ )
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import uuid
2
4
 
3
5
  from pydantic import BaseModel, Field
@@ -5,15 +7,12 @@ from typing import Dict, List, Optional
5
7
 
6
8
  from nsj_rest_lib2.compiler.edl_model.property_meta_model import PropertyMetaModel
7
9
  from nsj_rest_lib2.compiler.edl_model.repository_model import RepositoryModel
8
- from nsj_rest_lib2.compiler.edl_model.api_model import APIModel
9
10
  from nsj_rest_lib2.compiler.edl_model.trait_property_meta_model import (
10
11
  TraitPropertyMetaModel,
11
12
  )
12
13
 
13
14
 
14
- class EntityModel(BaseModel):
15
- edl_version: Optional[str] = Field(default="1.0", description="Versão do EDL")
16
- escopo: str = Field(..., description="Escopo do EDL (define a aplicação).")
15
+ class EntityModelBase(BaseModel):
17
16
  description: str = Field(..., description="Descrição da entidade.")
18
17
  id: str = Field(
19
18
  ...,
@@ -22,13 +21,6 @@ class EntityModel(BaseModel):
22
21
  trait_from: Optional[str] = Field(
23
22
  None, description="Identificador da entidade que a trait estende."
24
23
  )
25
- version: Optional[str] = Field(
26
- default="1.0", description="Versão da entidade (padrão: 1.0)."
27
- )
28
- abstract: Optional[bool] = Field(
29
- default=False,
30
- description="Indica se a entidade é abstrata (padrão: False). Caso positivo, não gera código, mas pode ser usada na geração de código de outras entidades.",
31
- )
32
24
  mixins: Optional[List[str]] = Field(
33
25
  None,
34
26
  description="Lista de mixins (blocos reutilizáveis) aplicados ao modelo.",
@@ -59,16 +51,19 @@ class EntityModel(BaseModel):
59
51
  properties: Dict[str, PropertyMetaModel] = Field(
60
52
  ..., description="Dicionário de propriedades do modelo."
61
53
  )
54
+ components: Optional[Dict[str, "EntityModelBase"]] = Field(
55
+ None,
56
+ description="Entidades filhas, relacionadas por composição e definidas inline (evitando a criação de novos arquivos EDL para a definição de entidades componentes da entidade atual).",
57
+ )
62
58
  repository: RepositoryModel = Field(
63
59
  ..., description="Configurações de mapeamento para o banco de dados."
64
60
  )
65
- api: APIModel = Field(
66
- ...,
67
- description="Definição da API REST associada ao modelo, com todos os seus endpoints.",
68
- )
69
61
 
70
62
  # Propriedades de controle da compilação (não fazem parte do JSON de representação das entidades)
71
63
  tenant: int = Field(default=0, exclude=True)
72
64
  grupo_empresarial: uuid.UUID = Field(
73
65
  default=uuid.UUID("00000000-0000-0000-0000-000000000000"), exclude=True
74
66
  )
67
+
68
+
69
+ EntityModelBase.model_rebuild()
@@ -4,7 +4,7 @@ from typing import Annotated, List, Union
4
4
  from pydantic import StringConstraints
5
5
 
6
6
  REGEX_EXTERNAL_REF = r"^(\w+)\/(\w+)$"
7
- REGEX_INTERNAL_REF = r"^#\/(\w+)\/(\w+)$"
7
+ REGEX_INTERNAL_REF = r"^#\/components\/(\w+)$"
8
8
 
9
9
  ExternalRefType = Annotated[str, StringConstraints(pattern=REGEX_EXTERNAL_REF)]
10
10
  InternalRefType = Annotated[str, StringConstraints(pattern=REGEX_INTERNAL_REF)]
@@ -3,7 +3,7 @@ import ast
3
3
  import black
4
4
 
5
5
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
6
- from nsj_rest_lib2.compiler.edl_model.repository_model import RepositoryModel
6
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
7
7
  from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
8
8
  from nsj_rest_lib2.compiler.util.type_naming_util import compile_entity_class_name
9
9
 
@@ -14,9 +14,10 @@ class EntityCompiler:
14
14
 
15
15
  def compile(
16
16
  self,
17
- entity_model: EntityModel,
17
+ entity_model: EntityModelBase,
18
18
  ast_entity_attributes: list[ast.stmt],
19
19
  props_pk: list[str],
20
+ prefix_class_name: str,
20
21
  ) -> tuple[str, str]:
21
22
  # Imports
22
23
  imports = [
@@ -49,7 +50,11 @@ class EntityCompiler:
49
50
  )
50
51
 
51
52
  default_order_props = []
52
- if entity_model.api and entity_model.api.default_sort:
53
+ if (
54
+ isinstance(entity_model, EntityModel)
55
+ and entity_model.api
56
+ and entity_model.api.default_sort
57
+ ):
53
58
  default_order_props = entity_model.api.default_sort
54
59
 
55
60
  default_order_fields = []
@@ -67,7 +72,7 @@ class EntityCompiler:
67
72
  if CompilerStrUtil.to_snake_case(props_pk[0]) not in default_order_fields:
68
73
  default_order_fields.append(CompilerStrUtil.to_snake_case(props_pk[0]))
69
74
 
70
- class_name = compile_entity_class_name(entity_model.id)
75
+ class_name = compile_entity_class_name(entity_model.id, prefix_class_name)
71
76
  ast_class = ast.ClassDef(
72
77
  name=class_name,
73
78
  bases=[ast.Name(id="EntityBase", ctx=ast.Load())],
@@ -6,6 +6,7 @@ from nsj_rest_lib2.compiler.compiler_structures import (
6
6
  PropertiesCompilerStructure,
7
7
  )
8
8
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
9
+ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
9
10
  from nsj_rest_lib2.compiler.edl_model.primitives import (
10
11
  BasicTypes,
11
12
  CardinalityTypes,
@@ -29,16 +30,18 @@ from nsj_rest_lib2.compiler.util.type_util import TypeUtil
29
30
  # TODO pattern
30
31
  # TODO lowercase
31
32
  # TODO uppercase
32
- # TODO Adicionar o nome da entidade, no nome das classes de enum (para evitar conflitos no caso das traits)
33
33
 
34
34
 
35
35
  class EDLPropertyCompiler:
36
+
36
37
  def compile(
37
38
  self,
38
39
  properties_structure: PropertiesCompilerStructure,
39
40
  map_unique_by_property: dict[str, IndexCompilerStructure],
40
- entity_model: EntityModel,
41
+ escopo: str,
42
+ entity_model: EntityModelBase,
41
43
  entity_models: dict[str, EntityModel],
44
+ prefx_class_name: str,
42
45
  ) -> tuple[
43
46
  list[ast.stmt],
44
47
  list[ast.stmt],
@@ -52,22 +55,23 @@ class EDLPropertyCompiler:
52
55
  # TODO Criar opção de campo calculado?
53
56
 
54
57
  # Descobrindo os atributos marcados como PK (e recuperando a chave primária)
55
- # pk_keys = []
56
- # for pkey in properties_structure.properties:
57
- # prop = properties_structure.properties[pkey]
58
-
59
- # if isinstance(prop.type, PrimitiveTypes):
60
- # if prop.pk:
61
- # pk_keys.append(pkey)
62
-
63
- # if len(pk_keys) > 1:
64
- # raise Exception(
65
- # f"Entidade '{entity_model.id}' possui mais de uma chave primária (ainda não suportado): {pk_keys}"
66
- # )
67
- # elif len(pk_keys) == 0:
68
- # raise Exception(
69
- # f"Entidade '{entity_model.id}' não tem nenhuma chave primária (ainda não suportado)"
70
- # )
58
+ # TODO Verificar se devemos manter essa verificação
59
+ pk_keys = []
60
+ for pkey in properties_structure.properties:
61
+ prop = properties_structure.properties[pkey]
62
+
63
+ if isinstance(prop.type, PrimitiveTypes):
64
+ if prop.pk:
65
+ pk_keys.append(pkey)
66
+
67
+ if len(pk_keys) > 1:
68
+ raise Exception(
69
+ f"Entidade '{entity_model.id}' possui mais de uma chave primária (ainda não suportado): {pk_keys}"
70
+ )
71
+ elif len(pk_keys) == 0:
72
+ raise Exception(
73
+ f"Entidade '{entity_model.id}' não tem nenhuma chave primária (ainda não suportado)"
74
+ )
71
75
 
72
76
  # pk_key = pk_keys[0]
73
77
 
@@ -87,11 +91,12 @@ class EDLPropertyCompiler:
87
91
  prop = properties_structure.properties[pkey]
88
92
 
89
93
  # DTO
90
- ## Tratando propriedade simples (não array, não object)
91
94
  if isinstance(prop.type, PrimitiveTypes):
95
+ # Tratando propriedade simples (não array, não object)
92
96
  self._compile_simple_property(
93
97
  properties_structure,
94
98
  map_unique_by_property,
99
+ escopo,
95
100
  entity_model,
96
101
  ast_dto_attributes,
97
102
  ast_entity_attributes,
@@ -99,9 +104,11 @@ class EDLPropertyCompiler:
99
104
  enum_classes,
100
105
  pkey,
101
106
  prop,
107
+ prefx_class_name,
102
108
  )
103
109
 
104
110
  elif isinstance(prop.type, str):
111
+ # Tratando propriedade de relacionamento
105
112
  external_match = re.match(REGEX_EXTERNAL_REF, prop.type)
106
113
  internal_match = re.match(REGEX_INTERNAL_REF, prop.type)
107
114
 
@@ -117,6 +124,7 @@ class EDLPropertyCompiler:
117
124
  entity_models,
118
125
  properties_structure,
119
126
  ast_dto_attributes,
127
+ ast_entity_attributes,
120
128
  related_imports,
121
129
  relations_dependencies,
122
130
  pkey,
@@ -124,8 +132,18 @@ class EDLPropertyCompiler:
124
132
  )
125
133
 
126
134
  elif internal_match:
127
- # TODO
128
- pass
135
+ related_entity_id = internal_match.group(1)
136
+
137
+ self._compile_internal_relation(
138
+ related_entity_id,
139
+ entity_model,
140
+ properties_structure,
141
+ ast_dto_attributes,
142
+ ast_entity_attributes,
143
+ pkey,
144
+ prop,
145
+ prefx_class_name,
146
+ )
129
147
  else:
130
148
  raise Exception(
131
149
  f"Tipo da propriedade '{pkey}' não suportado: {prop.type}"
@@ -142,8 +160,10 @@ class EDLPropertyCompiler:
142
160
  ast_dto_attributes,
143
161
  ast_entity_attributes,
144
162
  fixed_filters,
163
+ escopo,
145
164
  entity_model,
146
165
  enum_classes,
166
+ prefx_class_name,
147
167
  )
148
168
 
149
169
  return (
@@ -165,8 +185,10 @@ class EDLPropertyCompiler:
165
185
  ast_dto_attributes: list[ast.stmt],
166
186
  ast_entity_attributes: list[ast.stmt],
167
187
  fixed_filters: list[tuple[str, BasicTypes]],
168
- entity_model: EntityModel,
188
+ escopo: str,
189
+ entity_model: EntityModelBase,
169
190
  enum_classes: list[ast.stmt],
191
+ prefx_class_name: str,
170
192
  ):
171
193
  enum_class_name = None
172
194
  keywords = []
@@ -272,7 +294,9 @@ class EDLPropertyCompiler:
272
294
 
273
295
  # Trtando de uma definição de enum
274
296
  if prop.domain_config:
275
- result = self._compile_domain_config(pkey, prop, entity_model)
297
+ result = self._compile_domain_config(
298
+ pkey, prop, escopo, entity_model, prefx_class_name
299
+ )
276
300
  if not result:
277
301
  raise Exception(f"Erro desconhecido ao compilar a propriedade {pkey}")
278
302
 
@@ -342,17 +366,18 @@ class EDLPropertyCompiler:
342
366
  ast_entity_attributes.append(ast_entity_attr)
343
367
 
344
368
  # Guardando como um fixed_filter
345
- # TODO Pernsar em validações para esse value (se está de acordo com o tipo ou enum)
369
+ # TODO Pensar em validações para esse value (se está de acordo com o tipo ou enum)
346
370
  fixed_filters.append((pkey, prop.value))
347
371
 
348
372
  def _compile_external_relation(
349
373
  self,
350
374
  related_entity_id: str,
351
375
  related_entity_key: str,
352
- entity_model: EntityModel,
376
+ entity_model: EntityModelBase,
353
377
  entity_models: dict[str, EntityModel],
354
378
  properties_structure: PropertiesCompilerStructure,
355
379
  ast_dto_attributes: list[ast.stmt],
380
+ ast_entity_attributes: list[ast.stmt],
356
381
  related_imports: list[tuple[str, str, str]],
357
382
  relations_dependencies: list[RelationDependency],
358
383
  pkey: str,
@@ -412,15 +437,68 @@ class EDLPropertyCompiler:
412
437
  pkey,
413
438
  related_dto_class_name,
414
439
  related_entity_class_name,
440
+ prop,
415
441
  )
416
442
 
417
443
  elif prop.cardinality == CardinalityTypes.C1_1:
418
444
  self._build_ast_1_1(
419
445
  properties_structure,
420
446
  ast_dto_attributes,
447
+ ast_entity_attributes,
421
448
  pkey,
422
449
  related_dto_class_name,
423
450
  related_entity_class_name,
451
+ prop,
452
+ )
453
+
454
+ elif prop.cardinality == CardinalityTypes.CN_N:
455
+ # TODO
456
+ pass
457
+ else:
458
+ raise Exception(
459
+ f"Propriedade '{pkey}' da entidade '{entity_model.id}' possui cardinalidade inválida ou não suportada: {prop.cardinality}"
460
+ )
461
+
462
+ def _compile_internal_relation(
463
+ self,
464
+ related_entity_id: str,
465
+ entity_model: EntityModelBase,
466
+ properties_structure: PropertiesCompilerStructure,
467
+ ast_dto_attributes: list[ast.stmt],
468
+ ast_entity_attributes: list[ast.stmt],
469
+ pkey: str,
470
+ prop: PropertyMetaModel,
471
+ prefx_class_name: str,
472
+ ):
473
+ # Resolvendo o nome das classes de DTO e Entity
474
+ related_dto_class_name = compile_dto_class_name(
475
+ related_entity_id, f"{prefx_class_name}_{entity_model.id}"
476
+ )
477
+ related_entity_class_name = compile_entity_class_name(
478
+ related_entity_id, f"{prefx_class_name}_{entity_model.id}"
479
+ )
480
+
481
+ # Instanciando o ast
482
+ if prop.cardinality == CardinalityTypes.C1_N:
483
+ # Para relacionamentos 1_N
484
+ self._build_ast_1_N(
485
+ properties_structure,
486
+ ast_dto_attributes,
487
+ pkey,
488
+ related_dto_class_name,
489
+ related_entity_class_name,
490
+ prop,
491
+ )
492
+
493
+ elif prop.cardinality == CardinalityTypes.C1_1:
494
+ self._build_ast_1_1(
495
+ properties_structure,
496
+ ast_dto_attributes,
497
+ ast_entity_attributes,
498
+ pkey,
499
+ related_dto_class_name,
500
+ related_entity_class_name,
501
+ prop,
424
502
  )
425
503
 
426
504
  elif prop.cardinality == CardinalityTypes.CN_N:
@@ -438,7 +516,10 @@ class EDLPropertyCompiler:
438
516
  pkey: str,
439
517
  related_dto_class_name: str,
440
518
  related_entity_class_name: str,
519
+ prop: PropertyMetaModel,
441
520
  ):
521
+ # TODO Verificar uso da propriedade relation_key_field do Rest_lib_1
522
+
442
523
  # Propriedade do property descriptor
443
524
  keywords = [
444
525
  ast.keyword(
@@ -451,6 +532,23 @@ class EDLPropertyCompiler:
451
532
  ),
452
533
  ]
453
534
 
535
+ # Tratando das opções básicas do descritor de propriedade
536
+ if properties_structure.required and pkey in properties_structure.required:
537
+ keywords.append(ast.keyword(arg="not_null", value=ast.Constant(True)))
538
+
539
+ if prop.max_length:
540
+ keywords.append(ast.keyword(arg="max", value=ast.Constant(prop.max_length)))
541
+ if prop.min_length:
542
+ keywords.append(ast.keyword(arg="min", value=ast.Constant(prop.min_length)))
543
+
544
+ if prop.validator:
545
+ keywords.append(
546
+ ast.keyword(
547
+ arg="validator",
548
+ value=ast.Name(prop.validator, ctx=ast.Load()),
549
+ )
550
+ )
551
+
454
552
  # Resolvendo a coluna usada no relacionamento
455
553
  if (
456
554
  not properties_structure.entity_properties
@@ -461,7 +559,10 @@ class EDLPropertyCompiler:
461
559
  f"Propriedade '{pkey}' possui um relacionamento, mas nenhuma coluna de relacioanamento foi apontada na propriedade correspondente no repository."
462
560
  )
463
561
 
464
- relation_column = properties_structure.entity_properties[pkey].relation_column
562
+ relation_column_ref = properties_structure.entity_properties[
563
+ pkey
564
+ ].relation_column
565
+ relation_column = str(relation_column_ref).split("/")[-1]
465
566
 
466
567
  keywords.append(
467
568
  ast.keyword(
@@ -490,9 +591,11 @@ class EDLPropertyCompiler:
490
591
  self,
491
592
  properties_structure: PropertiesCompilerStructure,
492
593
  ast_dto_attributes: list[ast.stmt],
594
+ ast_entity_attributes: list[ast.stmt],
493
595
  pkey: str,
494
596
  related_dto_class_name: str,
495
597
  related_entity_class_name: str,
598
+ prop: PropertyMetaModel,
496
599
  ):
497
600
  # Propriedade do property descriptor
498
601
  keywords = [
@@ -502,6 +605,24 @@ class EDLPropertyCompiler:
502
605
  ),
503
606
  ]
504
607
 
608
+ # Tratando das opções básicas do descritor de propriedade
609
+ if properties_structure.required and pkey in properties_structure.required:
610
+ keywords.append(ast.keyword(arg="not_null", value=ast.Constant(True)))
611
+
612
+ if (
613
+ properties_structure.main_properties
614
+ and pkey in properties_structure.main_properties
615
+ ):
616
+ keywords.append(ast.keyword(arg="resume", value=ast.Constant(True)))
617
+
618
+ if prop.validator:
619
+ keywords.append(
620
+ ast.keyword(
621
+ arg="validator",
622
+ value=ast.Name(prop.validator, ctx=ast.Load()),
623
+ )
624
+ )
625
+
505
626
  # Resolvendo a coluna usada no relacionamento
506
627
  if (
507
628
  not properties_structure.entity_properties
@@ -521,6 +642,9 @@ class EDLPropertyCompiler:
521
642
  owner_relation = True
522
643
  relation_column = relation_column.split("/")[-1]
523
644
 
645
+ # TODO Verificar, porque desconfio que o apontamento para a coluna de relacionamento
646
+ # para o caso do relacionamento OTHER, não é suportado pelo RestLib (acho que, quando
647
+ # o dono é OTHER, o RestLib sempre aponta para a PK da entidade corrente).
524
648
  keywords.append(
525
649
  ast.keyword(
526
650
  arg="relation_field",
@@ -539,7 +663,18 @@ class EDLPropertyCompiler:
539
663
  ),
540
664
  )
541
665
  )
666
+ else:
667
+ # Adicionando propriedade, para o campo de relação, no DTO (quando for o dono da relação)
668
+ ast_dto_attributes.append(
669
+ self._build_dto_property_ast(relation_column, PrimitiveTypes.UUID)
670
+ )
542
671
 
672
+ # Adicionando propriedade, para o campo de relação, no Entity (quando for o dono da relação)
673
+ ast_entity_attributes.append(
674
+ self._build_entity_property_ast(relation_column, PrimitiveTypes.UUID)
675
+ )
676
+
677
+ # Adicionando a propriedade em si do relacionamento, no DTO
543
678
  ast_attr = ast.AnnAssign(
544
679
  target=ast.Name(id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()),
545
680
  annotation=ast.Name(
@@ -556,10 +691,57 @@ class EDLPropertyCompiler:
556
691
 
557
692
  ast_dto_attributes.append(ast_attr)
558
693
 
694
+ def _build_dto_property_ast(
695
+ self,
696
+ name: str,
697
+ type: PrimitiveTypes | str,
698
+ keywords: list[ast.keyword] = [],
699
+ ):
700
+ if isinstance(type, PrimitiveTypes):
701
+ type_str = TypeUtil.property_type_to_python_type(type)
702
+ else:
703
+ type_str = type
704
+
705
+ return ast.AnnAssign(
706
+ target=ast.Name(
707
+ id=CompilerStrUtil.to_snake_case(name),
708
+ ctx=ast.Store(),
709
+ ),
710
+ annotation=ast.Name(
711
+ id=type_str,
712
+ ctx=ast.Load(),
713
+ ),
714
+ value=ast.Call(
715
+ func=ast.Name(id="DTOField", ctx=ast.Load()),
716
+ args=[],
717
+ keywords=keywords,
718
+ ),
719
+ simple=1,
720
+ )
721
+
722
+ def _build_entity_property_ast(
723
+ self,
724
+ name: str,
725
+ type: PrimitiveTypes,
726
+ ):
727
+ return ast.AnnAssign(
728
+ target=ast.Name(
729
+ id=CompilerStrUtil.to_snake_case(name),
730
+ ctx=ast.Store(),
731
+ ),
732
+ annotation=ast.Name(
733
+ id=TypeUtil.property_type_to_python_type(type),
734
+ ctx=ast.Load(),
735
+ ),
736
+ value=ast.Constant(value=None),
737
+ simple=1,
738
+ )
739
+
559
740
  def _compile_simple_property(
560
741
  self,
561
742
  properties_structure,
562
743
  map_unique_by_property,
744
+ escopo,
563
745
  entity_model,
564
746
  ast_dto_attributes,
565
747
  ast_entity_attributes,
@@ -567,6 +749,7 @@ class EDLPropertyCompiler:
567
749
  enum_classes,
568
750
  pkey,
569
751
  prop,
752
+ prefx_class_name: str,
570
753
  ):
571
754
  enum_class_name = None
572
755
  keywords = []
@@ -620,18 +803,18 @@ class EDLPropertyCompiler:
620
803
  if prop.type in [PrimitiveTypes.STRING, PrimitiveTypes.EMAIL]:
621
804
  if prop.max_length:
622
805
  max = prop.max_length
623
- elif prop.min_length:
806
+ if prop.min_length:
624
807
  min = prop.min_length
625
808
  elif prop.type in [PrimitiveTypes.INTEGER, PrimitiveTypes.NUMBER]:
626
809
  if prop.minimum:
627
810
  min = prop.minimum
628
- elif prop.maximum:
811
+ if prop.maximum:
629
812
  max = prop.maximum
630
813
 
631
814
  if max:
632
- keywords.append(ast.keyword(arg="max", value=ast.Constant(prop.max_length)))
815
+ keywords.append(ast.keyword(arg="max", value=ast.Constant(max)))
633
816
  if min:
634
- keywords.append(ast.keyword(arg="min", value=ast.Constant(prop.min_length)))
817
+ keywords.append(ast.keyword(arg="min", value=ast.Constant(min)))
635
818
 
636
819
  if (
637
820
  properties_structure.search_properties
@@ -735,7 +918,9 @@ class EDLPropertyCompiler:
735
918
  )
736
919
 
737
920
  if prop.domain_config:
738
- result = self._compile_domain_config(pkey, prop, entity_model)
921
+ result = self._compile_domain_config(
922
+ pkey, prop, escopo, entity_model, prefx_class_name
923
+ )
739
924
  if not result:
740
925
  raise Exception(f"Erro desconhecido ao compilar a propriedade {pkey}")
741
926
 
@@ -766,35 +951,11 @@ class EDLPropertyCompiler:
766
951
  else:
767
952
  prop_type = TypeUtil.property_type_to_python_type(prop.type)
768
953
 
769
- ast_attr = ast.AnnAssign(
770
- target=ast.Name(id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()),
771
- annotation=ast.Name(
772
- id=prop_type,
773
- ctx=ast.Load(),
774
- ),
775
- value=ast.Call(
776
- func=ast.Name(id="DTOField", ctx=ast.Load()),
777
- args=[],
778
- keywords=keywords,
779
- ),
780
- simple=1,
781
- )
782
-
954
+ ast_attr = self._build_dto_property_ast(pkey, prop_type, keywords)
783
955
  ast_dto_attributes.append(ast_attr)
784
956
 
785
957
  # Entity
786
- ast_entity_attr = ast.AnnAssign(
787
- target=ast.Name(
788
- id=CompilerStrUtil.to_snake_case(entity_field_name),
789
- ctx=ast.Store(),
790
- ),
791
- annotation=ast.Name(
792
- id=TypeUtil.property_type_to_python_type(prop.type),
793
- ctx=ast.Load(),
794
- ),
795
- value=ast.Constant(value=None),
796
- simple=1,
797
- )
958
+ ast_entity_attr = self._build_entity_property_ast(entity_field_name, prop.type)
798
959
 
799
960
  ast_entity_attributes.append(ast_entity_attr)
800
961
 
@@ -802,7 +963,9 @@ class EDLPropertyCompiler:
802
963
  self,
803
964
  pkey: str,
804
965
  prop: PropertyMetaModel | TraitPropertyMetaModel,
805
- entity_model: EntityModel,
966
+ escopo: str,
967
+ entity_model: EntityModelBase,
968
+ prefx_class_name: str,
806
969
  ) -> tuple[str, ast.stmt] | None:
807
970
  if not prop.domain_config:
808
971
  return None
@@ -844,7 +1007,7 @@ class EDLPropertyCompiler:
844
1007
  ast_values.append(ast_value)
845
1008
 
846
1009
  # Instanciando o atributo AST
847
- enum_class_name = f"{CompilerStrUtil.to_pascal_case(entity_model.escopo)}{CompilerStrUtil.to_pascal_case(entity_model.id)}{CompilerStrUtil.to_pascal_case(pkey)}Enum"
1010
+ enum_class_name = f"{CompilerStrUtil.to_pascal_case(escopo)}{CompilerStrUtil.to_pascal_case(prefx_class_name)}{CompilerStrUtil.to_pascal_case(entity_model.id)}{CompilerStrUtil.to_pascal_case(pkey)}Enum"
848
1011
  ast_enum_class = ast.ClassDef(
849
1012
  name=enum_class_name,
850
1013
  bases=[
@@ -0,0 +1,21 @@
1
+ import uuid
2
+
3
+ from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
4
+
5
+
6
+ def compile_namespace_keys(
7
+ tenant: str | int | None, grupo_empresarial: str | uuid.UUID | None
8
+ ) -> tuple[str, str, str]:
9
+ grupo_key = f"tenant_{tenant}.ge_{grupo_empresarial}"
10
+ tenant_key = f"tenant_{tenant}"
11
+ default_key = "default"
12
+
13
+ return (grupo_key, tenant_key, default_key)
14
+
15
+
16
+ def compile_dto_class_name(entity_id: str, prefx_class_name: str = "") -> str:
17
+ return f"{CompilerStrUtil.to_pascal_case(prefx_class_name)}{CompilerStrUtil.to_pascal_case(entity_id)}DTO"
18
+
19
+
20
+ def compile_entity_class_name(entity_id: str, prefx_class_name: str = "") -> str:
21
+ return f"{CompilerStrUtil.to_pascal_case(prefx_class_name)}{CompilerStrUtil.to_pascal_case(entity_id)}Entity"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.12
3
+ Version: 0.0.14
4
4
  Summary: Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
5
5
  Home-page: https://github.com/Nasajon/nsj_rest_lib2
6
6
  Author: Nasajon Sistemas
@@ -23,6 +23,7 @@ setup.cfg
23
23
  ./nsj_rest_lib2/compiler/edl_model/api_model.py
24
24
  ./nsj_rest_lib2/compiler/edl_model/column_meta_model.py
25
25
  ./nsj_rest_lib2/compiler/edl_model/entity_model.py
26
+ ./nsj_rest_lib2/compiler/edl_model/entity_model_base.py
26
27
  ./nsj_rest_lib2/compiler/edl_model/index_model.py
27
28
  ./nsj_rest_lib2/compiler/edl_model/primitives.py
28
29
  ./nsj_rest_lib2/compiler/edl_model/property_meta_model.py
@@ -58,6 +59,7 @@ nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py
58
59
  nsj_rest_lib2/compiler/edl_model/api_model.py
59
60
  nsj_rest_lib2/compiler/edl_model/column_meta_model.py
60
61
  nsj_rest_lib2/compiler/edl_model/entity_model.py
62
+ nsj_rest_lib2/compiler/edl_model/entity_model_base.py
61
63
  nsj_rest_lib2/compiler/edl_model/index_model.py
62
64
  nsj_rest_lib2/compiler/edl_model/primitives.py
63
65
  nsj_rest_lib2/compiler/edl_model/property_meta_model.py
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = nsj_rest_lib2
3
- version = 0.0.12
3
+ version = 0.0.14
4
4
  author = Nasajon Sistemas
5
5
  author_email = contact.dev@nasajon.com.br
6
6
  description = Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
@@ -1,21 +0,0 @@
1
- import uuid
2
-
3
- from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
4
-
5
-
6
- def compile_namespace_keys(
7
- tenant: str | int | None, grupo_empresarial: str | uuid.UUID | None
8
- ) -> tuple[str, str, str]:
9
- grupo_key = f"tenant_{tenant}.ge_{grupo_empresarial}"
10
- tenant_key = f"tenant_{tenant}"
11
- default_key = "default"
12
-
13
- return (grupo_key, tenant_key, default_key)
14
-
15
-
16
- def compile_dto_class_name(entity_id: str) -> str:
17
- return f"{CompilerStrUtil.to_pascal_case(entity_id)}DTO"
18
-
19
-
20
- def compile_entity_class_name(entity_id: str) -> str:
21
- return f"{CompilerStrUtil.to_pascal_case(entity_id)}Entity"
File without changes
@@ -317,8 +317,8 @@ class EntityLoader:
317
317
  namespace.module = module
318
318
  namespace.entities_dict = module.__dict__
319
319
 
320
- self._safe_exec(source_dto, namespace.entities_dict, "DTO source")
321
320
  self._safe_exec(source_entity, namespace.entities_dict, "Entity source")
321
+ self._safe_exec(source_dto, namespace.entities_dict, "DTO source")
322
322
 
323
323
  # Gravando a entidade no dict de entidades carregadas
324
324
  loaded_entity = LoadedEntity()