sera-2 1.11.2__py3-none-any.whl → 1.12.0__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.
- sera/make/make_python_model.py +17 -5
- sera/make/make_typescript_model.py +230 -10
- sera/models/_datatype.py +7 -0
- {sera_2-1.11.2.dist-info → sera_2-1.12.0.dist-info}/METADATA +1 -1
- {sera_2-1.11.2.dist-info → sera_2-1.12.0.dist-info}/RECORD +6 -6
- {sera_2-1.11.2.dist-info → sera_2-1.12.0.dist-info}/WHEEL +0 -0
sera/make/make_python_model.py
CHANGED
@@ -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
|
-
|
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
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
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
|
-
|
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(
|
sera/models/_datatype.py
CHANGED
@@ -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:
|
@@ -13,9 +13,9 @@ sera/make/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
sera/make/__main__.py,sha256=G5O7s6135-708honwqMFn2yPTs06WbGQTHpupID0eZ4,1417
|
14
14
|
sera/make/make_app.py,sha256=n9NtW73O3s_5Q31VHIRmnd-jEIcpDO7ksAsOdovde2s,5999
|
15
15
|
sera/make/make_python_api.py,sha256=kq5DClmEeeNgg-a3Bb_8GN9jxvjnhjmW3RfBHNzynO8,25407
|
16
|
-
sera/make/make_python_model.py,sha256=
|
16
|
+
sera/make/make_python_model.py,sha256=AlNJyyovb99TWocS2jtfTxy0C5YaFizx-Bhwdw1mUNw,41923
|
17
17
|
sera/make/make_python_services.py,sha256=RsinYZdfkrTlTn9CT50VgqGs9w6IZawsJx-KEmqfnEY,2062
|
18
|
-
sera/make/make_typescript_model.py,sha256=-
|
18
|
+
sera/make/make_typescript_model.py,sha256=-Z3vHblUcEpWvMMdzQGZ9XWhUjLv99PBJGqZHsF0m1o,63686
|
19
19
|
sera/misc/__init__.py,sha256=Dh4uDq0D4N53h3zhvmwfa5a0TPVRSUvLzb0hkFuPirk,411
|
20
20
|
sera/misc/_formatter.py,sha256=aCGYL08l8f3aLODHxSocxBBwkRYEo3K1QzCDEn3suj0,1685
|
21
21
|
sera/misc/_utils.py,sha256=V5g4oLGHOhUCR75Kkcn1w01pAvGvaepK-T8Z3pIgHjI,1450
|
@@ -23,7 +23,7 @@ sera/models/__init__.py,sha256=vJC5Kzo_N7wd16ocNPy1VvAZDGNiWeiAhWJ4ihATKvA,780
|
|
23
23
|
sera/models/_class.py,sha256=Wf0e8x6-szG9TzoFkAlqj7_dG0SCICMBw_333n3paxk,2514
|
24
24
|
sera/models/_collection.py,sha256=ZnQEriKC4X88Zz48Kn1AVZKH-1_l8OgWa-zf2kcQOOE,1414
|
25
25
|
sera/models/_constraints.py,sha256=L6QwKL3hRJ5DvvIB4JNgLoyvTKbE9FrpYRzezM4CweE,1484
|
26
|
-
sera/models/_datatype.py,sha256=
|
26
|
+
sera/models/_datatype.py,sha256=RDn0lDl_b0O_PwRqobcD1O903owEAEoMzRf4dyRcgBk,6819
|
27
27
|
sera/models/_default.py,sha256=ABggW6qdPR4ZDqIPJdJ0GCGQ-7kfsfZmQ_DchgZEa-I,137
|
28
28
|
sera/models/_enum.py,sha256=sy0q7E646F-APsqrVQ52r1fAQ_DCAeaNq5YM5QN3zIk,2070
|
29
29
|
sera/models/_module.py,sha256=8QRSCubZmdDP9rL58rGAS6X5VCrkc1ZHvuMu1I1KrWk,5043
|
@@ -32,6 +32,6 @@ sera/models/_parse.py,sha256=uw6fvvh1ucGqE2jFTCCr-e6_qMfZfSVpaPolNxmrHww,9897
|
|
32
32
|
sera/models/_property.py,sha256=SJSm5fZJimd2rQuL4UH_aZuNyp9v7x64xMbEVbtYx8Q,5633
|
33
33
|
sera/models/_schema.py,sha256=r-Gqg9Lb_wR3UrbNvfXXgt_qs5bts0t2Ve7aquuF_OI,1155
|
34
34
|
sera/typing.py,sha256=Q4QMfbtfrCjC9tFfsZPhsAnbNX4lm4NHQ9lmjNXYdV0,772
|
35
|
-
sera_2-1.
|
36
|
-
sera_2-1.
|
37
|
-
sera_2-1.
|
35
|
+
sera_2-1.12.0.dist-info/METADATA,sha256=9OsTsh39Me41u3v-tRUiddDVkLKE-Qra7eMQLa8Kt2k,857
|
36
|
+
sera_2-1.12.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
37
|
+
sera_2-1.12.0.dist-info/RECORD,,
|
File without changes
|