nsj-rest-lib2 0.0.18__py3-none-any.whl → 0.0.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,9 +12,15 @@ from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
12
12
  from nsj_rest_lib2.compiler.edl_model.entity_model_root import EntityModelRoot
13
13
  from nsj_rest_lib2.compiler.edl_model.primitives import REGEX_EXTERNAL_REF
14
14
  from nsj_rest_lib2.compiler.entity_compiler import EntityCompiler
15
- from nsj_rest_lib2.compiler.model import CompilerResult
15
+ from nsj_rest_lib2.compiler.model import CompilerResult, RelationDependency
16
16
  from nsj_rest_lib2.compiler.property_compiler import EDLPropertyCompiler
17
17
 
18
+ from nsj_rest_lib2.compiler.util.type_naming_util import (
19
+ compile_dto_class_name,
20
+ compile_entity_class_name,
21
+ compile_namespace_keys,
22
+ )
23
+
18
24
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
19
25
 
20
26
  from nsj_rest_lib2.settings import get_logger
@@ -96,6 +102,27 @@ class EDLCompiler:
96
102
  if not escopo:
97
103
  raise Exception(f"Escopo não definido para a entidade: {entity_model.id}.")
98
104
 
105
+ # Tratando dos dados base para a extensão parcial
106
+ partial_metadata: dict[str, str] | None = None
107
+ partial_base_model: EntityModel | None = None
108
+ if isinstance(entity_model, EntityModel) and entity_model.partial_of:
109
+ if entity_model.partial_of not in entity_models:
110
+ raise Exception(
111
+ f"Entidade base '{entity_model.partial_of}' não encontrada para a extensão parcial '{entity_model.id}'."
112
+ )
113
+
114
+ base_model_candidate = entity_models[entity_model.partial_of]
115
+ if not isinstance(base_model_candidate, EntityModel):
116
+ raise Exception(
117
+ f"Entidade base '{entity_model.partial_of}' da extensão parcial '{entity_model.id}' é inválida."
118
+ )
119
+
120
+ self._validate_partial_model(entity_model, base_model_candidate, entity_models)
121
+ partial_metadata = self._build_partial_metadata(
122
+ entity_model, base_model_candidate
123
+ )
124
+ partial_base_model = base_model_candidate
125
+
99
126
  # Criando um mapa de índices por nome de property
100
127
  # TODO Implementar tratamento dos índices de apoio às query (não de unicidade)
101
128
  map_indexes_by_property: dict[str, list[IndexCompilerStructure]] = {}
@@ -131,6 +158,18 @@ class EDLCompiler:
131
158
  prefx_class_name,
132
159
  )
133
160
 
161
+ # Adicionando os imports da extensão parcial
162
+ if partial_metadata:
163
+ related_imports.append(
164
+ (
165
+ partial_metadata["module"],
166
+ partial_metadata["dto_class"],
167
+ partial_metadata["entity_class"],
168
+ )
169
+ )
170
+
171
+ related_imports = self._deduplicate_related_imports(related_imports)
172
+
134
173
  # Gerando o buffer para os códigos de DTO e Entity
135
174
  dto_code = ""
136
175
  entity_code = ""
@@ -175,6 +214,7 @@ class EDLCompiler:
175
214
  related_imports,
176
215
  fixed_filters,
177
216
  prefx_class_name,
217
+ partial_metadata,
178
218
  )
179
219
 
180
220
  # Gerando o código da Entity
@@ -183,13 +223,29 @@ class EDLCompiler:
183
223
  ast_entity_attributes,
184
224
  props_pk,
185
225
  prefx_class_name,
226
+ partial_metadata,
186
227
  )
187
228
 
188
229
  # Extendendo os buffers com os códigos gerados
189
230
  dto_code += code_dto
190
231
  entity_code += code_entity
232
+
233
+ # Adicionando as dependências das relações
191
234
  relations_dependencies_complete.extend(relations_dependencies)
192
235
 
