sera-2 1.11.2__tar.gz → 1.12.0__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 (37) hide show
  1. {sera_2-1.11.2 → sera_2-1.12.0}/PKG-INFO +1 -1
  2. {sera_2-1.11.2 → sera_2-1.12.0}/pyproject.toml +1 -1
  3. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/make_python_model.py +17 -5
  4. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/make_typescript_model.py +230 -10
  5. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_datatype.py +7 -0
  6. {sera_2-1.11.2 → sera_2-1.12.0}/README.md +0 -0
  7. {sera_2-1.11.2 → sera_2-1.12.0}/sera/__init__.py +0 -0
  8. {sera_2-1.11.2 → sera_2-1.12.0}/sera/constants.py +0 -0
  9. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/__init__.py +0 -0
  10. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/api_helper.py +0 -0
  11. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/base_orm.py +0 -0
  12. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/base_service.py +0 -0
  13. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/dag/__init__.py +0 -0
  14. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/dag/_dag.py +0 -0
  15. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/middlewares/__init__.py +0 -0
  16. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/middlewares/auth.py +0 -0
  17. {sera_2-1.11.2 → sera_2-1.12.0}/sera/libs/middlewares/uscp.py +0 -0
  18. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/__init__.py +0 -0
  19. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/__main__.py +0 -0
  20. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/make_app.py +0 -0
  21. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/make_python_api.py +0 -0
  22. {sera_2-1.11.2 → sera_2-1.12.0}/sera/make/make_python_services.py +0 -0
  23. {sera_2-1.11.2 → sera_2-1.12.0}/sera/misc/__init__.py +0 -0
  24. {sera_2-1.11.2 → sera_2-1.12.0}/sera/misc/_formatter.py +0 -0
  25. {sera_2-1.11.2 → sera_2-1.12.0}/sera/misc/_utils.py +0 -0
  26. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/__init__.py +0 -0
  27. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_class.py +0 -0
  28. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_collection.py +0 -0
  29. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_constraints.py +0 -0
  30. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_default.py +0 -0
  31. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_enum.py +0 -0
  32. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_module.py +0 -0
  33. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_multi_lingual_string.py +0 -0
  34. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_parse.py +0 -0
  35. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_property.py +0 -0
  36. {sera_2-1.11.2 → sera_2-1.12.0}/sera/models/_schema.py +0 -0
  37. {sera_2-1.11.2 → sera_2-1.12.0}/sera/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sera-2
3
- Version: 1.11.2
3
+ Version: 1.12.0
4
4
  Summary:
5
5
  Author: Binh Vu
6
6
  Author-email: bvu687@gmail.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "sera-2"
3
- version = "1.11.2"
3
+ version = "1.12.0"
4
4
  description = ""
5
5
  authors = ["Binh Vu <bvu687@gmail.com>"]
6
6
  readme = "README.md"
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from operator import is_
3
4
  from typing import Callable, Sequence
4
5
 
5
6
  from codegen.models import AST, DeferredVar, PredefinedFn, Program, expr, stmt
@@ -296,11 +297,14 @@ def make_python_data_model(
296
297
  ],
297
298
  )
298
299
 
300
+ if prop.cardinality.is_star_to_many():
301
+ pytype = pytype.as_list_type()
302
+ elif prop.is_optional:
303
+ pytype = pytype.as_optional_type()
304
+
299
305
  for dep in pytype.deps:
300
306
  program.import_(dep, True)
301
307
 
302
- if prop.cardinality.is_star_to_many():
303
- pytype = pytype.as_list_type()
304
308
  cls_ast(stmt.DefClassVarStatement(prop.name, pytype.type))
305
309
 
306
310
  # has_to_db = True
@@ -453,11 +457,14 @@ def make_python_data_model(
453
457
  ],
454
458
  )
455
459
 
460
+ if prop.cardinality.is_star_to_many():
461
+ pytype = pytype.as_list_type()
462
+ elif prop.is_optional:
463
+ pytype = pytype.as_optional_type()
464
+
456
465
  for dep in pytype.deps:
457
466
  program.import_(dep, True)
458
467
 
