nsj-rest-lib2 0.0.17__tar.gz → 0.0.18__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.17 → nsj_rest_lib2-0.0.18}/PKG-INFO +1 -1
  2. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/compiler.py +7 -2
  3. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/compiler_structures.py +1 -0
  4. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/dto_compiler.py +10 -4
  5. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/entity_model_base.py +4 -0
  6. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/property_compiler.py +116 -13
  7. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2.egg-info/PKG-INFO +1 -1
  8. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/setup.cfg +1 -1
  9. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/README.md +0 -0
  10. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/__init__.py +0 -0
  11. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/__init__.py +0 -0
  12. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/ai_compiler.py +0 -0
  13. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
  14. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
  15. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
  16. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
  17. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/entity_model.py +0 -0
  18. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/entity_model_root.py +0 -0
  19. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
  20. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/primitives.py +0 -0
  21. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
  22. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
  23. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py +0 -0
  24. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/entity_compiler.py +0 -0
  25. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/model.py +0 -0
  26. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
  27. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
  28. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -0
  29. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
  30. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/controller/__init__.py +0 -0
  31. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/controller/dynamic_controller.py +0 -0
  32. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/exception.py +0 -0
  33. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/redis_config.py +0 -0
  34. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/service/__init__.py +0 -0
  35. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/service/entity_loader.py +0 -0
  36. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2/settings.py +0 -0
  37. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2.egg-info/SOURCES.txt +0 -0
  38. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
  39. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2.egg-info/requires.txt +0 -0
  40. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
  41. {nsj_rest_lib2-0.0.17 → nsj_rest_lib2-0.0.18}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.17
3
+ Version: 0.0.18
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
@@ -118,7 +118,7 @@ class EDLCompiler:
118
118
  ast_dto_attributes,
119
119
  ast_entity_attributes,
120
120
  props_pk,
121
- enum_classes,
121
+ aux_classes,
122
122
  related_imports,
123
123
  relations_dependencies,
124
124
  fixed_filters,
@@ -171,7 +171,7 @@ class EDLCompiler:
171
171
  dto_class_name, code_dto = self._dto_compiler.compile(
172
172
  entity_model,
173
173
  ast_dto_attributes,
174
- enum_classes,
174
+ aux_classes,
175
175
  related_imports,
176
176
  fixed_filters,
177
177
  prefx_class_name,
@@ -310,6 +310,11 @@ class EDLCompiler:
310
310
  entity_model.extends_properties
311
311
  )
312
312
 
313
+ if entity_model.composed_properties:
314
+ properties_structure.composed_properties.update(
315
+ entity_model.composed_properties
316
+ )
317
+
313
318
  if entity_model.repository.properties:
314
319
  properties_structure.entity_properties.update(
315
320
  entity_model.repository.properties
@@ -25,6 +25,7 @@ class PropertiesCompilerStructure:
25
25
  self.entity_properties: dict[str, ColumnMetaModel] = {}
26
26
  self.trait_properties: dict[str, TraitPropertyMetaModel] = {}
27
27
  self.extends_properties: dict[str, ExtendsPropertyMetaModel] = {}
28
+ self.composed_properties: dict[str, list[str]] = {}
28
29
 
29
30
 
30
31
  class ComponentsCompilerStructure:
@@ -16,7 +16,7 @@ class DTOCompiler:
16
16
  self,
17
17
  entity_model: EntityModelBase,
18
18
  ast_dto_attributes: list[ast.stmt],
19
- enum_classes: list[ast.stmt],
19
+ aux_classes: list[ast.stmt],
20
20
  related_imports: list[tuple[str, str, str]],
21
21
  fixed_filters: list[tuple[str, BasicTypes]],
22
22
  prefx_class_name: str,
@@ -30,8 +30,8 @@ class DTOCompiler:
30
30
  :param ast_dto_attributes: Atributos do DTO
31
31
  :type ast_dto_attributes: list[ast.stmt]
32
32
 
33
- :param enum_classes: Classes de enumeração
34
- :type enum_classes: list[ast.stmt]
33
+ :param aux_classes: Classes auxiliares (enums, agregadores, etc.)
34
+ :type aux_classes: list[ast.stmt]
35
35
 
36
36
  :return: Código compilado do DTO
37
37
  :rtype: str
@@ -86,6 +86,12 @@ class DTOCompiler:
86
86
  names=[ast.alias(name="DTOObjectField", asname=None)],
87
87
  level=0,
88
88
  ),
89
+ # from nsj_rest_lib.descriptor import DTOAggregator
90
+ ast.ImportFrom(
91
+ module="nsj_rest_lib.descriptor",
92
+ names=[ast.alias(name="DTOAggregator", asname=None)],
93
+ level=0,
94
+ ),
89
95
  ]
90
96
 
91
97
  for import_ in related_imports:
@@ -135,7 +141,7 @@ class DTOCompiler:
135
141
 
136
142
  # Definindo o módulo
