@zenstackhq/sdk 3.0.0-alpha.9 → 3.0.0-beta.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/dist/index.cjs +354 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -32
- package/dist/index.d.ts +69 -32
- package/dist/index.js +364 -176
- package/dist/index.js.map +1 -1
- package/dist/schema.d.cts +45 -17
- package/dist/schema.d.ts +45 -17
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -8,12 +8,11 @@ var __export = (target, all) => {
|
|
|
8
8
|
// src/model-utils.ts
|
|
9
9
|
var model_utils_exports = {};
|
|
10
10
|
__export(model_utils_exports, {
|
|
11
|
+
DELEGATE_AUX_RELATION_PREFIX: () => DELEGATE_AUX_RELATION_PREFIX,
|
|
11
12
|
getAttribute: () => getAttribute,
|
|
12
13
|
getAuthDecl: () => getAuthDecl,
|
|
13
14
|
getContainingModel: () => getContainingModel,
|
|
14
|
-
|
|
15
|
-
getModelUniqueFields: () => getModelUniqueFields,
|
|
16
|
-
getRecursiveBases: () => getRecursiveBases,
|
|
15
|
+
getIdFields: () => getIdFields,
|
|
17
16
|
hasAttribute: () => hasAttribute,
|
|
18
17
|
isDelegateModel: () => isDelegateModel,
|
|
19
18
|
isFromStdlib: () => isFromStdlib,
|
|
@@ -21,24 +20,25 @@ __export(model_utils_exports, {
|
|
|
21
20
|
isUniqueField: () => isUniqueField,
|
|
22
21
|
resolved: () => resolved
|
|
23
22
|
});
|
|
24
|
-
import {
|
|
25
|
-
|
|
23
|
+
import { isDataModel, isLiteralExpr, isModel } from "@zenstackhq/language/ast";
|
|
24
|
+
import { getAllFields, getModelIdFields, getModelUniqueFields } from "@zenstackhq/language/utils";
|
|
25
|
+
function isIdField(field, contextModel) {
|
|
26
26
|
if (hasAttribute(field, "@id")) {
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
|
-
const
|
|
30
|
-
const modelLevelIds = getModelIdFields(model);
|
|
29
|
+
const modelLevelIds = getModelIdFields(contextModel);
|
|
31
30
|
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
|
|
32
31
|
return true;
|
|
33
32
|
}
|
|
34
|
-
|
|
33
|
+
const allFields = getAllFields(contextModel);
|
|
34
|
+
if (allFields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
|
-
const firstUniqueField =
|
|
37
|
+
const firstUniqueField = allFields.find((f) => hasAttribute(f, "@unique"));
|
|
38
38
|
if (firstUniqueField) {
|
|
39
39
|
return firstUniqueField.name === field.name;
|
|
40
40
|
}
|
|
41
|
-
const modelLevelUnique = getModelUniqueFields(
|
|
41
|
+
const modelLevelUnique = getModelUniqueFields(contextModel);
|
|
42
42
|
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
|
|
43
43
|
return true;
|
|
44
44
|
}
|
|
@@ -53,67 +53,6 @@ function getAttribute(decl, name) {
|
|
|
53
53
|
return decl.attributes.find((attr) => attr.decl.$refText === name);
|
|
54
54
|
}
|
|
55
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
56
|
function isDelegateModel(node) {
|
|
118
57
|
return isDataModel(node) && hasAttribute(node, "@@delegate");
|
|
119
58
|
}
|
|
@@ -156,11 +95,18 @@ function getAuthDecl(model) {
|
|
|
156
95
|
return found;
|
|
157
96
|
}
|
|
158
97
|
__name(getAuthDecl, "getAuthDecl");
|
|
98
|
+
function getIdFields(dm) {
|
|
99
|
+
return getAllFields(dm).filter((f) => isIdField(f, dm)).map((f) => f.name);
|
|
100
|
+
}
|
|
101
|
+
__name(getIdFields, "getIdFields");
|
|
102
|
+
var DELEGATE_AUX_RELATION_PREFIX = "delegate_aux";
|
|
159
103
|
|
|
160
104
|
// src/prisma/prisma-schema-generator.ts
|
|
161
|
-
import {
|
|
105
|
+
import { lowerCaseFirst } from "@zenstackhq/common-helpers";
|
|
106
|
+
import { BooleanLiteral, DataModel, DataSource as DataSource2, Enum as Enum2, GeneratorDecl, isArrayExpr, isDataModel as isDataModel2, isInvocationExpr, isLiteralExpr as isLiteralExpr2, isModel as isModel2, isNullExpr, isReferenceExpr, isStringLiteral, isTypeDef, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
|
|
107
|
+
import { getAllAttributes, getAllFields as getAllFields2, isDelegateModel as isDelegateModel2 } from "@zenstackhq/language/utils";
|
|
162
108
|
import { AstUtils } from "langium";
|
|
163
|
-
import { match
|
|
109
|
+
import { match } from "ts-pattern";
|
|
164
110
|
|
|
165
111
|
// src/prisma/indent-string.ts
|
|
166
112
|
function indentString(string, count = 4) {
|
|
@@ -553,6 +499,7 @@ var EnumField = class extends DeclarationBase {
|
|
|
553
499
|
};
|
|
554
500
|
|
|
555
501
|
// src/prisma/prisma-schema-generator.ts
|
|
502
|
+
var IDENTIFIER_NAME_MAX_LENGTH = 50 - DELEGATE_AUX_RELATION_PREFIX.length;
|
|
556
503
|
var PrismaSchemaGenerator = class {
|
|
557
504
|
static {
|
|
558
505
|
__name(this, "PrismaSchemaGenerator");
|
|
@@ -564,6 +511,8 @@ var PrismaSchemaGenerator = class {
|
|
|
564
511
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
565
512
|
|
|
566
513
|
`;
|
|
514
|
+
// a mapping from full names to shortened names
|
|
515
|
+
shortNameMap = /* @__PURE__ */ new Map();
|
|
567
516
|
constructor(zmodel) {
|
|
568
517
|
this.zmodel = zmodel;
|
|
569
518
|
}
|
|
@@ -627,16 +576,22 @@ var PrismaSchemaGenerator = class {
|
|
|
627
576
|
}
|
|
628
577
|
generateModel(prisma, decl) {
|
|
629
578
|
const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
|
|
630
|
-
|
|
579
|
+
const allFields = getAllFields2(decl, true);
|
|
580
|
+
for (const field of allFields) {
|
|
631
581
|
if (model_utils_exports.hasAttribute(field, "@computed")) {
|
|
632
582
|
continue;
|
|
633
583
|
}
|
|
634
|
-
this.
|
|
584
|
+
if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
|
|
585
|
+
this.generateModelField(model, field, decl);
|
|
586
|
+
}
|
|
635
587
|
}
|
|
636
|
-
|
|
588
|
+
const allAttributes = getAllAttributes(decl);
|
|
589
|
+
for (const attr of allAttributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
|
|
637
590
|
this.generateContainerAttribute(model, attr);
|
|
638
591
|
}
|
|
639
592
|
decl.comments.forEach((c) => model.addComment(c));
|
|
593
|
+
this.generateDelegateRelationForBase(model, decl);
|
|
594
|
+
this.generateDelegateRelationForConcrete(model, decl);
|
|
640
595
|
}
|
|
641
596
|
isPrismaAttribute(attr) {
|
|
642
597
|
if (!attr.decl.ref) {
|
|
@@ -659,7 +614,7 @@ var PrismaSchemaGenerator = class {
|
|
|
659
614
|
getStringLiteral(node) {
|
|
660
615
|
return isStringLiteral(node) ? node.value : void 0;
|
|
661
616
|
}
|
|
662
|
-
generateModelField(model, field, addToFront = false) {
|
|
617
|
+
generateModelField(model, field, contextModel, addToFront = false) {
|
|
663
618
|
let fieldType;
|
|
664
619
|
if (field.type.type) {
|
|
665
620
|
fieldType = field.type.type;
|
|
@@ -685,7 +640,7 @@ var PrismaSchemaGenerator = class {
|
|
|
685
640
|
const type = new ModelFieldType(fieldType, isArray, field.type.optional);
|
|
686
641
|
const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
|
|
687
642
|
// when building physical schema, exclude `@default` for id fields inherited from delegate base
|
|
688
|
-
!(model_utils_exports.isIdField(field) && this.isInheritedFromDelegate(field) && attr.decl.$refText === "@default")
|
|
643
|
+
!(model_utils_exports.isIdField(field, contextModel) && this.isInheritedFromDelegate(field, contextModel) && attr.decl.$refText === "@default")
|
|
689
644
|
)).map((attr) => this.makeFieldAttribute(attr));
|
|
690
645
|
const docs = [
|
|
691
646
|
...field.comments
|
|
@@ -707,16 +662,8 @@ var PrismaSchemaGenerator = class {
|
|
|
707
662
|
const model = AstUtils.getContainerOfType(node, isModel2);
|
|
708
663
|
return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
|
|
709
664
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
throw new Error(`Unsupported field type with default value: ${field.type.type}`);
|
|
713
|
-
});
|
|
714
|
-
result.attributes.push(new FieldAttribute("@default", [
|
|
715
|
-
new AttributeArg(void 0, dummyDefaultValue)
|
|
716
|
-
]));
|
|
717
|
-
}
|
|
718
|
-
isInheritedFromDelegate(field) {
|
|
719
|
-
return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
|
|
665
|
+
isInheritedFromDelegate(field, contextModel) {
|
|
666
|
+
return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
|
|
720
667
|
}
|
|
721
668
|
makeFieldAttribute(attr) {
|
|
722
669
|
const attrName = attr.decl.ref.name;
|
|
@@ -729,9 +676,9 @@ var PrismaSchemaGenerator = class {
|
|
|
729
676
|
if (isLiteralExpr2(node)) {
|
|
730
677
|
const argType = match(node.$type).with(StringLiteral, () => "String").with(NumberLiteral, () => "Number").with(BooleanLiteral, () => "Boolean").exhaustive();
|
|
731
678
|
return new AttributeArgValue(argType, node.value);
|
|
732
|
-
} else if (
|
|
679
|
+
} else if (isArrayExpr(node)) {
|
|
733
680
|
return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
|
|
734
|
-
} else if (
|
|
681
|
+
} else if (isReferenceExpr(node)) {
|
|
735
682
|
return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
|
|
736
683
|
} else if (isInvocationExpr(node)) {
|
|
737
684
|
return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
|
|
@@ -773,12 +720,66 @@ var PrismaSchemaGenerator = class {
|
|
|
773
720
|
];
|
|
774
721
|
_enum.addField(field.name, attributes, docs);
|
|
775
722
|
}
|
|
723
|
+
generateDelegateRelationForBase(model, decl) {
|
|
724
|
+
if (!isDelegateModel2(decl)) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
const concreteModels = this.getConcreteModels(decl);
|
|
728
|
+
concreteModels.forEach((concrete) => {
|
|
729
|
+
const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(concrete.name)}`);
|
|
730
|
+
model.addField(auxName, new ModelFieldType(concrete.name, false, true));
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
generateDelegateRelationForConcrete(model, concreteDecl) {
|
|
734
|
+
const base = concreteDecl.baseModel?.ref;
|
|
735
|
+
if (!base) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
const idFields = getIdFields(base);
|
|
739
|
+
const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(base.name)}`);
|
|
740
|
+
model.addField(relationField, base.name, [
|
|
741
|
+
new FieldAttribute("@relation", [
|
|
742
|
+
new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
|
|
743
|
+
new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
|
|
744
|
+
new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
|
|
745
|
+
new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
|
|
746
|
+
])
|
|
747
|
+
]);
|
|
748
|
+
}
|
|
749
|
+
getConcreteModels(dataModel) {
|
|
750
|
+
if (!isDelegateModel2(dataModel)) {
|
|
751
|
+
return [];
|
|
752
|
+
}
|
|
753
|
+
return dataModel.$container.declarations.filter((d) => isDataModel2(d) && d !== dataModel && d.baseModel?.ref === dataModel);
|
|
754
|
+
}
|
|
755
|
+
truncate(name) {
|
|
756
|
+
if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
|
|
757
|
+
return name;
|
|
758
|
+
}
|
|
759
|
+
const existing = this.shortNameMap.get(name);
|
|
760
|
+
if (existing) {
|
|
761
|
+
return existing;
|
|
762
|
+
}
|
|
763
|
+
const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
|
|
764
|
+
let index = 0;
|
|
765
|
+
let shortName = `${baseName}_${index}`;
|
|
766
|
+
while (true) {
|
|
767
|
+
const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
|
|
768
|
+
if (!conflict) {
|
|
769
|
+
this.shortNameMap.set(name, shortName);
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
index++;
|
|
773
|
+
shortName = `${baseName}_${index}`;
|
|
774
|
+
}
|
|
775
|
+
return shortName;
|
|
776
|
+
}
|
|
776
777
|
};
|
|
777
778
|
|
|
778
779
|
// src/ts-schema-generator.ts
|
|
779
780
|
import { invariant } from "@zenstackhq/common-helpers";
|
|
780
|
-
import {
|
|
781
|
-
import {
|
|
781
|
+
import { isArrayExpr as isArrayExpr2, isBinaryExpr, isDataField, isDataModel as isDataModel3, isDataSource, isEnum, isEnumField, isInvocationExpr as isInvocationExpr2, isLiteralExpr as isLiteralExpr3, isMemberAccessExpr, isNullExpr as isNullExpr2, isProcedure, isReferenceExpr as isReferenceExpr2, isThisExpr, isTypeDef as isTypeDef2, isUnaryExpr } from "@zenstackhq/language/ast";
|
|
782
|
+
import { getAllAttributes as getAllAttributes2, getAllFields as getAllFields3, isDataFieldReference } from "@zenstackhq/language/utils";
|
|
782
783
|
import fs from "fs";
|
|
783
784
|
import path from "path";
|
|
784
785
|
import { match as match2 } from "ts-pattern";
|
|
@@ -787,29 +788,26 @@ var TsSchemaGenerator = class {
|
|
|
787
788
|
static {
|
|
788
789
|
__name(this, "TsSchemaGenerator");
|
|
789
790
|
}
|
|
790
|
-
async generate(
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
791
|
+
async generate(model, outputDir) {
|
|
792
|
+
fs.mkdirSync(outputDir, {
|
|
793
|
+
recursive: true
|
|
794
|
+
});
|
|
795
|
+
this.generateSchema(model, outputDir);
|
|
796
|
+
this.generateModelsAndTypeDefs(model, outputDir);
|
|
797
|
+
this.generateInputTypes(model, outputDir);
|
|
798
|
+
}
|
|
799
|
+
generateSchema(model, outputDir) {
|
|
796
800
|
const statements = [];
|
|
797
801
|
this.generateSchemaStatements(model, statements);
|
|
798
802
|
this.generateBannerComments(statements);
|
|
799
|
-
const
|
|
803
|
+
const schemaOutputFile = path.join(outputDir, "schema.ts");
|
|
804
|
+
const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
800
805
|
const printer = ts.createPrinter();
|
|
801
806
|
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
802
|
-
fs.
|
|
803
|
-
recursive: true
|
|
804
|
-
});
|
|
805
|
-
fs.writeFileSync(outputFile, result);
|
|
806
|
-
return {
|
|
807
|
-
model,
|
|
808
|
-
warnings
|
|
809
|
-
};
|
|
807
|
+
fs.writeFileSync(schemaOutputFile, result);
|
|
810
808
|
}
|
|
811
809
|
generateSchemaStatements(model, statements) {
|
|
812
|
-
const hasComputedFields = model.declarations.some((d) =>
|
|
810
|
+
const hasComputedFields = model.declarations.some((d) => isDataModel3(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
|
|
813
811
|
const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
814
812
|
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
|
|
815
813
|
...hasComputedFields ? [
|
|
@@ -834,7 +832,11 @@ var TsSchemaGenerator = class {
|
|
|
834
832
|
// provider
|
|
835
833
|
ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
|
|
836
834
|
// models
|
|
837
|
-
ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
|
|
835
|
+
ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
|
|
836
|
+
// typeDefs
|
|
837
|
+
...model.declarations.some(isTypeDef2) ? [
|
|
838
|
+
ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
|
|
839
|
+
] : []
|
|
838
840
|
];
|
|
839
841
|
const enums = model.declarations.filter(isEnum);
|
|
840
842
|
if (enums.length > 0) {
|
|
@@ -858,20 +860,45 @@ var TsSchemaGenerator = class {
|
|
|
858
860
|
], true);
|
|
859
861
|
}
|
|
860
862
|
createModelsObject(model) {
|
|
861
|
-
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) =>
|
|
863
|
+
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel3(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
|
|
864
|
+
}
|
|
865
|
+
createTypeDefsObject(model) {
|
|
866
|
+
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isTypeDef2(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
|
|
862
867
|
}
|
|
863
868
|
createDataModelObject(dm) {
|
|
869
|
+
const allFields = getAllFields3(dm);
|
|
870
|
+
const allAttributes = getAllAttributes2(dm).filter((attr) => {
|
|
871
|
+
if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
return true;
|
|
875
|
+
});
|
|
876
|
+
const subModels = this.getSubModels(dm);
|
|
864
877
|
const fields = [
|
|
878
|
+
// name
|
|
879
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
|
|
880
|
+
// baseModel
|
|
881
|
+
...dm.baseModel ? [
|
|
882
|
+
ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
|
|
883
|
+
] : [],
|
|
865
884
|
// fields
|
|
866
|
-
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(
|
|
885
|
+
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
|
|
867
886
|
// attributes
|
|
868
|
-
...
|
|
869
|
-
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(
|
|
887
|
+
...allAttributes.length > 0 ? [
|
|
888
|
+
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
|
|
870
889
|
] : [],
|
|
871
890
|
// idFields
|
|
872
|
-
ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(
|
|
891
|
+
ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
|
|
873
892
|
// uniqueFields
|
|
874
|
-
ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
|
|
893
|
+
ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
|
|
894
|
+
// isDelegate
|
|
895
|
+
...isDelegateModel(dm) ? [
|
|
896
|
+
ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
|
|
897
|
+
] : [],
|
|
898
|
+
// subModels
|
|
899
|
+
...subModels.length > 0 ? [
|
|
900
|
+
ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
|
|
901
|
+
] : []
|
|
875
902
|
];
|
|
876
903
|
const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
|
|
877
904
|
if (computedFields.length > 0) {
|
|
@@ -879,8 +906,31 @@ var TsSchemaGenerator = class {
|
|
|
879
906
|
}
|
|
880
907
|
return ts.factory.createObjectLiteralExpression(fields, true);
|
|
881
908
|
}
|
|
909
|
+
getSubModels(dm) {
|
|
910
|
+
return dm.$container.declarations.filter(isDataModel3).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
|
|
911
|
+
}
|
|
912
|
+
createTypeDefObject(td) {
|
|
913
|
+
const allFields = getAllFields3(td);
|
|
914
|
+
const allAttributes = getAllAttributes2(td);
|
|
915
|
+
const fields = [
|
|
916
|
+
// name
|
|
917
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
|
|
918
|
+
// fields
|
|
919
|
+
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
|
|
920
|
+
// attributes
|
|
921
|
+
...allAttributes.length > 0 ? [
|
|
922
|
+
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
|
|
923
|
+
] : []
|
|
924
|
+
];
|
|
925
|
+
return ts.factory.createObjectLiteralExpression(fields, true);
|
|
926
|
+
}
|
|
882
927
|
createComputedFieldsObject(fields) {
|
|
883
|
-
return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
|
|
928
|
+
return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
|
|
929
|
+
// parameter: `context: { currentModel: string }`
|
|
930
|
+
ts.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, ts.factory.createTypeLiteralNode([
|
|
931
|
+
ts.factory.createPropertySignature(void 0, "currentModel", void 0, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
|
|
932
|
+
]), void 0)
|
|
933
|
+
], ts.factory.createTypeReferenceNode("OperandExpression", [
|
|
884
934
|
ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
|
|
885
935
|
]), ts.factory.createBlock([
|
|
886
936
|
ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
|
|
@@ -898,11 +948,14 @@ var TsSchemaGenerator = class {
|
|
|
898
948
|
}
|
|
899
949
|
return result;
|
|
900
950
|
}
|
|
901
|
-
|
|
951
|
+
createDataFieldObject(field, contextModel) {
|
|
902
952
|
const objectFields = [
|
|
953
|
+
// name
|
|
954
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
|
|
955
|
+
// type
|
|
903
956
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
|
|
904
957
|
];
|
|
905
|
-
if (isIdField(field)) {
|
|
958
|
+
if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
|
|
906
959
|
objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
|
|
907
960
|
}
|
|
908
961
|
if (isUniqueField(field)) {
|
|
@@ -917,6 +970,13 @@ var TsSchemaGenerator = class {
|
|
|
917
970
|
if (hasAttribute(field, "@updatedAt")) {
|
|
918
971
|
objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
|
|
919
972
|
}
|
|
973
|
+
if (contextModel && // id fields are duplicated in inherited models
|
|
974
|
+
!isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
|
|
975
|
+
objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
|
|
976
|
+
}
|
|
977
|
+
if (this.isDiscriminatorField(field)) {
|
|
978
|
+
objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
|
|
979
|
+
}
|
|
920
980
|
if (field.attributes.length > 0) {
|
|
921
981
|
objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
|
|
922
982
|
}
|
|
@@ -951,7 +1011,7 @@ var TsSchemaGenerator = class {
|
|
|
951
1011
|
if (hasAttribute(field, "@computed")) {
|
|
952
1012
|
objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
|
|
953
1013
|
}
|
|
954
|
-
if (
|
|
1014
|
+
if (isDataModel3(field.type.reference?.ref)) {
|
|
955
1015
|
objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
|
|
956
1016
|
}
|
|
957
1017
|
const fkFor = this.getForeignKeyFor(field);
|
|
@@ -960,31 +1020,19 @@ var TsSchemaGenerator = class {
|
|
|
960
1020
|
}
|
|
961
1021
|
return ts.factory.createObjectLiteralExpression(objectFields, true);
|
|
962
1022
|
}
|
|
1023
|
+
isDiscriminatorField(field) {
|
|
1024
|
+
const origin = field.$container;
|
|
1025
|
+
return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && isDataFieldReference(arg.value) && arg.value.target.ref === field);
|
|
1026
|
+
}
|
|
963
1027
|
getDataSourceProvider(model) {
|
|
964
1028
|
const dataSource = model.declarations.find(isDataSource);
|
|
965
1029
|
invariant(dataSource, "No data source found in the model");
|
|
966
1030
|
const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
|
|
967
1031
|
invariant(isLiteralExpr3(providerExpr), "Provider must be a literal");
|
|
968
1032
|
const type = providerExpr.value;
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
return {
|
|
973
|
-
type,
|
|
974
|
-
url: urlExpr.value,
|
|
975
|
-
env: void 0
|
|
976
|
-
};
|
|
977
|
-
} else if (isInvocationExpr2(urlExpr)) {
|
|
978
|
-
invariant(urlExpr.function.$refText === "env", 'only "env" function is supported');
|
|
979
|
-
invariant(urlExpr.args.length === 1, "env function must have one argument");
|
|
980
|
-
return {
|
|
981
|
-
type,
|
|
982
|
-
env: urlExpr.args[0].value.value,
|
|
983
|
-
url: void 0
|
|
984
|
-
};
|
|
985
|
-
} else {
|
|
986
|
-
throw new Error("Unsupported URL type");
|
|
987
|
-
}
|
|
1033
|
+
return {
|
|
1034
|
+
type
|
|
1035
|
+
};
|
|
988
1036
|
}
|
|
989
1037
|
getFieldMappedDefault(field) {
|
|
990
1038
|
const defaultAttr = getAttribute(field, "@default");
|
|
@@ -1004,9 +1052,9 @@ var TsSchemaGenerator = class {
|
|
|
1004
1052
|
"Decimal",
|
|
1005
1053
|
"BigInt"
|
|
1006
1054
|
].includes(fieldType.type) ? Number(lit) : lit;
|
|
1007
|
-
} else if (
|
|
1055
|
+
} else if (isArrayExpr2(expr)) {
|
|
1008
1056
|
return expr.items.map((item) => this.getMappedValue(item, fieldType));
|
|
1009
|
-
} else if (
|
|
1057
|
+
} else if (isReferenceExpr2(expr) && isEnumField(expr.target.ref)) {
|
|
1010
1058
|
return expr.target.ref.name;
|
|
1011
1059
|
} else if (isInvocationExpr2(expr)) {
|
|
1012
1060
|
return {
|
|
@@ -1072,7 +1120,7 @@ var TsSchemaGenerator = class {
|
|
|
1072
1120
|
return ts.factory.createObjectLiteralExpression(relationFields);
|
|
1073
1121
|
}
|
|
1074
1122
|
getReferenceNames(expr) {
|
|
1075
|
-
return
|
|
1123
|
+
return isArrayExpr2(expr) && expr.items.map((item) => item.target.$refText);
|
|
1076
1124
|
}
|
|
1077
1125
|
getForeignKeyFor(field) {
|
|
1078
1126
|
const result = [];
|
|
@@ -1080,7 +1128,7 @@ var TsSchemaGenerator = class {
|
|
|
1080
1128
|
const relation = getAttribute(f, "@relation");
|
|
1081
1129
|
if (relation) {
|
|
1082
1130
|
for (const arg of relation.args) {
|
|
1083
|
-
if (arg.name === "fields" &&
|
|
1131
|
+
if (arg.name === "fields" && isArrayExpr2(arg.value) && arg.value.items.some((el) => isReferenceExpr2(el) && el.target.ref === field)) {
|
|
1084
1132
|
result.push(f.name);
|
|
1085
1133
|
}
|
|
1086
1134
|
}
|
|
@@ -1089,7 +1137,7 @@ var TsSchemaGenerator = class {
|
|
|
1089
1137
|
return result;
|
|
1090
1138
|
}
|
|
1091
1139
|
getOppositeRelationField(field) {
|
|
1092
|
-
if (!field.type.reference?.ref || !
|
|
1140
|
+
if (!field.type.reference?.ref || !isDataModel3(field.type.reference?.ref)) {
|
|
1093
1141
|
return void 0;
|
|
1094
1142
|
}
|
|
1095
1143
|
const sourceModel = field.$container;
|
|
@@ -1123,38 +1171,37 @@ var TsSchemaGenerator = class {
|
|
|
1123
1171
|
}
|
|
1124
1172
|
return void 0;
|
|
1125
1173
|
}
|
|
1126
|
-
getIdFields(dm) {
|
|
1127
|
-
return dm.fields.filter(isIdField).map((f) => f.name);
|
|
1128
|
-
}
|
|
1129
1174
|
createUniqueFieldsObject(dm) {
|
|
1130
1175
|
const properties = [];
|
|
1131
|
-
|
|
1176
|
+
const allFields = getAllFields3(dm);
|
|
1177
|
+
for (const field of allFields) {
|
|
1132
1178
|
if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
|
|
1133
1179
|
properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
|
|
1134
1180
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
|
|
1135
1181
|
])));
|
|
1136
1182
|
}
|
|
1137
1183
|
}
|
|
1184
|
+
const allAttributes = getAllAttributes2(dm);
|
|
1138
1185
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
1139
|
-
for (const attr of
|
|
1186
|
+
for (const attr of allAttributes) {
|
|
1140
1187
|
if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
|
|
1141
1188
|
const fieldNames = this.getReferenceNames(attr.args[0].value);
|
|
1142
1189
|
if (!fieldNames) {
|
|
1143
1190
|
continue;
|
|
1144
1191
|
}
|
|
1145
1192
|
if (fieldNames.length === 1) {
|
|
1146
|
-
const fieldDef =
|
|
1193
|
+
const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
|
|
1147
1194
|
properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
|
|
1148
1195
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
|
|
1149
1196
|
])));
|
|
1150
1197
|
} else {
|
|
1151
|
-
const key =
|
|
1198
|
+
const key = this.getCompoundUniqueKey(attr, fieldNames);
|
|
1152
1199
|
if (seenKeys.has(key)) {
|
|
1153
1200
|
continue;
|
|
1154
1201
|
}
|
|
1155
1202
|
seenKeys.add(key);
|
|
1156
|
-
properties.push(ts.factory.createPropertyAssignment(
|
|
1157
|
-
const fieldDef =
|
|
1203
|
+
properties.push(ts.factory.createPropertyAssignment(key, ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
|
|
1204
|
+
const fieldDef = allFields.find((f) => f.name === field);
|
|
1158
1205
|
return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
|
|
1159
1206
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
|
|
1160
1207
|
]));
|
|
@@ -1164,6 +1211,14 @@ var TsSchemaGenerator = class {
|
|
|
1164
1211
|
}
|
|
1165
1212
|
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
1166
1213
|
}
|
|
1214
|
+
getCompoundUniqueKey(attr, fieldNames) {
|
|
1215
|
+
const nameArg = attr.args.find((arg) => arg.$resolvedParam.name === "name");
|
|
1216
|
+
if (nameArg && isLiteralExpr3(nameArg.value)) {
|
|
1217
|
+
return nameArg.value.value;
|
|
1218
|
+
} else {
|
|
1219
|
+
return fieldNames.join("_");
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1167
1222
|
generateFieldTypeLiteral(field) {
|
|
1168
1223
|
invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
|
|
1169
1224
|
return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
|
|
@@ -1246,7 +1301,7 @@ var TsSchemaGenerator = class {
|
|
|
1246
1301
|
]);
|
|
1247
1302
|
}
|
|
1248
1303
|
createExpression(value) {
|
|
1249
|
-
return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(
|
|
1304
|
+
return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(isReferenceExpr2, (expr) => this.createRefExpression(expr)).when(isArrayExpr2, (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(() => {
|
|
1250
1305
|
throw new Error(`Unsupported attribute arg value: ${value.$type}`);
|
|
1251
1306
|
});
|
|
1252
1307
|
}
|
|
@@ -1289,7 +1344,7 @@ var TsSchemaGenerator = class {
|
|
|
1289
1344
|
]);
|
|
1290
1345
|
}
|
|
1291
1346
|
createRefExpression(expr) {
|
|
1292
|
-
if (
|
|
1347
|
+
if (isDataField(expr.target.ref)) {
|
|
1293
1348
|
return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
|
|
1294
1349
|
this.createLiteralNode(expr.target.$refText)
|
|
1295
1350
|
]);
|
|
@@ -1318,10 +1373,154 @@ var TsSchemaGenerator = class {
|
|
|
1318
1373
|
throw new Error(`Unsupported literal type: ${type}`);
|
|
1319
1374
|
});
|
|
1320
1375
|
}
|
|
1376
|
+
generateModelsAndTypeDefs(model, outputDir) {
|
|
1377
|
+
const statements = [];
|
|
1378
|
+
statements.push(this.generateSchemaImport(model, true, true));
|
|
1379
|
+
statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
1380
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
|
|
1381
|
+
...model.declarations.some(isTypeDef2) ? [
|
|
1382
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
|
|
1383
|
+
] : []
|
|
1384
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
|
|
1385
|
+
const dataModels = model.declarations.filter(isDataModel3);
|
|
1386
|
+
for (const dm of dataModels) {
|
|
1387
|
+
let modelType = ts.factory.createTypeAliasDeclaration([
|
|
1388
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1389
|
+
], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
|
|
1390
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1391
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
|
|
1392
|
+
]));
|
|
1393
|
+
if (dm.comments.length > 0) {
|
|
1394
|
+
modelType = this.generateDocs(modelType, dm);
|
|
1395
|
+
}
|
|
1396
|
+
statements.push(modelType);
|
|
1397
|
+
}
|
|
1398
|
+
const typeDefs = model.declarations.filter(isTypeDef2);
|
|
1399
|
+
for (const td of typeDefs) {
|
|
1400
|
+
let typeDef = ts.factory.createTypeAliasDeclaration([
|
|
1401
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1402
|
+
], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
|
|
1403
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1404
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
|
|
1405
|
+
]));
|
|
1406
|
+
if (td.comments.length > 0) {
|
|
1407
|
+
typeDef = this.generateDocs(typeDef, td);
|
|
1408
|
+
}
|
|
1409
|
+
statements.push(typeDef);
|
|
1410
|
+
}
|
|
1411
|
+
const enums = model.declarations.filter(isEnum);
|
|
1412
|
+
for (const e of enums) {
|
|
1413
|
+
let enumDecl = ts.factory.createVariableStatement([
|
|
1414
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1415
|
+
], ts.factory.createVariableDeclarationList([
|
|
1416
|
+
ts.factory.createVariableDeclaration(e.name, void 0, void 0, ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("$schema"), ts.factory.createIdentifier("enums")), ts.factory.createIdentifier(e.name)))
|
|
1417
|
+
], ts.NodeFlags.Const));
|
|
1418
|
+
if (e.comments.length > 0) {
|
|
1419
|
+
enumDecl = this.generateDocs(enumDecl, e);
|
|
1420
|
+
}
|
|
1421
|
+
statements.push(enumDecl);
|
|
1422
|
+
let typeAlias = ts.factory.createTypeAliasDeclaration([
|
|
1423
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1424
|
+
], e.name, void 0, ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)), ts.factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)))));
|
|
1425
|
+
if (e.comments.length > 0) {
|
|
1426
|
+
typeAlias = this.generateDocs(typeAlias, e);
|
|
1427
|
+
}
|
|
1428
|
+
statements.push(typeAlias);
|
|
1429
|
+
}
|
|
1430
|
+
this.generateBannerComments(statements);
|
|
1431
|
+
const outputFile = path.join(outputDir, "models.ts");
|
|
1432
|
+
const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
1433
|
+
const printer = ts.createPrinter();
|
|
1434
|
+
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
1435
|
+
fs.writeFileSync(outputFile, result);
|
|
1436
|
+
}
|
|
1437
|
+
generateSchemaImport(model, schemaObject, schemaType) {
|
|
1438
|
+
const importSpecifiers = [];
|
|
1439
|
+
if (schemaObject) {
|
|
1440
|
+
if (model.declarations.some(isEnum)) {
|
|
1441
|
+
importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
if (schemaType) {
|
|
1445
|
+
importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
|
|
1446
|
+
}
|
|
1447
|
+
return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
|
|
1448
|
+
}
|
|
1449
|
+
generateDocs(tsDecl, decl) {
|
|
1450
|
+
return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
|
|
1451
|
+
* ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
|
|
1452
|
+
`, true);
|
|
1453
|
+
}
|
|
1454
|
+
generateInputTypes(model, outputDir) {
|
|
1455
|
+
const dataModels = model.declarations.filter(isDataModel3);
|
|
1456
|
+
const statements = [];
|
|
1457
|
+
statements.push(this.generateSchemaImport(model, false, true));
|
|
1458
|
+
const inputTypes = [
|
|
1459
|
+
"FindManyArgs",
|
|
1460
|
+
"FindUniqueArgs",
|
|
1461
|
+
"FindFirstArgs",
|
|
1462
|
+
"CreateArgs",
|
|
1463
|
+
"CreateManyArgs",
|
|
1464
|
+
"CreateManyAndReturnArgs",
|
|
1465
|
+
"UpdateArgs",
|
|
1466
|
+
"UpdateManyArgs",
|
|
1467
|
+
"UpdateManyAndReturnArgs",
|
|
1468
|
+
"UpsertArgs",
|
|
1469
|
+
"DeleteArgs",
|
|
1470
|
+
"DeleteManyArgs",
|
|
1471
|
+
"CountArgs",
|
|
1472
|
+
"AggregateArgs",
|
|
1473
|
+
"GroupByArgs",
|
|
1474
|
+
"WhereInput",
|
|
1475
|
+
"SelectInput",
|
|
1476
|
+
"IncludeInput",
|
|
1477
|
+
"OmitInput"
|
|
1478
|
+
];
|
|
1479
|
+
const inputTypeNameFixes = {
|
|
1480
|
+
SelectInput: "Select",
|
|
1481
|
+
IncludeInput: "Include",
|
|
1482
|
+
OmitInput: "Omit"
|
|
1483
|
+
};
|
|
1484
|
+
statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports(inputTypes.map((inputType) => ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(`${inputType} as $${inputType}`))))), ts.factory.createStringLiteral("@zenstackhq/runtime")));
|
|
1485
|
+
statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
|
|
1486
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
|
|
1487
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
|
|
1488
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
|
|
1489
|
+
for (const dm of dataModels) {
|
|
1490
|
+
for (const inputType of inputTypes) {
|
|
1491
|
+
const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
|
|
1492
|
+
statements.push(ts.factory.createTypeAliasDeclaration([
|
|
1493
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1494
|
+
], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
|
|
1495
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1496
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
|
|
1497
|
+
])));
|
|
1498
|
+
}
|
|
1499
|
+
statements.push(ts.factory.createTypeAliasDeclaration([
|
|
1500
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1501
|
+
], `${dm.name}GetPayload`, [
|
|
1502
|
+
ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
|
|
1503
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1504
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
|
|
1505
|
+
ts.factory.createLiteralTypeNode(ts.factory.createTrue())
|
|
1506
|
+
]))
|
|
1507
|
+
], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
|
|
1508
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1509
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
|
|
1510
|
+
ts.factory.createTypeReferenceNode("Args")
|
|
1511
|
+
])));
|
|
1512
|
+
}
|
|
1513
|
+
this.generateBannerComments(statements);
|
|
1514
|
+
const outputFile = path.join(outputDir, "input.ts");
|
|
1515
|
+
const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
1516
|
+
const printer = ts.createPrinter();
|
|
1517
|
+
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
1518
|
+
fs.writeFileSync(outputFile, result);
|
|
1519
|
+
}
|
|
1321
1520
|
};
|
|
1322
1521
|
|
|
1323
1522
|
// src/zmodel-code-generator.ts
|
|
1324
|
-
import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataModel as DataModel2, DataModelAttribute,
|
|
1523
|
+
import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataField, DataFieldAttribute, DataModel as DataModel2, DataModelAttribute, 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, UnaryExpr } from "@zenstackhq/language/ast";
|
|
1325
1524
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1326
1525
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1327
1526
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1409,21 +1608,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
|
1409
1608
|
return `${ast.name} = ${this.generate(ast.value)}`;
|
|
1410
1609
|
}
|
|
1411
1610
|
_generateDataModel(ast) {
|
|
1412
|
-
return `${ast.
|
|
1611
|
+
return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
|
|
1413
1612
|
${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") : ""}
|
|
1414
1613
|
}`;
|
|
1415
1614
|
}
|
|
1416
|
-
|
|
1615
|
+
_generateDataField(ast) {
|
|
1417
1616
|
return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1418
1617
|
}
|
|
1419
1618
|
fieldType(type) {
|
|
1420
|
-
const baseType = type.type ? type.type : type.$type == "
|
|
1619
|
+
const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
|
|
1421
1620
|
return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
|
|
1422
1621
|
}
|
|
1423
1622
|
_generateDataModelAttribute(ast) {
|
|
1424
1623
|
return this.attribute(ast);
|
|
1425
1624
|
}
|
|
1426
|
-
|
|
1625
|
+
_generateDataFieldAttribute(ast) {
|
|
1427
1626
|
return this.attribute(ast);
|
|
1428
1627
|
}
|
|
1429
1628
|
attribute(ast) {
|
|
@@ -1507,9 +1706,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
|
|
|
1507
1706
|
${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") : ""}
|
|
1508
1707
|
}`;
|
|
1509
1708
|
}
|
|
1510
|
-
_generateTypeDefField(ast) {
|
|
1511
|
-
return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1512
|
-
}
|
|
1513
1709
|
argument(ast) {
|
|
1514
1710
|
return this.generate(ast.value);
|
|
1515
1711
|
}
|
|
@@ -1635,13 +1831,13 @@ _ts_decorate([
|
|
|
1635
1831
|
_ts_metadata("design:returntype", void 0)
|
|
1636
1832
|
], ZModelCodeGenerator.prototype, "_generateDataModel", null);
|
|
1637
1833
|
_ts_decorate([
|
|
1638
|
-
gen(
|
|
1834
|
+
gen(DataField),
|
|
1639
1835
|
_ts_metadata("design:type", Function),
|
|
1640
1836
|
_ts_metadata("design:paramtypes", [
|
|
1641
|
-
typeof
|
|
1837
|
+
typeof DataField === "undefined" ? Object : DataField
|
|
1642
1838
|
]),
|
|
1643
1839
|
_ts_metadata("design:returntype", void 0)
|
|
1644
|
-
], ZModelCodeGenerator.prototype, "
|
|
1840
|
+
], ZModelCodeGenerator.prototype, "_generateDataField", null);
|
|
1645
1841
|
_ts_decorate([
|
|
1646
1842
|
gen(DataModelAttribute),
|
|
1647
1843
|
_ts_metadata("design:type", Function),
|
|
@@ -1651,13 +1847,13 @@ _ts_decorate([
|
|
|
1651
1847
|
_ts_metadata("design:returntype", void 0)
|
|
1652
1848
|
], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
|
|
1653
1849
|
_ts_decorate([
|
|
1654
|
-
gen(
|
|
1850
|
+
gen(DataFieldAttribute),
|
|
1655
1851
|
_ts_metadata("design:type", Function),
|
|
1656
1852
|
_ts_metadata("design:paramtypes", [
|
|
1657
|
-
typeof
|
|
1853
|
+
typeof DataFieldAttribute === "undefined" ? Object : DataFieldAttribute
|
|
1658
1854
|
]),
|
|
1659
1855
|
_ts_metadata("design:returntype", void 0)
|
|
1660
|
-
], ZModelCodeGenerator.prototype, "
|
|
1856
|
+
], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
|
|
1661
1857
|
_ts_decorate([
|
|
1662
1858
|
gen(AttributeArg2),
|
|
1663
1859
|
_ts_metadata("design:type", Function),
|
|
@@ -1822,14 +2018,6 @@ _ts_decorate([
|
|
|
1822
2018
|
]),
|
|
1823
2019
|
_ts_metadata("design:returntype", void 0)
|
|
1824
2020
|
], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
|
|
1825
|
-
_ts_decorate([
|
|
1826
|
-
gen(TypeDefField),
|
|
1827
|
-
_ts_metadata("design:type", Function),
|
|
1828
|
-
_ts_metadata("design:paramtypes", [
|
|
1829
|
-
typeof TypeDefField === "undefined" ? Object : TypeDefField
|
|
1830
|
-
]),
|
|
1831
|
-
_ts_metadata("design:returntype", void 0)
|
|
1832
|
-
], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
|
|
1833
2021
|
export {
|
|
1834
2022
|
model_utils_exports as ModelUtils,
|
|
1835
2023
|
PrismaSchemaGenerator,
|