236
+ # Adicionando as dependências da extensão parcial
237
+ if partial_metadata and partial_base_model:
238
+ relation_dependency = RelationDependency()
239
+ if not partial_base_model.api or not partial_base_model.api.resource:
240
+ raise Exception(
241
+ f"Entidade base '{partial_base_model.id}' não possui configuração de API necessária para extensão parcial."
242
+ )
243
+ relation_dependency.entity_resource = partial_base_model.api.resource
244
+ relation_dependency.entity_scope = partial_base_model.escopo
245
+ relation_dependency.tenant = partial_base_model.tenant
246
+ relation_dependency.grupo_empresarial = partial_base_model.grupo_empresarial
247
+ relations_dependencies_complete.append(relation_dependency)
248
+
193
249
  # Construindo o resultado
194
250
  compiler_result = CompilerResult()
195
251
  compiler_result.entity_class_name = entity_class_name
@@ -212,6 +268,138 @@ class EDLCompiler:
212
268
 
213
269
  return compiler_result
214
270
 
271
+ def _validate_partial_model(
272
+ self,
273
+ partial_model: EntityModel,
274
+ base_model: EntityModel,
275
+ entity_models: dict[str, EntityModel],
276
+ ) -> None:
277
+ base_properties_structure = PropertiesCompilerStructure()
278
+ self._make_properties_structures(
279
+ base_properties_structure,
280
+ base_model,
281
+ entity_models,
282
+ )
283
+ aggregated_base_properties = set(base_properties_structure.properties.keys())
284
+
285
+ duplicated_properties = aggregated_base_properties.intersection(
286
+ set(partial_model.properties.keys())
287
+ )
288
+ if duplicated_properties:
289
+ raise Exception(
290
+ f"Extensão parcial '{partial_model.id}' redefine propriedades da entidade base '{base_model.id}': {sorted(duplicated_properties)}."
291
+ )
292
+
293
+ lists_to_check = {
294
+ "required": partial_model.required,
295
+ "main_properties": partial_model.main_properties,
296
+ "partition_data": partial_model.partition_data,
297
+ "search_properties": partial_model.search_properties,
298
+ "metric_label": partial_model.metric_label,
299
+ }
300
+
301
+ for list_name, values in lists_to_check.items():
302
+ if not values:
303
+ continue
304
+
305
+ conflicts = [
306
+ value
307
+ for value in values
308
+ if isinstance(value, str) and value in aggregated_base_properties
309
+ ]
310
+ if conflicts:
311
+ raise Exception(
312
+ f"Extensão parcial '{partial_model.id}' utiliza propriedades da entidade base '{base_model.id}' em '{list_name}': {conflicts}."
313
+ )
314
+
315
+ link = partial_model.repository.link_to_base
316
+ if not link:
317
+ raise Exception(
318
+ f"Extensão parcial '{partial_model.id}' requer configuração 'link_to_base' no bloco 'repository'."
319
+ )
320
+
321
+ if not link.base_property:
322
+ raise Exception(
323
+ f"Extensão parcial '{partial_model.id}' requer 'base_property' definido em 'link_to_base'."
324
+ )
325
+
326
+ if not link.column:
327
+ raise Exception(
328
+ f"Extensão parcial '{partial_model.id}' requer 'column' definido em 'link_to_base'."
329
+ )
330
+
331
+ if link.base_property not in aggregated_base_properties:
332
+ raise Exception(
333
+ f"'base_property' '{link.base_property}' não corresponde a uma propriedade da entidade base '{base_model.id}'."
334
+ )
335
+
336
+ # if not base_model.api or not base_model.api.resource:
337
+ # raise Exception(
338
+ # f"Entidade base '{base_model.id}' não possui configuração de API compatível com extensões parciais."
339
+ # )
340
+
341
+ def _build_partial_metadata(
342
+ self, partial_model: EntityModel, base_model: EntityModel
343
+ ) -> dict[str, str]:
344
+ link = partial_model.repository.link_to_base
345
+ if link is None:
346
+ raise Exception(
347
+ f"Extensão parcial '{partial_model.id}' está sem configuração 'link_to_base'."
348
+ )
349
+
350
+ grupo_key, tenant_key, default_key = compile_namespace_keys(
351
+ base_model.tenant, base_model.grupo_empresarial
352
+ )
353
+ namespace = self._resolve_namespace_key(
354
+ base_model.tenant,
355
+ base_model.grupo_empresarial,
356
+ grupo_key,
357
+ tenant_key,
358
+ default_key,
359
+ )
360
+
361
+ return {
362
+ "module": namespace,
363
+ "dto_class": compile_dto_class_name(base_model.id),
364
+ "entity_class": compile_entity_class_name(base_model.id),
365
+ "relation_field": link.column,
366
+ "related_entity_field": link.base_property,
367
+ }
368
+
369
+ def _resolve_namespace_key(
370
+ self,
371
+ tenant: str | int | None,
372
+ grupo_empresarial,
373
+ grupo_key: str,
374
+ tenant_key: str,
375
+ default_key: str,
376
+ ) -> str:
377
+ has_tenant = tenant not in (None, 0, "0")
378
+ has_grupo = (
379
+ grupo_empresarial
380
+ and str(grupo_empresarial) != "00000000-0000-0000-0000-000000000000"
381
+ )
382
+
383
+ if has_tenant and has_grupo:
384
+ return grupo_key
385
+ if has_tenant:
386
+ return tenant_key
387
+ return default_key
388
+
389
+ def _deduplicate_related_imports(
390
+ self, related_imports: list[tuple[str, str, str]]
391
+ ) -> list[tuple[str, str, str]]:
392
+ deduped: list[tuple[str, str, str]] = []
393
+ seen: set[tuple[str, str, str]] = set()
394
+
395
+ for import_tuple in related_imports:
396
+ if import_tuple in seen:
397
+ continue
398
+ seen.add(import_tuple)
399
+ deduped.append(import_tuple)
400
+
401
+ return deduped
402
+
215
403
  def _make_components_structures(
216
404
  self,
217
405
  components_structure: ComponentsCompilerStructure,
@@ -290,7 +478,35 @@ class EDLCompiler:
290
478
  # Populando com as propriedades da entidade atual
291
479
  properties_structure.properties.update(entity_model.properties)
292
480
  if entity_model.main_properties:
293
- properties_structure.main_properties.extend(entity_model.main_properties)
481
+ for main_property in entity_model.main_properties:
482
+ if not isinstance(main_property, str):
483
+ continue
484
+
485
+ if "/" in main_property:
486
+ path_parts = [
487
+ part.strip() for part in main_property.split("/") if part
488
+ ]
489
+ if len(path_parts) < 2 or not path_parts[0]:
490
+ raise Exception(
491
+ f"Propriedade resumo inválida '{main_property}' na entidade '{entity_model.id}'."
492
+ )
493
+
494
+ relation_name = path_parts[0]
495
+ resume_path_parts = path_parts[1:]
496
+ resume_field = ".".join(resume_path_parts)
497
+
498
+ if relation_name not in properties_structure.main_properties:
499
+ properties_structure.main_properties.append(relation_name)
500
+
501
+ resume_fields = properties_structure.main_resume_fields.setdefault(
502
+ relation_name, []
503
+ )
504
+
505
+ if resume_field and resume_field not in resume_fields:
506
+ resume_fields.append(resume_field)
507
+ else:
508
+ if main_property not in properties_structure.main_properties:
509
+ properties_structure.main_properties.append(main_property)
294
510
  if entity_model.required:
295
511
  properties_structure.required.extend(entity_model.required)
296
512
  if entity_model.partition_data:
@@ -404,6 +620,10 @@ class EDLCompiler:
404
620
  if entity_model.trait_from:
405
621
  entities.append(entity_model.trait_from)
406
622
 
623
+ # Adicionando dependências por classes parciais
624
+ if isinstance(entity_model, EntityModel) and entity_model.partial_of:
625
+ entities.append(entity_model.partial_of)
626
+
407
627
  # Populando com as dependências de propriedades de relacionamento
408
628
  relations = self._list_dependencies_relations(entity_model)
409
629
 
@@ -486,19 +706,19 @@ if __name__ == "__main__":
486
706
  compiler = EDLCompiler()
487
707
  compiler_results = compiler.compile_models(entities)
488
708
 
489
- for compiler_result in compiler_results:
490
- print("==========================================================")
491
- print(f"Entity: {compiler_result.entity_class_name}")
492
- print(f"{compiler_result.entity_code}")
493
- print("\n")
494
- print("==========================================================")
495
- print(f"DTO: {compiler_result.dto_class_name}")
496
- print(f"{compiler_result.dto_code}")
497
- print("\n")
498
-
499
- print("==========================================================")
500
- print("API Expose: ", compiler_result.api_expose)
501
- print("API Route Path: ", compiler_result.api_resource)
502
- print("API Verbs: ", compiler_result.api_verbs)
503
- print("==========================================================")
504
- print("\n")
709
+ with open("output_compilacao_local.py", "w") as f:
710
+ for compiler_result in compiler_results:
711
+ f.write("==========================================================\n")
712
+ f.write(f"Entity: {compiler_result.entity_class_name}\n")
713
+ f.write(f"{compiler_result.entity_code}\n")
714
+ f.write("\n")
715
+ f.write("==========================================================\n")
716
+ f.write(f"DTO: {compiler_result.dto_class_name}\n")
717
+ f.write(f"{compiler_result.dto_code}\n")
718
+ f.write("\n")
719
+ f.write("==========================================================\n")
720
+ f.write(f"API Expose: {compiler_result.api_expose}\n")
721
+ f.write(f"API Route Path: {compiler_result.api_resource}\n")
722
+ f.write(f"API Verbs: {compiler_result.api_verbs}\n")
723
+ f.write("==========================================================\n")
724
+ f.write("\n")
@@ -18,6 +18,7 @@ class PropertiesCompilerStructure:
18
18
  def __init__(self) -> None:
19
19
  self.properties: dict[str, PropertyMetaModel] = {}
20
20
  self.main_properties: list[str] = []
21
+ self.main_resume_fields: dict[str, list[str]] = {}
21
22
  self.required: list[str] = []
22
23
  self.partition_data: list[str] = []
23
24
  self.search_properties: list[str] = []
@@ -20,6 +20,7 @@ class DTOCompiler:
20
20
  related_imports: list[tuple[str, str, str]],
21
21
  fixed_filters: list[tuple[str, BasicTypes]],
22
22
  prefx_class_name: str,
23
+ partial_metadata: dict[str, str] | None,
23
24
  ) -> tuple[str, str]:
24
25
  """
25
26
  Compila o código do DTO a partir do AST e retorna o código compilado.
@@ -110,15 +111,42 @@ class DTOCompiler:
110
111
  )
111
112
  )
112
113
 
114
+ # Keywords para a extensão parcial
115
+ decorator_keywords: list[ast.keyword] = []
116
+
117
+ if partial_metadata:
118
+ partial_dict_keys = [
119
+ ast.Constant(value="dto"),
120
+ ast.Constant(value="relation_field"),
121
+ ]
122
+ partial_dict_values = [
123
+ ast.Name(id=partial_metadata["dto_class"], ctx=ast.Load()),
124
+ ast.Constant(value=partial_metadata["relation_field"]),
125
+ ]
126
+
127
+ related_field = partial_metadata.get("related_entity_field")
128
+ if related_field:
129
+ partial_dict_keys.append(ast.Constant(value="related_entity_field"))
130
+ partial_dict_values.append(ast.Constant(value=related_field))
131
+
132
+ decorator_keywords.append(
133
+ ast.keyword(
134
+ arg="partial_of",
135
+ value=ast.Dict(
136
+ keys=partial_dict_keys,
137
+ values=partial_dict_values,
138
+ ),
139
+ )
140
+ )
141
+
113
142
  # Keywords para tipos usados em fixed_filters
114
- keywords_decorator_dto = []
115
- for fixed_filter in fixed_filters:
116
- keywords_decorator_dto.append(
143
+ if fixed_filters:
144
+ decorator_keywords.append(
117
145
  ast.keyword(
118
146
  arg="fixed_filters",
119
147
  value=ast.Dict(
120
- keys=[ast.Constant(value=fixed_filter[0])],
121
- values=[ast.Constant(value=fixed_filter[1])],
148
+ keys=[ast.Constant(value=item[0]) for item in fixed_filters],
149
+ values=[ast.Constant(value=item[1]) for item in fixed_filters],
122
150
  ),
123
151
  )
124
152
  )
@@ -133,7 +161,7 @@ class DTOCompiler:
133
161
  ast.Call(
134
162
  func=ast.Name(id="DTO", ctx=ast.Load()),
135
163
  args=[],
136
- keywords=keywords_decorator_dto,
164
+ keywords=decorator_keywords,
137
165
  )
138
166
  ],
139
167
  body=ast_dto_attributes,
@@ -29,6 +29,10 @@ class EntityModelBase(BaseModel):
29
29
  trait_from: Optional[str] = Field(
30
30
  None, description="Identificador da entidade que a trait estende."
31
31
  )
32
+ partial_of: Optional[str] = Field(
33
+ None,
34
+ description="Identificador da entidade base estendida por esta extensão parcial (relacionamento 1x1 transparente).",
35
+ )
32
36
  mixins: Optional[List[str]] = Field(
33
37
  None,
34
38
  description="Lista de mixins (blocos reutilizáveis) aplicados ao modelo.",
@@ -5,6 +5,25 @@ from nsj_rest_lib2.compiler.edl_model.column_meta_model import ColumnMetaModel
5
5
  from nsj_rest_lib2.compiler.edl_model.index_model import IndexModel
6
6
 
7
7
 
8
+ class RepositoryLinkToBaseModel(BaseModel):
9
+ base_property: str = Field(
10
+ ...,
11
+ description="Nome da propriedade na entidade base utilizada para o relacionamento 1x1.",
12
+ )
13
+ column: str = Field(
14
+ ...,
15
+ description="Nome da coluna (ou propriedade) na entidade parcial responsável por referenciar a entidade base.",
16
+ )
17
+ on_delete: Optional[str] = Field(
18
+ None,
19
+ description="Política de exclusão configurada no relacionamento com a entidade base.",
20
+ )
21
+ nullable: Optional[bool] = Field(
22
+ False,
23
+ description="Indica se o relacionamento com a entidade base pode ser nulo.",
24
+ )
25
+
26
+
8
27
  class RepositoryModel(BaseModel):
9
28
  map: str = Field(
10
29
  ..., description="Nome da tabela, no BD, para a qual a entidade é mapeada."
@@ -22,3 +41,7 @@ class RepositoryModel(BaseModel):
22
41
  indexes: Optional[List[IndexModel]] = Field(
23
42
  None, description="Lista de índices de banco de dados, associados à entidade."
24
43
  )
44
+ link_to_base: Optional[RepositoryLinkToBaseModel] = Field(
45
+ None,
46
+ description="Configuração de relacionamento 1x1 com a entidade base (extensões parciais).",
47
+ )
@@ -18,6 +18,7 @@ class EntityCompiler:
18
18
  ast_entity_attributes: list[ast.stmt],
19
19
  props_pk: list[str],
20
20
  prefix_class_name: str,
21
+ partial_metadata: dict[str, str] | None,
21
22
  ) -> tuple[str, str]:
22
23
  # Imports
23
24
  imports = [
@@ -39,25 +40,53 @@ class EntityCompiler:
39
40
  ),
40
41
  ]
41
42
 
43
+ if partial_metadata:
44
+ imports.append(
45
+ ast.ImportFrom(
46
+ module=f"dynamic.{partial_metadata['module']}",
47
+ names=[
48
+ ast.alias(name=partial_metadata["entity_class"], asname=None)
49
+ ],
50
+ level=0,
51
+ )
52
+ )
53
+
42
54
  # Entity
43
55
  if len(props_pk) > 1:
44
56
  raise Exception(
45
57
  f"Entidade '{entity_model.id}' possui mais de uma chave primária (ainda não suportado): {props_pk}"
46
58
  )
47
- elif len(props_pk) <= 0:
59
+
60
+ if len(props_pk) == 0 and not partial_metadata:
48
61
  raise Exception(
49
62
  f"Entidade '{entity_model.id}' não possui nenhuma chave primária (ainda não suportado)."
50
63
  )
51
64
 
52
65
  default_order_props = []
53
66
 
54
- key_field = props_pk[0]
55
- if entity_model.repository.properties:
56
- if (
57
- key_field in entity_model.repository.properties
58
- and entity_model.repository.properties[key_field].column
59
- ):
60
- key_field = entity_model.repository.properties[props_pk[0]].column
67
+ # Resolvendo o nome da coluna da chave primária
68
+ if len(props_pk) == 1:
69
+ key_field_property = props_pk[0]
70
+ else:
71
+ key_field_property = (
72
+ partial_metadata["relation_field"] if partial_metadata else None
73
+ )
74
+
75
+ key_field = key_field_property
76
+ if (
77
+ len(props_pk) == 1
78
+ and entity_model.repository.properties
79
+ and key_field_property in entity_model.repository.properties
80
+ and entity_model.repository.properties[key_field_property].column
81
+ ):
82
+ key_field = entity_model.repository.properties[key_field_property].column
83
+ elif partial_metadata and partial_metadata.get("relation_field"):
84
+ key_field = partial_metadata["relation_field"]
85
+
86
+ if key_field is None:
87
+ raise Exception(
88
+ f"Não foi possível determinar a chave primária para a entidade '{entity_model.id}'."
89
+ )
61
90
 
62
91
  if (
63
92
  isinstance(entity_model, EntityModel)
@@ -90,28 +119,9 @@ class EntityCompiler:
90
119
  ast.Call(
91
120
  func=ast.Name(id="Entity", ctx=ast.Load()),
92
121
  args=[],
93
- keywords=[
94
- ast.keyword(
95
- arg="table_name",
96
- value=ast.Constant(value=entity_model.repository.map),
97
- ),
98
- ast.keyword(
99
- arg="pk_field",
100
- value=ast.Constant(
101
- value=CompilerStrUtil.to_snake_case(key_field)
102
- ),
103
- ),
104
- ast.keyword(
105
- arg="default_order_fields",
106
- value=ast.List(
107
- elts=[
108
- ast.Constant(value=field)
109
- for field in default_order_fields
110
- ],
111
- ctx=ast.Load(),
112
- ),
113
- ),
114
- ],
122
+ keywords=self._build_entity_decorator_keywords(
123
+ entity_model, key_field, default_order_fields, partial_metadata
124
+ ),
115
125
  )
116
126
  ],
117
127
  body=ast_entity_attributes,
@@ -131,3 +141,50 @@ class EntityCompiler:
131
141
  code = black.format_str(code, mode=black.FileMode())
132
142
 
133
143
  return (class_name, code)
144
+
145
+ def _build_entity_decorator_keywords(
146
+ self,
147
+ entity_model: EntityModelBase,
148
+ key_field: str,
149
+ default_order_fields: list[str],
150
+ partial_metadata: dict[str, str] | None,
151
+ ) -> list[ast.keyword]:
152
+ keywords = [
153
+ ast.keyword(
154
+ arg="table_name",
155
+ value=ast.Constant(value=entity_model.repository.map),
156
+ ),
157
+ ]
158
+
159
+ if not partial_metadata:
160
+ keywords.extend(
161
+ [
162
+ ast.keyword(
163
+ arg="pk_field",
164
+ value=ast.Constant(
165
+ value=CompilerStrUtil.to_snake_case(key_field)
166
+ ),
167
+ ),
168
+ ast.keyword(
169
+ arg="default_order_fields",
170
+ value=ast.List(
171
+ elts=[
172
+ ast.Constant(value=field)
173
+ for field in default_order_fields
174
+ ],
175
+ ctx=ast.Load(),
176
+ ),
177
+ ),
178
+ ]
179
+ )
180
+
181
+ if partial_metadata:
182
+ keywords.insert(
183
+ 0,
184
+ ast.keyword(
185
+ arg="partial_of",
186
+ value=ast.Name(id=partial_metadata["entity_class"], ctx=ast.Load()),
187
+ ),
188
+ )
189
+
190
+ return keywords
@@ -64,12 +64,16 @@ class EDLPropertyCompiler:
64
64
  if prop.pk:
65
65
  pk_keys.append(pkey)
66
66
 
67
+ is_partial_extension = (
68
+ isinstance(entity_model, EntityModel) and bool(entity_model.partial_of)
69
+ )
70
+
67
71
  if not entity_model.mixin:
68
72
  if len(pk_keys) > 1:
69
73
  raise Exception(
70
74
  f"Entidade '{entity_model.id}' possui mais de uma chave primária (ainda não suportado): {pk_keys}"
71
75
  )
72
- elif len(pk_keys) == 0:
76
+ elif len(pk_keys) == 0 and not is_partial_extension:
73
77
  raise Exception(
74
78
  f"Entidade '{entity_model.id}' não tem nenhuma chave primária (ainda não suportado)"
75
79
  )
@@ -670,6 +674,18 @@ class EDLPropertyCompiler:
670
674
  )
671
675
  )
672
676
 
677
+ resume_fields = properties_structure.main_resume_fields.get(pkey)
678
+ if resume_fields:
679
+ keywords.append(
680
+ ast.keyword(
681
+ arg="resume_fields",
682
+ value=ast.List(
683
+ elts=[ast.Constant(value=field) for field in resume_fields],
684
+ ctx=ast.Load(),
685
+ ),
686
+ )
687
+ )
688
+
673
689
  # Resolvendo a coluna usada no relacionamento
674
690
  if (
675
691
  not properties_structure.entity_properties
@@ -736,6 +752,18 @@ class EDLPropertyCompiler:
736
752
  ):
737
753
  keywords.append(ast.keyword(arg="resume", value=ast.Constant(True)))
738
754
 
755
+ resume_fields = properties_structure.main_resume_fields.get(pkey)
756
+ if resume_fields:
757
+ keywords.append(
758
+ ast.keyword(
759
+ arg="resume_fields",
760
+ value=ast.List(
761
+ elts=[ast.Constant(value=field) for field in resume_fields],
762
+ ctx=ast.Load(),
763
+ ),
764
+ )
765
+ )
766
+
739
767
  if prop.validator:
740
768
  keywords.append(
741
769
  ast.keyword(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.18
3
+ Version: 0.0.20
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
@@ -4,23 +4,23 @@ nsj_rest_lib2/redis_config.py,sha256=4KLcvYS3nJO7PMQgF6F9_j6r-TyqcS7TBbd3LEQuKDU
4
4
  nsj_rest_lib2/settings.py,sha256=Hn_o1HZmievnYb8D1kNT2Nq-OEjxbyNjOiOpbnFsMwE,367
5
5
  nsj_rest_lib2/compiler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  nsj_rest_lib2/compiler/ai_compiler.py,sha256=shAtN4T0ai_52qh15L3mK1QbeC6glHOR6C3J3gj14II,9029
7
- nsj_rest_lib2/compiler/compiler.py,sha256=xz1xYP7mY1hqzuuwDo-ATlU1X-8ldhGmFwEIUtQbOeo,18638
8
- nsj_rest_lib2/compiler/compiler_structures.py,sha256=cgA4ldqOoBYH8qxS99G2hd5Tgo7M1yzN0O_VIVpw3TI,1378
9
- nsj_rest_lib2/compiler/dto_compiler.py,sha256=qK0LHmXAlY_snm6QncIO0S4GiRtHYgtd74xSodK8MQA,5670
10
- nsj_rest_lib2/compiler/entity_compiler.py,sha256=A0fiLFF7dGXM2uH5cknmAX-cQ-9nu4Ubujp-m5NmgYE,4780
7
+ nsj_rest_lib2/compiler/compiler.py,sha256=K8npaE6BPs_Bxu3uSvB-hZF5JEIxgu4sVsKYqLk6wcI,27572
8
+ nsj_rest_lib2/compiler/compiler_structures.py,sha256=a_DF_nU4VgCt0sWJI03Ky6fPHvoIM0cjMkwQb_dYv6Q,1437
9
+ nsj_rest_lib2/compiler/dto_compiler.py,sha256=mvZo19owtpFTjanCE20T0jmBKjhKXIVUsnR5raiGoRM,6728
10
+ nsj_rest_lib2/compiler/entity_compiler.py,sha256=-mDA1-dHKYp0umQi1A4GbA0F1hlaC-gQRqj69vkADC4,6536
11
11
  nsj_rest_lib2/compiler/model.py,sha256=QDBoM26qoZdiNcykl1nvXCrFDhg-6Q__QzVq6uY1QzE,1460
12
- nsj_rest_lib2/compiler/property_compiler.py,sha256=G4xY8cX9TU2c5oNLRRKlU4sQ4b4bzR2KAjBleQmrX6Y,40471
12
+ nsj_rest_lib2/compiler/property_compiler.py,sha256=Kqo9c1AvAjBN-7A4PBvrrXRPkngogH7FUZ6-pMuf8TE,41460
13
13
  nsj_rest_lib2/compiler/edl_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py,sha256=664QBDcOgVnyfwtUOXO1W7AKaZhueBG335x5DuogruY,7644
15
15
  nsj_rest_lib2/compiler/edl_model/api_model.py,sha256=pH0Uiq_64AGvkHqwY44TrulWWZXbi6M0EKJWUhSqKj0,837
16
16
  nsj_rest_lib2/compiler/edl_model/column_meta_model.py,sha256=s0sEVkoW1hV2_hto1mws4XhzKGH_b4NzhaOiwFH25Ks,694
17
17
  nsj_rest_lib2/compiler/edl_model/entity_model.py,sha256=Yc6wvjsiwacmz796mZIU-i9hxzNV9yuLPdULGKYHNbM,854
18
- nsj_rest_lib2/compiler/edl_model/entity_model_base.py,sha256=7AVyxmYtwZYVm6hNXQm-EBO3LMYkMHPf1ZFQrt0wZ3Q,4160
18
+ nsj_rest_lib2/compiler/edl_model/entity_model_base.py,sha256=eRn0pirIPHvniqGpT0xE-mmgqz5RIVtqghxcnfxKNdQ,4345
19
19
  nsj_rest_lib2/compiler/edl_model/entity_model_root.py,sha256=VinsxFlNyCaKKk37ZzcbmWaWgoUP2-dZBG61Ke7NvVs,231
20
20
  nsj_rest_lib2/compiler/edl_model/index_model.py,sha256=cXWlu0hxtro5vvYoirkDW4R3PCnBW5oCCWjRJ6AX5zE,508
21
21
  nsj_rest_lib2/compiler/edl_model/primitives.py,sha256=GTo8e1mf9munvl_J1-fmaXgSJ8yQvGX56f2rwS85M1Y,1459
22
22
  nsj_rest_lib2/compiler/edl_model/property_meta_model.py,sha256=ie3roNZAqYTwz7q0TTdceMjY5khnBiED2yp0XBqqk7E,3909
23
- nsj_rest_lib2/compiler/edl_model/repository_model.py,sha256=Vt1HxlaoifP4w5ij1laKDkD1-COBihE8EX1HkdEDUSo,977
23
+ nsj_rest_lib2/compiler/edl_model/repository_model.py,sha256=OmtUzSq2LKmM76VXefGrKwg8xtVFCutt3JNH2nv42qU,1821
24
24
  nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py,sha256=NtMVZeOPu3LJwXI-8tCOLVuQiGua_0t7kL1h9gL7HuM,657
25
25
  nsj_rest_lib2/compiler/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  nsj_rest_lib2/compiler/util/str_util.py,sha256=lVP1yHhj1pOd6ULtTnkcfX6Gqrpe4yCBratHUhBNGcI,843
@@ -30,7 +30,7 @@ nsj_rest_lib2/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
30
30
  nsj_rest_lib2/controller/dynamic_controller.py,sha256=XMqxe1NW-NE5XwomXb4pSNdALQHpP74Hc26R4fnmXqg,15194
31
31
  nsj_rest_lib2/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  nsj_rest_lib2/service/entity_loader.py,sha256=uB0xXih9Px2jSTMdZNIu6_3dngE37K7adKX03cYSRug,15660
33
- nsj_rest_lib2-0.0.18.dist-info/METADATA,sha256=5HB_H5qhmsBFRU6DI9uMmXYyzLobZe-2aLUMFIMM_qc,1585
34
- nsj_rest_lib2-0.0.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- nsj_rest_lib2-0.0.18.dist-info/top_level.txt,sha256=L6zh0EfH8_rur7OJ8_V-El-XEMf4qg3bkF8ADgqLVIA,14
36
- nsj_rest_lib2-0.0.18.dist-info/RECORD,,
33
+ nsj_rest_lib2-0.0.20.dist-info/METADATA,sha256=SC3lNUvvmPq0kvWSdMfvbyzpo0jOTGY0VrVGR7bhBLU,1585
34
+ nsj_rest_lib2-0.0.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ nsj_rest_lib2-0.0.20.dist-info/top_level.txt,sha256=L6zh0EfH8_rur7OJ8_V-El-XEMf4qg3bkF8ADgqLVIA,14
36
+ nsj_rest_lib2-0.0.20.dist-info/RECORD,,