137
143
  module = ast.Module(
138
- body=imports + enum_classes + [ast_class],
144
+ body=imports + aux_classes + [ast_class],
139
145
  type_ignores=[],
140
146
  )
141
147
  module = ast.fix_missing_locations(module)
@@ -63,6 +63,10 @@ class EntityModelBase(BaseModel):
63
63
  properties: Dict[str, PropertyMetaModel] = Field(
64
64
  ..., description="Dicionário de propriedades do modelo."
65
65
  )
66
+ composed_properties: Optional[Dict[str, List[str]]] = Field(
67
+ None,
68
+ description="Dicionário que define grupos de propriedades compostas, permitindo agrupar propriedades existentes em DTOs agregados.",
69
+ )
66
70
  components: Optional[Dict[str, "EntityModelBase"]] = Field(
67
71
  None,
68
72
  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).",
@@ -80,17 +80,60 @@ class EDLPropertyCompiler:
80
80
  ast_dto_attributes = []
81
81
  ast_entity_attributes = []
82
82
  props_pk = []
83
- enum_classes = []
83
+ aux_classes = []
84
84
  related_imports = []
85
85
  relations_dependencies = []
86
86
  fixed_filters = []
87
87
 
88
88
  if properties_structure.properties is None:
89
- return (ast_dto_attributes, ast_entity_attributes, props_pk, enum_classes)
89
+ return (ast_dto_attributes, ast_entity_attributes, props_pk, aux_classes)
90
+
91
+ composed_properties = properties_structure.composed_properties or {}
92
+
93
+ aggregator_class_names: dict[str, str] = {}
94
+ aggregator_dto_attributes: dict[str, list[ast.stmt]] = {}
95
+ aggregated_property_to_group: dict[str, str] = {}
96
+
97
+ for composed_key, composed_list in composed_properties.items():
98
+ if not composed_list:
99
+ continue
100
+
101
+ composed_class_name = (
102
+ f"{CompilerStrUtil.to_pascal_case(escopo)}"
103
+ f"{CompilerStrUtil.to_pascal_case(prefx_class_name)}"
104
+ f"{CompilerStrUtil.to_pascal_case(entity_model.id)}"
105
+ f"{CompilerStrUtil.to_pascal_case(composed_key)}AggregatorDTO"
106
+ )
107
+
108
+ aggregator_class_names[composed_key] = composed_class_name
109
+ aggregator_dto_attributes[composed_key] = []
110
+
111
+ for composed_property in composed_list:
112
+ if composed_property in aggregated_property_to_group:
113
+ raise Exception(
114
+ f"Propriedade '{composed_property}' da entidade '{entity_model.id}' está associada a mais de um composed_property."
115
+ )
116
+
117
+ if composed_property not in properties_structure.properties:
118
+ raise Exception(
119
+ f"Propriedade '{composed_property}' referenciada no composed_property '{composed_key}' não encontrada na entidade '{entity_model.id}'."
120
+ )
121
+
122
+ aggregated_property_to_group[composed_property] = composed_key
90
123
 
91
124
  for pkey in properties_structure.properties:
92
125
  prop = properties_structure.properties[pkey]
93
126
 
127
+ composed_key = aggregated_property_to_group.get(pkey)
128
+ if composed_key:
129
+ if prop.pk:
130
+ raise Exception(
131
+ f"Propriedade '{pkey}' não pode ser utilizada em composed_properties por ser chave primária."
132
+ )
133
+ target_dto_attributes = aggregator_dto_attributes[composed_key]
134
+ else:
135
+ target_dto_attributes = ast_dto_attributes
136
+
94
137
  # DTO
95
138
  if isinstance(prop.type, PrimitiveTypes):
96
139
  # Tratando propriedade simples (não array, não object)
@@ -99,10 +142,10 @@ class EDLPropertyCompiler:
99
142
  map_unique_by_property,
100
143
  escopo,
101
144
  entity_model,
102
- ast_dto_attributes,
145
+ target_dto_attributes,
103
146
  ast_entity_attributes,
104
147
  props_pk,
105
- enum_classes,
148
+ aux_classes,
106
149
  pkey,
107
150
  prop,
108
151
  prefx_class_name,
@@ -124,7 +167,7 @@ class EDLPropertyCompiler:
124
167
  entity_model,
125
168
  entity_models,
126
169
  properties_structure,
127
- ast_dto_attributes,
170
+ target_dto_attributes,
128
171
  ast_entity_attributes,
129
172
  related_imports,
130
173
  relations_dependencies,
@@ -139,7 +182,7 @@ class EDLPropertyCompiler:
139
182
  related_entity_id,
140
183
  entity_model,
141
184
  properties_structure,
142
- ast_dto_attributes,
185
+ target_dto_attributes,
143
186
  ast_entity_attributes,
144
187
  pkey,
145
188
  prop,
@@ -163,7 +206,7 @@ class EDLPropertyCompiler:
163
206
  fixed_filters,
