sera-2 1.14.4__py3-none-any.whl → 1.14.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/make/__main__.py +1 -1
- sera/make/make_typescript_model.py +18 -11
- sera/models/_class.py +9 -1
- sera/models/_datatype.py +1 -1
- sera/models/_parse.py +5 -1
- sera/models/_property.py +7 -1
- {sera_2-1.14.4.dist-info → sera_2-1.14.5.dist-info}/METADATA +1 -1
- {sera_2-1.14.4.dist-info → sera_2-1.14.5.dist-info}/RECORD +9 -9
- {sera_2-1.14.4.dist-info → sera_2-1.14.5.dist-info}/WHEEL +0 -0
sera/make/__main__.py
CHANGED
@@ -23,6 +23,7 @@ from sera.models import (
|
|
23
23
|
Schema,
|
24
24
|
TsTypeWithDep,
|
25
25
|
)
|
26
|
+
from sera.typing import is_set
|
26
27
|
|
27
28
|
|
28
29
|
def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
@@ -336,8 +337,8 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
336
337
|
f"{cls.name}Id",
|
337
338
|
deps=[f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}Id"],
|
338
339
|
)
|
339
|
-
|
340
|
-
# for none id properties, we need to include a type for "invalid" value
|
340
|
+
elif tstype.type not in schema.enums:
|
341
|
+
# for none id & none enum properties, we need to include a type for "invalid" value
|
341
342
|
tstype = _inject_type_for_invalid_value(tstype)
|
342
343
|
|
343
344
|
if prop.is_optional:
|
@@ -355,9 +356,15 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
355
356
|
and prop.db.is_auto_increment
|
356
357
|
):
|
357
358
|
create_propvalue = expr.ExprConstant(-1)
|
359
|
+
elif is_set(prop.data.default_value):
|
360
|
+
create_propvalue = expr.ExprConstant(prop.data.default_value)
|
358
361
|
else:
|
359
362
|
if tstype.type in idprop_aliases:
|
360
363
|
create_propvalue = idprop_aliases[tstype.type].get_default()
|
364
|
+
elif tstype.type in schema.enums:
|
365
|
+
create_propvalue = expr.ExprConstant(
|
366
|
+
next(iter(schema.enums[tstype.type].values.values())).value
|
367
|
+
)
|
361
368
|
else:
|
362
369
|
create_propvalue = tstype.get_default()
|
363
370
|
|
@@ -537,7 +544,6 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
537
544
|
],
|
538
545
|
)
|
539
546
|
if prop.cardinality.is_star_to_many():
|
540
|
-
tstype = tstype.as_list_type()
|
541
547
|
create_propvalue = expr.ExprConstant([])
|
542
548
|
update_propvalue = PredefinedFn.map_list(
|
543
549
|
PredefinedFn.attr_getter(
|
@@ -578,6 +584,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
578
584
|
),
|
579
585
|
)
|
580
586
|
)
|
587
|
+
|
581
588
|
if not prop.data.is_private:
|
582
589
|
# private property does not include in the public record
|
583
590
|
to_record_args.append(
|
@@ -612,11 +619,9 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
612
619
|
),
|
613
620
|
)
|
614
621
|
)
|
622
|
+
|
623
|
+
tstype = tstype.as_list_type()
|
615
624
|
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()
|
620
625
|
create_propvalue = expr.ExprMethodCall(
|
621
626
|
expr.ExprIdent(tstype.type),
|
622
627
|
"create",
|
@@ -729,6 +734,11 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
729
734
|
)
|
730
735
|
)
|
731
736
|
|
737
|
+
if prop.is_optional:
|
738
|
+
# convert type to optional - for list type, we don't need to do this
|
739
|
+
# as we will use empty list as no value
|
740
|
+
tstype = tstype.as_optional_type()
|
741
|
+
|
732
742
|
for dep in tstype.deps:
|
733
743
|
program.import_(
|
734
744
|
dep,
|
@@ -1407,16 +1417,13 @@ def make_typescript_enum(schema: Schema, target_pkg: Package):
|
|
1407
1417
|
stmt.LineBreak(),
|
1408
1418
|
lambda ast: ast.class_like("enum", enum.name)(
|
1409
1419
|
*[
|
1410
|
-
stmt.
|
1420
|
+
stmt.DefEnumValueStatement(
|
1411
1421
|
name=value.name,
|
1412
|
-
type=None,
|
1413
1422
|
value=expr.ExprConstant(value.value),
|
1414
1423
|
)
|
1415
1424
|
for value in enum.values.values()
|
1416
1425
|
]
|
1417
1426
|
),
|
1418
|
-
stmt.LineBreak(),
|
1419
|
-
stmt.TypescriptStatement("export " + enum.name + ";"),
|
1420
1427
|
)
|
1421
1428
|
pkg.module(enum.get_tsmodule_name()).write(program)
|
1422
1429
|
|
sera/models/_class.py
CHANGED
@@ -51,6 +51,7 @@ class Class:
|
|
51
51
|
Get the ID property of this class.
|
52
52
|
The ID property is the one tagged with is_primary_key
|
53
53
|
"""
|
54
|
+
id_props = []
|
54
55
|
for prop in self.properties.values():
|
55
56
|
if (
|
56
57
|
isinstance(prop, DataProperty)
|
@@ -60,7 +61,14 @@ class Class:
|
|
60
61
|
assert (
|
61
62
|
self.db is not None
|
62
63
|
), "This class is not stored in the database and thus, cannot have a primary key"
|
63
|
-
|
64
|
+
id_props.append(prop)
|
65
|
+
if len(id_props) > 1:
|
66
|
+
raise ValueError(
|
67
|
+
f"Class {self.name} has more than one primary key property: {', '.join(p.name for p in id_props)}"
|
68
|
+
)
|
69
|
+
if len(id_props) == 1:
|
70
|
+
return id_props[0]
|
71
|
+
# if there is no primary key, we return None
|
64
72
|
assert (
|
65
73
|
self.db is None
|
66
74
|
), f"The class {self.name} is stored in the database and thus, must have a primary key"
|
sera/models/_datatype.py
CHANGED
@@ -82,7 +82,7 @@ class TsTypeWithDep:
|
|
82
82
|
return expr.ExprConstant(0)
|
83
83
|
if self.type == "boolean":
|
84
84
|
return expr.ExprConstant(False)
|
85
|
-
if self.type
|
85
|
+
if self.type.endswith("| undefined"):
|
86
86
|
return expr.ExprConstant("undefined")
|
87
87
|
if self.type.endswith("| string)") or self.type.endswith("| string"):
|
88
88
|
return expr.ExprConstant("")
|
sera/models/_parse.py
CHANGED
@@ -36,6 +36,7 @@ from sera.models._property import (
|
|
36
36
|
SystemControlledAttrs,
|
37
37
|
)
|
38
38
|
from sera.models._schema import Schema
|
39
|
+
from sera.typing import UNSET
|
39
40
|
|
40
41
|
|
41
42
|
def parse_schema(name: str, files: Sequence[Path | str]) -> Schema:
|
@@ -140,6 +141,7 @@ def _parse_property(
|
|
140
141
|
system_controlled=_parse_system_controlled_attrs(
|
141
142
|
_data.get("system_controlled")
|
142
143
|
),
|
144
|
+
default_value=UNSET if "default_value" not in _data else _data["default_value"],
|
143
145
|
)
|
144
146
|
|
145
147
|
assert isinstance(prop, dict), prop
|
@@ -237,7 +239,9 @@ def _parse_datatype(schema: Schema, datatype: dict | str) -> DataType:
|
|
237
239
|
sqltype=SQLTypeWithDep(
|
238
240
|
type="String", mapped_pytype="str", deps=["sqlalchemy.String"]
|
239
241
|
),
|
240
|
-
tstype=TsTypeWithDep(
|
242
|
+
tstype=TsTypeWithDep(
|
243
|
+
type=enum.name, deps=[f"@.models.enums.{enum.name}"]
|
244
|
+
),
|
241
245
|
is_list=is_list,
|
242
246
|
)
|
243
247
|
|
sera/models/_property.py
CHANGED
@@ -2,12 +2,15 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from dataclasses import dataclass, field
|
4
4
|
from enum import Enum
|
5
|
-
from typing import TYPE_CHECKING, Literal, Optional
|
5
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional
|
6
|
+
|
7
|
+
from msgspec import UNSET
|
6
8
|
|
7
9
|
from sera.models._constraints import Constraint
|
8
10
|
from sera.models._datatype import DataType
|
9
11
|
from sera.models._default import DefaultFactory
|
10
12
|
from sera.models._multi_lingual_string import MultiLingualString
|
13
|
+
from sera.typing import UnsetType
|
11
14
|
|
12
15
|
if TYPE_CHECKING:
|
13
16
|
from sera.models._class import Class
|
@@ -111,6 +114,9 @@ class PropDataAttrs:
|
|
111
114
|
# if this property is controlled by the system, the attributes for the system-controlled property
|
112
115
|
system_controlled: Optional[SystemControlledAttrs] = None
|
113
116
|
|
117
|
+
# default value of this property if it is not provided (then optional is false by default)
|
118
|
+
default_value: Any | UnsetType = UNSET
|
119
|
+
|
114
120
|
|
115
121
|
@dataclass(kw_only=True)
|
116
122
|
class Property:
|
@@ -14,28 +14,28 @@ sera/libs/middlewares/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
14
14
|
sera/libs/middlewares/auth.py,sha256=r6aix1ZBwxMd1Jv5hMCTB8a_gFOJQ6egvxIrf3DWEOs,2323
|
15
15
|
sera/libs/middlewares/uscp.py,sha256=H5umW8iEQSCdb_MJ5Im49kxg1E7TpxSg1p2_2A5zI1U,2600
|
16
16
|
sera/make/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
sera/make/__main__.py,sha256=
|
17
|
+
sera/make/__main__.py,sha256=HRfOR53p351h6KblVvYm3DLhDIfEtk6R0kjl78_S_S8,1453
|
18
18
|
sera/make/make_app.py,sha256=n9NtW73O3s_5Q31VHIRmnd-jEIcpDO7ksAsOdovde2s,5999
|
19
19
|
sera/make/make_python_api.py,sha256=iXGbKQ3IJvsY1ur_fhurr_THFNnH66E3Wl85o0emUbw,26853
|
20
20
|
sera/make/make_python_model.py,sha256=cRb-fuHX0WH7XPAAliu6lycC0iEjE5kcKg4bBU40GwQ,61275
|
21
21
|
sera/make/make_python_services.py,sha256=0ZpWLwQ7Nwfn8BXAikAB4JRpNknpSJyJgY5b1cjtxV4,2073
|
22
|
-
sera/make/make_typescript_model.py,sha256=
|
22
|
+
sera/make/make_typescript_model.py,sha256=4yLCLIzP2jeXfmOeee6nNS_qd7_7iPinV2vQh1IfbLs,64000
|
23
23
|
sera/misc/__init__.py,sha256=Dh4uDq0D4N53h3zhvmwfa5a0TPVRSUvLzb0hkFuPirk,411
|
24
24
|
sera/misc/_formatter.py,sha256=aCGYL08l8f3aLODHxSocxBBwkRYEo3K1QzCDEn3suj0,1685
|
25
25
|
sera/misc/_utils.py,sha256=V5g4oLGHOhUCR75Kkcn1w01pAvGvaepK-T8Z3pIgHjI,1450
|
26
26
|
sera/models/__init__.py,sha256=vJC5Kzo_N7wd16ocNPy1VvAZDGNiWeiAhWJ4ihATKvA,780
|
27
|
-
sera/models/_class.py,sha256=
|
27
|
+
sera/models/_class.py,sha256=1J4Bd_LanzhhDWwZFHWGtFYD7lupe_alaB3D02ebNDI,2862
|
28
28
|
sera/models/_collection.py,sha256=ZnQEriKC4X88Zz48Kn1AVZKH-1_l8OgWa-zf2kcQOOE,1414
|
29
29
|
sera/models/_constraints.py,sha256=RpWDU-TfCslXaMUaTG9utWbl5z8Z6nzvF_fhqlek6ew,1987
|
30
|
-
sera/models/_datatype.py,sha256=
|
30
|
+
sera/models/_datatype.py,sha256=cC6Wm0IvobDF5Tq9Jy_ncbjPWBRl3ECGBy0wJyDDMzU,7281
|
31
31
|
sera/models/_default.py,sha256=ABggW6qdPR4ZDqIPJdJ0GCGQ-7kfsfZmQ_DchgZEa-I,137
|
32
32
|
sera/models/_enum.py,sha256=sy0q7E646F-APsqrVQ52r1fAQ_DCAeaNq5YM5QN3zIk,2070
|
33
33
|
sera/models/_module.py,sha256=I-GfnTgAa-5R87qTAvEzOt-VVEGeFBBwubGCgUkXVSw,5159
|
34
34
|
sera/models/_multi_lingual_string.py,sha256=JETN6k00VH4wrA4w5vAHMEJV8fp3SY9bJebskFTjQLA,1186
|
35
|
-
sera/models/_parse.py,sha256=
|
36
|
-
sera/models/_property.py,sha256=
|
35
|
+
sera/models/_parse.py,sha256=MaGZty29lsVUFumWqNanIjAwptBNOMbVZMXLZ2A9_2g,12317
|
36
|
+
sera/models/_property.py,sha256=2rSLs9JjSesrxrEugE7krYaBQOivKU882I8mZN94FlI,7017
|
37
37
|
sera/models/_schema.py,sha256=VxJEiqgVvbXgcSUK4UW6JnRcggk4nsooVSE6MyXmfNY,1636
|
38
38
|
sera/typing.py,sha256=Fl4-UzLJu1GdLLk_g87fA7nT9wQGelNnGzag6dg_0gs,980
|
39
|
-
sera_2-1.14.
|
40
|
-
sera_2-1.14.
|
41
|
-
sera_2-1.14.
|
39
|
+
sera_2-1.14.5.dist-info/METADATA,sha256=vwWtB6bjalDopfemBjaZj3CI2D4S9seb-diDw98smxY,852
|
40
|
+
sera_2-1.14.5.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
41
|
+
sera_2-1.14.5.dist-info/RECORD,,
|
File without changes
|