sera-2 1.26.3__tar.gz → 1.26.5__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.
- {sera_2-1.26.3 → sera_2-1.26.5}/PKG-INFO +3 -3
- {sera_2-1.26.3 → sera_2-1.26.5}/pyproject.toml +1 -1
- sera_2-1.26.5/sera/make/make_typescript_model.py +465 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/ts_frontend/make_class_schema.py +0 -1
- sera_2-1.26.5/sera/make/ts_frontend/make_draft_model.py +811 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/ts_frontend/make_query.py +33 -15
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_datatype.py +16 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_parse.py +9 -1
- sera_2-1.26.3/sera/make/make_typescript_model.py +0 -1319
- {sera_2-1.26.3 → sera_2-1.26.5}/README.md +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/constants.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/exports/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/exports/schema.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/exports/test.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/api_helper.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/api_test_helper.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/base_orm.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/base_service.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_dcg.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_edge.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_flow.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_fn_signature.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_node.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_runtime.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/directed_computing_graph/_type_conversion.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/middlewares/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/middlewares/auth.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/middlewares/uscp.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/libs/search_helper.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/__main__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/make_app.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/make_python_api.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/make_python_model.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/make_python_services.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/py_backend/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/py_backend/misc.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/ts_frontend/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/ts_frontend/make_enums.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/make/ts_frontend/misc.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/misc/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/misc/_formatter.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/misc/_utils.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/__init__.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_class.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_collection.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_constraints.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_default.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_enum.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_module.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_multi_lingual_string.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_property.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/models/_schema.py +0 -0
- {sera_2-1.26.3 → sera_2-1.26.5}/sera/typing.py +0 -0
@@ -1,14 +1,14 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: sera-2
|
3
|
-
Version: 1.26.
|
3
|
+
Version: 1.26.5
|
4
4
|
Summary:
|
5
|
-
Home-page: https://github.com/binh-vu/sera
|
6
5
|
Author: Binh Vu
|
7
6
|
Author-email: bvu687@gmail.com
|
8
7
|
Requires-Python: >=3.12,<4.0
|
9
8
|
Classifier: Programming Language :: Python :: 3
|
10
9
|
Classifier: Programming Language :: Python :: 3.12
|
11
10
|
Classifier: Programming Language :: Python :: 3.13
|
11
|
+
Classifier: Programming Language :: Python :: 3.14
|
12
12
|
Requires-Dist: black (==25.1.0)
|
13
13
|
Requires-Dist: codegen-2 (>=2.15.1,<3.0.0)
|
14
14
|
Requires-Dist: graph-wrapper (>=1.7.3,<2.0.0)
|
@@ -0,0 +1,465 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from codegen.models import PredefinedFn, Program, expr, stmt
|
4
|
+
from codegen.models.var import DeferredVar
|
5
|
+
from loguru import logger
|
6
|
+
|
7
|
+
from sera.make.ts_frontend.make_class_schema import make_class_schema
|
8
|
+
from sera.make.ts_frontend.make_draft_model import make_draft
|
9
|
+
from sera.make.ts_frontend.make_query import make_query
|
10
|
+
from sera.misc import assert_isinstance, assert_not_null, to_camel_case, to_snake_case
|
11
|
+
from sera.models import (
|
12
|
+
Class,
|
13
|
+
DataProperty,
|
14
|
+
Enum,
|
15
|
+
ObjectProperty,
|
16
|
+
Package,
|
17
|
+
Schema,
|
18
|
+
TsTypeWithDep,
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
23
|
+
"""Generate TypeScript data model from the schema. The data model aligns with the public data model in Python, not the database model."""
|
24
|
+
app = target_pkg.app
|
25
|
+
|
26
|
+
# mapping from type alias of idprop to its real type
|
27
|
+
idprop_aliases = {}
|
28
|
+
for cls in schema.classes.values():
|
29
|
+
idprop = cls.get_id_property()
|
30
|
+
if idprop is not None:
|
31
|
+
idprop_aliases[f"{cls.name}Id"] = (
|
32
|
+
idprop.get_data_model_datatype().get_typescript_type()
|
33
|
+
)
|
34
|
+
|
35
|
+
def get_normal_deser_args(
|
36
|
+
prop: DataProperty | ObjectProperty,
|
37
|
+
) -> expr.Expr:
|
38
|
+
"""Extract the value from the data record from the server response to set to the class property in the client."""
|
39
|
+
handle_optional = lambda value: expr.ExprTernary(
|
40
|
+
expr.ExprNotEqual(value, expr.ExprConstant(None)),
|
41
|
+
value,
|
42
|
+
expr.ExprConstant("undefined"),
|
43
|
+
)
|
44
|
+
|
45
|
+
if isinstance(prop, DataProperty):
|
46
|
+
value = PredefinedFn.attr_getter(
|
47
|
+
expr.ExprIdent("data"), expr.ExprIdent(prop.name)
|
48
|
+
)
|
49
|
+
if prop.is_optional:
|
50
|
+
value = handle_optional(value)
|
51
|
+
value.true_expr = (
|
52
|
+
prop.datatype.get_typescript_type().get_json_deser_func(
|
53
|
+
value.true_expr
|
54
|
+
)
|
55
|
+
)
|
56
|
+
else:
|
57
|
+
value = prop.datatype.get_typescript_type().get_json_deser_func(value)
|
58
|
+
|
59
|
+
return value
|
60
|
+
|
61
|
+
assert isinstance(prop, ObjectProperty)
|
62
|
+
if prop.target.db is not None:
|
63
|
+
value = PredefinedFn.attr_getter(
|
64
|
+
expr.ExprIdent("data"), expr.ExprIdent(prop.name + "_id")
|
65
|
+
)
|
66
|
+
if prop.is_optional:
|
67
|
+
value = handle_optional(value)
|
68
|
+
return value
|
69
|
+
else:
|
70
|
+
if prop.cardinality.is_star_to_many():
|
71
|
+
# optional type for a list is simply an empty list, we don't need to check for None
|
72
|
+
value = PredefinedFn.map_list(
|
73
|
+
PredefinedFn.attr_getter(
|
74
|
+
expr.ExprIdent("data"),
|
75
|
+
expr.ExprIdent(prop.name),
|
76
|
+
),
|
77
|
+
lambda item: expr.ExprMethodCall(
|
78
|
+
expr.ExprIdent(
|
79
|
+
assert_isinstance(prop, ObjectProperty).target.name
|
80
|
+
),
|
81
|
+
"deser",
|
82
|
+
[item],
|
83
|
+
),
|
84
|
+
)
|
85
|
+
return value
|
86
|
+
else:
|
87
|
+
value = expr.ExprFuncCall(
|
88
|
+
PredefinedFn.attr_getter(
|
89
|
+
expr.ExprIdent(prop.target.name),
|
90
|
+
expr.ExprIdent("deser"),
|
91
|
+
),
|
92
|
+
[
|
93
|
+
PredefinedFn.attr_getter(
|
94
|
+
expr.ExprIdent("data"),
|
95
|
+
expr.ExprIdent(prop.name),
|
96
|
+
)
|
97
|
+
],
|
98
|
+
)
|
99
|
+
if prop.is_optional:
|
100
|
+
value = handle_optional(value)
|
101
|
+
return value
|
102
|
+
|
103
|
+
def make_normal(cls: Class, pkg: Package):
|
104
|
+
"""Make a data model for the normal Python data model"""
|
105
|
+
if not cls.is_public:
|
106
|
+
# skip classes that are not public
|
107
|
+
return
|
108
|
+
|
109
|
+
idprop = cls.get_id_property()
|
110
|
+
program = Program()
|
111
|
+
program.import_(
|
112
|
+
f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
|
113
|
+
)
|
114
|
+
|
115
|
+
prop_defs = []
|
116
|
+
prop_constructor_assigns = []
|
117
|
+
deser_args = []
|
118
|
+
|
119
|
+
for prop in cls.properties.values():
|
120
|
+
if prop.data.is_private:
|
121
|
+
# skip private fields as this is for APIs exchange
|
122
|
+
continue
|
123
|
+
|
124
|
+
propname = to_camel_case(prop.name)
|
125
|
+
|
126
|
+
if isinstance(prop, DataProperty):
|
127
|
+
tstype = prop.get_data_model_datatype().get_typescript_type()
|
128
|
+
for dep in tstype.deps:
|
129
|
+
program.import_(dep, True)
|
130
|
+
|
131
|
+
if idprop is not None and prop.name == idprop.name:
|
132
|
+
# use id type alias
|
133
|
+
tstype = TsTypeWithDep(
|
134
|
+
type=f"{cls.name}Id", spectype=tstype.spectype
|
135
|
+
)
|
136
|
+
|
137
|
+
if prop.is_optional:
|
138
|
+
# convert type to optional
|
139
|
+
tstype = tstype.as_optional_type()
|
140
|
+
|
141
|
+
deser_args.append(
|
142
|
+
(
|
143
|
+
expr.ExprIdent(propname),
|
144
|
+
get_normal_deser_args(prop),
|
145
|
+
)
|
146
|
+
)
|
147
|
+
else:
|
148
|
+
assert isinstance(prop, ObjectProperty)
|
149
|
+
if prop.target.db is not None:
|
150
|
+
# this class is stored in the database, we store the id instead
|
151
|
+
propname = propname + "Id"
|
152
|
+
tstype = TsTypeWithDep(
|
153
|
+
type=f"{prop.target.name}Id",
|
154
|
+
spectype=assert_not_null(prop.target.get_id_property())
|
155
|
+
.get_data_model_datatype()
|
156
|
+
.get_typescript_type()
|
157
|
+
.spectype,
|
158
|
+
deps=(
|
159
|
+
[
|
160
|
+
f"@.models.{prop.target.get_tsmodule_name()}.{prop.target.name}.{prop.target.name}Id"
|
161
|
+
]
|
162
|
+
if prop.target.name != cls.name
|
163
|
+
else []
|
164
|
+
),
|
165
|
+
)
|
166
|
+
if prop.cardinality.is_star_to_many():
|
167
|
+
tstype = tstype.as_list_type()
|
168
|
+
elif prop.is_optional:
|
169
|
+
# convert type to optional only if it isn't a list
|
170
|
+
tstype = tstype.as_optional_type()
|
171
|
+
deser_args.append(
|
172
|
+
(
|
173
|
+
expr.ExprIdent(propname),
|
174
|
+
get_normal_deser_args(prop),
|
175
|
+
)
|
176
|
+
)
|
177
|
+
else:
|
178
|
+
# we are going to store the whole object
|
179
|
+
tstype = TsTypeWithDep(
|
180
|
+
type=prop.target.name,
|
181
|
+
spectype=prop.target.name,
|
182
|
+
deps=[
|
183
|
+
f"@.models.{prop.target.get_tsmodule_name()}.{prop.target.name}.{prop.target.name}"
|
184
|
+
],
|
185
|
+
)
|
186
|
+
if prop.cardinality.is_star_to_many():
|
187
|
+
tstype = tstype.as_list_type()
|
188
|
+
deser_args.append(
|
189
|
+
(
|
190
|
+
expr.ExprIdent(propname),
|
191
|
+
get_normal_deser_args(prop),
|
192
|
+
)
|
193
|
+
)
|
194
|
+
else:
|
195
|
+
if prop.is_optional:
|
196
|
+
# convert type to optional only if it isn't a list
|
197
|
+
tstype = tstype.as_optional_type()
|
198
|
+
deser_args.append(
|
199
|
+
(
|
200
|
+
expr.ExprIdent(propname),
|
201
|
+
get_normal_deser_args(prop),
|
202
|
+
)
|
203
|
+
)
|
204
|
+
|
205
|
+
for dep in tstype.deps:
|
206
|
+
program.import_(
|
207
|
+
dep,
|
208
|
+
True,
|
209
|
+
)
|
210
|
+
|
211
|
+
prop_defs.append(stmt.DefClassVarStatement(propname, tstype.type))
|
212
|
+
prop_constructor_assigns.append(
|
213
|
+
stmt.AssignStatement(
|
214
|
+
PredefinedFn.attr_getter(
|
215
|
+
expr.ExprIdent("this"),
|
216
|
+
expr.ExprIdent(propname),
|
217
|
+
),
|
218
|
+
expr.ExprIdent("args." + propname),
|
219
|
+
)
|
220
|
+
)
|
221
|
+
|
222
|
+
program.root(
|
223
|
+
stmt.LineBreak(),
|
224
|
+
(
|
225
|
+
stmt.TypescriptStatement(
|
226
|
+
f"export type {cls.name}Id = {idprop.get_data_model_datatype().get_typescript_type().type};"
|
227
|
+
)
|
228
|
+
if idprop is not None
|
229
|
+
else None
|
230
|
+
),
|
231
|
+
stmt.LineBreak(),
|
232
|
+
lambda ast00: ast00.class_like(
|
233
|
+
"interface",
|
234
|
+
cls.name + "ConstructorArgs",
|
235
|
+
)(*prop_defs),
|
236
|
+
stmt.LineBreak(),
|
237
|
+
lambda ast10: ast10.class_(cls.name)(
|
238
|
+
*prop_defs,
|
239
|
+
stmt.LineBreak(),
|
240
|
+
lambda ast11: ast11.func(
|
241
|
+
"constructor",
|
242
|
+
[
|
243
|
+
DeferredVar.simple(
|
244
|
+
"args", expr.ExprIdent(cls.name + "ConstructorArgs")
|
245
|
+
),
|
246
|
+
],
|
247
|
+
)(*prop_constructor_assigns),
|
248
|
+
stmt.LineBreak(),
|
249
|
+
lambda ast12: ast12.func(
|
250
|
+
"className",
|
251
|
+
[],
|
252
|
+
expr.ExprIdent("string"),
|
253
|
+
is_static=True,
|
254
|
+
modifiers=["get"],
|
255
|
+
comment="Name of the class in the Schema",
|
256
|
+
)(
|
257
|
+
stmt.ReturnStatement(expr.ExprConstant(cls.name)),
|
258
|
+
),
|
259
|
+
stmt.LineBreak(),
|
260
|
+
lambda ast12: ast12.func(
|
261
|
+
"deser",
|
262
|
+
[
|
263
|
+
DeferredVar.simple("data", expr.ExprIdent("any")),
|
264
|
+
],
|
265
|
+
expr.ExprIdent(cls.name),
|
266
|
+
is_static=True,
|
267
|
+
comment="Deserialize the data from the server to create a new instance of the class",
|
268
|
+
)(
|
269
|
+
lambda ast: ast.return_(
|
270
|
+
expr.ExprNewInstance(
|
271
|
+
expr.ExprIdent(cls.name), [PredefinedFn.dict(deser_args)]
|
272
|
+
)
|
273
|
+
)
|
274
|
+
),
|
275
|
+
stmt.LineBreak(),
|
276
|
+
lambda ast13: ast13.func(
|
277
|
+
"toDraft",
|
278
|
+
[],
|
279
|
+
expr.ExprIdent(f"Draft{cls.name}"),
|
280
|
+
comment="Convert the class instance to a draft for editing",
|
281
|
+
)(
|
282
|
+
stmt.ReturnStatement(
|
283
|
+
expr.ExprMethodCall(
|
284
|
+
expr.ExprIdent(f"Draft{cls.name}"),
|
285
|
+
"update",
|
286
|
+
[expr.ExprIdent("this")],
|
287
|
+
)
|
288
|
+
),
|
289
|
+
),
|
290
|
+
),
|
291
|
+
)
|
292
|
+
|
293
|
+
pkg.module(cls.name).write(program)
|
294
|
+
|
295
|
+
def make_table(cls: Class, pkg: Package):
|
296
|
+
if not cls.is_public or cls.db is None:
|
297
|
+
# skip classes that are not public and not stored in the database
|
298
|
+
return
|
299
|
+
|
300
|
+
outmod = pkg.module(cls.name + "Table")
|
301
|
+
if outmod.exists():
|
302
|
+
# skip if the module already exists
|
303
|
+
logger.info(f"Module {outmod.path} already exists, skip")
|
304
|
+
return
|
305
|
+
|
306
|
+
program = Program()
|
307
|
+
program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}", True)
|
308
|
+
program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}Id", True)
|
309
|
+
program.import_(f"@.models.{pkg.dir.name}.{cls.name}Query.query", True)
|
310
|
+
program.import_(
|
311
|
+
f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
|
312
|
+
)
|
313
|
+
program.import_("sera-db.Table", True)
|
314
|
+
program.import_("sera-db.DB", True)
|
315
|
+
|
316
|
+
program.root(
|
317
|
+
stmt.LineBreak(),
|
318
|
+
lambda ast00: ast00.class_(
|
319
|
+
f"{cls.name}Table",
|
320
|
+
[expr.ExprIdent(f"Table<{cls.name}Id, {cls.name}, Draft{cls.name}>")],
|
321
|
+
)(
|
322
|
+
lambda ast01: ast01.func(
|
323
|
+
"constructor",
|
324
|
+
[
|
325
|
+
DeferredVar.simple(
|
326
|
+
"db",
|
327
|
+
expr.ExprIdent("DB"),
|
328
|
+
)
|
329
|
+
],
|
330
|
+
)(
|
331
|
+
stmt.SingleExprStatement(
|
332
|
+
expr.ExprFuncCall(
|
333
|
+
expr.ExprIdent("super"),
|
334
|
+
[
|
335
|
+
PredefinedFn.dict(
|
336
|
+
[
|
337
|
+
(
|
338
|
+
expr.ExprIdent("cls"),
|
339
|
+
expr.ExprIdent(cls.name),
|
340
|
+
),
|
341
|
+
(
|
342
|
+
expr.ExprIdent("remoteURL"),
|
343
|
+
expr.ExprConstant(
|
344
|
+
f"/api/{to_snake_case(cls.name).replace('_', '-')}"
|
345
|
+
),
|
346
|
+
),
|
347
|
+
(
|
348
|
+
expr.ExprIdent("db"),
|
349
|
+
expr.ExprIdent("db"),
|
350
|
+
),
|
351
|
+
(
|
352
|
+
expr.ExprIdent("queryProcessor"),
|
353
|
+
expr.ExprIdent("query"),
|
354
|
+
),
|
355
|
+
]
|
356
|
+
)
|
357
|
+
],
|
358
|
+
)
|
359
|
+
)
|
360
|
+
),
|
361
|
+
),
|
362
|
+
)
|
363
|
+
|
364
|
+
outmod.write(program)
|
365
|
+
|
366
|
+
def make_index(pkg: Package):
|
367
|
+
outmod = pkg.module("index")
|
368
|
+
if outmod.exists():
|
369
|
+
# skip if the module already exists
|
370
|
+
logger.info(f"Module {outmod.path} already exists, skip")
|
371
|
+
return
|
372
|
+
|
373
|
+
export_types = []
|
374
|
+
export_iso_types = [] # isolatedModules required separate export type clause
|
375
|
+
|
376
|
+
program = Program()
|
377
|
+
program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}", True)
|
378
|
+
export_types.append(cls.name)
|
379
|
+
if cls.db is not None:
|
380
|
+
# only import the id if this class is stored in the database
|
381
|
+
program.import_(f"@.models.{pkg.dir.name}.{cls.name}.{cls.name}Id", True)
|
382
|
+
export_iso_types.append(f"{cls.name}Id")
|
383
|
+
|
384
|
+
program.import_(
|
385
|
+
f"@.models.{pkg.dir.name}.{cls.name}Schema.{cls.name}Schema", True
|
386
|
+
)
|
387
|
+
program.import_(
|
388
|
+
f"@.models.{pkg.dir.name}.{cls.name}Query.{cls.name}Query", True
|
389
|
+
)
|
390
|
+
export_types.append(f"{cls.name}Schema")
|
391
|
+
export_iso_types.append(f"{cls.name}Query")
|
392
|
+
program.import_(
|
393
|
+
f"@.models.{pkg.dir.name}.{cls.name}Schema.{cls.name}SchemaType", True
|
394
|
+
)
|
395
|
+
export_iso_types.append(f"{cls.name}SchemaType")
|
396
|
+
|
397
|
+
program.import_(
|
398
|
+
f"@.models.{pkg.dir.name}.Draft{cls.name}.Draft{cls.name}", True
|
399
|
+
)
|
400
|
+
export_types.append(f"Draft{cls.name}")
|
401
|
+
if cls.db is not None:
|
402
|
+
program.import_(
|
403
|
+
f"@.models.{pkg.dir.name}.{cls.name}Table.{cls.name}Table", True
|
404
|
+
)
|
405
|
+
export_types.append(f"{cls.name}Table")
|
406
|
+
|
407
|
+
program.root(
|
408
|
+
stmt.LineBreak(),
|
409
|
+
stmt.TypescriptStatement("export { %s };" % (", ".join(export_types))),
|
410
|
+
(
|
411
|
+
stmt.TypescriptStatement(
|
412
|
+
"export type { %s };" % (", ".join(export_iso_types))
|
413
|
+
)
|
414
|
+
),
|
415
|
+
)
|
416
|
+
|
417
|
+
outmod.write(program)
|
418
|
+
|
419
|
+
for cls in schema.topological_sort():
|
420
|
+
pkg = target_pkg.pkg(cls.get_tsmodule_name())
|
421
|
+
make_normal(cls, pkg)
|
422
|
+
make_draft(schema, cls, pkg, idprop_aliases)
|
423
|
+
make_query(schema, cls, pkg)
|
424
|
+
make_table(cls, pkg)
|
425
|
+
make_class_schema(schema, cls, pkg)
|
426
|
+
|
427
|
+
make_index(pkg)
|
428
|
+
|
429
|
+
|
430
|
+
def make_typescript_enum(schema: Schema, target_pkg: Package):
|
431
|
+
"""Make typescript enum for the schema"""
|
432
|
+
enum_pkg = target_pkg.pkg("enums")
|
433
|
+
|
434
|
+
def make_enum(enum: Enum, pkg: Package):
|
435
|
+
program = Program()
|
436
|
+
program.root(
|
437
|
+
stmt.LineBreak(),
|
438
|
+
lambda ast: ast.class_like("enum", enum.name)(
|
439
|
+
*[
|
440
|
+
stmt.DefEnumValueStatement(
|
441
|
+
name=value.name,
|
442
|
+
value=expr.ExprConstant(value.value),
|
443
|
+
)
|
444
|
+
for value in enum.values.values()
|
445
|
+
]
|
446
|
+
),
|
447
|
+
)
|
448
|
+
pkg.module(enum.get_tsmodule_name()).write(program)
|
449
|
+
|
450
|
+
for enum in schema.enums.values():
|
451
|
+
make_enum(enum, enum_pkg)
|
452
|
+
|
453
|
+
program = Program()
|
454
|
+
for enum in schema.enums.values():
|
455
|
+
program.import_(f"@.models.enums.{enum.get_tsmodule_name()}.{enum.name}", True)
|
456
|
+
|
457
|
+
program.root(
|
458
|
+
stmt.LineBreak(),
|
459
|
+
stmt.TypescriptStatement(
|
460
|
+
"export { "
|
461
|
+
+ ", ".join([enum.name for enum in schema.enums.values()])
|
462
|
+
+ "};"
|
463
|
+
),
|
464
|
+
)
|
465
|
+
enum_pkg.module("index").write(program)
|