459
- if prop.cardinality.is_star_to_many():
460
- pytype = pytype.as_list_type()
461
468
  cls_ast(stmt.DefClassVarStatement(prop.name, pytype.type))
462
469
 
463
470
  cls_ast(
@@ -690,7 +697,12 @@ def make_python_relational_model(
690
697
  program.import_(dep, True)
691
698
 
692
699
  propname = prop.name
693
- proptype = f"Mapped[{sqltype.mapped_pytype}]"
700
+
701
+ if prop.is_optional:
702
+ program.import_("typing.Optional", True)
703
+ proptype = f"Mapped[Optional[{sqltype.mapped_pytype}]]"
704
+ else:
705
+ proptype = f"Mapped[{sqltype.mapped_pytype}]"
694
706
 
695
707
  propvalargs: list[expr.Expr] = [expr.ExprIdent(sqltype.type)]
696
708
  if prop.db.is_primary_key:
@@ -75,6 +75,10 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
75
75
  # use id type alias
76
76
  tstype = TsTypeWithDep(f"{cls.name}Id")
77
77
 
78
+ if prop.is_optional:
79
+ # convert type to optional
80
+ tstype = tstype.as_optional_type()
81
+
78
82
  deser_args.append(
79
83
  (
80
84
  expr.ExprIdent(propname),
@@ -95,6 +99,9 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
95
99
  )
96
100
  if prop.cardinality.is_star_to_many():
97
101
  tstype = tstype.as_list_type()
102
+ elif prop.is_optional:
103
+ # convert type to optional only if it isn't a list
104
+ tstype = tstype.as_optional_type()
98
105
  deser_args.append(
99
106
  (
100
107
  expr.ExprIdent(propname),
@@ -134,6 +141,9 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
134
141
  )
135
142
  )
136
143
  else:
144
+ if prop.is_optional:
145
+ # convert type to optional only if it isn't a list
146
+ tstype = tstype.as_optional_type()
137
147
  deser_args.append(
138
148
  (
139
149
  expr.ExprIdent(propname),
@@ -270,6 +280,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
270
280
  create_args = []
271
281
  update_args = []
272
282
  ser_args = []
283
+ to_record_args = []
273
284
  update_field_funcs: list[Callable[[AST], Any]] = []
274
285
 
275
286
  prop2tsname = {}
@@ -329,6 +340,10 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
329
340
  # for none id properties, we need to include a type for "invalid" value
330
341
  tstype = _inject_type_for_invalid_value(tstype)
331
342
 
343
+ if prop.is_optional:
344
+ # convert type to optional
345
+ tstype = tstype.as_optional_type()
346
+
332
347
  for dep in tstype.deps:
333
348
  program.import_(dep, True)
334
349
 
@@ -410,6 +425,41 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
410
425
  ),
411
426
  )
412
427
  )
428
+
429
+ if not prop.data.is_private:
430
+ # private property does not include in the public record
431
+ to_record_args.append(
432
+ (
433
+ expr.ExprIdent(propname),
434
+ (
435
+ expr.ExprTernary(
436
+ PredefinedFn.attr_getter(
437
+ expr.ExprFuncCall(
438
+ PredefinedFn.attr_getter(
439
+ expr.ExprIdent(draft_validators),
440
+ expr.ExprIdent(propname),
441
+ ),
442
+ [
443
+ PredefinedFn.attr_getter(
444
+ expr.ExprIdent("this"),
445
+ expr.ExprIdent(propname),
446
+ )
447
+ ],
448
+ ),
449
+ expr.ExprIdent("isValid"),
450
+ ),
451
+ PredefinedFn.attr_getter(
452
+ expr.ExprIdent("this"), expr.ExprIdent(propname)
453
+ ),
454
+ expr.ExprIdent("undefined"),
455
+ )
456
+ if prop.is_optional
457
+ else PredefinedFn.attr_getter(
458
+ expr.ExprIdent("this"), expr.ExprIdent(propname)
459
+ )
460
+ ),
461
+ )
462
+ )
413
463
  if not (prop.db is not None and prop.db.is_primary_key):
414
464
  # skip observable for primary key as it is not needed
415
465
  observable_args.append(
@@ -438,6 +488,10 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
438
488
  tstype = tstype.as_list_type()
439
489
  create_propvalue = expr.ExprConstant([])
440
490
  else:
491
+ if prop.is_optional:
492
+ # convert type to optional - for list type, we don't need to do this
493
+ # as we will use empty list as no value
494
+ tstype = tstype.as_optional_type()
441
495
  # if target class has an auto-increment primary key, we set a different default value
442
496
  # to be -1 to avoid start from 0
443
497
  target_idprop = prop.target.get_id_property()
@@ -463,6 +517,17 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
463
517
  ),
464
518
  )
465
519
  )
