@zenstackhq/sdk 2.16.0 → 3.0.0-alpha.1
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.
- package/LICENSE +1 -1
- package/dist/index.cjs +1906 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +196 -0
- package/dist/index.d.ts +196 -0
- package/dist/index.js +1872 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.cjs +19 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +138 -0
- package/dist/schema.d.ts +138 -0
- package/dist/schema.js +1 -0
- package/dist/schema.js.map +1 -0
- package/package.json +43 -39
- package/README.md +0 -5
- package/ast.d.ts +0 -1
- package/ast.js +0 -18
- package/ast.js.map +0 -1
- package/code-gen.d.ts +0 -37
- package/code-gen.js +0 -114
- package/code-gen.js.map +0 -1
- package/constants.d.ts +0 -15
- package/constants.js +0 -21
- package/constants.js.map +0 -1
- package/dmmf-helpers/aggregate-helpers.d.ts +0 -5
- package/dmmf-helpers/aggregate-helpers.js +0 -65
- package/dmmf-helpers/aggregate-helpers.js.map +0 -1
- package/dmmf-helpers/include-helpers.d.ts +0 -2
- package/dmmf-helpers/include-helpers.js +0 -88
- package/dmmf-helpers/include-helpers.js.map +0 -1
- package/dmmf-helpers/index.d.ts +0 -7
- package/dmmf-helpers/index.js +0 -24
- package/dmmf-helpers/index.js.map +0 -1
- package/dmmf-helpers/missing-types-helper.d.ts +0 -2
- package/dmmf-helpers/missing-types-helper.js +0 -14
- package/dmmf-helpers/missing-types-helper.js.map +0 -1
- package/dmmf-helpers/model-helpers.d.ts +0 -16
- package/dmmf-helpers/model-helpers.js +0 -38
- package/dmmf-helpers/model-helpers.js.map +0 -1
- package/dmmf-helpers/modelArgs-helpers.d.ts +0 -2
- package/dmmf-helpers/modelArgs-helpers.js +0 -67
- package/dmmf-helpers/modelArgs-helpers.js.map +0 -1
- package/dmmf-helpers/select-helpers.d.ts +0 -2
- package/dmmf-helpers/select-helpers.js +0 -152
- package/dmmf-helpers/select-helpers.js.map +0 -1
- package/dmmf-helpers/types.d.ts +0 -20
- package/dmmf-helpers/types.js +0 -3
- package/dmmf-helpers/types.js.map +0 -1
- package/index.d.ts +0 -11
- package/index.js +0 -30
- package/index.js.map +0 -1
- package/model-meta-generator.d.ts +0 -24
- package/model-meta-generator.js +0 -458
- package/model-meta-generator.js.map +0 -1
- package/names.d.ts +0 -9
- package/names.js +0 -17
- package/names.js.map +0 -1
- package/path.d.ts +0 -4
- package/path.js +0 -15
- package/path.js.map +0 -1
- package/policy.d.ts +0 -13
- package/policy.js +0 -57
- package/policy.js.map +0 -1
- package/prisma.d.ts +0 -21
- package/prisma.js +0 -84
- package/prisma.js.map +0 -1
- package/types.d.ts +0 -97
- package/types.js +0 -14
- package/types.js.map +0 -1
- package/typescript-expression-transformer.d.ts +0 -64
- package/typescript-expression-transformer.js +0 -491
- package/typescript-expression-transformer.js.map +0 -1
- package/utils.d.ts +0 -103
- package/utils.js +0 -633
- package/utils.js.map +0 -1
- package/validation.d.ts +0 -7
- package/validation.js +0 -37
- package/validation.js.map +0 -1
- package/zmodel-code-generator.d.ts +0 -66
- package/zmodel-code-generator.js +0 -353
- package/zmodel-code-generator.js.map +0 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,1872 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// src/model-utils.ts
|
|
9
|
+
var model_utils_exports = {};
|
|
10
|
+
__export(model_utils_exports, {
|
|
11
|
+
getAttribute: () => getAttribute,
|
|
12
|
+
getAuthDecl: () => getAuthDecl,
|
|
13
|
+
getContainingModel: () => getContainingModel,
|
|
14
|
+
getModelIdFields: () => getModelIdFields,
|
|
15
|
+
getModelUniqueFields: () => getModelUniqueFields,
|
|
16
|
+
getRecursiveBases: () => getRecursiveBases,
|
|
17
|
+
hasAttribute: () => hasAttribute,
|
|
18
|
+
isDelegateModel: () => isDelegateModel,
|
|
19
|
+
isFromStdlib: () => isFromStdlib,
|
|
20
|
+
isIdField: () => isIdField,
|
|
21
|
+
isUniqueField: () => isUniqueField,
|
|
22
|
+
resolved: () => resolved
|
|
23
|
+
});
|
|
24
|
+
import { isArrayExpr, isDataModel, isLiteralExpr, isModel, isReferenceExpr } from "@zenstackhq/language/ast";
|
|
25
|
+
function isIdField(field) {
|
|
26
|
+
if (hasAttribute(field, "@id")) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const model = field.$container;
|
|
30
|
+
const modelLevelIds = getModelIdFields(model);
|
|
31
|
+
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (model.fields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const firstUniqueField = model.fields.find((f) => hasAttribute(f, "@unique"));
|
|
38
|
+
if (firstUniqueField) {
|
|
39
|
+
return firstUniqueField.name === field.name;
|
|
40
|
+
}
|
|
41
|
+
const modelLevelUnique = getModelUniqueFields(model);
|
|
42
|
+
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
__name(isIdField, "isIdField");
|
|
48
|
+
function hasAttribute(decl, name) {
|
|
49
|
+
return !!getAttribute(decl, name);
|
|
50
|
+
}
|
|
51
|
+
__name(hasAttribute, "hasAttribute");
|
|
52
|
+
function getAttribute(decl, name) {
|
|
53
|
+
return decl.attributes.find((attr) => attr.decl.$refText === name);
|
|
54
|
+
}
|
|
55
|
+
__name(getAttribute, "getAttribute");
|
|
56
|
+
function getModelIdFields(model) {
|
|
57
|
+
const modelsToCheck = model.$baseMerged ? [
|
|
58
|
+
model
|
|
59
|
+
] : [
|
|
60
|
+
model,
|
|
61
|
+
...getRecursiveBases(model)
|
|
62
|
+
];
|
|
63
|
+
for (const modelToCheck of modelsToCheck) {
|
|
64
|
+
const idAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@id");
|
|
65
|
+
if (!idAttr) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === "fields");
|
|
69
|
+
if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
return fieldsArg.value.items.filter((item) => isReferenceExpr(item)).map((item) => item.target.ref);
|
|
73
|
+
}
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
__name(getModelIdFields, "getModelIdFields");
|
|
77
|
+
function getModelUniqueFields(model) {
|
|
78
|
+
const modelsToCheck = model.$baseMerged ? [
|
|
79
|
+
model
|
|
80
|
+
] : [
|
|
81
|
+
model,
|
|
82
|
+
...getRecursiveBases(model)
|
|
83
|
+
];
|
|
84
|
+
for (const modelToCheck of modelsToCheck) {
|
|
85
|
+
const uniqueAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@unique");
|
|
86
|
+
if (!uniqueAttr) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === "fields");
|
|
90
|
+
if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
return fieldsArg.value.items.filter((item) => isReferenceExpr(item)).map((item) => item.target.ref);
|
|
94
|
+
}
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
__name(getModelUniqueFields, "getModelUniqueFields");
|
|
98
|
+
function getRecursiveBases(dataModel, includeDelegate = true, seen = /* @__PURE__ */ new Set()) {
|
|
99
|
+
const result = [];
|
|
100
|
+
if (seen.has(dataModel)) {
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
seen.add(dataModel);
|
|
104
|
+
dataModel.superTypes.forEach((superType) => {
|
|
105
|
+
const baseDecl = superType.ref;
|
|
106
|
+
if (baseDecl) {
|
|
107
|
+
if (!includeDelegate && isDelegateModel(baseDecl)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
result.push(baseDecl);
|
|
111
|
+
result.push(...getRecursiveBases(baseDecl, includeDelegate, seen));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
__name(getRecursiveBases, "getRecursiveBases");
|
|
117
|
+
function isDelegateModel(node) {
|
|
118
|
+
return isDataModel(node) && hasAttribute(node, "@@delegate");
|
|
119
|
+
}
|
|
120
|
+
__name(isDelegateModel, "isDelegateModel");
|
|
121
|
+
function isUniqueField(field) {
|
|
122
|
+
if (hasAttribute(field, "@unique")) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
const modelIds = getAttribute(field.$container, "@@unique");
|
|
126
|
+
if (modelIds && modelIds.args.some((arg) => isLiteralExpr(arg.value) && arg.value.value === field.name)) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
__name(isUniqueField, "isUniqueField");
|
|
132
|
+
function isFromStdlib(node) {
|
|
133
|
+
const model = getContainingModel(node);
|
|
134
|
+
return !!model && !!model.$document && model.$document.uri.path.endsWith("stdlib.zmodel");
|
|
135
|
+
}
|
|
136
|
+
__name(isFromStdlib, "isFromStdlib");
|
|
137
|
+
function getContainingModel(node) {
|
|
138
|
+
if (!node) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return isModel(node) ? node : getContainingModel(node.$container);
|
|
142
|
+
}
|
|
143
|
+
__name(getContainingModel, "getContainingModel");
|
|
144
|
+
function resolved(ref) {
|
|
145
|
+
if (!ref.ref) {
|
|
146
|
+
throw new Error(`Reference not resolved: ${ref.$refText}`);
|
|
147
|
+
}
|
|
148
|
+
return ref.ref;
|
|
149
|
+
}
|
|
150
|
+
__name(resolved, "resolved");
|
|
151
|
+
function getAuthDecl(model) {
|
|
152
|
+
let found = model.declarations.find((d) => isDataModel(d) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
|
|
153
|
+
if (!found) {
|
|
154
|
+
found = model.declarations.find((d) => isDataModel(d) && d.name === "User");
|
|
155
|
+
}
|
|
156
|
+
return found;
|
|
157
|
+
}
|
|
158
|
+
__name(getAuthDecl, "getAuthDecl");
|
|
159
|
+
|
|
160
|
+
// src/prisma/prisma-schema-generator.ts
|
|
161
|
+
import { BooleanLiteral, DataModel, DataSource as DataSource2, Enum as Enum2, GeneratorDecl, isArrayExpr as isArrayExpr2, isInvocationExpr, isLiteralExpr as isLiteralExpr2, isModel as isModel2, isNullExpr, isReferenceExpr as isReferenceExpr2, isStringLiteral, isTypeDef, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
|
|
162
|
+
import { AstUtils } from "langium";
|
|
163
|
+
import { match, P } from "ts-pattern";
|
|
164
|
+
|
|
165
|
+
// src/prisma/indent-string.ts
|
|
166
|
+
function indentString(string, count = 4) {
|
|
167
|
+
const indent = " ";
|
|
168
|
+
return string.replace(/^(?!\s*$)/gm, indent.repeat(count));
|
|
169
|
+
}
|
|
170
|
+
__name(indentString, "indentString");
|
|
171
|
+
|
|
172
|
+
// src/prisma/prisma-builder.ts
|
|
173
|
+
var PrismaModel = class {
|
|
174
|
+
static {
|
|
175
|
+
__name(this, "PrismaModel");
|
|
176
|
+
}
|
|
177
|
+
datasources = [];
|
|
178
|
+
generators = [];
|
|
179
|
+
models = [];
|
|
180
|
+
enums = [];
|
|
181
|
+
addDataSource(name, fields = []) {
|
|
182
|
+
const ds = new DataSource(name, fields);
|
|
183
|
+
this.datasources.push(ds);
|
|
184
|
+
return ds;
|
|
185
|
+
}
|
|
186
|
+
addGenerator(name, fields) {
|
|
187
|
+
const generator = new Generator(name, fields);
|
|
188
|
+
this.generators.push(generator);
|
|
189
|
+
return generator;
|
|
190
|
+
}
|
|
191
|
+
addModel(name) {
|
|
192
|
+
const model = new Model(name, false);
|
|
193
|
+
this.models.push(model);
|
|
194
|
+
return model;
|
|
195
|
+
}
|
|
196
|
+
addView(name) {
|
|
197
|
+
const model = new Model(name, true);
|
|
198
|
+
this.models.push(model);
|
|
199
|
+
return model;
|
|
200
|
+
}
|
|
201
|
+
addEnum(name) {
|
|
202
|
+
const e = new Enum(name);
|
|
203
|
+
this.enums.push(e);
|
|
204
|
+
return e;
|
|
205
|
+
}
|
|
206
|
+
toString() {
|
|
207
|
+
return [
|
|
208
|
+
...this.datasources,
|
|
209
|
+
...this.generators,
|
|
210
|
+
...this.enums,
|
|
211
|
+
...this.models
|
|
212
|
+
].map((d) => d.toString()).join("\n\n");
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var DataSource = class {
|
|
216
|
+
static {
|
|
217
|
+
__name(this, "DataSource");
|
|
218
|
+
}
|
|
219
|
+
name;
|
|
220
|
+
fields;
|
|
221
|
+
constructor(name, fields = []) {
|
|
222
|
+
this.name = name;
|
|
223
|
+
this.fields = fields;
|
|
224
|
+
}
|
|
225
|
+
toString() {
|
|
226
|
+
return `datasource ${this.name} {
|
|
227
|
+
` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `
|
|
228
|
+
}`;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
var Generator = class {
|
|
232
|
+
static {
|
|
233
|
+
__name(this, "Generator");
|
|
234
|
+
}
|
|
235
|
+
name;
|
|
236
|
+
fields;
|
|
237
|
+
constructor(name, fields) {
|
|
238
|
+
this.name = name;
|
|
239
|
+
this.fields = fields;
|
|
240
|
+
}
|
|
241
|
+
toString() {
|
|
242
|
+
return `generator ${this.name} {
|
|
243
|
+
` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `
|
|
244
|
+
}`;
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
var DeclarationBase = class {
|
|
248
|
+
static {
|
|
249
|
+
__name(this, "DeclarationBase");
|
|
250
|
+
}
|
|
251
|
+
documentations;
|
|
252
|
+
constructor(documentations = []) {
|
|
253
|
+
this.documentations = documentations;
|
|
254
|
+
}
|
|
255
|
+
addComment(name) {
|
|
256
|
+
this.documentations.push(name);
|
|
257
|
+
return name;
|
|
258
|
+
}
|
|
259
|
+
toString() {
|
|
260
|
+
return this.documentations.map((x) => `${x}
|
|
261
|
+
`).join("");
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
var ContainerDeclaration = class extends DeclarationBase {
|
|
265
|
+
static {
|
|
266
|
+
__name(this, "ContainerDeclaration");
|
|
267
|
+
}
|
|
268
|
+
attributes;
|
|
269
|
+
constructor(documentations = [], attributes = []) {
|
|
270
|
+
super(documentations), this.attributes = attributes;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
var FieldDeclaration = class extends DeclarationBase {
|
|
274
|
+
static {
|
|
275
|
+
__name(this, "FieldDeclaration");
|
|
276
|
+
}
|
|
277
|
+
attributes;
|
|
278
|
+
constructor(documentations = [], attributes = []) {
|
|
279
|
+
super(documentations), this.attributes = attributes;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
var Model = class extends ContainerDeclaration {
|
|
283
|
+
static {
|
|
284
|
+
__name(this, "Model");
|
|
285
|
+
}
|
|
286
|
+
name;
|
|
287
|
+
isView;
|
|
288
|
+
fields;
|
|
289
|
+
constructor(name, isView, documentations = []) {
|
|
290
|
+
super(documentations), this.name = name, this.isView = isView, this.fields = [];
|
|
291
|
+
}
|
|
292
|
+
addField(name, type, attributes = [], documentations = [], addToFront = false) {
|
|
293
|
+
const field = new ModelField(name, type, attributes, documentations);
|
|
294
|
+
if (addToFront) {
|
|
295
|
+
this.fields.unshift(field);
|
|
296
|
+
} else {
|
|
297
|
+
this.fields.push(field);
|
|
298
|
+
}
|
|
299
|
+
return field;
|
|
300
|
+
}
|
|
301
|
+
addAttribute(name, args = []) {
|
|
302
|
+
const attr = new ContainerAttribute(name, args);
|
|
303
|
+
this.attributes.push(attr);
|
|
304
|
+
return attr;
|
|
305
|
+
}
|
|
306
|
+
toString() {
|
|
307
|
+
const result = [
|
|
308
|
+
...this.fields
|
|
309
|
+
];
|
|
310
|
+
if (this.attributes.length > 0) {
|
|
311
|
+
result.push("");
|
|
312
|
+
}
|
|
313
|
+
result.push(...this.attributes);
|
|
314
|
+
return super.toString() + `${this.isView ? "view" : "model"} ${this.name} {
|
|
315
|
+
` + indentString(result.map((d) => d.toString()).join("\n")) + `
|
|
316
|
+
}`;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var ModelFieldType = class {
|
|
320
|
+
static {
|
|
321
|
+
__name(this, "ModelFieldType");
|
|
322
|
+
}
|
|
323
|
+
type;
|
|
324
|
+
array;
|
|
325
|
+
optional;
|
|
326
|
+
constructor(type, array, optional) {
|
|
327
|
+
this.type = type;
|
|
328
|
+
this.array = array;
|
|
329
|
+
this.optional = optional;
|
|
330
|
+
}
|
|
331
|
+
toString() {
|
|
332
|
+
return `${this.type}${this.array ? "[]" : ""}${this.optional ? "?" : ""}`;
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
var ModelField = class extends FieldDeclaration {
|
|
336
|
+
static {
|
|
337
|
+
__name(this, "ModelField");
|
|
338
|
+
}
|
|
339
|
+
name;
|
|
340
|
+
type;
|
|
341
|
+
constructor(name, type, attributes = [], documentations = []) {
|
|
342
|
+
super(documentations, attributes), this.name = name, this.type = type;
|
|
343
|
+
}
|
|
344
|
+
addAttribute(name, args = []) {
|
|
345
|
+
const attr = new FieldAttribute(name, args);
|
|
346
|
+
this.attributes.push(attr);
|
|
347
|
+
return attr;
|
|
348
|
+
}
|
|
349
|
+
toString() {
|
|
350
|
+
return super.toString() + `${this.name} ${this.type}` + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
var FieldAttribute = class {
|
|
354
|
+
static {
|
|
355
|
+
__name(this, "FieldAttribute");
|
|
356
|
+
}
|
|
357
|
+
name;
|
|
358
|
+
args;
|
|
359
|
+
constructor(name, args = []) {
|
|
360
|
+
this.name = name;
|
|
361
|
+
this.args = args;
|
|
362
|
+
}
|
|
363
|
+
toString() {
|
|
364
|
+
return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
var ContainerAttribute = class {
|
|
368
|
+
static {
|
|
369
|
+
__name(this, "ContainerAttribute");
|
|
370
|
+
}
|
|
371
|
+
name;
|
|
372
|
+
args;
|
|
373
|
+
constructor(name, args = []) {
|
|
374
|
+
this.name = name;
|
|
375
|
+
this.args = args;
|
|
376
|
+
}
|
|
377
|
+
toString() {
|
|
378
|
+
return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
var AttributeArg = class {
|
|
382
|
+
static {
|
|
383
|
+
__name(this, "AttributeArg");
|
|
384
|
+
}
|
|
385
|
+
name;
|
|
386
|
+
value;
|
|
387
|
+
constructor(name, value) {
|
|
388
|
+
this.name = name;
|
|
389
|
+
this.value = value;
|
|
390
|
+
}
|
|
391
|
+
toString() {
|
|
392
|
+
return this.name ? `${this.name}: ${this.value}` : this.value.toString();
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
var AttributeArgValue = class {
|
|
396
|
+
static {
|
|
397
|
+
__name(this, "AttributeArgValue");
|
|
398
|
+
}
|
|
399
|
+
type;
|
|
400
|
+
value;
|
|
401
|
+
constructor(type, value) {
|
|
402
|
+
this.type = type;
|
|
403
|
+
this.value = value;
|
|
404
|
+
switch (type) {
|
|
405
|
+
case "String":
|
|
406
|
+
if (typeof value !== "string") throw new Error("Value must be string");
|
|
407
|
+
break;
|
|
408
|
+
case "Number":
|
|
409
|
+
if (typeof value !== "number" && typeof value !== "string") throw new Error("Value must be number or string");
|
|
410
|
+
break;
|
|
411
|
+
case "Boolean":
|
|
412
|
+
if (typeof value !== "boolean") throw new Error("Value must be boolean");
|
|
413
|
+
break;
|
|
414
|
+
case "Array":
|
|
415
|
+
if (!Array.isArray(value)) throw new Error("Value must be array");
|
|
416
|
+
break;
|
|
417
|
+
case "FieldReference":
|
|
418
|
+
if (typeof value !== "string" && !(value instanceof FieldReference)) throw new Error("Value must be string or FieldReference");
|
|
419
|
+
break;
|
|
420
|
+
case "FunctionCall":
|
|
421
|
+
if (!(value instanceof FunctionCall)) throw new Error("Value must be FunctionCall");
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
toString() {
|
|
426
|
+
switch (this.type) {
|
|
427
|
+
case "String":
|
|
428
|
+
return JSON.stringify(this.value);
|
|
429
|
+
case "Number":
|
|
430
|
+
return this.value.toString();
|
|
431
|
+
case "FieldReference": {
|
|
432
|
+
if (typeof this.value === "string") {
|
|
433
|
+
return this.value;
|
|
434
|
+
} else {
|
|
435
|
+
const fr = this.value;
|
|
436
|
+
let r = fr.field;
|
|
437
|
+
if (fr.args.length > 0) {
|
|
438
|
+
r += "(" + fr.args.map((a) => a.toString()).join(",") + ")";
|
|
439
|
+
}
|
|
440
|
+
return r;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
case "FunctionCall":
|
|
444
|
+
return this.value.toString();
|
|
445
|
+
case "Boolean":
|
|
446
|
+
return this.value ? "true" : "false";
|
|
447
|
+
case "Array":
|
|
448
|
+
return "[" + this.value.map((v) => v.toString()).join(", ") + "]";
|
|
449
|
+
default:
|
|
450
|
+
throw new Error(`Unknown attribute value type ${this.type}`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
var FieldReference = class {
|
|
455
|
+
static {
|
|
456
|
+
__name(this, "FieldReference");
|
|
457
|
+
}
|
|
458
|
+
field;
|
|
459
|
+
args;
|
|
460
|
+
constructor(field, args = []) {
|
|
461
|
+
this.field = field;
|
|
462
|
+
this.args = args;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
var FieldReferenceArg = class {
|
|
466
|
+
static {
|
|
467
|
+
__name(this, "FieldReferenceArg");
|
|
468
|
+
}
|
|
469
|
+
name;
|
|
470
|
+
value;
|
|
471
|
+
constructor(name, value) {
|
|
472
|
+
this.name = name;
|
|
473
|
+
this.value = value;
|
|
474
|
+
}
|
|
475
|
+
toString() {
|
|
476
|
+
return `${this.name}: ${this.value}`;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
var FunctionCall = class {
|
|
480
|
+
static {
|
|
481
|
+
__name(this, "FunctionCall");
|
|
482
|
+
}
|
|
483
|
+
func;
|
|
484
|
+
args;
|
|
485
|
+
constructor(func, args = []) {
|
|
486
|
+
this.func = func;
|
|
487
|
+
this.args = args;
|
|
488
|
+
}
|
|
489
|
+
toString() {
|
|
490
|
+
return `${this.func}(` + this.args.map((a) => a.toString()).join(", ") + ")";
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
var FunctionCallArg = class {
|
|
494
|
+
static {
|
|
495
|
+
__name(this, "FunctionCallArg");
|
|
496
|
+
}
|
|
497
|
+
value;
|
|
498
|
+
constructor(value) {
|
|
499
|
+
this.value = value;
|
|
500
|
+
}
|
|
501
|
+
toString() {
|
|
502
|
+
return this.value;
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var Enum = class extends ContainerDeclaration {
|
|
506
|
+
static {
|
|
507
|
+
__name(this, "Enum");
|
|
508
|
+
}
|
|
509
|
+
name;
|
|
510
|
+
fields;
|
|
511
|
+
constructor(name, documentations = []) {
|
|
512
|
+
super(documentations), this.name = name, this.fields = [];
|
|
513
|
+
}
|
|
514
|
+
addField(name, attributes = [], documentations = []) {
|
|
515
|
+
const field = new EnumField(name, attributes, documentations);
|
|
516
|
+
this.fields.push(field);
|
|
517
|
+
return field;
|
|
518
|
+
}
|
|
519
|
+
addAttribute(name, args = []) {
|
|
520
|
+
const attr = new ContainerAttribute(name, args);
|
|
521
|
+
this.attributes.push(attr);
|
|
522
|
+
return attr;
|
|
523
|
+
}
|
|
524
|
+
addComment(name) {
|
|
525
|
+
this.documentations.push(name);
|
|
526
|
+
return name;
|
|
527
|
+
}
|
|
528
|
+
toString() {
|
|
529
|
+
return super.toString() + `enum ${this.name} {
|
|
530
|
+
` + indentString([
|
|
531
|
+
...this.fields,
|
|
532
|
+
...this.attributes
|
|
533
|
+
].map((d) => d.toString()).join("\n")) + "\n}";
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var EnumField = class extends DeclarationBase {
|
|
537
|
+
static {
|
|
538
|
+
__name(this, "EnumField");
|
|
539
|
+
}
|
|
540
|
+
name;
|
|
541
|
+
attributes;
|
|
542
|
+
constructor(name, attributes = [], documentations = []) {
|
|
543
|
+
super(documentations), this.name = name, this.attributes = attributes;
|
|
544
|
+
}
|
|
545
|
+
addAttribute(name, args = []) {
|
|
546
|
+
const attr = new FieldAttribute(name, args);
|
|
547
|
+
this.attributes.push(attr);
|
|
548
|
+
return attr;
|
|
549
|
+
}
|
|
550
|
+
toString() {
|
|
551
|
+
return super.toString() + this.name + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/prisma/prisma-schema-generator.ts
|
|
556
|
+
var PrismaSchemaGenerator = class {
|
|
557
|
+
static {
|
|
558
|
+
__name(this, "PrismaSchemaGenerator");
|
|
559
|
+
}
|
|
560
|
+
zmodel;
|
|
561
|
+
PRELUDE;
|
|
562
|
+
constructor(zmodel) {
|
|
563
|
+
this.zmodel = zmodel;
|
|
564
|
+
this.PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
|
|
565
|
+
// DO NOT MODIFY THIS FILE //
|
|
566
|
+
// This file is automatically generated by ZenStack CLI and should not be manually updated. //
|
|
567
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
568
|
+
|
|
569
|
+
`;
|
|
570
|
+
}
|
|
571
|
+
async generate() {
|
|
572
|
+
const prisma = new PrismaModel();
|
|
573
|
+
for (const decl of this.zmodel.declarations) {
|
|
574
|
+
switch (decl.$type) {
|
|
575
|
+
case DataSource2:
|
|
576
|
+
this.generateDataSource(prisma, decl);
|
|
577
|
+
break;
|
|
578
|
+
case Enum2:
|
|
579
|
+
this.generateEnum(prisma, decl);
|
|
580
|
+
break;
|
|
581
|
+
case DataModel:
|
|
582
|
+
this.generateModel(prisma, decl);
|
|
583
|
+
break;
|
|
584
|
+
case GeneratorDecl:
|
|
585
|
+
this.generateGenerator(prisma, decl);
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return this.PRELUDE + prisma.toString();
|
|
590
|
+
}
|
|
591
|
+
generateDataSource(prisma, dataSource) {
|
|
592
|
+
const fields = dataSource.fields.map((f) => ({
|
|
593
|
+
name: f.name,
|
|
594
|
+
text: this.configExprToText(f.value)
|
|
595
|
+
}));
|
|
596
|
+
prisma.addDataSource(dataSource.name, fields);
|
|
597
|
+
}
|
|
598
|
+
configExprToText(expr) {
|
|
599
|
+
if (isLiteralExpr2(expr)) {
|
|
600
|
+
return this.literalToText(expr);
|
|
601
|
+
} else if (isInvocationExpr(expr)) {
|
|
602
|
+
const fc = this.makeFunctionCall(expr);
|
|
603
|
+
return fc.toString();
|
|
604
|
+
} else {
|
|
605
|
+
return this.configArrayToText(expr);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
configArrayToText(expr) {
|
|
609
|
+
return "[" + expr.items.map((item) => {
|
|
610
|
+
if (isLiteralExpr2(item)) {
|
|
611
|
+
return this.literalToText(item);
|
|
612
|
+
} else {
|
|
613
|
+
return item.name + (item.args.length > 0 ? "(" + item.args.map((arg) => this.configInvocationArgToText(arg)).join(", ") + ")" : "");
|
|
614
|
+
}
|
|
615
|
+
}).join(", ") + "]";
|
|
616
|
+
}
|
|
617
|
+
configInvocationArgToText(arg) {
|
|
618
|
+
return `${arg.name}: ${this.literalToText(arg.value)}`;
|
|
619
|
+
}
|
|
620
|
+
literalToText(expr) {
|
|
621
|
+
return JSON.stringify(expr.value);
|
|
622
|
+
}
|
|
623
|
+
generateGenerator(prisma, decl) {
|
|
624
|
+
prisma.addGenerator(decl.name, decl.fields.map((f) => ({
|
|
625
|
+
name: f.name,
|
|
626
|
+
text: this.configExprToText(f.value)
|
|
627
|
+
})));
|
|
628
|
+
}
|
|
629
|
+
generateModel(prisma, decl) {
|
|
630
|
+
const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
|
|
631
|
+
for (const field of decl.fields) {
|
|
632
|
+
if (model_utils_exports.hasAttribute(field, "@computed")) {
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
this.generateModelField(model, field);
|
|
636
|
+
}
|
|
637
|
+
for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
|
|
638
|
+
this.generateContainerAttribute(model, attr);
|
|
639
|
+
}
|
|
640
|
+
decl.comments.forEach((c) => model.addComment(c));
|
|
641
|
+
}
|
|
642
|
+
isPrismaAttribute(attr) {
|
|
643
|
+
if (!attr.decl.ref) {
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
return attr.decl.ref.attributes.some((a) => a.decl.ref?.name === "@@@prisma");
|
|
647
|
+
}
|
|
648
|
+
getUnsupportedFieldType(fieldType) {
|
|
649
|
+
if (fieldType.unsupported) {
|
|
650
|
+
const value = this.getStringLiteral(fieldType.unsupported.value);
|
|
651
|
+
if (value) {
|
|
652
|
+
return `Unsupported("${value}")`;
|
|
653
|
+
} else {
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
} else {
|
|
657
|
+
return void 0;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
getStringLiteral(node) {
|
|
661
|
+
return isStringLiteral(node) ? node.value : void 0;
|
|
662
|
+
}
|
|
663
|
+
generateModelField(model, field, addToFront = false) {
|
|
664
|
+
let fieldType;
|
|
665
|
+
if (field.type.type) {
|
|
666
|
+
fieldType = field.type.type;
|
|
667
|
+
} else if (field.type.reference?.ref) {
|
|
668
|
+
if (isTypeDef(field.type.reference.ref)) {
|
|
669
|
+
fieldType = "Json";
|
|
670
|
+
} else {
|
|
671
|
+
fieldType = field.type.reference.ref.name;
|
|
672
|
+
}
|
|
673
|
+
} else {
|
|
674
|
+
const unsupported = this.getUnsupportedFieldType(field.type);
|
|
675
|
+
if (unsupported) {
|
|
676
|
+
fieldType = unsupported;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (!fieldType) {
|
|
680
|
+
throw new Error(`Field type is not resolved: ${field.$container.name}.${field.name}`);
|
|
681
|
+
}
|
|
682
|
+
const isArray = (
|
|
683
|
+
// typed-JSON fields should be translated to scalar Json type
|
|
684
|
+
isTypeDef(field.type.reference?.ref) ? false : field.type.array
|
|
685
|
+
);
|
|
686
|
+
const type = new ModelFieldType(fieldType, isArray, field.type.optional);
|
|
687
|
+
const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
|
|
688
|
+
// when building physical schema, exclude `@default` for id fields inherited from delegate base
|
|
689
|
+
!(model_utils_exports.isIdField(field) && this.isInheritedFromDelegate(field) && attr.decl.$refText === "@default")
|
|
690
|
+
)).map((attr) => this.makeFieldAttribute(attr));
|
|
691
|
+
const docs = [
|
|
692
|
+
...field.comments
|
|
693
|
+
];
|
|
694
|
+
const result = model.addField(field.name, type, attributes, docs, addToFront);
|
|
695
|
+
return result;
|
|
696
|
+
}
|
|
697
|
+
isDefaultWithPluginInvocation(attr) {
|
|
698
|
+
if (attr.decl.ref?.name !== "@default") {
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
const expr = attr.args[0]?.value;
|
|
702
|
+
if (!expr) {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
return AstUtils.streamAst(expr).some((node) => isInvocationExpr(node) && this.isFromPlugin(node.function.ref));
|
|
706
|
+
}
|
|
707
|
+
isFromPlugin(node) {
|
|
708
|
+
const model = AstUtils.getContainerOfType(node, isModel2);
|
|
709
|
+
return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
|
|
710
|
+
}
|
|
711
|
+
setDummyDefault(result, field) {
|
|
712
|
+
const dummyDefaultValue = match(field.type.type).with("String", () => new AttributeArgValue("String", "")).with(P.union("Int", "BigInt", "Float", "Decimal"), () => new AttributeArgValue("Number", "0")).with("Boolean", () => new AttributeArgValue("Boolean", "false")).with("DateTime", () => new AttributeArgValue("FunctionCall", new FunctionCall("now"))).with("Json", () => new AttributeArgValue("String", "{}")).with("Bytes", () => new AttributeArgValue("String", "")).otherwise(() => {
|
|
713
|
+
throw new Error(`Unsupported field type with default value: ${field.type.type}`);
|
|
714
|
+
});
|
|
715
|
+
result.attributes.push(new FieldAttribute("@default", [
|
|
716
|
+
new AttributeArg(void 0, dummyDefaultValue)
|
|
717
|
+
]));
|
|
718
|
+
}
|
|
719
|
+
isInheritedFromDelegate(field) {
|
|
720
|
+
return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
|
|
721
|
+
}
|
|
722
|
+
makeFieldAttribute(attr) {
|
|
723
|
+
const attrName = attr.decl.ref.name;
|
|
724
|
+
return new FieldAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg)));
|
|
725
|
+
}
|
|
726
|
+
makeAttributeArg(arg) {
|
|
727
|
+
return new AttributeArg(arg.name, this.makeAttributeArgValue(arg.value));
|
|
728
|
+
}
|
|
729
|
+
makeAttributeArgValue(node) {
|
|
730
|
+
if (isLiteralExpr2(node)) {
|
|
731
|
+
const argType = match(node.$type).with(StringLiteral, () => "String").with(NumberLiteral, () => "Number").with(BooleanLiteral, () => "Boolean").exhaustive();
|
|
732
|
+
return new AttributeArgValue(argType, node.value);
|
|
733
|
+
} else if (isArrayExpr2(node)) {
|
|
734
|
+
return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
|
|
735
|
+
} else if (isReferenceExpr2(node)) {
|
|
736
|
+
return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
|
|
737
|
+
} else if (isInvocationExpr(node)) {
|
|
738
|
+
return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
|
|
739
|
+
} else {
|
|
740
|
+
throw Error(`Unsupported attribute argument expression type: ${node.$type}`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
exprToText(expr) {
|
|
744
|
+
return new ZModelCodeGenerator({
|
|
745
|
+
quote: "double"
|
|
746
|
+
}).generate(expr);
|
|
747
|
+
}
|
|
748
|
+
makeFunctionCall(node) {
|
|
749
|
+
return new FunctionCall(node.function.ref.name, node.args.map((arg) => {
|
|
750
|
+
const val = match(arg.value).when(isStringLiteral, (v) => `"${v.value}"`).when(isLiteralExpr2, (v) => v.value.toString()).when(isNullExpr, () => "null").otherwise(() => {
|
|
751
|
+
throw new Error("Function call argument must be literal or null");
|
|
752
|
+
});
|
|
753
|
+
return new FunctionCallArg(val);
|
|
754
|
+
}));
|
|
755
|
+
}
|
|
756
|
+
generateContainerAttribute(container, attr) {
|
|
757
|
+
const attrName = attr.decl.ref.name;
|
|
758
|
+
container.attributes.push(new ContainerAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg))));
|
|
759
|
+
}
|
|
760
|
+
generateEnum(prisma, decl) {
|
|
761
|
+
const _enum = prisma.addEnum(decl.name);
|
|
762
|
+
for (const field of decl.fields) {
|
|
763
|
+
this.generateEnumField(_enum, field);
|
|
764
|
+
}
|
|
765
|
+
for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
|
|
766
|
+
this.generateContainerAttribute(_enum, attr);
|
|
767
|
+
}
|
|
768
|
+
decl.comments.forEach((c) => _enum.addComment(c));
|
|
769
|
+
}
|
|
770
|
+
generateEnumField(_enum, field) {
|
|
771
|
+
const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).map((attr) => this.makeFieldAttribute(attr));
|
|
772
|
+
const docs = [
|
|
773
|
+
...field.comments
|
|
774
|
+
];
|
|
775
|
+
_enum.addField(field.name, attributes, docs);
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// src/ts-schema-generator.ts
|
|
780
|
+
import { loadDocument } from "@zenstackhq/language";
|
|
781
|
+
import { isArrayExpr as isArrayExpr3, isBinaryExpr, isDataModel as isDataModel2, isDataModelField, isDataSource, isEnum, isEnumField, isInvocationExpr as isInvocationExpr2, isLiteralExpr as isLiteralExpr3, isMemberAccessExpr, isNullExpr as isNullExpr2, isProcedure, isReferenceExpr as isReferenceExpr3, isThisExpr, isUnaryExpr } from "@zenstackhq/language/ast";
|
|
782
|
+
import fs from "node:fs";
|
|
783
|
+
import path from "node:path";
|
|
784
|
+
import invariant from "tiny-invariant";
|
|
785
|
+
import { match as match2 } from "ts-pattern";
|
|
786
|
+
import * as ts from "typescript";
|
|
787
|
+
var TsSchemaGenerator = class {
|
|
788
|
+
static {
|
|
789
|
+
__name(this, "TsSchemaGenerator");
|
|
790
|
+
}
|
|
791
|
+
async generate(schemaFile, pluginModelFiles, outputFile) {
|
|
792
|
+
const loaded = await loadDocument(schemaFile, pluginModelFiles);
|
|
793
|
+
if (!loaded.success) {
|
|
794
|
+
throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
|
|
795
|
+
}
|
|
796
|
+
const { model, warnings } = loaded;
|
|
797
|
+
const statements = [];
|
|
798
|
+
this.generateSchemaStatements(model, statements);
|
|
799
|
+
this.generateBannerComments(statements);
|
|
800
|
+
const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
801
|
+
const printer = ts.createPrinter();
|
|
802
|
+
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
803
|
+
fs.mkdirSync(path.dirname(outputFile), {
|
|
804
|
+
recursive: true
|
|
805
|
+
});
|
|
806
|
+
fs.writeFileSync(outputFile, result);
|
|
807
|
+
return {
|
|
808
|
+
model,
|
|
809
|
+
warnings
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
generateSchemaStatements(model, statements) {
|
|
813
|
+
const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
|
|
814
|
+
const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
815
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
|
|
816
|
+
...hasComputedFields ? [
|
|
817
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("OperandExpression"))
|
|
818
|
+
] : [],
|
|
819
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
|
|
820
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
|
|
821
|
+
statements.push(runtimeImportDecl);
|
|
822
|
+
const { type: providerType } = this.getDataSourceProvider(model);
|
|
823
|
+
switch (providerType) {
|
|
824
|
+
case "sqlite": {
|
|
825
|
+
const pathImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("path"), void 0), ts.factory.createStringLiteral("node:path"));
|
|
826
|
+
statements.push(pathImportDecl);
|
|
827
|
+
const urlImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("url"), void 0), ts.factory.createStringLiteral("node:url"));
|
|
828
|
+
statements.push(urlImportDecl);
|
|
829
|
+
const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
830
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
|
|
831
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/sqlite-utils"));
|
|
832
|
+
statements.push(dialectConfigImportDecl);
|
|
833
|
+
break;
|
|
834
|
+
}
|
|
835
|
+
case "postgresql": {
|
|
836
|
+
const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
837
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
|
|
838
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/pg-utils"));
|
|
839
|
+
statements.push(dialectConfigImportDecl);
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
const declaration = ts.factory.createVariableStatement([
|
|
844
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
845
|
+
], ts.factory.createVariableDeclarationList([
|
|
846
|
+
ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createSatisfiesExpression(ts.factory.createAsExpression(this.createSchemaObject(model), ts.factory.createTypeReferenceNode("const")), ts.factory.createTypeReferenceNode("SchemaDef")))
|
|
847
|
+
], ts.NodeFlags.Const));
|
|
848
|
+
statements.push(declaration);
|
|
849
|
+
const typeDeclaration = ts.factory.createTypeAliasDeclaration([
|
|
850
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
851
|
+
], "SchemaType", void 0, ts.factory.createTypeReferenceNode("typeof schema"));
|
|
852
|
+
statements.push(typeDeclaration);
|
|
853
|
+
}
|
|
854
|
+
createSchemaObject(model) {
|
|
855
|
+
const properties = [
|
|
856
|
+
// provider
|
|
857
|
+
ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
|
|
858
|
+
// models
|
|
859
|
+
ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
|
|
860
|
+
];
|
|
861
|
+
const enums = model.declarations.filter(isEnum);
|
|
862
|
+
if (enums.length > 0) {
|
|
863
|
+
properties.push(ts.factory.createPropertyAssignment("enums", ts.factory.createObjectLiteralExpression(enums.map((e) => ts.factory.createPropertyAssignment(e.name, this.createEnumObject(e))), true)));
|
|
864
|
+
}
|
|
865
|
+
const authType = getAuthDecl(model);
|
|
866
|
+
if (authType) {
|
|
867
|
+
properties.push(ts.factory.createPropertyAssignment("authType", this.createLiteralNode(authType.name)));
|
|
868
|
+
}
|
|
869
|
+
const procedures = model.declarations.filter(isProcedure);
|
|
870
|
+
if (procedures.length > 0) {
|
|
871
|
+
properties.push(ts.factory.createPropertyAssignment("procedures", this.createProceduresObject(procedures)));
|
|
872
|
+
}
|
|
873
|
+
properties.push(ts.factory.createPropertyAssignment("plugins", ts.factory.createObjectLiteralExpression([], true)));
|
|
874
|
+
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
875
|
+
}
|
|
876
|
+
createProviderObject(model) {
|
|
877
|
+
const dsProvider = this.getDataSourceProvider(model);
|
|
878
|
+
return ts.factory.createObjectLiteralExpression([
|
|
879
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type)),
|
|
880
|
+
ts.factory.createPropertyAssignment("dialectConfigProvider", this.createDialectConfigProvider(dsProvider))
|
|
881
|
+
], true);
|
|
882
|
+
}
|
|
883
|
+
createModelsObject(model) {
|
|
884
|
+
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel2(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
|
|
885
|
+
}
|
|
886
|
+
createDataModelObject(dm) {
|
|
887
|
+
const fields = [
|
|
888
|
+
// fields
|
|
889
|
+
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(dm.fields.filter((field) => !hasAttribute(field, "@ignore")).map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataModelFieldObject(field))), true)),
|
|
890
|
+
// attributes
|
|
891
|
+
...dm.attributes.length > 0 ? [
|
|
892
|
+
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
|
|
893
|
+
] : [],
|
|
894
|
+
// idFields
|
|
895
|
+
ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
|
|
896
|
+
// uniqueFields
|
|
897
|
+
ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
|
|
898
|
+
];
|
|
899
|
+
const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
|
|
900
|
+
if (computedFields.length > 0) {
|
|
901
|
+
fields.push(ts.factory.createPropertyAssignment("computedFields", this.createComputedFieldsObject(computedFields)));
|
|
902
|
+
}
|
|
903
|
+
return ts.factory.createObjectLiteralExpression(fields, true);
|
|
904
|
+
}
|
|
905
|
+
createComputedFieldsObject(fields) {
|
|
906
|
+
return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
|
|
907
|
+
ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
|
|
908
|
+
]), ts.factory.createBlock([
|
|
909
|
+
ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
|
|
910
|
+
ts.factory.createStringLiteral("This is a stub for computed field")
|
|
911
|
+
]))
|
|
912
|
+
], true))), true);
|
|
913
|
+
}
|
|
914
|
+
mapTypeToTSSyntaxKeyword(type) {
|
|
915
|
+
return match2(type).with("String", () => ts.SyntaxKind.StringKeyword).with("Boolean", () => ts.SyntaxKind.BooleanKeyword).with("Int", () => ts.SyntaxKind.NumberKeyword).with("Float", () => ts.SyntaxKind.NumberKeyword).with("BigInt", () => ts.SyntaxKind.BigIntKeyword).with("Decimal", () => ts.SyntaxKind.NumberKeyword).otherwise(() => ts.SyntaxKind.UnknownKeyword);
|
|
916
|
+
}
|
|
917
|
+
createDataModelFieldObject(field) {
|
|
918
|
+
const objectFields = [
|
|
919
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
|
|
920
|
+
];
|
|
921
|
+
if (isIdField(field)) {
|
|
922
|
+
objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
|
|
923
|
+
}
|
|
924
|
+
if (isUniqueField(field)) {
|
|
925
|
+
objectFields.push(ts.factory.createPropertyAssignment("unique", ts.factory.createTrue()));
|
|
926
|
+
}
|
|
927
|
+
if (field.type.optional) {
|
|
928
|
+
objectFields.push(ts.factory.createPropertyAssignment("optional", ts.factory.createTrue()));
|
|
929
|
+
}
|
|
930
|
+
if (field.type.array) {
|
|
931
|
+
objectFields.push(ts.factory.createPropertyAssignment("array", ts.factory.createTrue()));
|
|
932
|
+
}
|
|
933
|
+
if (hasAttribute(field, "@updatedAt")) {
|
|
934
|
+
objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
|
|
935
|
+
}
|
|
936
|
+
if (field.attributes.length > 0) {
|
|
937
|
+
objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
|
|
938
|
+
}
|
|
939
|
+
const defaultValue = this.getMappedDefault(field);
|
|
940
|
+
if (defaultValue !== void 0) {
|
|
941
|
+
if (typeof defaultValue === "object") {
|
|
942
|
+
if ("call" in defaultValue) {
|
|
943
|
+
objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
|
|
944
|
+
ts.factory.createStringLiteral(defaultValue.call),
|
|
945
|
+
...defaultValue.args.length > 0 ? [
|
|
946
|
+
ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createLiteralNode(arg)))
|
|
947
|
+
] : []
|
|
948
|
+
])));
|
|
949
|
+
} else if ("authMember" in defaultValue) {
|
|
950
|
+
objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, [
|
|
951
|
+
ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
|
|
952
|
+
ts.factory.createStringLiteral("auth")
|
|
953
|
+
]),
|
|
954
|
+
ts.factory.createArrayLiteralExpression(defaultValue.authMember.map((m) => ts.factory.createStringLiteral(m)))
|
|
955
|
+
])));
|
|
956
|
+
} else {
|
|
957
|
+
throw new Error(`Unsupported default value type for field ${field.name}`);
|
|
958
|
+
}
|
|
959
|
+
} else {
|
|
960
|
+
objectFields.push(ts.factory.createPropertyAssignment("default", typeof defaultValue === "string" ? ts.factory.createStringLiteral(defaultValue) : typeof defaultValue === "number" ? ts.factory.createNumericLiteral(defaultValue) : defaultValue === true ? ts.factory.createTrue() : ts.factory.createFalse()));
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
if (hasAttribute(field, "@computed")) {
|
|
964
|
+
objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
|
|
965
|
+
}
|
|
966
|
+
if (isDataModel2(field.type.reference?.ref)) {
|
|
967
|
+
objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
|
|
968
|
+
}
|
|
969
|
+
const fkFor = this.getForeignKeyFor(field);
|
|
970
|
+
if (fkFor && fkFor.length > 0) {
|
|
971
|
+
objectFields.push(ts.factory.createPropertyAssignment("foreignKeyFor", ts.factory.createArrayLiteralExpression(fkFor.map((fk) => ts.factory.createStringLiteral(fk)), true)));
|
|
972
|
+
}
|
|
973
|
+
return ts.factory.createObjectLiteralExpression(objectFields, true);
|
|
974
|
+
}
|
|
975
|
+
getDataSourceProvider(model) {
|
|
976
|
+
const dataSource = model.declarations.find(isDataSource);
|
|
977
|
+
invariant(dataSource, "No data source found in the model");
|
|
978
|
+
const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
|
|
979
|
+
invariant(isLiteralExpr3(providerExpr), "Provider must be a literal");
|
|
980
|
+
const type = providerExpr.value;
|
|
981
|
+
const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
|
|
982
|
+
invariant(isLiteralExpr3(urlExpr) || isInvocationExpr2(urlExpr), "URL must be a literal or env function");
|
|
983
|
+
if (isLiteralExpr3(urlExpr)) {
|
|
984
|
+
return {
|
|
985
|
+
type,
|
|
986
|
+
url: urlExpr.value,
|
|
987
|
+
env: void 0
|
|
988
|
+
};
|
|
989
|
+
} else if (isInvocationExpr2(urlExpr)) {
|
|
990
|
+
invariant(urlExpr.function.$refText === "env", 'only "env" function is supported');
|
|
991
|
+
invariant(urlExpr.args.length === 1, "env function must have one argument");
|
|
992
|
+
return {
|
|
993
|
+
type,
|
|
994
|
+
env: urlExpr.args[0].value.value,
|
|
995
|
+
url: void 0
|
|
996
|
+
};
|
|
997
|
+
} else {
|
|
998
|
+
throw new Error("Unsupported URL type");
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
getMappedDefault(field) {
|
|
1002
|
+
const defaultAttr = getAttribute(field, "@default");
|
|
1003
|
+
if (!defaultAttr) {
|
|
1004
|
+
return void 0;
|
|
1005
|
+
}
|
|
1006
|
+
const defaultValue = defaultAttr.args[0]?.value;
|
|
1007
|
+
invariant(defaultValue, "Expected a default value");
|
|
1008
|
+
if (isLiteralExpr3(defaultValue)) {
|
|
1009
|
+
const lit = defaultValue.value;
|
|
1010
|
+
return field.type.type === "Boolean" ? lit : [
|
|
1011
|
+
"Int",
|
|
1012
|
+
"Float",
|
|
1013
|
+
"Decimal",
|
|
1014
|
+
"BigInt"
|
|
1015
|
+
].includes(field.type.type) ? Number(lit) : lit;
|
|
1016
|
+
} else if (isReferenceExpr3(defaultValue) && isEnumField(defaultValue.target.ref)) {
|
|
1017
|
+
return defaultValue.target.ref.name;
|
|
1018
|
+
} else if (isInvocationExpr2(defaultValue)) {
|
|
1019
|
+
return {
|
|
1020
|
+
call: defaultValue.function.$refText,
|
|
1021
|
+
args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
|
|
1022
|
+
};
|
|
1023
|
+
} else if (this.isAuthMemberAccess(defaultValue)) {
|
|
1024
|
+
return {
|
|
1025
|
+
authMember: this.getMemberAccessChain(defaultValue)
|
|
1026
|
+
};
|
|
1027
|
+
} else {
|
|
1028
|
+
throw new Error(`Unsupported default value type for field ${field.name}`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
getMemberAccessChain(expr) {
|
|
1032
|
+
if (!isMemberAccessExpr(expr.operand)) {
|
|
1033
|
+
return [
|
|
1034
|
+
expr.member.$refText
|
|
1035
|
+
];
|
|
1036
|
+
} else {
|
|
1037
|
+
return [
|
|
1038
|
+
...this.getMemberAccessChain(expr.operand),
|
|
1039
|
+
expr.member.$refText
|
|
1040
|
+
];
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
isAuthMemberAccess(expr) {
|
|
1044
|
+
if (isMemberAccessExpr(expr)) {
|
|
1045
|
+
return this.isAuthInvocation(expr.operand) || this.isAuthMemberAccess(expr.operand);
|
|
1046
|
+
} else {
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
isAuthInvocation(expr) {
|
|
1051
|
+
return isInvocationExpr2(expr) && expr.function.$refText === "auth" && model_utils_exports.isFromStdlib(expr.function.ref);
|
|
1052
|
+
}
|
|
1053
|
+
createRelationObject(field) {
|
|
1054
|
+
const relationFields = [];
|
|
1055
|
+
const oppositeRelation = this.getOppositeRelationField(field);
|
|
1056
|
+
if (oppositeRelation) {
|
|
1057
|
+
relationFields.push(ts.factory.createPropertyAssignment("opposite", ts.factory.createStringLiteral(oppositeRelation.name)));
|
|
1058
|
+
}
|
|
1059
|
+
const relationName = this.getRelationName(field);
|
|
1060
|
+
if (relationName) {
|
|
1061
|
+
relationFields.push(ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(relationName)));
|
|
1062
|
+
}
|
|
1063
|
+
const relation = getAttribute(field, "@relation");
|
|
1064
|
+
if (relation) {
|
|
1065
|
+
for (const arg of relation.args) {
|
|
1066
|
+
const param = arg.$resolvedParam.name;
|
|
1067
|
+
if (param === "fields" || param === "references") {
|
|
1068
|
+
const fieldNames = this.getReferenceNames(arg.value);
|
|
1069
|
+
if (fieldNames) {
|
|
1070
|
+
relationFields.push(ts.factory.createPropertyAssignment(param, ts.factory.createArrayLiteralExpression(fieldNames.map((el) => ts.factory.createStringLiteral(el)))));
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
if (param === "onDelete" || param === "onUpdate") {
|
|
1074
|
+
const action = arg.value.target.$refText;
|
|
1075
|
+
relationFields.push(ts.factory.createPropertyAssignment(param, ts.factory.createStringLiteral(action)));
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
return ts.factory.createObjectLiteralExpression(relationFields);
|
|
1080
|
+
}
|
|
1081
|
+
getReferenceNames(expr) {
|
|
1082
|
+
return isArrayExpr3(expr) && expr.items.map((item) => item.target.$refText);
|
|
1083
|
+
}
|
|
1084
|
+
getForeignKeyFor(field) {
|
|
1085
|
+
const result = [];
|
|
1086
|
+
for (const f of field.$container.fields) {
|
|
1087
|
+
const relation = getAttribute(f, "@relation");
|
|
1088
|
+
if (relation) {
|
|
1089
|
+
for (const arg of relation.args) {
|
|
1090
|
+
if (arg.name === "fields" && isArrayExpr3(arg.value) && arg.value.items.some((el) => isReferenceExpr3(el) && el.target.ref === field)) {
|
|
1091
|
+
result.push(f.name);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
return result;
|
|
1097
|
+
}
|
|
1098
|
+
getOppositeRelationField(field) {
|
|
1099
|
+
if (!field.type.reference?.ref || !isDataModel2(field.type.reference?.ref)) {
|
|
1100
|
+
return void 0;
|
|
1101
|
+
}
|
|
1102
|
+
const sourceModel = field.$container;
|
|
1103
|
+
const targetModel = field.type.reference.ref;
|
|
1104
|
+
const relationName = this.getRelationName(field);
|
|
1105
|
+
for (const otherField of targetModel.fields) {
|
|
1106
|
+
if (otherField === field) {
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
if (otherField.type.reference?.ref === sourceModel) {
|
|
1110
|
+
if (relationName) {
|
|
1111
|
+
const otherRelationName = this.getRelationName(otherField);
|
|
1112
|
+
if (otherRelationName === relationName) {
|
|
1113
|
+
return otherField;
|
|
1114
|
+
}
|
|
1115
|
+
} else {
|
|
1116
|
+
return otherField;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
return void 0;
|
|
1121
|
+
}
|
|
1122
|
+
getRelationName(field) {
|
|
1123
|
+
const relation = getAttribute(field, "@relation");
|
|
1124
|
+
if (relation) {
|
|
1125
|
+
const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
|
|
1126
|
+
if (nameArg) {
|
|
1127
|
+
invariant(isLiteralExpr3(nameArg.value), "name must be a literal");
|
|
1128
|
+
return nameArg.value.value;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return void 0;
|
|
1132
|
+
}
|
|
1133
|
+
getIdFields(dm) {
|
|
1134
|
+
return dm.fields.filter(isIdField).map((f) => f.name);
|
|
1135
|
+
}
|
|
1136
|
+
createUniqueFieldsObject(dm) {
|
|
1137
|
+
const properties = [];
|
|
1138
|
+
for (const field of dm.fields) {
|
|
1139
|
+
if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
|
|
1140
|
+
properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
|
|
1141
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
|
|
1142
|
+
])));
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
for (const attr of dm.attributes) {
|
|
1146
|
+
if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
|
|
1147
|
+
const fieldNames = this.getReferenceNames(attr.args[0].value);
|
|
1148
|
+
if (!fieldNames) {
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
if (fieldNames.length === 1) {
|
|
1152
|
+
const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
|
|
1153
|
+
properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
|
|
1154
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
|
|
1155
|
+
])));
|
|
1156
|
+
} else {
|
|
1157
|
+
properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
|
|
1158
|
+
const fieldDef = dm.fields.find((f) => f.name === field);
|
|
1159
|
+
return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
|
|
1160
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
|
|
1161
|
+
]));
|
|
1162
|
+
}))));
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
1167
|
+
}
|
|
1168
|
+
createEnumObject(e) {
|
|
1169
|
+
return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
|
|
1170
|
+
}
|
|
1171
|
+
getLiteral(expr) {
|
|
1172
|
+
if (!isLiteralExpr3(expr)) {
|
|
1173
|
+
throw new Error("Expected a literal expression");
|
|
1174
|
+
}
|
|
1175
|
+
switch (expr?.$type) {
|
|
1176
|
+
case "StringLiteral":
|
|
1177
|
+
case "BooleanLiteral":
|
|
1178
|
+
return expr.value;
|
|
1179
|
+
case "NumberLiteral":
|
|
1180
|
+
return parseFloat(expr.value);
|
|
1181
|
+
default:
|
|
1182
|
+
throw new Error("Unsupported literal type");
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
createLiteralNode(arg) {
|
|
1186
|
+
return arg === null ? ts.factory.createNull() : typeof arg === "string" ? ts.factory.createStringLiteral(arg) : typeof arg === "number" ? ts.factory.createNumericLiteral(arg) : arg === true ? ts.factory.createTrue() : arg === false ? ts.factory.createFalse() : void 0;
|
|
1187
|
+
}
|
|
1188
|
+
createDialectConfigProvider(dsProvider) {
|
|
1189
|
+
const type = dsProvider.type;
|
|
1190
|
+
let urlExpr;
|
|
1191
|
+
if (dsProvider.env !== void 0) {
|
|
1192
|
+
urlExpr = ts.factory.createIdentifier(`process.env['${dsProvider.env}']`);
|
|
1193
|
+
} else {
|
|
1194
|
+
urlExpr = ts.factory.createStringLiteral(dsProvider.url);
|
|
1195
|
+
if (type === "sqlite") {
|
|
1196
|
+
let parsedUrl;
|
|
1197
|
+
try {
|
|
1198
|
+
parsedUrl = new URL(dsProvider.url);
|
|
1199
|
+
} catch {
|
|
1200
|
+
}
|
|
1201
|
+
if (parsedUrl) {
|
|
1202
|
+
if (parsedUrl.protocol !== "file:") {
|
|
1203
|
+
throw new Error("Invalid SQLite URL: only file protocol is supported");
|
|
1204
|
+
}
|
|
1205
|
+
urlExpr = ts.factory.createStringLiteral(dsProvider.url.replace(/^file:/, ""));
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
return match2(type).with("sqlite", () => {
|
|
1210
|
+
return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
|
|
1211
|
+
ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
|
|
1212
|
+
urlExpr,
|
|
1213
|
+
ts.factory.createIdentifier(`typeof __dirname !== 'undefined' ? __dirname : path.dirname(url.fileURLToPath(import.meta.url))`)
|
|
1214
|
+
]))
|
|
1215
|
+
], true));
|
|
1216
|
+
}).with("postgresql", () => {
|
|
1217
|
+
return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
|
|
1218
|
+
ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
|
|
1219
|
+
urlExpr
|
|
1220
|
+
]))
|
|
1221
|
+
], true));
|
|
1222
|
+
}).otherwise(() => {
|
|
1223
|
+
throw new Error(`Unsupported provider: ${type}`);
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
createProceduresObject(procedures) {
|
|
1227
|
+
return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
|
|
1228
|
+
}
|
|
1229
|
+
createProcedureObject(proc) {
|
|
1230
|
+
const params = ts.factory.createArrayLiteralExpression(proc.params.map((param) => ts.factory.createObjectLiteralExpression([
|
|
1231
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(param.name)),
|
|
1232
|
+
...param.optional ? [
|
|
1233
|
+
ts.factory.createPropertyAssignment("optional", ts.factory.createTrue())
|
|
1234
|
+
] : [],
|
|
1235
|
+
ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(param.type.type ?? param.type.reference.$refText))
|
|
1236
|
+
])), true);
|
|
1237
|
+
const paramsType = ts.factory.createTupleTypeNode([
|
|
1238
|
+
...proc.params.map((param) => ts.factory.createNamedTupleMember(void 0, ts.factory.createIdentifier(param.name), void 0, ts.factory.createTypeLiteralNode([
|
|
1239
|
+
ts.factory.createPropertySignature(void 0, ts.factory.createStringLiteral("name"), void 0, ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(param.name))),
|
|
1240
|
+
ts.factory.createPropertySignature(void 0, ts.factory.createStringLiteral("type"), void 0, ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(param.type.type ?? param.type.reference.$refText))),
|
|
1241
|
+
...param.optional ? [
|
|
1242
|
+
ts.factory.createPropertySignature(void 0, ts.factory.createStringLiteral("optional"), void 0, ts.factory.createLiteralTypeNode(ts.factory.createTrue()))
|
|
1243
|
+
] : []
|
|
1244
|
+
])))
|
|
1245
|
+
]);
|
|
1246
|
+
return ts.factory.createObjectLiteralExpression([
|
|
1247
|
+
ts.factory.createPropertyAssignment("params", ts.factory.createAsExpression(params, paramsType)),
|
|
1248
|
+
ts.factory.createPropertyAssignment("returnType", ts.factory.createStringLiteral(proc.returnType.type ?? proc.returnType.reference.$refText)),
|
|
1249
|
+
...proc.mutation ? [
|
|
1250
|
+
ts.factory.createPropertyAssignment("mutation", ts.factory.createTrue())
|
|
1251
|
+
] : []
|
|
1252
|
+
], true);
|
|
1253
|
+
}
|
|
1254
|
+
generateBannerComments(statements) {
|
|
1255
|
+
const banner = `////////////////////////////////////////////////////////////////////////////////////////////
|
|
1256
|
+
// DO NOT MODIFY THIS FILE //
|
|
1257
|
+
// This file is automatically generated by ZenStack CLI and should not be manually updated. //
|
|
1258
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
1259
|
+
|
|
1260
|
+
`;
|
|
1261
|
+
ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
|
|
1262
|
+
}
|
|
1263
|
+
createAttributeObject(attr) {
|
|
1264
|
+
return ts.factory.createObjectLiteralExpression([
|
|
1265
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(attr.decl.$refText)),
|
|
1266
|
+
...attr.args.length > 0 ? [
|
|
1267
|
+
ts.factory.createPropertyAssignment("args", ts.factory.createArrayLiteralExpression(attr.args.map((arg) => this.createAttributeArg(arg))))
|
|
1268
|
+
] : []
|
|
1269
|
+
]);
|
|
1270
|
+
}
|
|
1271
|
+
createAttributeArg(arg) {
|
|
1272
|
+
return ts.factory.createObjectLiteralExpression([
|
|
1273
|
+
// name
|
|
1274
|
+
...arg.$resolvedParam?.name ? [
|
|
1275
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(arg.$resolvedParam.name))
|
|
1276
|
+
] : [],
|
|
1277
|
+
// value
|
|
1278
|
+
ts.factory.createPropertyAssignment("value", this.createExpression(arg.value))
|
|
1279
|
+
]);
|
|
1280
|
+
}
|
|
1281
|
+
createExpression(value) {
|
|
1282
|
+
return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(isReferenceExpr3, (expr) => this.createRefExpression(expr)).when(isArrayExpr3, (expr) => this.createArrayExpression(expr)).when(isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(isNullExpr2, () => this.createNullExpression()).when(isThisExpr, () => this.createThisExpression()).otherwise(() => {
|
|
1283
|
+
throw new Error(`Unsupported attribute arg value: ${value.$type}`);
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
createThisExpression() {
|
|
1287
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._this"), void 0, []);
|
|
1288
|
+
}
|
|
1289
|
+
createMemberExpression(expr) {
|
|
1290
|
+
const members = [];
|
|
1291
|
+
let current = expr;
|
|
1292
|
+
while (isMemberAccessExpr(current)) {
|
|
1293
|
+
members.unshift(current.member.$refText);
|
|
1294
|
+
current = current.operand;
|
|
1295
|
+
}
|
|
1296
|
+
const receiver = current;
|
|
1297
|
+
const args = [
|
|
1298
|
+
this.createExpression(receiver),
|
|
1299
|
+
ts.factory.createArrayLiteralExpression(members.map((m) => ts.factory.createStringLiteral(m)))
|
|
1300
|
+
];
|
|
1301
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, args);
|
|
1302
|
+
}
|
|
1303
|
+
createNullExpression() {
|
|
1304
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._null"), void 0, []);
|
|
1305
|
+
}
|
|
1306
|
+
createBinaryExpression(expr) {
|
|
1307
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.binary"), void 0, [
|
|
1308
|
+
this.createExpression(expr.left),
|
|
1309
|
+
this.createLiteralNode(expr.operator),
|
|
1310
|
+
this.createExpression(expr.right)
|
|
1311
|
+
]);
|
|
1312
|
+
}
|
|
1313
|
+
createUnaryExpression(expr) {
|
|
1314
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.unary"), void 0, [
|
|
1315
|
+
this.createLiteralNode(expr.operator),
|
|
1316
|
+
this.createExpression(expr.operand)
|
|
1317
|
+
]);
|
|
1318
|
+
}
|
|
1319
|
+
createArrayExpression(expr) {
|
|
1320
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.array"), void 0, [
|
|
1321
|
+
ts.factory.createArrayLiteralExpression(expr.items.map((item) => this.createExpression(item)))
|
|
1322
|
+
]);
|
|
1323
|
+
}
|
|
1324
|
+
createRefExpression(expr) {
|
|
1325
|
+
if (isDataModelField(expr.target.ref)) {
|
|
1326
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
|
|
1327
|
+
this.createLiteralNode(expr.target.$refText)
|
|
1328
|
+
]);
|
|
1329
|
+
} else if (isEnumField(expr.target.ref)) {
|
|
1330
|
+
return this.createLiteralExpression("StringLiteral", expr.target.$refText);
|
|
1331
|
+
} else {
|
|
1332
|
+
throw new Error(`Unsupported reference type: ${expr.target.$refText}`);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
createCallExpression(expr) {
|
|
1336
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
|
|
1337
|
+
ts.factory.createStringLiteral(expr.function.$refText),
|
|
1338
|
+
...expr.args.length > 0 ? [
|
|
1339
|
+
ts.factory.createArrayLiteralExpression(expr.args.map((arg) => this.createExpression(arg.value)))
|
|
1340
|
+
] : []
|
|
1341
|
+
]);
|
|
1342
|
+
}
|
|
1343
|
+
createLiteralExpression(type, value) {
|
|
1344
|
+
return match2(type).with("BooleanLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
|
|
1345
|
+
this.createLiteralNode(value)
|
|
1346
|
+
])).with("NumberLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
|
|
1347
|
+
ts.factory.createIdentifier(value)
|
|
1348
|
+
])).with("StringLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
|
|
1349
|
+
this.createLiteralNode(value)
|
|
1350
|
+
])).otherwise(() => {
|
|
1351
|
+
throw new Error(`Unsupported literal type: ${type}`);
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
// src/zmodel-code-generator.ts
|
|
1357
|
+
import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataModel as DataModel2, DataModelAttribute, DataModelField, DataModelFieldAttribute, DataSource as DataSource3, Enum as Enum3, EnumField as EnumField2, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl as GeneratorDecl2, InvocationExpr, LiteralExpr, MemberAccessExpr, Model as Model2, NullExpr, NumberLiteral as NumberLiteral2, ObjectExpr, Plugin, PluginField, ReferenceArg, ReferenceExpr, StringLiteral as StringLiteral2, ThisExpr, TypeDef, TypeDefField, UnaryExpr } from "@zenstackhq/language/ast";
|
|
1358
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
1359
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1360
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1361
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1362
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1363
|
+
}
|
|
1364
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
1365
|
+
function _ts_metadata(k, v) {
|
|
1366
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1367
|
+
}
|
|
1368
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
1369
|
+
var generationHandlers = /* @__PURE__ */ new Map();
|
|
1370
|
+
function gen(name) {
|
|
1371
|
+
return function(_target, _propertyKey, descriptor) {
|
|
1372
|
+
if (!generationHandlers.get(name)) {
|
|
1373
|
+
generationHandlers.set(name, descriptor);
|
|
1374
|
+
}
|
|
1375
|
+
return descriptor;
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
__name(gen, "gen");
|
|
1379
|
+
var ZModelCodeGenerator = class {
|
|
1380
|
+
static {
|
|
1381
|
+
__name(this, "ZModelCodeGenerator");
|
|
1382
|
+
}
|
|
1383
|
+
options;
|
|
1384
|
+
constructor(options) {
|
|
1385
|
+
this.options = {
|
|
1386
|
+
binaryExprNumberOfSpaces: options?.binaryExprNumberOfSpaces ?? 1,
|
|
1387
|
+
unaryExprNumberOfSpaces: options?.unaryExprNumberOfSpaces ?? 0,
|
|
1388
|
+
indent: options?.indent ?? 4,
|
|
1389
|
+
quote: options?.quote ?? "single"
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Generates ZModel source code from AST.
|
|
1394
|
+
*/
|
|
1395
|
+
generate(ast) {
|
|
1396
|
+
const handler = generationHandlers.get(ast.$type);
|
|
1397
|
+
if (!handler) {
|
|
1398
|
+
throw new Error(`No generation handler found for ${ast.$type}`);
|
|
1399
|
+
}
|
|
1400
|
+
return handler.value.call(this, ast);
|
|
1401
|
+
}
|
|
1402
|
+
_generateModel(ast) {
|
|
1403
|
+
return ast.declarations.map((d) => this.generate(d)).join("\n\n");
|
|
1404
|
+
}
|
|
1405
|
+
_generateDataSource(ast) {
|
|
1406
|
+
return `datasource ${ast.name} {
|
|
1407
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
1408
|
+
}`;
|
|
1409
|
+
}
|
|
1410
|
+
_generateEnum(ast) {
|
|
1411
|
+
return `enum ${ast.name} {
|
|
1412
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
1413
|
+
}`;
|
|
1414
|
+
}
|
|
1415
|
+
_generateEnumField(ast) {
|
|
1416
|
+
return `${ast.name}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1417
|
+
}
|
|
1418
|
+
_generateGenerator(ast) {
|
|
1419
|
+
return `generator ${ast.name} {
|
|
1420
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
1421
|
+
}`;
|
|
1422
|
+
}
|
|
1423
|
+
_generateConfigField(ast) {
|
|
1424
|
+
return `${ast.name} = ${this.generate(ast.value)}`;
|
|
1425
|
+
}
|
|
1426
|
+
_generateConfigArrayExpr(ast) {
|
|
1427
|
+
return `[${ast.items.map((x) => this.generate(x)).join(", ")}]`;
|
|
1428
|
+
}
|
|
1429
|
+
_generateConfigInvocationExpr(ast) {
|
|
1430
|
+
if (ast.args.length === 0) {
|
|
1431
|
+
return ast.name;
|
|
1432
|
+
} else {
|
|
1433
|
+
return `${ast.name}(${ast.args.map((x) => (x.name ? x.name + ": " : "") + this.generate(x.value)).join(", ")})`;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
_generatePlugin(ast) {
|
|
1437
|
+
return `plugin ${ast.name} {
|
|
1438
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
1439
|
+
}`;
|
|
1440
|
+
}
|
|
1441
|
+
_generatePluginField(ast) {
|
|
1442
|
+
return `${ast.name} = ${this.generate(ast.value)}`;
|
|
1443
|
+
}
|
|
1444
|
+
_generateDataModel(ast) {
|
|
1445
|
+
return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
|
|
1446
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attributes.length > 0 ? "\n\n" + ast.attributes.map((x) => this.indent + this.generate(x)).join("\n") : ""}
|
|
1447
|
+
}`;
|
|
1448
|
+
}
|
|
1449
|
+
_generateDataModelField(ast) {
|
|
1450
|
+
return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1451
|
+
}
|
|
1452
|
+
fieldType(type) {
|
|
1453
|
+
const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
|
|
1454
|
+
return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
|
|
1455
|
+
}
|
|
1456
|
+
_generateDataModelAttribute(ast) {
|
|
1457
|
+
return this.attribute(ast);
|
|
1458
|
+
}
|
|
1459
|
+
_generateDataModelFieldAttribute(ast) {
|
|
1460
|
+
return this.attribute(ast);
|
|
1461
|
+
}
|
|
1462
|
+
attribute(ast) {
|
|
1463
|
+
const args = ast.args.length ? `(${ast.args.map((x) => this.generate(x)).join(", ")})` : "";
|
|
1464
|
+
return `${resolved(ast.decl).name}${args}`;
|
|
1465
|
+
}
|
|
1466
|
+
_generateAttributeArg(ast) {
|
|
1467
|
+
if (ast.name) {
|
|
1468
|
+
return `${ast.name}: ${this.generate(ast.value)}`;
|
|
1469
|
+
} else {
|
|
1470
|
+
return this.generate(ast.value);
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
_generateObjectExpr(ast) {
|
|
1474
|
+
return `{ ${ast.fields.map((field) => this.objectField(field)).join(", ")} }`;
|
|
1475
|
+
}
|
|
1476
|
+
objectField(field) {
|
|
1477
|
+
return `${field.name}: ${this.generate(field.value)}`;
|
|
1478
|
+
}
|
|
1479
|
+
_generateArrayExpr(ast) {
|
|
1480
|
+
return `[${ast.items.map((item) => this.generate(item)).join(", ")}]`;
|
|
1481
|
+
}
|
|
1482
|
+
_generateLiteralExpr(ast) {
|
|
1483
|
+
return this.options.quote === "single" ? `'${ast.value}'` : `"${ast.value}"`;
|
|
1484
|
+
}
|
|
1485
|
+
_generateNumberLiteral(ast) {
|
|
1486
|
+
return ast.value.toString();
|
|
1487
|
+
}
|
|
1488
|
+
_generateBooleanLiteral(ast) {
|
|
1489
|
+
return ast.value.toString();
|
|
1490
|
+
}
|
|
1491
|
+
_generateUnaryExpr(ast) {
|
|
1492
|
+
return `${ast.operator}${this.unaryExprSpace}${this.generate(ast.operand)}`;
|
|
1493
|
+
}
|
|
1494
|
+
_generateBinaryExpr(ast) {
|
|
1495
|
+
const operator = ast.operator;
|
|
1496
|
+
const isCollectionPredicate = this.isCollectionPredicateOperator(operator);
|
|
1497
|
+
const rightExpr = this.generate(ast.right);
|
|
1498
|
+
const { left: isLeftParenthesis, right: isRightParenthesis } = this.isParenthesesNeededForBinaryExpr(ast);
|
|
1499
|
+
return `${isLeftParenthesis ? "(" : ""}${this.generate(ast.left)}${isLeftParenthesis ? ")" : ""}${isCollectionPredicate ? "" : this.binaryExprSpace}${operator}${isCollectionPredicate ? "" : this.binaryExprSpace}${isRightParenthesis ? "(" : ""}${isCollectionPredicate ? `[${rightExpr}]` : rightExpr}${isRightParenthesis ? ")" : ""}`;
|
|
1500
|
+
}
|
|
1501
|
+
_generateReferenceExpr(ast) {
|
|
1502
|
+
const args = ast.args.length ? `(${ast.args.map((x) => this.generate(x)).join(", ")})` : "";
|
|
1503
|
+
return `${ast.target.ref?.name}${args}`;
|
|
1504
|
+
}
|
|
1505
|
+
_generateReferenceArg(ast) {
|
|
1506
|
+
return `${ast.name}:${this.generate(ast.value)}`;
|
|
1507
|
+
}
|
|
1508
|
+
_generateMemberExpr(ast) {
|
|
1509
|
+
return `${this.generate(ast.operand)}.${ast.member.ref?.name}`;
|
|
1510
|
+
}
|
|
1511
|
+
_generateInvocationExpr(ast) {
|
|
1512
|
+
return `${ast.function.ref?.name}(${ast.args.map((x) => this.argument(x)).join(", ")})`;
|
|
1513
|
+
}
|
|
1514
|
+
_generateNullExpr() {
|
|
1515
|
+
return "null";
|
|
1516
|
+
}
|
|
1517
|
+
_generateThisExpr() {
|
|
1518
|
+
return "this";
|
|
1519
|
+
}
|
|
1520
|
+
_generateAttribute(ast) {
|
|
1521
|
+
return `attribute ${ast.name}(${ast.params.map((x) => this.generate(x)).join(", ")})`;
|
|
1522
|
+
}
|
|
1523
|
+
_generateAttributeParam(ast) {
|
|
1524
|
+
return `${ast.default ? "_ " : ""}${ast.name}: ${this.generate(ast.type)}`;
|
|
1525
|
+
}
|
|
1526
|
+
_generateAttributeParamType(ast) {
|
|
1527
|
+
return `${ast.type ?? ast.reference?.$refText}${ast.array ? "[]" : ""}${ast.optional ? "?" : ""}`;
|
|
1528
|
+
}
|
|
1529
|
+
_generateFunctionDecl(ast) {
|
|
1530
|
+
return `function ${ast.name}(${ast.params.map((x) => this.generate(x)).join(", ")}) ${ast.returnType ? ": " + this.generate(ast.returnType) : ""} {}`;
|
|
1531
|
+
}
|
|
1532
|
+
_generateFunctionParam(ast) {
|
|
1533
|
+
return `${ast.name}: ${this.generate(ast.type)}`;
|
|
1534
|
+
}
|
|
1535
|
+
_generateFunctionParamType(ast) {
|
|
1536
|
+
return `${ast.type ?? ast.reference?.$refText}${ast.array ? "[]" : ""}`;
|
|
1537
|
+
}
|
|
1538
|
+
_generateTypeDef(ast) {
|
|
1539
|
+
return `type ${ast.name} {
|
|
1540
|
+
${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attributes.length > 0 ? "\n\n" + ast.attributes.map((x) => this.indent + this.generate(x)).join("\n") : ""}
|
|
1541
|
+
}`;
|
|
1542
|
+
}
|
|
1543
|
+
_generateTypeDefField(ast) {
|
|
1544
|
+
return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1545
|
+
}
|
|
1546
|
+
argument(ast) {
|
|
1547
|
+
return this.generate(ast.value);
|
|
1548
|
+
}
|
|
1549
|
+
get binaryExprSpace() {
|
|
1550
|
+
return " ".repeat(this.options.binaryExprNumberOfSpaces);
|
|
1551
|
+
}
|
|
1552
|
+
get unaryExprSpace() {
|
|
1553
|
+
return " ".repeat(this.options.unaryExprNumberOfSpaces);
|
|
1554
|
+
}
|
|
1555
|
+
get indent() {
|
|
1556
|
+
return " ".repeat(this.options.indent);
|
|
1557
|
+
}
|
|
1558
|
+
isParenthesesNeededForBinaryExpr(ast) {
|
|
1559
|
+
const result = {
|
|
1560
|
+
left: false,
|
|
1561
|
+
right: false
|
|
1562
|
+
};
|
|
1563
|
+
const operator = ast.operator;
|
|
1564
|
+
const isCollectionPredicate = this.isCollectionPredicateOperator(operator);
|
|
1565
|
+
const currentPriority = BinaryExprOperatorPriority[operator];
|
|
1566
|
+
if (ast.left.$type === BinaryExpr && BinaryExprOperatorPriority[ast.left["operator"]] < currentPriority) {
|
|
1567
|
+
result.left = true;
|
|
1568
|
+
}
|
|
1569
|
+
if (!isCollectionPredicate && ast.right.$type === BinaryExpr && BinaryExprOperatorPriority[ast.right["operator"]] <= currentPriority) {
|
|
1570
|
+
result.right = true;
|
|
1571
|
+
}
|
|
1572
|
+
return result;
|
|
1573
|
+
}
|
|
1574
|
+
isCollectionPredicateOperator(op) {
|
|
1575
|
+
return [
|
|
1576
|
+
"?",
|
|
1577
|
+
"!",
|
|
1578
|
+
"^"
|
|
1579
|
+
].includes(op);
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
_ts_decorate([
|
|
1583
|
+
gen(Model2),
|
|
1584
|
+
_ts_metadata("design:type", Function),
|
|
1585
|
+
_ts_metadata("design:paramtypes", [
|
|
1586
|
+
typeof Model2 === "undefined" ? Object : Model2
|
|
1587
|
+
]),
|
|
1588
|
+
_ts_metadata("design:returntype", void 0)
|
|
1589
|
+
], ZModelCodeGenerator.prototype, "_generateModel", null);
|
|
1590
|
+
_ts_decorate([
|
|
1591
|
+
gen(DataSource3),
|
|
1592
|
+
_ts_metadata("design:type", Function),
|
|
1593
|
+
_ts_metadata("design:paramtypes", [
|
|
1594
|
+
typeof DataSource3 === "undefined" ? Object : DataSource3
|
|
1595
|
+
]),
|
|
1596
|
+
_ts_metadata("design:returntype", void 0)
|
|
1597
|
+
], ZModelCodeGenerator.prototype, "_generateDataSource", null);
|
|
1598
|
+
_ts_decorate([
|
|
1599
|
+
gen(Enum3),
|
|
1600
|
+
_ts_metadata("design:type", Function),
|
|
1601
|
+
_ts_metadata("design:paramtypes", [
|
|
1602
|
+
typeof Enum3 === "undefined" ? Object : Enum3
|
|
1603
|
+
]),
|
|
1604
|
+
_ts_metadata("design:returntype", void 0)
|
|
1605
|
+
], ZModelCodeGenerator.prototype, "_generateEnum", null);
|
|
1606
|
+
_ts_decorate([
|
|
1607
|
+
gen(EnumField2),
|
|
1608
|
+
_ts_metadata("design:type", Function),
|
|
1609
|
+
_ts_metadata("design:paramtypes", [
|
|
1610
|
+
typeof EnumField2 === "undefined" ? Object : EnumField2
|
|
1611
|
+
]),
|
|
1612
|
+
_ts_metadata("design:returntype", void 0)
|
|
1613
|
+
], ZModelCodeGenerator.prototype, "_generateEnumField", null);
|
|
1614
|
+
_ts_decorate([
|
|
1615
|
+
gen(GeneratorDecl2),
|
|
1616
|
+
_ts_metadata("design:type", Function),
|
|
1617
|
+
_ts_metadata("design:paramtypes", [
|
|
1618
|
+
typeof GeneratorDecl2 === "undefined" ? Object : GeneratorDecl2
|
|
1619
|
+
]),
|
|
1620
|
+
_ts_metadata("design:returntype", void 0)
|
|
1621
|
+
], ZModelCodeGenerator.prototype, "_generateGenerator", null);
|
|
1622
|
+
_ts_decorate([
|
|
1623
|
+
gen(ConfigField),
|
|
1624
|
+
_ts_metadata("design:type", Function),
|
|
1625
|
+
_ts_metadata("design:paramtypes", [
|
|
1626
|
+
typeof ConfigField === "undefined" ? Object : ConfigField
|
|
1627
|
+
]),
|
|
1628
|
+
_ts_metadata("design:returntype", void 0)
|
|
1629
|
+
], ZModelCodeGenerator.prototype, "_generateConfigField", null);
|
|
1630
|
+
_ts_decorate([
|
|
1631
|
+
gen(ConfigArrayExpr),
|
|
1632
|
+
_ts_metadata("design:type", Function),
|
|
1633
|
+
_ts_metadata("design:paramtypes", [
|
|
1634
|
+
typeof ConfigArrayExpr === "undefined" ? Object : ConfigArrayExpr
|
|
1635
|
+
]),
|
|
1636
|
+
_ts_metadata("design:returntype", void 0)
|
|
1637
|
+
], ZModelCodeGenerator.prototype, "_generateConfigArrayExpr", null);
|
|
1638
|
+
_ts_decorate([
|
|
1639
|
+
gen(ConfigInvocationExpr),
|
|
1640
|
+
_ts_metadata("design:type", Function),
|
|
1641
|
+
_ts_metadata("design:paramtypes", [
|
|
1642
|
+
typeof ConfigInvocationExpr === "undefined" ? Object : ConfigInvocationExpr
|
|
1643
|
+
]),
|
|
1644
|
+
_ts_metadata("design:returntype", void 0)
|
|
1645
|
+
], ZModelCodeGenerator.prototype, "_generateConfigInvocationExpr", null);
|
|
1646
|
+
_ts_decorate([
|
|
1647
|
+
gen(Plugin),
|
|
1648
|
+
_ts_metadata("design:type", Function),
|
|
1649
|
+
_ts_metadata("design:paramtypes", [
|
|
1650
|
+
typeof Plugin === "undefined" ? Object : Plugin
|
|
1651
|
+
]),
|
|
1652
|
+
_ts_metadata("design:returntype", void 0)
|
|
1653
|
+
], ZModelCodeGenerator.prototype, "_generatePlugin", null);
|
|
1654
|
+
_ts_decorate([
|
|
1655
|
+
gen(PluginField),
|
|
1656
|
+
_ts_metadata("design:type", Function),
|
|
1657
|
+
_ts_metadata("design:paramtypes", [
|
|
1658
|
+
typeof PluginField === "undefined" ? Object : PluginField
|
|
1659
|
+
]),
|
|
1660
|
+
_ts_metadata("design:returntype", void 0)
|
|
1661
|
+
], ZModelCodeGenerator.prototype, "_generatePluginField", null);
|
|
1662
|
+
_ts_decorate([
|
|
1663
|
+
gen(DataModel2),
|
|
1664
|
+
_ts_metadata("design:type", Function),
|
|
1665
|
+
_ts_metadata("design:paramtypes", [
|
|
1666
|
+
typeof DataModel2 === "undefined" ? Object : DataModel2
|
|
1667
|
+
]),
|
|
1668
|
+
_ts_metadata("design:returntype", void 0)
|
|
1669
|
+
], ZModelCodeGenerator.prototype, "_generateDataModel", null);
|
|
1670
|
+
_ts_decorate([
|
|
1671
|
+
gen(DataModelField),
|
|
1672
|
+
_ts_metadata("design:type", Function),
|
|
1673
|
+
_ts_metadata("design:paramtypes", [
|
|
1674
|
+
typeof DataModelField === "undefined" ? Object : DataModelField
|
|
1675
|
+
]),
|
|
1676
|
+
_ts_metadata("design:returntype", void 0)
|
|
1677
|
+
], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
|
|
1678
|
+
_ts_decorate([
|
|
1679
|
+
gen(DataModelAttribute),
|
|
1680
|
+
_ts_metadata("design:type", Function),
|
|
1681
|
+
_ts_metadata("design:paramtypes", [
|
|
1682
|
+
typeof DataModelAttribute === "undefined" ? Object : DataModelAttribute
|
|
1683
|
+
]),
|
|
1684
|
+
_ts_metadata("design:returntype", void 0)
|
|
1685
|
+
], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
|
|
1686
|
+
_ts_decorate([
|
|
1687
|
+
gen(DataModelFieldAttribute),
|
|
1688
|
+
_ts_metadata("design:type", Function),
|
|
1689
|
+
_ts_metadata("design:paramtypes", [
|
|
1690
|
+
typeof DataModelFieldAttribute === "undefined" ? Object : DataModelFieldAttribute
|
|
1691
|
+
]),
|
|
1692
|
+
_ts_metadata("design:returntype", void 0)
|
|
1693
|
+
], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
|
|
1694
|
+
_ts_decorate([
|
|
1695
|
+
gen(AttributeArg2),
|
|
1696
|
+
_ts_metadata("design:type", Function),
|
|
1697
|
+
_ts_metadata("design:paramtypes", [
|
|
1698
|
+
typeof AttributeArg2 === "undefined" ? Object : AttributeArg2
|
|
1699
|
+
]),
|
|
1700
|
+
_ts_metadata("design:returntype", void 0)
|
|
1701
|
+
], ZModelCodeGenerator.prototype, "_generateAttributeArg", null);
|
|
1702
|
+
_ts_decorate([
|
|
1703
|
+
gen(ObjectExpr),
|
|
1704
|
+
_ts_metadata("design:type", Function),
|
|
1705
|
+
_ts_metadata("design:paramtypes", [
|
|
1706
|
+
typeof ObjectExpr === "undefined" ? Object : ObjectExpr
|
|
1707
|
+
]),
|
|
1708
|
+
_ts_metadata("design:returntype", void 0)
|
|
1709
|
+
], ZModelCodeGenerator.prototype, "_generateObjectExpr", null);
|
|
1710
|
+
_ts_decorate([
|
|
1711
|
+
gen(ArrayExpr),
|
|
1712
|
+
_ts_metadata("design:type", Function),
|
|
1713
|
+
_ts_metadata("design:paramtypes", [
|
|
1714
|
+
typeof ArrayExpr === "undefined" ? Object : ArrayExpr
|
|
1715
|
+
]),
|
|
1716
|
+
_ts_metadata("design:returntype", void 0)
|
|
1717
|
+
], ZModelCodeGenerator.prototype, "_generateArrayExpr", null);
|
|
1718
|
+
_ts_decorate([
|
|
1719
|
+
gen(StringLiteral2),
|
|
1720
|
+
_ts_metadata("design:type", Function),
|
|
1721
|
+
_ts_metadata("design:paramtypes", [
|
|
1722
|
+
typeof LiteralExpr === "undefined" ? Object : LiteralExpr
|
|
1723
|
+
]),
|
|
1724
|
+
_ts_metadata("design:returntype", void 0)
|
|
1725
|
+
], ZModelCodeGenerator.prototype, "_generateLiteralExpr", null);
|
|
1726
|
+
_ts_decorate([
|
|
1727
|
+
gen(NumberLiteral2),
|
|
1728
|
+
_ts_metadata("design:type", Function),
|
|
1729
|
+
_ts_metadata("design:paramtypes", [
|
|
1730
|
+
typeof NumberLiteral2 === "undefined" ? Object : NumberLiteral2
|
|
1731
|
+
]),
|
|
1732
|
+
_ts_metadata("design:returntype", void 0)
|
|
1733
|
+
], ZModelCodeGenerator.prototype, "_generateNumberLiteral", null);
|
|
1734
|
+
_ts_decorate([
|
|
1735
|
+
gen(BooleanLiteral2),
|
|
1736
|
+
_ts_metadata("design:type", Function),
|
|
1737
|
+
_ts_metadata("design:paramtypes", [
|
|
1738
|
+
typeof BooleanLiteral2 === "undefined" ? Object : BooleanLiteral2
|
|
1739
|
+
]),
|
|
1740
|
+
_ts_metadata("design:returntype", void 0)
|
|
1741
|
+
], ZModelCodeGenerator.prototype, "_generateBooleanLiteral", null);
|
|
1742
|
+
_ts_decorate([
|
|
1743
|
+
gen(UnaryExpr),
|
|
1744
|
+
_ts_metadata("design:type", Function),
|
|
1745
|
+
_ts_metadata("design:paramtypes", [
|
|
1746
|
+
typeof UnaryExpr === "undefined" ? Object : UnaryExpr
|
|
1747
|
+
]),
|
|
1748
|
+
_ts_metadata("design:returntype", void 0)
|
|
1749
|
+
], ZModelCodeGenerator.prototype, "_generateUnaryExpr", null);
|
|
1750
|
+
_ts_decorate([
|
|
1751
|
+
gen(BinaryExpr),
|
|
1752
|
+
_ts_metadata("design:type", Function),
|
|
1753
|
+
_ts_metadata("design:paramtypes", [
|
|
1754
|
+
typeof BinaryExpr === "undefined" ? Object : BinaryExpr
|
|
1755
|
+
]),
|
|
1756
|
+
_ts_metadata("design:returntype", void 0)
|
|
1757
|
+
], ZModelCodeGenerator.prototype, "_generateBinaryExpr", null);
|
|
1758
|
+
_ts_decorate([
|
|
1759
|
+
gen(ReferenceExpr),
|
|
1760
|
+
_ts_metadata("design:type", Function),
|
|
1761
|
+
_ts_metadata("design:paramtypes", [
|
|
1762
|
+
typeof ReferenceExpr === "undefined" ? Object : ReferenceExpr
|
|
1763
|
+
]),
|
|
1764
|
+
_ts_metadata("design:returntype", void 0)
|
|
1765
|
+
], ZModelCodeGenerator.prototype, "_generateReferenceExpr", null);
|
|
1766
|
+
_ts_decorate([
|
|
1767
|
+
gen(ReferenceArg),
|
|
1768
|
+
_ts_metadata("design:type", Function),
|
|
1769
|
+
_ts_metadata("design:paramtypes", [
|
|
1770
|
+
typeof ReferenceArg === "undefined" ? Object : ReferenceArg
|
|
1771
|
+
]),
|
|
1772
|
+
_ts_metadata("design:returntype", void 0)
|
|
1773
|
+
], ZModelCodeGenerator.prototype, "_generateReferenceArg", null);
|
|
1774
|
+
_ts_decorate([
|
|
1775
|
+
gen(MemberAccessExpr),
|
|
1776
|
+
_ts_metadata("design:type", Function),
|
|
1777
|
+
_ts_metadata("design:paramtypes", [
|
|
1778
|
+
typeof MemberAccessExpr === "undefined" ? Object : MemberAccessExpr
|
|
1779
|
+
]),
|
|
1780
|
+
_ts_metadata("design:returntype", void 0)
|
|
1781
|
+
], ZModelCodeGenerator.prototype, "_generateMemberExpr", null);
|
|
1782
|
+
_ts_decorate([
|
|
1783
|
+
gen(InvocationExpr),
|
|
1784
|
+
_ts_metadata("design:type", Function),
|
|
1785
|
+
_ts_metadata("design:paramtypes", [
|
|
1786
|
+
typeof InvocationExpr === "undefined" ? Object : InvocationExpr
|
|
1787
|
+
]),
|
|
1788
|
+
_ts_metadata("design:returntype", void 0)
|
|
1789
|
+
], ZModelCodeGenerator.prototype, "_generateInvocationExpr", null);
|
|
1790
|
+
_ts_decorate([
|
|
1791
|
+
gen(NullExpr),
|
|
1792
|
+
_ts_metadata("design:type", Function),
|
|
1793
|
+
_ts_metadata("design:paramtypes", []),
|
|
1794
|
+
_ts_metadata("design:returntype", void 0)
|
|
1795
|
+
], ZModelCodeGenerator.prototype, "_generateNullExpr", null);
|
|
1796
|
+
_ts_decorate([
|
|
1797
|
+
gen(ThisExpr),
|
|
1798
|
+
_ts_metadata("design:type", Function),
|
|
1799
|
+
_ts_metadata("design:paramtypes", []),
|
|
1800
|
+
_ts_metadata("design:returntype", void 0)
|
|
1801
|
+
], ZModelCodeGenerator.prototype, "_generateThisExpr", null);
|
|
1802
|
+
_ts_decorate([
|
|
1803
|
+
gen(Attribute),
|
|
1804
|
+
_ts_metadata("design:type", Function),
|
|
1805
|
+
_ts_metadata("design:paramtypes", [
|
|
1806
|
+
typeof Attribute === "undefined" ? Object : Attribute
|
|
1807
|
+
]),
|
|
1808
|
+
_ts_metadata("design:returntype", void 0)
|
|
1809
|
+
], ZModelCodeGenerator.prototype, "_generateAttribute", null);
|
|
1810
|
+
_ts_decorate([
|
|
1811
|
+
gen(AttributeParam),
|
|
1812
|
+
_ts_metadata("design:type", Function),
|
|
1813
|
+
_ts_metadata("design:paramtypes", [
|
|
1814
|
+
typeof AttributeParam === "undefined" ? Object : AttributeParam
|
|
1815
|
+
]),
|
|
1816
|
+
_ts_metadata("design:returntype", void 0)
|
|
1817
|
+
], ZModelCodeGenerator.prototype, "_generateAttributeParam", null);
|
|
1818
|
+
_ts_decorate([
|
|
1819
|
+
gen(AttributeParamType),
|
|
1820
|
+
_ts_metadata("design:type", Function),
|
|
1821
|
+
_ts_metadata("design:paramtypes", [
|
|
1822
|
+
typeof AttributeParamType === "undefined" ? Object : AttributeParamType
|
|
1823
|
+
]),
|
|
1824
|
+
_ts_metadata("design:returntype", void 0)
|
|
1825
|
+
], ZModelCodeGenerator.prototype, "_generateAttributeParamType", null);
|
|
1826
|
+
_ts_decorate([
|
|
1827
|
+
gen(FunctionDecl),
|
|
1828
|
+
_ts_metadata("design:type", Function),
|
|
1829
|
+
_ts_metadata("design:paramtypes", [
|
|
1830
|
+
typeof FunctionDecl === "undefined" ? Object : FunctionDecl
|
|
1831
|
+
]),
|
|
1832
|
+
_ts_metadata("design:returntype", void 0)
|
|
1833
|
+
], ZModelCodeGenerator.prototype, "_generateFunctionDecl", null);
|
|
1834
|
+
_ts_decorate([
|
|
1835
|
+
gen(FunctionParam),
|
|
1836
|
+
_ts_metadata("design:type", Function),
|
|
1837
|
+
_ts_metadata("design:paramtypes", [
|
|
1838
|
+
typeof FunctionParam === "undefined" ? Object : FunctionParam
|
|
1839
|
+
]),
|
|
1840
|
+
_ts_metadata("design:returntype", void 0)
|
|
1841
|
+
], ZModelCodeGenerator.prototype, "_generateFunctionParam", null);
|
|
1842
|
+
_ts_decorate([
|
|
1843
|
+
gen(FunctionParamType),
|
|
1844
|
+
_ts_metadata("design:type", Function),
|
|
1845
|
+
_ts_metadata("design:paramtypes", [
|
|
1846
|
+
typeof FunctionParamType === "undefined" ? Object : FunctionParamType
|
|
1847
|
+
]),
|
|
1848
|
+
_ts_metadata("design:returntype", void 0)
|
|
1849
|
+
], ZModelCodeGenerator.prototype, "_generateFunctionParamType", null);
|
|
1850
|
+
_ts_decorate([
|
|
1851
|
+
gen(TypeDef),
|
|
1852
|
+
_ts_metadata("design:type", Function),
|
|
1853
|
+
_ts_metadata("design:paramtypes", [
|
|
1854
|
+
typeof TypeDef === "undefined" ? Object : TypeDef
|
|
1855
|
+
]),
|
|
1856
|
+
_ts_metadata("design:returntype", void 0)
|
|
1857
|
+
], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
|
|
1858
|
+
_ts_decorate([
|
|
1859
|
+
gen(TypeDefField),
|
|
1860
|
+
_ts_metadata("design:type", Function),
|
|
1861
|
+
_ts_metadata("design:paramtypes", [
|
|
1862
|
+
typeof TypeDefField === "undefined" ? Object : TypeDefField
|
|
1863
|
+
]),
|
|
1864
|
+
_ts_metadata("design:returntype", void 0)
|
|
1865
|
+
], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
|
|
1866
|
+
export {
|
|
1867
|
+
model_utils_exports as ModelUtils,
|
|
1868
|
+
PrismaSchemaGenerator,
|
|
1869
|
+
TsSchemaGenerator,
|
|
1870
|
+
ZModelCodeGenerator
|
|
1871
|
+
};
|
|
1872
|
+
//# sourceMappingURL=index.js.map
|