164
207
  escopo,
165
208
  entity_model,
166
- enum_classes,
209
+ aux_classes,
167
210
  prefx_class_name,
168
211
  )
169
212
 
@@ -180,15 +223,32 @@ class EDLPropertyCompiler:
180
223
  fixed_filters,
181
224
  escopo,
182
225
  entity_model,
183
- enum_classes,
226
+ aux_classes,
184
227
  prefx_class_name,
185
228
  )
186
229
 
230
+ for composed_key, class_name in aggregator_class_names.items():
231
+ dto_attributes = aggregator_dto_attributes.get(composed_key, [])
232
+
233
+ aux_classes.append(
234
+ self._build_aggregator_class_ast(
235
+ class_name=class_name,
236
+ dto_attributes=dto_attributes,
237
+ )
238
+ )
239
+
240
+ ast_dto_attributes.append(
241
+ self._build_dto_aggregator_ast(
242
+ name=composed_key,
243
+ class_name=class_name,
244
+ )
245
+ )
246
+
187
247
  return (
188
248
  ast_dto_attributes,
189
249
  ast_entity_attributes,
190
250
  props_pk,
191
- enum_classes,
251
+ aux_classes,
192
252
  related_imports,
193
253
  relations_dependencies,
194
254
  fixed_filters,
@@ -205,7 +265,7 @@ class EDLPropertyCompiler:
205
265
  fixed_filters: list[tuple[str, BasicTypes]],
206
266
  escopo: str,
207
267
  entity_model: EntityModelBase,
208
- enum_classes: list[ast.stmt],
268
+ aux_classes: list[ast.stmt],
209
269
  prefx_class_name: str,
210
270
  ):
211
271
  enum_class_name = None
@@ -319,7 +379,7 @@ class EDLPropertyCompiler:
319
379
  raise Exception(f"Erro desconhecido ao compilar a propriedade {pkey}")
320
380
 
321
381
  enum_class_name, ast_enum_class = result
322
- enum_classes.append(ast_enum_class)
382
+ aux_classes.append(ast_enum_class)
323
383
 
324
384
  # Resolvendo o nome da propriedade no Entity
325
385
  if (
@@ -387,6 +447,49 @@ class EDLPropertyCompiler:
387
447
  # TODO Pensar em validações para esse value (se está de acordo com o tipo ou enum)
388
448
  fixed_filters.append((pkey, prop.value))
389
449
 
450
+ def _build_aggregator_class_ast(
451
+ self,
452
+ class_name: str,
453
+ dto_attributes: list[ast.stmt],
454
+ ):
455
+ body = dto_attributes if dto_attributes else [ast.Pass()]
456
+
457
+ return ast.ClassDef(
458
+ name=class_name,
459
+ bases=[ast.Name(id="DTOBase", ctx=ast.Load())],
460
+ keywords=[],
461
+ decorator_list=[
462
+ ast.Call(
463
+ func=ast.Name(id="DTO", ctx=ast.Load()),
464
+ args=[],
465
+ keywords=[],
466
+ )
467
+ ],
468
+ body=body,
469
+ )
470
+
471
+ def _build_dto_aggregator_ast(
472
+ self,
473
+ name: str,
474
+ class_name: str,
475
+ ):
476
+ return ast.AnnAssign(
477
+ target=ast.Name(
478
+ id=CompilerStrUtil.to_snake_case(name),
479
+ ctx=ast.Store(),
480
+ ),
481
+ annotation=ast.Name(
482
+ id=class_name,
483
+ ctx=ast.Load(),
484
+ ),
485
+ value=ast.Call(
486
+ func=ast.Name(id="DTOAggregator", ctx=ast.Load()),
487
+ args=[ast.Name(id=class_name, ctx=ast.Load())],
488
+ keywords=[],
489
+ ),
490
+ simple=1,
491
+ )
492
+
390
493
  def _compile_external_relation(
391
494
  self,
392
495
  related_entity_id: str,
@@ -774,7 +877,7 @@ class EDLPropertyCompiler:
774
877
  ast_dto_attributes,
775
878
  ast_entity_attributes,
776
879
  props_pk,
777
- enum_classes,
880
+ aux_classes,
778
881
  pkey,
779
882
  prop,
780
883
  prefx_class_name: str,
@@ -953,7 +1056,7 @@ class EDLPropertyCompiler:
953
1056
  raise Exception(f"Erro desconhecido ao compilar a propriedade {pkey}")
954
1057
 
955
1058
  enum_class_name, ast_enum_class = result
956
- enum_classes.append(ast_enum_class)
1059
+ aux_classes.append(ast_enum_class)
957
1060
 
958
1061
  # Resolvendo o nome da propriedade no Entity
959
1062
  if (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.17
3
+ Version: 0.0.18
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
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = nsj_rest_lib2
3
- version = 0.0.17
3
+ version = 0.0.18
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).
File without changes