520
+
521
+ if not prop.data.is_private:
522
+ # private property does not include in the public record
523
+ to_record_args.append(
524
+ (
525
+ expr.ExprIdent(propname),
526
+ PredefinedFn.attr_getter(
527
+ expr.ExprIdent("this"), expr.ExprIdent(propname)
528
+ ),
529
+ )
530
+ )
466
531
  else:
467
532
  # we are going to store the whole object
468
533
  tstype = TsTypeWithDep(
@@ -492,10 +557,66 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
492
557
  expr.ExprIdent("this"), expr.ExprIdent(propname)
493
558
  ),
494
559
  lambda item: expr.ExprMethodCall(item, "ser", []),
560
+ (
561
+ (
562
+ lambda item: PredefinedFn.attr_getter(
563
+ expr.ExprFuncCall(
564
+ PredefinedFn.attr_getter(
565
+ expr.ExprIdent(
566
+ draft_validators
567
+ ),
568
+ expr.ExprIdent(propname),
569
+ ),
570
+ [item],
571
+ ),
572
+ expr.ExprIdent("isValid"),
573
+ )
574
+ )
575
+ if prop.is_optional
576
+ else None
577
+ ),
495
578
  ),
496
579
  )
497
580
  )
581
+ if not prop.data.is_private:
582
+ # private property does not include in the public record
583
+ to_record_args.append(
584
+ (
585
+ expr.ExprIdent(propname),
586
+ PredefinedFn.map_list(
587
+ PredefinedFn.attr_getter(
588
+ expr.ExprIdent("this"),
589
+ expr.ExprIdent(propname),
590
+ ),
591
+ lambda item: expr.ExprMethodCall(
592
+ item, "toRecord", []
593
+ ),
594
+ (
595
+ (
596
+ lambda item: PredefinedFn.attr_getter(
597
+ expr.ExprFuncCall(
598
+ PredefinedFn.attr_getter(
599
+ expr.ExprIdent(
600
+ draft_validators
601
+ ),
602
+ expr.ExprIdent(propname),
603
+ ),
604
+ [item],
605
+ ),
606
+ expr.ExprIdent("isValid"),
607
+ )
608
+ )
609
+ if prop.is_optional
610
+ else None
611
+ ),
612
+ ),
613
+ )
614
+ )
498
615
  else:
616
+ if prop.is_optional:
617
+ # convert type to optional - for list type, we don't need to do this
618
+ # as we will use empty list as no value
619
+ tstype = tstype.as_optional_type()
499
620
  create_propvalue = expr.ExprMethodCall(
500
621
  expr.ExprIdent(tstype.type),
501
622
  "create",
@@ -510,18 +631,103 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
510
631
  ),
511
632
  ],
512
633
  )
