sera-2 1.6.3__py3-none-any.whl → 1.6.5__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/libs/base_orm.py CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from typing import Optional
4
4
 
5
5
  import orjson
6
+ from msgspec.json import decode, encode
6
7
  from sera.typing import UNSET
7
8
  from sqlalchemy import LargeBinary, TypeDecorator
8
9
  from sqlalchemy import create_engine as sqlalchemy_create_engine
@@ -50,13 +51,12 @@ class DataclassType(TypeDecorator):
50
51
  def process_bind_param(self, value, dialect):
51
52
  if value is None:
52
53
  return None
53
- return orjson.dumps(value.to_dict())
54
+ return encode(value)
54
55
 
55
56
  def process_result_value(self, value, dialect):
56
57
  if value is None:
57
58
  return None
58
- result = orjson.loads(value)
59
- return self.cls.from_dict(result)
59
+ return decode(value, type=self.cls)
60
60
 
61
61
 
62
62
  class ListDataclassType(TypeDecorator):
@@ -72,13 +72,12 @@ class ListDataclassType(TypeDecorator):
72
72
  def process_bind_param(self, value, dialect):
73
73
  if value is None:
74
74
  return None
75
- return orjson.dumps([x.to_dict() for x in value])
75
+ return encode(value)
76
76
 
77
77
  def process_result_value(self, value, dialect):
78
78
  if value is None:
79
79
  return None
80
- result = orjson.loads(value)
81
- return [self.cls.from_dict(x) for x in result]
80
+ return decode(value, type=list[self.cls])
82
81
 
83
82
 
84
83
  class DictDataclassType(TypeDecorator):
@@ -94,13 +93,12 @@ class DictDataclassType(TypeDecorator):
94
93
  def process_bind_param(self, value, dialect):
95
94
  if value is None:
96
95
  return None
97
- return orjson.dumps({k: v.to_dict() for k, v in value.items()})
96
+ return encode(value)
98
97
 
99
98
  def process_result_value(self, value, dialect):
100
99
  if value is None:
101
100
  return None
102
- result = orjson.loads(value)
103
- return {k: self.cls.from_dict(v) for k, v in result.items()}
101
+ return decode(value, type=dict[str, self.cls])
104
102
 
105
103
 
106
104
  def create_engine(
@@ -49,6 +49,9 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
49
49
 
50
50
  idprop = cls.get_id_property()
51
51
  program = Program()
52
+ program.import_(
53
+ f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
54
+ )
52
55
 
53
56
  prop_defs = []
54
57
  prop_constructor_assigns = []
@@ -202,6 +205,21 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
202
205
  )
203
206
  )
204
207
  ),
208
+ stmt.LineBreak(),
209
+ lambda ast13: ast13.func(
210
+ "toDraft",
211
+ [],
212
+ expr.ExprIdent(f"Draft{cls.name}"),
213
+ comment="Convert the class instance to a draft for editing",
214
+ )(
215
+ stmt.ReturnStatement(
216
+ expr.ExprMethodCall(
217
+ expr.ExprIdent(f"Draft{cls.name}"),
218
+ "update",
219
+ [expr.ExprIdent("this")],
220
+ )
221
+ ),
222
+ ),
205
223
  ),
206
224
  )
207
225
 
@@ -719,7 +737,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
719
737
  return
720
738
 
721
739
  program = Program()
722
- prop_defs: list[tuple[expr.Expr, expr.Expr]] = []
740
+ prop_defs: list[tuple[DataProperty | ObjectProperty, expr.Expr, expr.Expr]] = []
723
741
 
724
742
  for prop in cls.properties.values():
725
743
  # we must include private properties that are needed during upsert for our forms.
@@ -798,6 +816,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
798
816
 
799
817
  prop_defs.append(
800
818
  (
819
+ prop,
801
820
  expr.ExprIdent(propname),
802
821
  PredefinedFn.dict(
803
822
  [
@@ -820,28 +839,105 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
820
839
  )
821
840
  )
822
841
 
823
- program.import_("sera-db.Schema", True)
842
+ for type in ["Schema", "ObjectProperty", "DataProperty"]:
843
+ program.import_(f"sera-db.{type}", True)
844
+
845
+ program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}", True)
846
+ program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}Id", True)
824
847
  program.import_(
825
848
  f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
826
849
  )
827
850
  program.root(
828
851
  stmt.LineBreak(),
829
852
  stmt.TypescriptStatement(
830
- f"export type {cls.name}Properties = "
831
- + " | ".join(
853
+ f"export type {cls.name}SchemaType = "
854
+ + PredefinedFn.dict(
832
855
  [
833
- expr.ExprConstant(to_camel_case(prop.name)).to_typescript()
834
- for prop in cls.properties.values()
856
+ (expr.ExprIdent("id"), expr.ExprIdent(f"{cls.name}Id")),
857
+ (
858
+ expr.ExprIdent("publicProperties"),
859
+ expr.ExprIdent(
860
+ " | ".join(
861
+ [
862
+ expr.ExprConstant(
863
+ to_camel_case(prop.name)
864
+ ).to_typescript()
865
+ for prop in cls.properties.values()
866
+ if not prop.data.is_private
867
+ ]
868
+ )
869
+ ),
870
+ ),
871
+ (
872
+ expr.ExprIdent("allProperties"),
873
+ expr.ExprIdent(
874
+ f"{cls.name}SchemaType['publicProperties']"
875
+ + (
876
+ " | "
877
+ + " | ".join(
878
+ [
879
+ expr.ExprConstant(
880
+ to_camel_case(prop.name)
881
+ ).to_typescript()
882
+ for prop in cls.properties.values()
883
+ if prop.data.is_private
884
+ ]
885
+ )
886
+ if any(
887
+ prop.data.is_private
888
+ for prop in cls.properties.values()
889
+ )
890
+ else ""
891
+ )
892
+ ),
893
+ ),
894
+ (
895
+ expr.ExprIdent("cls"),
896
+ expr.ExprIdent(cls.name),
897
+ ),
898
+ (
899
+ expr.ExprIdent("draftCls"),
900
+ expr.ExprIdent(f"Draft{cls.name}"),
901
+ ),
835
902
  ]
836
- )
903
+ ).to_typescript()
904
+ + ";",
905
+ ),
906
+ stmt.LineBreak(),
907
+ stmt.TypescriptStatement(
908
+ f"const publicProperties: Record<{cls.name}SchemaType['publicProperties'], DataProperty | ObjectProperty> = "
909
+ + PredefinedFn.dict(
910
+ [
911
+ (prop_name, prop_def)
912
+ for prop, prop_name, prop_def in prop_defs
913
+ if not prop.data.is_private
914
+ ]
915
+ ).to_typescript()
837
916
  + ";"
838
917
  ),
839
918
  stmt.LineBreak(),
840
919
  stmt.TypescriptStatement(
841
- f"export const {cls.name}Schema: Schema<Draft{cls.name}, {cls.name}Properties> = "
920
+ f"export const {cls.name}Schema: Schema<{cls.name}SchemaType> = "
842
921
  + PredefinedFn.dict(
843
922
  [
844
- (expr.ExprIdent("properties"), PredefinedFn.dict(prop_defs)),
923
+ (
924
+ expr.ExprIdent("publicProperties"),
925
+ expr.ExprIdent("publicProperties"),
926
+ ),
927
+ (
928
+ expr.ExprIdent("allProperties"),
929
+ expr.ExprIdent(
930
+ "{ ...publicProperties, "
931
+ + ", ".join(
932
+ [
933
+ f"{prop_name.to_typescript()}: {prop_def.to_typescript()}"
934
+ for prop, prop_name, prop_def in prop_defs
935
+ if prop.data.is_private
936
+ ]
937
+ )
938
+ + "}"
939
+ ),
940
+ ),
845
941
  ]
846
942
  + (
847
943
  [
@@ -868,33 +964,43 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
868
964
  logger.info(f"Module {outmod.path} already exists, skip")
869
965
  return
870
966
 
967
+ export_types = []
968
+ export_iso_types = [] # isolatedModules required separate export type clause
969
+
871
970
  program = Program()
872
971
  program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}", True)
972
+ export_types.append(cls.name)
873
973
  if cls.db is not None:
874
974
  # only import the id if this class is stored in the database
875
975
  program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}Id", True)
976
+ export_iso_types.append(f"{cls.name}Id")
977
+
876
978
  program.import_(
877
979
  f"@.models.{pkg.dir.name}.{cls.name}Schema.{cls.name}Schema", True
878
980
  )
981
+ export_types.append(f"{cls.name}Schema")
982
+ program.import_(
983
+ f"@.models.{pkg.dir.name}.{cls.name}Schema.{cls.name}SchemaType", True
984
+ )
985
+ export_iso_types.append(f"{cls.name}SchemaType")
986
+
879
987
  program.import_(
880
988
  f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
881
989
  )
990
+ export_types.append(f"Draft{cls.name}")
882
991
  if cls.db is not None:
883
992
  program.import_(
884
993
  f"@.models.{pkg.dir.name}.{cls.name}Table.{cls.name}Table", True
885
994
  )
995
+ export_types.append(f"{cls.name}Table")
886
996
 
887
997
  program.root(
888
998
  stmt.LineBreak(),
889
- stmt.TypescriptStatement(
890
- f"export {{ {cls.name}, Draft{cls.name}, {cls.name}Table, {cls.name}Schema }};"
891
- if cls.db is not None
892
- else f"export {{ {cls.name}, Draft{cls.name}, {cls.name}Schema }};"
893
- ),
999
+ stmt.TypescriptStatement("export { %s };" % (", ".join(export_types))),
894
1000
  (
895
- stmt.TypescriptStatement(f"export type {{ {cls.name}Id }};")
896
- if cls.db
897
- else None
1001
+ stmt.TypescriptStatement(
1002
+ "export type { %s };" % (", ".join(export_iso_types))
1003
+ )
898
1004
  ),
899
1005
  )
900
1006
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sera-2
3
- Version: 1.6.3
3
+ Version: 1.6.5
4
4
  Summary:
5
5
  Author: Binh Vu
6
6
  Author-email: bvu687@gmail.com
@@ -2,7 +2,7 @@ sera/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  sera/constants.py,sha256=mzAaMyIx8TJK0-RYYJ5I24C4s0Uvj26OLMJmBo0pxHI,123
3
3
  sera/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  sera/libs/api_helper.py,sha256=hUEy0INHM18lxTQ348tgbXNceOHcjiAnqmuL_8CRpLQ,2509
5
- sera/libs/base_orm.py,sha256=sTiHvbvLALSFygCITKFTXK1w-8UtxXGT_Te-1PEAiCI,3094
5
+ sera/libs/base_orm.py,sha256=dyh0OT2sbHku5qPJXvRzYAHRTSXvvbQaS-Qwg65Bw04,2918
6
6
  sera/libs/base_service.py,sha256=l5D4IjxIiz8LBRranUYddb8J0Y6SwSyetKYTLrCUdQA,4098
7
7
  sera/make/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  sera/make/__main__.py,sha256=G5O7s6135-708honwqMFn2yPTs06WbGQTHpupID0eZ4,1417
@@ -10,7 +10,7 @@ sera/make/make_app.py,sha256=n9NtW73O3s_5Q31VHIRmnd-jEIcpDO7ksAsOdovde2s,5999
10
10
  sera/make/make_python_api.py,sha256=RuJUm9z-4plBEtjobeOPr12o27OT-0tSeXI4ZlM3IY0,29433
11
11
  sera/make/make_python_model.py,sha256=xf4revAwVWEnF6QhxbbqPyUGgXOOB--Gu3jPxsESg0Y,36593
12
12
  sera/make/make_python_services.py,sha256=RsinYZdfkrTlTn9CT50VgqGs9w6IZawsJx-KEmqfnEY,2062
13
- sera/make/make_typescript_model.py,sha256=rm_QUGSSmGeXAvFcTeJ4qeq1dFog2DERZ0Mo1r1Yak0,37553
13
+ sera/make/make_typescript_model.py,sha256=KWseO3VGLlXfNVjwDF31Nh8q9Wat-hmiS4DJh0r0UCo,42303
14
14
  sera/misc/__init__.py,sha256=Dh4uDq0D4N53h3zhvmwfa5a0TPVRSUvLzb0hkFuPirk,411
15
15
  sera/misc/_formatter.py,sha256=aCGYL08l8f3aLODHxSocxBBwkRYEo3K1QzCDEn3suj0,1685
16
16
  sera/misc/_utils.py,sha256=V5g4oLGHOhUCR75Kkcn1w01pAvGvaepK-T8Z3pIgHjI,1450
@@ -27,6 +27,6 @@ sera/models/_parse.py,sha256=sJYfQtwek96ltpgxExG4xUbiLnU3qvNYhTP1CeyXGjs,9746
27
27
  sera/models/_property.py,sha256=CmEmgOShtSyNFq05YW3tGupwCIVRzPMKudXWld8utPk,5530
28
28
  sera/models/_schema.py,sha256=r-Gqg9Lb_wR3UrbNvfXXgt_qs5bts0t2Ve7aquuF_OI,1155
29
29
  sera/typing.py,sha256=Q4QMfbtfrCjC9tFfsZPhsAnbNX4lm4NHQ9lmjNXYdV0,772
30
- sera_2-1.6.3.dist-info/METADATA,sha256=BBwuS2iLs2Ubc7WnJa6Q8sOR4Fz8aqXx9iTkLd3PO4M,856
31
- sera_2-1.6.3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
32
- sera_2-1.6.3.dist-info/RECORD,,
30
+ sera_2-1.6.5.dist-info/METADATA,sha256=Gv3f8FNU3Wke6T_yvsNb5r5S92YeYxmg2ogy8kgsOXo,856
31
+ sera_2-1.6.5.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
32
+ sera_2-1.6.5.dist-info/RECORD,,
File without changes