@zenstackhq/sdk 3.0.0-alpha.9 → 3.0.0-beta.10
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 +396 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -34
- package/dist/index.d.ts +73 -34
- package/dist/index.js +408 -203
- package/dist/index.js.map +1 -1
- package/dist/schema.d.cts +46 -17
- package/dist/schema.d.ts +46 -17
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -41,12 +41,11 @@ module.exports = __toCommonJS(src_exports);
|
|
|
41
41
|
// src/model-utils.ts
|
|
42
42
|
var model_utils_exports = {};
|
|
43
43
|
__export(model_utils_exports, {
|
|
44
|
+
DELEGATE_AUX_RELATION_PREFIX: () => DELEGATE_AUX_RELATION_PREFIX,
|
|
44
45
|
getAttribute: () => getAttribute,
|
|
45
46
|
getAuthDecl: () => getAuthDecl,
|
|
46
47
|
getContainingModel: () => getContainingModel,
|
|
47
|
-
|
|
48
|
-
getModelUniqueFields: () => getModelUniqueFields,
|
|
49
|
-
getRecursiveBases: () => getRecursiveBases,
|
|
48
|
+
getIdFields: () => getIdFields,
|
|
50
49
|
hasAttribute: () => hasAttribute,
|
|
51
50
|
isDelegateModel: () => isDelegateModel,
|
|
52
51
|
isFromStdlib: () => isFromStdlib,
|
|
@@ -55,23 +54,24 @@ __export(model_utils_exports, {
|
|
|
55
54
|
resolved: () => resolved
|
|
56
55
|
});
|
|
57
56
|
var import_ast = require("@zenstackhq/language/ast");
|
|
58
|
-
|
|
57
|
+
var import_utils = require("@zenstackhq/language/utils");
|
|
58
|
+
function isIdField(field, contextModel) {
|
|
59
59
|
if (hasAttribute(field, "@id")) {
|
|
60
60
|
return true;
|
|
61
61
|
}
|
|
62
|
-
const
|
|
63
|
-
const modelLevelIds = getModelIdFields(model);
|
|
62
|
+
const modelLevelIds = (0, import_utils.getModelIdFields)(contextModel);
|
|
64
63
|
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
|
|
65
64
|
return true;
|
|
66
65
|
}
|
|
67
|
-
|
|
66
|
+
const allFields = (0, import_utils.getAllFields)(contextModel);
|
|
67
|
+
if (allFields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
|
|
68
68
|
return false;
|
|
69
69
|
}
|
|
70
|
-
const firstUniqueField =
|
|
70
|
+
const firstUniqueField = allFields.find((f) => hasAttribute(f, "@unique"));
|
|
71
71
|
if (firstUniqueField) {
|
|
72
72
|
return firstUniqueField.name === field.name;
|
|
73
73
|
}
|
|
74
|
-
const modelLevelUnique = getModelUniqueFields(
|
|
74
|
+
const modelLevelUnique = (0, import_utils.getModelUniqueFields)(contextModel);
|
|
75
75
|
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
|
|
76
76
|
return true;
|
|
77
77
|
}
|
|
@@ -86,67 +86,6 @@ function getAttribute(decl, name) {
|
|
|
86
86
|
return decl.attributes.find((attr) => attr.decl.$refText === name);
|
|
87
87
|
}
|
|
88
88
|
__name(getAttribute, "getAttribute");
|
|
89
|
-
function getModelIdFields(model) {
|
|
90
|
-
const modelsToCheck = model.$baseMerged ? [
|
|
91
|
-
model
|
|
92
|
-
] : [
|
|
93
|
-
model,
|
|
94
|
-
...getRecursiveBases(model)
|
|
95
|
-
];
|
|
96
|
-
for (const modelToCheck of modelsToCheck) {
|
|
97
|
-
const idAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@id");
|
|
98
|
-
if (!idAttr) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === "fields");
|
|
102
|
-
if (!fieldsArg || !(0, import_ast.isArrayExpr)(fieldsArg.value)) {
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
return fieldsArg.value.items.filter((item) => (0, import_ast.isReferenceExpr)(item)).map((item) => item.target.ref);
|
|
106
|
-
}
|
|
107
|
-
return [];
|
|
108
|
-
}
|
|
109
|
-
__name(getModelIdFields, "getModelIdFields");
|
|
110
|
-
function getModelUniqueFields(model) {
|
|
111
|
-
const modelsToCheck = model.$baseMerged ? [
|
|
112
|
-
model
|
|
113
|
-
] : [
|
|
114
|
-
model,
|
|
115
|
-
...getRecursiveBases(model)
|
|
116
|
-
];
|
|
117
|
-
for (const modelToCheck of modelsToCheck) {
|
|
118
|
-
const uniqueAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@unique");
|
|
119
|
-
if (!uniqueAttr) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === "fields");
|
|
123
|
-
if (!fieldsArg || !(0, import_ast.isArrayExpr)(fieldsArg.value)) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
return fieldsArg.value.items.filter((item) => (0, import_ast.isReferenceExpr)(item)).map((item) => item.target.ref);
|
|
127
|
-
}
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
__name(getModelUniqueFields, "getModelUniqueFields");
|
|
131
|
-
function getRecursiveBases(dataModel, includeDelegate = true, seen = /* @__PURE__ */ new Set()) {
|
|
132
|
-
const result = [];
|
|
133
|
-
if (seen.has(dataModel)) {
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
seen.add(dataModel);
|
|
137
|
-
dataModel.superTypes.forEach((superType) => {
|
|
138
|
-
const baseDecl = superType.ref;
|
|
139
|
-
if (baseDecl) {
|
|
140
|
-
if (!includeDelegate && isDelegateModel(baseDecl)) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
result.push(baseDecl);
|
|
144
|
-
result.push(...getRecursiveBases(baseDecl, includeDelegate, seen));
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
|
-
__name(getRecursiveBases, "getRecursiveBases");
|
|
150
89
|
function isDelegateModel(node) {
|
|
151
90
|
return (0, import_ast.isDataModel)(node) && hasAttribute(node, "@@delegate");
|
|
152
91
|
}
|
|
@@ -182,16 +121,23 @@ function resolved(ref) {
|
|
|
182
121
|
}
|
|
183
122
|
__name(resolved, "resolved");
|
|
184
123
|
function getAuthDecl(model) {
|
|
185
|
-
let found = model.declarations.find((d) => (0, import_ast.isDataModel)(d) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
|
|
124
|
+
let found = model.declarations.find((d) => ((0, import_ast.isDataModel)(d) || (0, import_ast.isTypeDef)(d)) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
|
|
186
125
|
if (!found) {
|
|
187
126
|
found = model.declarations.find((d) => (0, import_ast.isDataModel)(d) && d.name === "User");
|
|
188
127
|
}
|
|
189
128
|
return found;
|
|
190
129
|
}
|
|
191
130
|
__name(getAuthDecl, "getAuthDecl");
|
|
131
|
+
function getIdFields(dm) {
|
|
132
|
+
return (0, import_utils.getAllFields)(dm).filter((f) => isIdField(f, dm)).map((f) => f.name);
|
|
133
|
+
}
|
|
134
|
+
__name(getIdFields, "getIdFields");
|
|
135
|
+
var DELEGATE_AUX_RELATION_PREFIX = "delegate_aux";
|
|
192
136
|
|
|
193
137
|
// src/prisma/prisma-schema-generator.ts
|
|
138
|
+
var import_common_helpers = require("@zenstackhq/common-helpers");
|
|
194
139
|
var import_ast2 = require("@zenstackhq/language/ast");
|
|
140
|
+
var import_utils2 = require("@zenstackhq/language/utils");
|
|
195
141
|
var import_langium = require("langium");
|
|
196
142
|
var import_ts_pattern = require("ts-pattern");
|
|
197
143
|
|
|
@@ -586,6 +532,7 @@ var EnumField = class extends DeclarationBase {
|
|
|
586
532
|
};
|
|
587
533
|
|
|
588
534
|
// src/prisma/prisma-schema-generator.ts
|
|
535
|
+
var IDENTIFIER_NAME_MAX_LENGTH = 50 - DELEGATE_AUX_RELATION_PREFIX.length;
|
|
589
536
|
var PrismaSchemaGenerator = class {
|
|
590
537
|
static {
|
|
591
538
|
__name(this, "PrismaSchemaGenerator");
|
|
@@ -597,6 +544,8 @@ var PrismaSchemaGenerator = class {
|
|
|
597
544
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
598
545
|
|
|
599
546
|
`;
|
|
547
|
+
// a mapping from full names to shortened names
|
|
548
|
+
shortNameMap = /* @__PURE__ */ new Map();
|
|
600
549
|
constructor(zmodel) {
|
|
601
550
|
this.zmodel = zmodel;
|
|
602
551
|
}
|
|
@@ -660,16 +609,29 @@ var PrismaSchemaGenerator = class {
|
|
|
660
609
|
}
|
|
661
610
|
generateModel(prisma, decl) {
|
|
662
611
|
const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
|
|
663
|
-
|
|
612
|
+
const allFields = (0, import_utils2.getAllFields)(decl, true);
|
|
613
|
+
for (const field of allFields) {
|
|
664
614
|
if (model_utils_exports.hasAttribute(field, "@computed")) {
|
|
665
615
|
continue;
|
|
666
616
|
}
|
|
667
|
-
this.
|
|
617
|
+
if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
|
|
618
|
+
this.generateModelField(model, field, decl);
|
|
619
|
+
}
|
|
668
620
|
}
|
|
669
|
-
|
|
621
|
+
const allAttributes = (0, import_utils2.getAllAttributes)(decl);
|
|
622
|
+
for (const attr of allAttributes.filter((attr2) => this.isPrismaAttribute(attr2) && !this.isInheritedMapAttribute(attr2, decl))) {
|
|
670
623
|
this.generateContainerAttribute(model, attr);
|
|
671
624
|
}
|
|
672
625
|
decl.comments.forEach((c) => model.addComment(c));
|
|
626
|
+
this.generateDelegateRelationForBase(model, decl);
|
|
627
|
+
this.generateDelegateRelationForConcrete(model, decl);
|
|
628
|
+
}
|
|
629
|
+
isInheritedMapAttribute(attr, contextModel) {
|
|
630
|
+
if (attr.$container === contextModel) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
const attrName = attr.decl.ref?.name ?? attr.decl.$refText;
|
|
634
|
+
return attrName === "@@map";
|
|
673
635
|
}
|
|
674
636
|
isPrismaAttribute(attr) {
|
|
675
637
|
if (!attr.decl.ref) {
|
|
@@ -692,7 +654,7 @@ var PrismaSchemaGenerator = class {
|
|
|
692
654
|
getStringLiteral(node) {
|
|
693
655
|
return (0, import_ast2.isStringLiteral)(node) ? node.value : void 0;
|
|
694
656
|
}
|
|
695
|
-
generateModelField(model, field, addToFront = false) {
|
|
657
|
+
generateModelField(model, field, contextModel, addToFront = false) {
|
|
696
658
|
let fieldType;
|
|
697
659
|
if (field.type.type) {
|
|
698
660
|
fieldType = field.type.type;
|
|
@@ -716,9 +678,9 @@ var PrismaSchemaGenerator = class {
|
|
|
716
678
|
(0, import_ast2.isTypeDef)(field.type.reference?.ref) ? false : field.type.array
|
|
717
679
|
);
|
|
718
680
|
const type = new ModelFieldType(fieldType, isArray, field.type.optional);
|
|
719
|
-
const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.
|
|
681
|
+
const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithAuthInvocation(attr)).filter((attr) => (
|
|
720
682
|
// when building physical schema, exclude `@default` for id fields inherited from delegate base
|
|
721
|
-
!(model_utils_exports.isIdField(field) && this.isInheritedFromDelegate(field) && attr.decl.$refText === "@default")
|
|
683
|
+
!(model_utils_exports.isIdField(field, contextModel) && this.isInheritedFromDelegate(field, contextModel) && attr.decl.$refText === "@default")
|
|
722
684
|
)).map((attr) => this.makeFieldAttribute(attr));
|
|
723
685
|
const docs = [
|
|
724
686
|
...field.comments
|
|
@@ -726,7 +688,7 @@ var PrismaSchemaGenerator = class {
|
|
|
726
688
|
const result = model.addField(field.name, type, attributes, docs, addToFront);
|
|
727
689
|
return result;
|
|
728
690
|
}
|
|
729
|
-
|
|
691
|
+
isDefaultWithAuthInvocation(attr) {
|
|
730
692
|
if (attr.decl.ref?.name !== "@default") {
|
|
731
693
|
return false;
|
|
732
694
|
}
|
|
@@ -734,22 +696,10 @@ var PrismaSchemaGenerator = class {
|
|
|
734
696
|
if (!expr) {
|
|
735
697
|
return false;
|
|
736
698
|
}
|
|
737
|
-
return import_langium.AstUtils.streamAst(expr).some(
|
|
699
|
+
return import_langium.AstUtils.streamAst(expr).some(import_utils2.isAuthInvocation);
|
|
738
700
|
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
|
|
742
|
-
}
|
|
743
|
-
setDummyDefault(result, field) {
|
|
744
|
-
const dummyDefaultValue = (0, import_ts_pattern.match)(field.type.type).with("String", () => new AttributeArgValue("String", "")).with(import_ts_pattern.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(() => {
|
|
745
|
-
throw new Error(`Unsupported field type with default value: ${field.type.type}`);
|
|
746
|
-
});
|
|
747
|
-
result.attributes.push(new FieldAttribute("@default", [
|
|
748
|
-
new AttributeArg(void 0, dummyDefaultValue)
|
|
749
|
-
]));
|
|
750
|
-
}
|
|
751
|
-
isInheritedFromDelegate(field) {
|
|
752
|
-
return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
|
|
701
|
+
isInheritedFromDelegate(field, contextModel) {
|
|
702
|
+
return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
|
|
753
703
|
}
|
|
754
704
|
makeFieldAttribute(attr) {
|
|
755
705
|
const attrName = attr.decl.ref.name;
|
|
@@ -806,12 +756,66 @@ var PrismaSchemaGenerator = class {
|
|
|
806
756
|
];
|
|
807
757
|
_enum.addField(field.name, attributes, docs);
|
|
808
758
|
}
|
|
759
|
+
generateDelegateRelationForBase(model, decl) {
|
|
760
|
+
if (!(0, import_utils2.isDelegateModel)(decl)) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
const concreteModels = this.getConcreteModels(decl);
|
|
764
|
+
concreteModels.forEach((concrete) => {
|
|
765
|
+
const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(concrete.name)}`);
|
|
766
|
+
model.addField(auxName, new ModelFieldType(concrete.name, false, true));
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
generateDelegateRelationForConcrete(model, concreteDecl) {
|
|
770
|
+
const base = concreteDecl.baseModel?.ref;
|
|
771
|
+
if (!base) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
const idFields = getIdFields(base);
|
|
775
|
+
const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(base.name)}`);
|
|
776
|
+
model.addField(relationField, base.name, [
|
|
777
|
+
new FieldAttribute("@relation", [
|
|
778
|
+
new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
|
|
779
|
+
new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
|
|
780
|
+
new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
|
|
781
|
+
new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
|
|
782
|
+
])
|
|
783
|
+
]);
|
|
784
|
+
}
|
|
785
|
+
getConcreteModels(dataModel) {
|
|
786
|
+
if (!(0, import_utils2.isDelegateModel)(dataModel)) {
|
|
787
|
+
return [];
|
|
788
|
+
}
|
|
789
|
+
return dataModel.$container.declarations.filter((d) => (0, import_ast2.isDataModel)(d) && d !== dataModel && d.baseModel?.ref === dataModel);
|
|
790
|
+
}
|
|
791
|
+
truncate(name) {
|
|
792
|
+
if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
|
|
793
|
+
return name;
|
|
794
|
+
}
|
|
795
|
+
const existing = this.shortNameMap.get(name);
|
|
796
|
+
if (existing) {
|
|
797
|
+
return existing;
|
|
798
|
+
}
|
|
799
|
+
const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
|
|
800
|
+
let index = 0;
|
|
801
|
+
let shortName = `${baseName}_${index}`;
|
|
802
|
+
while (true) {
|
|
803
|
+
const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
|
|
804
|
+
if (!conflict) {
|
|
805
|
+
this.shortNameMap.set(name, shortName);
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
index++;
|
|
809
|
+
shortName = `${baseName}_${index}`;
|
|
810
|
+
}
|
|
811
|
+
return shortName;
|
|
812
|
+
}
|
|
809
813
|
};
|
|
810
814
|
|
|
811
815
|
// src/ts-schema-generator.ts
|
|
812
|
-
var
|
|
813
|
-
var import_language = require("@zenstackhq/language");
|
|
816
|
+
var import_common_helpers2 = require("@zenstackhq/common-helpers");
|
|
814
817
|
var import_ast3 = require("@zenstackhq/language/ast");
|
|
818
|
+
var import_utils3 = require("@zenstackhq/language/utils");
|
|
815
819
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
816
820
|
var import_node_path = __toESM(require("path"), 1);
|
|
817
821
|
var import_ts_pattern2 = require("ts-pattern");
|
|
@@ -820,41 +824,43 @@ var TsSchemaGenerator = class {
|
|
|
820
824
|
static {
|
|
821
825
|
__name(this, "TsSchemaGenerator");
|
|
822
826
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
|
|
827
|
+
usedExpressionUtils = false;
|
|
828
|
+
async generate(model, outputDir) {
|
|
829
|
+
import_node_fs.default.mkdirSync(outputDir, {
|
|
830
|
+
recursive: true
|
|
831
|
+
});
|
|
832
|
+
this.usedExpressionUtils = false;
|
|
833
|
+
this.generateSchema(model, outputDir);
|
|
834
|
+
this.generateModelsAndTypeDefs(model, outputDir);
|
|
835
|
+
this.generateInputTypes(model, outputDir);
|
|
836
|
+
}
|
|
837
|
+
generateSchema(model, outputDir) {
|
|
829
838
|
const statements = [];
|
|
830
839
|
this.generateSchemaStatements(model, statements);
|
|
831
840
|
this.generateBannerComments(statements);
|
|
832
|
-
const
|
|
841
|
+
const schemaOutputFile = import_node_path.default.join(outputDir, "schema.ts");
|
|
842
|
+
const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
833
843
|
const printer = ts.createPrinter();
|
|
834
844
|
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
835
|
-
import_node_fs.default.
|
|
836
|
-
recursive: true
|
|
837
|
-
});
|
|
838
|
-
import_node_fs.default.writeFileSync(outputFile, result);
|
|
839
|
-
return {
|
|
840
|
-
model,
|
|
841
|
-
warnings
|
|
842
|
-
};
|
|
845
|
+
import_node_fs.default.writeFileSync(schemaOutputFile, result);
|
|
843
846
|
}
|
|
844
847
|
generateSchemaStatements(model, statements) {
|
|
845
848
|
const hasComputedFields = model.declarations.some((d) => (0, import_ast3.isDataModel)(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
|
|
849
|
+
const schemaObject = this.createSchemaObject(model);
|
|
846
850
|
const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
847
851
|
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
|
|
848
852
|
...hasComputedFields ? [
|
|
849
853
|
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("OperandExpression"))
|
|
850
854
|
] : [],
|
|
851
|
-
|
|
855
|
+
...this.usedExpressionUtils ? [
|
|
856
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
|
|
857
|
+
] : []
|
|
852
858
|
])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
|
|
853
859
|
statements.push(runtimeImportDecl);
|
|
854
860
|
const declaration = ts.factory.createVariableStatement([
|
|
855
861
|
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
856
862
|
], ts.factory.createVariableDeclarationList([
|
|
857
|
-
ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createSatisfiesExpression(ts.factory.createAsExpression(
|
|
863
|
+
ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createSatisfiesExpression(ts.factory.createAsExpression(schemaObject, ts.factory.createTypeReferenceNode("const")), ts.factory.createTypeReferenceNode("SchemaDef")))
|
|
858
864
|
], ts.NodeFlags.Const));
|
|
859
865
|
statements.push(declaration);
|
|
860
866
|
const typeDeclaration = ts.factory.createTypeAliasDeclaration([
|
|
@@ -862,12 +868,20 @@ var TsSchemaGenerator = class {
|
|
|
862
868
|
], "SchemaType", void 0, ts.factory.createTypeReferenceNode("typeof schema"));
|
|
863
869
|
statements.push(typeDeclaration);
|
|
864
870
|
}
|
|
871
|
+
createExpressionUtilsCall(method, args) {
|
|
872
|
+
this.usedExpressionUtils = true;
|
|
873
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("ExpressionUtils"), method), void 0, args || []);
|
|
874
|
+
}
|
|
865
875
|
createSchemaObject(model) {
|
|
866
876
|
const properties = [
|
|
867
877
|
// provider
|
|
868
878
|
ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
|
|
869
879
|
// models
|
|
870
|
-
ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
|
|
880
|
+
ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
|
|
881
|
+
// typeDefs
|
|
882
|
+
...model.declarations.some(import_ast3.isTypeDef) ? [
|
|
883
|
+
ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
|
|
884
|
+
] : []
|
|
871
885
|
];
|
|
872
886
|
const enums = model.declarations.filter(import_ast3.isEnum);
|
|
873
887
|
if (enums.length > 0) {
|
|
@@ -893,18 +907,46 @@ var TsSchemaGenerator = class {
|
|
|
893
907
|
createModelsObject(model) {
|
|
894
908
|
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => (0, import_ast3.isDataModel)(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
|
|
895
909
|
}
|
|
910
|
+
createTypeDefsObject(model) {
|
|
911
|
+
return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => (0, import_ast3.isTypeDef)(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
|
|
912
|
+
}
|
|
896
913
|
createDataModelObject(dm) {
|
|
914
|
+
const allFields = (0, import_utils3.getAllFields)(dm);
|
|
915
|
+
const allAttributes = (0, import_utils3.getAllAttributes)(dm).filter((attr) => {
|
|
916
|
+
if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
|
|
917
|
+
return false;
|
|
918
|
+
}
|
|
919
|
+
return true;
|
|
920
|
+
});
|
|
921
|
+
const subModels = this.getSubModels(dm);
|
|
897
922
|
const fields = [
|
|
923
|
+
// name
|
|
924
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
|
|
925
|
+
// baseModel
|
|
926
|
+
...dm.baseModel ? [
|
|
927
|
+
ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
|
|
928
|
+
] : [],
|
|
898
929
|
// fields
|
|
899
|
-
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(
|
|
930
|
+
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
|
|
900
931
|
// attributes
|
|
901
|
-
...
|
|
902
|
-
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(
|
|
932
|
+
...allAttributes.length > 0 ? [
|
|
933
|
+
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
|
|
903
934
|
] : [],
|
|
904
935
|
// idFields
|
|
905
|
-
ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(
|
|
936
|
+
ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
|
|
906
937
|
// uniqueFields
|
|
907
|
-
ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
|
|
938
|
+
ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
|
|
939
|
+
// isDelegate
|
|
940
|
+
...isDelegateModel(dm) ? [
|
|
941
|
+
ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
|
|
942
|
+
] : [],
|
|
943
|
+
// subModels
|
|
944
|
+
...subModels.length > 0 ? [
|
|
945
|
+
ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
|
|
946
|
+
] : [],
|
|
947
|
+
...dm.isView ? [
|
|
948
|
+
ts.factory.createPropertyAssignment("isView", ts.factory.createTrue())
|
|
949
|
+
] : []
|
|
908
950
|
];
|
|
909
951
|
const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
|
|
910
952
|
if (computedFields.length > 0) {
|
|
@@ -912,8 +954,31 @@ var TsSchemaGenerator = class {
|
|
|
912
954
|
}
|
|
913
955
|
return ts.factory.createObjectLiteralExpression(fields, true);
|
|
914
956
|
}
|
|
957
|
+
getSubModels(dm) {
|
|
958
|
+
return dm.$container.declarations.filter(import_ast3.isDataModel).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
|
|
959
|
+
}
|
|
960
|
+
createTypeDefObject(td) {
|
|
961
|
+
const allFields = (0, import_utils3.getAllFields)(td);
|
|
962
|
+
const allAttributes = (0, import_utils3.getAllAttributes)(td);
|
|
963
|
+
const fields = [
|
|
964
|
+
// name
|
|
965
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
|
|
966
|
+
// fields
|
|
967
|
+
ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
|
|
968
|
+
// attributes
|
|
969
|
+
...allAttributes.length > 0 ? [
|
|
970
|
+
ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
|
|
971
|
+
] : []
|
|
972
|
+
];
|
|
973
|
+
return ts.factory.createObjectLiteralExpression(fields, true);
|
|
974
|
+
}
|
|
915
975
|
createComputedFieldsObject(fields) {
|
|
916
|
-
return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
|
|
976
|
+
return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
|
|
977
|
+
// parameter: `context: { modelAlias: string }`
|
|
978
|
+
ts.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, ts.factory.createTypeLiteralNode([
|
|
979
|
+
ts.factory.createPropertySignature(void 0, "modelAlias", void 0, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
|
|
980
|
+
]), void 0)
|
|
981
|
+
], ts.factory.createTypeReferenceNode("OperandExpression", [
|
|
917
982
|
ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
|
|
918
983
|
]), ts.factory.createBlock([
|
|
919
984
|
ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
|
|
@@ -931,11 +996,14 @@ var TsSchemaGenerator = class {
|
|
|
931
996
|
}
|
|
932
997
|
return result;
|
|
933
998
|
}
|
|
934
|
-
|
|
999
|
+
createDataFieldObject(field, contextModel) {
|
|
935
1000
|
const objectFields = [
|
|
1001
|
+
// name
|
|
1002
|
+
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
|
|
1003
|
+
// type
|
|
936
1004
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
|
|
937
1005
|
];
|
|
938
|
-
if (isIdField(field)) {
|
|
1006
|
+
if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
|
|
939
1007
|
objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
|
|
940
1008
|
}
|
|
941
1009
|
if (isUniqueField(field)) {
|
|
@@ -950,6 +1018,13 @@ var TsSchemaGenerator = class {
|
|
|
950
1018
|
if (hasAttribute(field, "@updatedAt")) {
|
|
951
1019
|
objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
|
|
952
1020
|
}
|
|
1021
|
+
if (contextModel && // id fields are duplicated in inherited models
|
|
1022
|
+
!isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
|
|
1023
|
+
objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
|
|
1024
|
+
}
|
|
1025
|
+
if (this.isDiscriminatorField(field)) {
|
|
1026
|
+
objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
|
|
1027
|
+
}
|
|
953
1028
|
if (field.attributes.length > 0) {
|
|
954
1029
|
objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
|
|
955
1030
|
}
|
|
@@ -957,15 +1032,17 @@ var TsSchemaGenerator = class {
|
|
|
957
1032
|
if (defaultValue !== void 0) {
|
|
958
1033
|
if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
|
|
959
1034
|
if ("call" in defaultValue) {
|
|
960
|
-
objectFields.push(ts.factory.createPropertyAssignment("default",
|
|
1035
|
+
objectFields.push(ts.factory.createPropertyAssignment("default", this.createExpressionUtilsCall("call", [
|
|
961
1036
|
ts.factory.createStringLiteral(defaultValue.call),
|
|
962
1037
|
...defaultValue.args.length > 0 ? [
|
|
963
|
-
ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.
|
|
1038
|
+
ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createExpressionUtilsCall("literal", [
|
|
1039
|
+
this.createLiteralNode(arg)
|
|
1040
|
+
])))
|
|
964
1041
|
] : []
|
|
965
1042
|
])));
|
|
966
1043
|
} else if ("authMember" in defaultValue) {
|
|
967
|
-
objectFields.push(ts.factory.createPropertyAssignment("default",
|
|
968
|
-
|
|
1044
|
+
objectFields.push(ts.factory.createPropertyAssignment("default", this.createExpressionUtilsCall("member", [
|
|
1045
|
+
this.createExpressionUtilsCall("call", [
|
|
969
1046
|
ts.factory.createStringLiteral("auth")
|
|
970
1047
|
]),
|
|
971
1048
|
ts.factory.createArrayLiteralExpression(defaultValue.authMember.map((m) => ts.factory.createStringLiteral(m)))
|
|
@@ -993,31 +1070,19 @@ var TsSchemaGenerator = class {
|
|
|
993
1070
|
}
|
|
994
1071
|
return ts.factory.createObjectLiteralExpression(objectFields, true);
|
|
995
1072
|
}
|
|
1073
|
+
isDiscriminatorField(field) {
|
|
1074
|
+
const origin = field.$container;
|
|
1075
|
+
return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && (0, import_utils3.isDataFieldReference)(arg.value) && arg.value.target.ref === field);
|
|
1076
|
+
}
|
|
996
1077
|
getDataSourceProvider(model) {
|
|
997
1078
|
const dataSource = model.declarations.find(import_ast3.isDataSource);
|
|
998
|
-
(0,
|
|
1079
|
+
(0, import_common_helpers2.invariant)(dataSource, "No data source found in the model");
|
|
999
1080
|
const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
|
|
1000
|
-
(0,
|
|
1081
|
+
(0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
|
|
1001
1082
|
const type = providerExpr.value;
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
return {
|
|
1006
|
-
type,
|
|
1007
|
-
url: urlExpr.value,
|
|
1008
|
-
env: void 0
|
|
1009
|
-
};
|
|
1010
|
-
} else if ((0, import_ast3.isInvocationExpr)(urlExpr)) {
|
|
1011
|
-
(0, import_common_helpers.invariant)(urlExpr.function.$refText === "env", 'only "env" function is supported');
|
|
1012
|
-
(0, import_common_helpers.invariant)(urlExpr.args.length === 1, "env function must have one argument");
|
|
1013
|
-
return {
|
|
1014
|
-
type,
|
|
1015
|
-
env: urlExpr.args[0].value.value,
|
|
1016
|
-
url: void 0
|
|
1017
|
-
};
|
|
1018
|
-
} else {
|
|
1019
|
-
throw new Error("Unsupported URL type");
|
|
1020
|
-
}
|
|
1083
|
+
return {
|
|
1084
|
+
type
|
|
1085
|
+
};
|
|
1021
1086
|
}
|
|
1022
1087
|
getFieldMappedDefault(field) {
|
|
1023
1088
|
const defaultAttr = getAttribute(field, "@default");
|
|
@@ -1025,7 +1090,7 @@ var TsSchemaGenerator = class {
|
|
|
1025
1090
|
return void 0;
|
|
1026
1091
|
}
|
|
1027
1092
|
const defaultValue = defaultAttr.args[0]?.value;
|
|
1028
|
-
(0,
|
|
1093
|
+
(0, import_common_helpers2.invariant)(defaultValue, "Expected a default value");
|
|
1029
1094
|
return this.getMappedValue(defaultValue, field.type);
|
|
1030
1095
|
}
|
|
1031
1096
|
getMappedValue(expr, fieldType) {
|
|
@@ -1150,44 +1215,43 @@ var TsSchemaGenerator = class {
|
|
|
1150
1215
|
if (relation) {
|
|
1151
1216
|
const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
|
|
1152
1217
|
if (nameArg) {
|
|
1153
|
-
(0,
|
|
1218
|
+
(0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
|
|
1154
1219
|
return nameArg.value.value;
|
|
1155
1220
|
}
|
|
1156
1221
|
}
|
|
1157
1222
|
return void 0;
|
|
1158
1223
|
}
|
|
1159
|
-
getIdFields(dm) {
|
|
1160
|
-
return dm.fields.filter(isIdField).map((f) => f.name);
|
|
1161
|
-
}
|
|
1162
1224
|
createUniqueFieldsObject(dm) {
|
|
1163
1225
|
const properties = [];
|
|
1164
|
-
|
|
1226
|
+
const allFields = (0, import_utils3.getAllFields)(dm);
|
|
1227
|
+
for (const field of allFields) {
|
|
1165
1228
|
if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
|
|
1166
1229
|
properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
|
|
1167
1230
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
|
|
1168
1231
|
])));
|
|
1169
1232
|
}
|
|
1170
1233
|
}
|
|
1234
|
+
const allAttributes = (0, import_utils3.getAllAttributes)(dm);
|
|
1171
1235
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
1172
|
-
for (const attr of
|
|
1236
|
+
for (const attr of allAttributes) {
|
|
1173
1237
|
if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
|
|
1174
1238
|
const fieldNames = this.getReferenceNames(attr.args[0].value);
|
|
1175
1239
|
if (!fieldNames) {
|
|
1176
1240
|
continue;
|
|
1177
1241
|
}
|
|
1178
1242
|
if (fieldNames.length === 1) {
|
|
1179
|
-
const fieldDef =
|
|
1243
|
+
const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
|
|
1180
1244
|
properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
|
|
1181
1245
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
|
|
1182
1246
|
])));
|
|
1183
1247
|
} else {
|
|
1184
|
-
const key =
|
|
1248
|
+
const key = this.getCompoundUniqueKey(attr, fieldNames);
|
|
1185
1249
|
if (seenKeys.has(key)) {
|
|
1186
1250
|
continue;
|
|
1187
1251
|
}
|
|
1188
1252
|
seenKeys.add(key);
|
|
1189
|
-
properties.push(ts.factory.createPropertyAssignment(
|
|
1190
|
-
const fieldDef =
|
|
1253
|
+
properties.push(ts.factory.createPropertyAssignment(key, ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
|
|
1254
|
+
const fieldDef = allFields.find((f) => f.name === field);
|
|
1191
1255
|
return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
|
|
1192
1256
|
ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
|
|
1193
1257
|
]));
|
|
@@ -1197,8 +1261,16 @@ var TsSchemaGenerator = class {
|
|
|
1197
1261
|
}
|
|
1198
1262
|
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
1199
1263
|
}
|
|
1264
|
+
getCompoundUniqueKey(attr, fieldNames) {
|
|
1265
|
+
const nameArg = attr.args.find((arg) => arg.$resolvedParam.name === "name");
|
|
1266
|
+
if (nameArg && (0, import_ast3.isLiteralExpr)(nameArg.value)) {
|
|
1267
|
+
return nameArg.value.value;
|
|
1268
|
+
} else {
|
|
1269
|
+
return fieldNames.join("_");
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1200
1272
|
generateFieldTypeLiteral(field) {
|
|
1201
|
-
(0,
|
|
1273
|
+
(0, import_common_helpers2.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
|
|
1202
1274
|
return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
|
|
1203
1275
|
}
|
|
1204
1276
|
createEnumObject(e) {
|
|
@@ -1284,7 +1356,7 @@ var TsSchemaGenerator = class {
|
|
|
1284
1356
|
});
|
|
1285
1357
|
}
|
|
1286
1358
|
createThisExpression() {
|
|
1287
|
-
return
|
|
1359
|
+
return this.createExpressionUtilsCall("_this");
|
|
1288
1360
|
}
|
|
1289
1361
|
createMemberExpression(expr) {
|
|
1290
1362
|
const members = [];
|
|
@@ -1298,32 +1370,32 @@ var TsSchemaGenerator = class {
|
|
|
1298
1370
|
this.createExpression(receiver),
|
|
1299
1371
|
ts.factory.createArrayLiteralExpression(members.map((m) => ts.factory.createStringLiteral(m)))
|
|
1300
1372
|
];
|
|
1301
|
-
return
|
|
1373
|
+
return this.createExpressionUtilsCall("member", args);
|
|
1302
1374
|
}
|
|
1303
1375
|
createNullExpression() {
|
|
1304
|
-
return
|
|
1376
|
+
return this.createExpressionUtilsCall("_null");
|
|
1305
1377
|
}
|
|
1306
1378
|
createBinaryExpression(expr) {
|
|
1307
|
-
return
|
|
1379
|
+
return this.createExpressionUtilsCall("binary", [
|
|
1308
1380
|
this.createExpression(expr.left),
|
|
1309
1381
|
this.createLiteralNode(expr.operator),
|
|
1310
1382
|
this.createExpression(expr.right)
|
|
1311
1383
|
]);
|
|
1312
1384
|
}
|
|
1313
1385
|
createUnaryExpression(expr) {
|
|
1314
|
-
return
|
|
1386
|
+
return this.createExpressionUtilsCall("unary", [
|
|
1315
1387
|
this.createLiteralNode(expr.operator),
|
|
1316
1388
|
this.createExpression(expr.operand)
|
|
1317
1389
|
]);
|
|
1318
1390
|
}
|
|
1319
1391
|
createArrayExpression(expr) {
|
|
1320
|
-
return
|
|
1392
|
+
return this.createExpressionUtilsCall("array", [
|
|
1321
1393
|
ts.factory.createArrayLiteralExpression(expr.items.map((item) => this.createExpression(item)))
|
|
1322
1394
|
]);
|
|
1323
1395
|
}
|
|
1324
1396
|
createRefExpression(expr) {
|
|
1325
|
-
if ((0, import_ast3.
|
|
1326
|
-
return
|
|
1397
|
+
if ((0, import_ast3.isDataField)(expr.target.ref)) {
|
|
1398
|
+
return this.createExpressionUtilsCall("field", [
|
|
1327
1399
|
this.createLiteralNode(expr.target.$refText)
|
|
1328
1400
|
]);
|
|
1329
1401
|
} else if ((0, import_ast3.isEnumField)(expr.target.ref)) {
|
|
@@ -1333,7 +1405,7 @@ var TsSchemaGenerator = class {
|
|
|
1333
1405
|
}
|
|
1334
1406
|
}
|
|
1335
1407
|
createCallExpression(expr) {
|
|
1336
|
-
return
|
|
1408
|
+
return this.createExpressionUtilsCall("call", [
|
|
1337
1409
|
ts.factory.createStringLiteral(expr.function.$refText),
|
|
1338
1410
|
...expr.args.length > 0 ? [
|
|
1339
1411
|
ts.factory.createArrayLiteralExpression(expr.args.map((arg) => this.createExpression(arg.value)))
|
|
@@ -1341,16 +1413,160 @@ var TsSchemaGenerator = class {
|
|
|
1341
1413
|
]);
|
|
1342
1414
|
}
|
|
1343
1415
|
createLiteralExpression(type, value) {
|
|
1344
|
-
return (0, import_ts_pattern2.match)(type).with("BooleanLiteral", () =>
|
|
1416
|
+
return (0, import_ts_pattern2.match)(type).with("BooleanLiteral", () => this.createExpressionUtilsCall("literal", [
|
|
1345
1417
|
this.createLiteralNode(value)
|
|
1346
|
-
])).with("NumberLiteral", () =>
|
|
1418
|
+
])).with("NumberLiteral", () => this.createExpressionUtilsCall("literal", [
|
|
1347
1419
|
ts.factory.createIdentifier(value)
|
|
1348
|
-
])).with("StringLiteral", () =>
|
|
1420
|
+
])).with("StringLiteral", () => this.createExpressionUtilsCall("literal", [
|
|
1349
1421
|
this.createLiteralNode(value)
|
|
1350
1422
|
])).otherwise(() => {
|
|
1351
1423
|
throw new Error(`Unsupported literal type: ${type}`);
|
|
1352
1424
|
});
|
|
1353
1425
|
}
|
|
1426
|
+
generateModelsAndTypeDefs(model, outputDir) {
|
|
1427
|
+
const statements = [];
|
|
1428
|
+
statements.push(this.generateSchemaImport(model, true, true));
|
|
1429
|
+
statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
|
|
1430
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
|
|
1431
|
+
...model.declarations.some(import_ast3.isTypeDef) ? [
|
|
1432
|
+
ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
|
|
1433
|
+
] : []
|
|
1434
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
|
|
1435
|
+
const dataModels = model.declarations.filter(import_ast3.isDataModel);
|
|
1436
|
+
for (const dm of dataModels) {
|
|
1437
|
+
let modelType = ts.factory.createTypeAliasDeclaration([
|
|
1438
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1439
|
+
], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
|
|
1440
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1441
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
|
|
1442
|
+
]));
|
|
1443
|
+
if (dm.comments.length > 0) {
|
|
1444
|
+
modelType = this.generateDocs(modelType, dm);
|
|
1445
|
+
}
|
|
1446
|
+
statements.push(modelType);
|
|
1447
|
+
}
|
|
1448
|
+
const typeDefs = model.declarations.filter(import_ast3.isTypeDef);
|
|
1449
|
+
for (const td of typeDefs) {
|
|
1450
|
+
let typeDef = ts.factory.createTypeAliasDeclaration([
|
|
1451
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1452
|
+
], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
|
|
1453
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1454
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
|
|
1455
|
+
]));
|
|
1456
|
+
if (td.comments.length > 0) {
|
|
1457
|
+
typeDef = this.generateDocs(typeDef, td);
|
|
1458
|
+
}
|
|
1459
|
+
statements.push(typeDef);
|
|
1460
|
+
}
|
|
1461
|
+
const enums = model.declarations.filter(import_ast3.isEnum);
|
|
1462
|
+
for (const e of enums) {
|
|
1463
|
+
let enumDecl = ts.factory.createVariableStatement([
|
|
1464
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1465
|
+
], ts.factory.createVariableDeclarationList([
|
|
1466
|
+
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)))
|
|
1467
|
+
], ts.NodeFlags.Const));
|
|
1468
|
+
if (e.comments.length > 0) {
|
|
1469
|
+
enumDecl = this.generateDocs(enumDecl, e);
|
|
1470
|
+
}
|
|
1471
|
+
statements.push(enumDecl);
|
|
1472
|
+
let typeAlias = ts.factory.createTypeAliasDeclaration([
|
|
1473
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1474
|
+
], 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)))));
|
|
1475
|
+
if (e.comments.length > 0) {
|
|
1476
|
+
typeAlias = this.generateDocs(typeAlias, e);
|
|
1477
|
+
}
|
|
1478
|
+
statements.push(typeAlias);
|
|
1479
|
+
}
|
|
1480
|
+
this.generateBannerComments(statements);
|
|
1481
|
+
const outputFile = import_node_path.default.join(outputDir, "models.ts");
|
|
1482
|
+
const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
1483
|
+
const printer = ts.createPrinter();
|
|
1484
|
+
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
1485
|
+
import_node_fs.default.writeFileSync(outputFile, result);
|
|
1486
|
+
}
|
|
1487
|
+
generateSchemaImport(model, schemaObject, schemaType) {
|
|
1488
|
+
const importSpecifiers = [];
|
|
1489
|
+
if (schemaObject) {
|
|
1490
|
+
if (model.declarations.some(import_ast3.isEnum)) {
|
|
1491
|
+
importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
if (schemaType) {
|
|
1495
|
+
importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
|
|
1496
|
+
}
|
|
1497
|
+
return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
|
|
1498
|
+
}
|
|
1499
|
+
generateDocs(tsDecl, decl) {
|
|
1500
|
+
return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
|
|
1501
|
+
* ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
|
|
1502
|
+
`, true);
|
|
1503
|
+
}
|
|
1504
|
+
generateInputTypes(model, outputDir) {
|
|
1505
|
+
const dataModels = model.declarations.filter(import_ast3.isDataModel);
|
|
1506
|
+
const statements = [];
|
|
1507
|
+
statements.push(this.generateSchemaImport(model, false, true));
|
|
1508
|
+
const inputTypes = [
|
|
1509
|
+
"FindManyArgs",
|
|
1510
|
+
"FindUniqueArgs",
|
|
1511
|
+
"FindFirstArgs",
|
|
1512
|
+
"CreateArgs",
|
|
1513
|
+
"CreateManyArgs",
|
|
1514
|
+
"CreateManyAndReturnArgs",
|
|
1515
|
+
"UpdateArgs",
|
|
1516
|
+
"UpdateManyArgs",
|
|
1517
|
+
"UpdateManyAndReturnArgs",
|
|
1518
|
+
"UpsertArgs",
|
|
1519
|
+
"DeleteArgs",
|
|
1520
|
+
"DeleteManyArgs",
|
|
1521
|
+
"CountArgs",
|
|
1522
|
+
"AggregateArgs",
|
|
1523
|
+
"GroupByArgs",
|
|
1524
|
+
"WhereInput",
|
|
1525
|
+
"SelectInput",
|
|
1526
|
+
"IncludeInput",
|
|
1527
|
+
"OmitInput"
|
|
1528
|
+
];
|
|
1529
|
+
const inputTypeNameFixes = {
|
|
1530
|
+
SelectInput: "Select",
|
|
1531
|
+
IncludeInput: "Include",
|
|
1532
|
+
OmitInput: "Omit"
|
|
1533
|
+
};
|
|
1534
|
+
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")));
|
|
1535
|
+
statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
|
|
1536
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
|
|
1537
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
|
|
1538
|
+
])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
|
|
1539
|
+
for (const dm of dataModels) {
|
|
1540
|
+
for (const inputType of inputTypes) {
|
|
1541
|
+
const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
|
|
1542
|
+
statements.push(ts.factory.createTypeAliasDeclaration([
|
|
1543
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1544
|
+
], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
|
|
1545
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1546
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
|
|
1547
|
+
])));
|
|
1548
|
+
}
|
|
1549
|
+
statements.push(ts.factory.createTypeAliasDeclaration([
|
|
1550
|
+
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
|
|
1551
|
+
], `${dm.name}GetPayload`, [
|
|
1552
|
+
ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
|
|
1553
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1554
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
|
|
1555
|
+
ts.factory.createLiteralTypeNode(ts.factory.createTrue())
|
|
1556
|
+
]))
|
|
1557
|
+
], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
|
|
1558
|
+
ts.factory.createTypeReferenceNode("$Schema"),
|
|
1559
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
|
|
1560
|
+
ts.factory.createTypeReferenceNode("Args")
|
|
1561
|
+
])));
|
|
1562
|
+
}
|
|
1563
|
+
this.generateBannerComments(statements);
|
|
1564
|
+
const outputFile = import_node_path.default.join(outputDir, "input.ts");
|
|
1565
|
+
const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
1566
|
+
const printer = ts.createPrinter();
|
|
1567
|
+
const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
|
|
1568
|
+
import_node_fs.default.writeFileSync(outputFile, result);
|
|
1569
|
+
}
|
|
1354
1570
|
};
|
|
1355
1571
|
|
|
1356
1572
|
// src/zmodel-code-generator.ts
|
|
@@ -1442,21 +1658,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
|
|
|
1442
1658
|
return `${ast.name} = ${this.generate(ast.value)}`;
|
|
1443
1659
|
}
|
|
1444
1660
|
_generateDataModel(ast) {
|
|
1445
|
-
return `${ast.
|
|
1661
|
+
return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
|
|
1446
1662
|
${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
1663
|
}`;
|
|
1448
1664
|
}
|
|
1449
|
-
|
|
1665
|
+
_generateDataField(ast) {
|
|
1450
1666
|
return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
|
|
1451
1667
|
}
|
|
1452
1668
|
fieldType(type) {
|
|
1453
|
-
const baseType = type.type ? type.type : type.$type == "
|
|
1669
|
+
const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
|
|
1454
1670
|
return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
|
|
1455
1671
|
}
|
|
1456
1672
|
_generateDataModelAttribute(ast) {
|
|
1457
1673
|
return this.attribute(ast);
|
|
1458
1674
|
}
|
|
1459
|
-
|
|
1675
|
+
_generateDataFieldAttribute(ast) {
|
|
1460
1676
|
return this.attribute(ast);
|
|
1461
1677
|
}
|
|
1462
1678
|
attribute(ast) {
|
|
@@ -1540,9 +1756,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
|
|
|
1540
1756
|
${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
1757
|
}`;
|
|
1542
1758
|
}
|
|
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
1759
|
argument(ast) {
|
|
1547
1760
|
return this.generate(ast.value);
|
|
1548
1761
|
}
|
|
@@ -1668,13 +1881,13 @@ _ts_decorate([
|
|
|
1668
1881
|
_ts_metadata("design:returntype", void 0)
|
|
1669
1882
|
], ZModelCodeGenerator.prototype, "_generateDataModel", null);
|
|
1670
1883
|
_ts_decorate([
|
|
1671
|
-
gen(import_ast4.
|
|
1884
|
+
gen(import_ast4.DataField),
|
|
1672
1885
|
_ts_metadata("design:type", Function),
|
|
1673
1886
|
_ts_metadata("design:paramtypes", [
|
|
1674
|
-
typeof import_ast4.
|
|
1887
|
+
typeof import_ast4.DataField === "undefined" ? Object : import_ast4.DataField
|
|
1675
1888
|
]),
|
|
1676
1889
|
_ts_metadata("design:returntype", void 0)
|
|
1677
|
-
], ZModelCodeGenerator.prototype, "
|
|
1890
|
+
], ZModelCodeGenerator.prototype, "_generateDataField", null);
|
|
1678
1891
|
_ts_decorate([
|
|
1679
1892
|
gen(import_ast4.DataModelAttribute),
|
|
1680
1893
|
_ts_metadata("design:type", Function),
|
|
@@ -1684,13 +1897,13 @@ _ts_decorate([
|
|
|
1684
1897
|
_ts_metadata("design:returntype", void 0)
|
|
1685
1898
|
], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
|
|
1686
1899
|
_ts_decorate([
|
|
1687
|
-
gen(import_ast4.
|
|
1900
|
+
gen(import_ast4.DataFieldAttribute),
|
|
1688
1901
|
_ts_metadata("design:type", Function),
|
|
1689
1902
|
_ts_metadata("design:paramtypes", [
|
|
1690
|
-
typeof import_ast4.
|
|
1903
|
+
typeof import_ast4.DataFieldAttribute === "undefined" ? Object : import_ast4.DataFieldAttribute
|
|
1691
1904
|
]),
|
|
1692
1905
|
_ts_metadata("design:returntype", void 0)
|
|
1693
|
-
], ZModelCodeGenerator.prototype, "
|
|
1906
|
+
], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
|
|
1694
1907
|
_ts_decorate([
|
|
1695
1908
|
gen(import_ast4.AttributeArg),
|
|
1696
1909
|
_ts_metadata("design:type", Function),
|
|
@@ -1855,14 +2068,6 @@ _ts_decorate([
|
|
|
1855
2068
|
]),
|
|
1856
2069
|
_ts_metadata("design:returntype", void 0)
|
|
1857
2070
|
], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
|
|
1858
|
-
_ts_decorate([
|
|
1859
|
-
gen(import_ast4.TypeDefField),
|
|
1860
|
-
_ts_metadata("design:type", Function),
|
|
1861
|
-
_ts_metadata("design:paramtypes", [
|
|
1862
|
-
typeof import_ast4.TypeDefField === "undefined" ? Object : import_ast4.TypeDefField
|
|
1863
|
-
]),
|
|
1864
|
-
_ts_metadata("design:returntype", void 0)
|
|
1865
|
-
], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
|
|
1866
2071
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1867
2072
|
0 && (module.exports = {
|
|
1868
2073
|
ModelUtils,
|