513
- ser_args.append(
514
- (
515
- expr.ExprIdent(prop.name),
516
- expr.ExprMethodCall(
517
- PredefinedFn.attr_getter(
518
- expr.ExprIdent("this"), expr.ExprIdent(propname)
634
+
635
+ if prop.is_optional:
636
+ ser_args.append(
637
+ (
638
+ expr.ExprIdent(prop.name),
639
+ expr.ExprTernary(
640
+ PredefinedFn.attr_getter(
641
+ expr.ExprFuncCall(
642
+ PredefinedFn.attr_getter(
643
+ expr.ExprIdent(draft_validators),
644
+ expr.ExprIdent(propname),
645
+ ),
646
+ [
647
+ PredefinedFn.attr_getter(
648
+ expr.ExprIdent("this"),
649
+ expr.ExprIdent(propname),
650
+ )
651
+ ],
652
+ ),
653
+ expr.ExprIdent("isValid"),
654
+ ),
655
+ expr.ExprMethodCall(
656
+ PredefinedFn.attr_getter(
657
+ expr.ExprIdent("this"),
658
+ expr.ExprIdent(propname),
659
+ ),
660
+ "ser",
661
+ [],
662
+ ),
663
+ expr.ExprIdent("undefined"),
519
664
  ),
520
- "ser",
521
- [],
522
- ),
665
+ )
523
666
  )
524
- )
667
+ if not prop.data.is_private:
668
+ # private property does not include in the public record
669
+ to_record_args.append(
670
+ (
671
+ expr.ExprIdent(propname),
672
+ expr.ExprTernary(
673
+ PredefinedFn.attr_getter(
674
+ expr.ExprFuncCall(
675
+ PredefinedFn.attr_getter(
676
+ expr.ExprIdent(
677
+ draft_validators
678
+ ),
679
+ expr.ExprIdent(propname),
680
+ ),
681
+ [
682
+ PredefinedFn.attr_getter(
683
+ expr.ExprIdent("this"),
684
+ expr.ExprIdent(propname),
685
+ )
686
+ ],
687
+ ),
688
+ expr.ExprIdent("isValid"),
689
+ ),
690
+ expr.ExprMethodCall(
691
+ PredefinedFn.attr_getter(
692
+ expr.ExprIdent("this"),
693
+ expr.ExprIdent(propname),
694
+ ),
695
+ "toRecord",
696
+ [],
697
+ ),
698
+ expr.ExprIdent("undefined"),
699
+ ),
700
+ )
701
+ )
702
+ else:
703
+ ser_args.append(
704
+ (
705
+ expr.ExprIdent(prop.name),
706
+ expr.ExprMethodCall(
707
+ PredefinedFn.attr_getter(
708
+ expr.ExprIdent("this"),
709
+ expr.ExprIdent(propname),
710
+ ),
711
+ "ser",
712
+ [],
713
+ ),
714
+ )
715
+ )
716
+ if not prop.data.is_private:
717
+ # private property does not include in the public record
718
+ to_record_args.append(
719
+ (
720
+ expr.ExprIdent(propname),
721
+ expr.ExprMethodCall(
722
+ PredefinedFn.attr_getter(
723
+ expr.ExprIdent("this"),
724
+ expr.ExprIdent(propname),
725
+ ),
726
+ "toRecord",
727
+ [],
728
+ ),
729
+ )
730
+ )
525
731
 
526
732
  for dep in tstype.deps:
527
733
  program.import_(
@@ -730,6 +936,20 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
730
936
  PredefinedFn.dict(ser_args),
731
937
  ),
732
938
  ),
939
+ stmt.LineBreak(),
940
+ lambda ast16: ast16.func(
941
+ "toRecord",
942
+ [],
943
+ expr.ExprIdent(cls.name),
944
+ comment="Convert the draft to a normal record. `isValid` must be called first to ensure all data is valid",
945
+ )(
946
+ stmt.ReturnStatement(
947
+ expr.ExprNewInstance(
948
+ expr.ExprIdent(cls.name),
949
+ [PredefinedFn.dict(to_record_args)],
950
+ ),
951
+ )
952
+ ),
733
953
  ),
734
954
  stmt.LineBreak(),
735
955
  stmt.TypescriptStatement(
@@ -97,6 +97,13 @@ class TsTypeWithDep:
97
97
  list_type = f"{self.type}[]"
98
98
  return TsTypeWithDep(type=list_type, deps=self.deps)
99
99
 
100
+ def as_optional_type(self) -> TsTypeWithDep:
101
+ if "undefined" in self.type:
102
+ raise NotImplementedError(
103
+ f"Have not handle nested optional yet: {self.type}"
104
+ )
105
+ return TsTypeWithDep(type=f"{self.type} | undefined", deps=self.deps)
106
+
100
107
 
101
108
  @dataclass
102
109
  class SQLTypeWithDep:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes