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.
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/PKG-INFO +1 -1
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/compiler.py +91 -13
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/compiler_structures.py +6 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/dto_compiler.py +4 -3
- nsj_rest_lib2-0.0.14/nsj_rest_lib2/compiler/edl_model/entity_model.py +23 -0
- 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
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/primitives.py +1 -1
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/entity_compiler.py +9 -4
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/property_compiler.py +222 -59
- nsj_rest_lib2-0.0.14/nsj_rest_lib2/compiler/util/type_naming_util.py +21 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/PKG-INFO +1 -1
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/SOURCES.txt +2 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/setup.cfg +1 -1
- nsj_rest_lib2-0.0.12/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -21
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/README.md +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/ai_compiler.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
- {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
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/model.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/controller/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/controller/dynamic_controller.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/exception.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/redis_config.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/service/__init__.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/service/entity_loader.py +1 -1
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/settings.py +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/requires.txt +0 -0
- {nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
- {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.
|
|
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
|
|
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:
|
|
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,
|
|
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 =
|
|
187
|
+
compiler_result.entity_code = entity_code
|
|
134
188
|
compiler_result.dto_class_name = dto_class_name
|
|
135
|
-
compiler_result.dto_code =
|
|
189
|
+
compiler_result.dto_code = dto_code
|
|
136
190
|
|
|
137
191
|
# Compilando questões das APIs
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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()
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/primitives.py
RENAMED
|
@@ -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"^#\/
|
|
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.
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
128
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py
RENAMED
|
File without changes
|
|
File without changes
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py
RENAMED
|
File without changes
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/index_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/compiler/edl_model/repository_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nsj_rest_lib2-0.0.12 → nsj_rest_lib2-0.0.14}/nsj_rest_lib2/controller/dynamic_controller.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|