@zenstackhq/sdk 3.0.0-alpha.11 → 3.0.0-alpha.13

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.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
- getModelIdFields: () => getModelIdFields,
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 { isArrayExpr, isDataModel, isLiteralExpr, isModel, isReferenceExpr } from "@zenstackhq/language/ast";
25
- function isIdField(field) {
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 model = field.$container;
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
- if (model.fields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
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 = model.fields.find((f) => hasAttribute(f, "@unique"));
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(model);
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 { BooleanLiteral, DataModel, DataSource as DataSource2, Enum as Enum2, GeneratorDecl, isArrayExpr as isArrayExpr2, isInvocationExpr, isLiteralExpr as isLiteralExpr2, isModel as isModel2, isNullExpr, isReferenceExpr as isReferenceExpr2, isStringLiteral, isTypeDef, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
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, P } from "ts-pattern";
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
- for (const field of decl.fields) {
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.generateModelField(model, field);
584
+ if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
585
+ this.generateModelField(model, field, decl);
586
+ }
635
587
  }
636
- for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
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
- setDummyDefault(result, field) {
711
- const dummyDefaultValue = match(field.type.type).with("String", () => new AttributeArgValue("String", "")).with(P.union("Int", "BigInt", "Float", "Decimal"), () => new AttributeArgValue("Number", "0")).with("Boolean", () => new AttributeArgValue("Boolean", "false")).with("DateTime", () => new AttributeArgValue("FunctionCall", new FunctionCall("now"))).with("Json", () => new AttributeArgValue("String", "{}")).with("Bytes", () => new AttributeArgValue("String", "")).otherwise(() => {
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 (isArrayExpr2(node)) {
679
+ } else if (isArrayExpr(node)) {
733
680
  return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
734
- } else if (isReferenceExpr2(node)) {
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,67 @@ 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
781
  import { loadDocument } from "@zenstackhq/language";
781
- import { isArrayExpr as isArrayExpr3, isBinaryExpr, isDataModel as isDataModel2, isDataModelField, isDataSource, isEnum, isEnumField, isInvocationExpr as isInvocationExpr2, isLiteralExpr as isLiteralExpr3, isMemberAccessExpr, isNullExpr as isNullExpr2, isProcedure, isReferenceExpr as isReferenceExpr3, isThisExpr, isUnaryExpr } from "@zenstackhq/language/ast";
782
+ import { 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";
783
+ import { getAllAttributes as getAllAttributes2, getAllFields as getAllFields3, isDataFieldReference } from "@zenstackhq/language/utils";
782
784
  import fs from "fs";
783
785
  import path from "path";
784
786
  import { match as match2 } from "ts-pattern";
@@ -797,7 +799,7 @@ var TsSchemaGenerator = class {
797
799
  recursive: true
798
800
  });
799
801
  this.generateSchema(model, outputDir);
800
- this.generateModels(model, outputDir);
802
+ this.generateModelsAndTypeDefs(model, outputDir);
801
803
  this.generateInputTypes(model, outputDir);
802
804
  }
803
805
  generateSchema(model, outputDir) {
@@ -811,7 +813,7 @@ var TsSchemaGenerator = class {
811
813
  fs.writeFileSync(schemaOutputFile, result);
812
814
  }
813
815
  generateSchemaStatements(model, statements) {
814
- const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
816
+ const hasComputedFields = model.declarations.some((d) => isDataModel3(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
815
817
  const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
816
818
  ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
817
819
  ...hasComputedFields ? [
@@ -836,7 +838,11 @@ var TsSchemaGenerator = class {
836
838
  // provider
837
839
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
838
840
  // models
839
- ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
841
+ ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
842
+ // typeDefs
843
+ ...model.declarations.some(isTypeDef2) ? [
844
+ ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
845
+ ] : []
840
846
  ];
841
847
  const enums = model.declarations.filter(isEnum);
842
848
  if (enums.length > 0) {
@@ -860,20 +866,45 @@ var TsSchemaGenerator = class {
860
866
  ], true);
861
867
  }
862
868
  createModelsObject(model) {
863
- return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel2(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
869
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel3(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
870
+ }
871
+ createTypeDefsObject(model) {
872
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isTypeDef2(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
864
873
  }
865
874
  createDataModelObject(dm) {
875
+ const allFields = getAllFields3(dm);
876
+ const allAttributes = getAllAttributes2(dm).filter((attr) => {
877
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
878
+ return false;
879
+ }
880
+ return true;
881
+ });
882
+ const subModels = this.getSubModels(dm);
866
883
  const fields = [
884
+ // name
885
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
886
+ // baseModel
887
+ ...dm.baseModel ? [
888
+ ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
889
+ ] : [],
867
890
  // fields
868
- ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(dm.fields.filter((field) => !hasAttribute(field, "@ignore")).map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataModelFieldObject(field))), true)),
891
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
869
892
  // attributes
870
- ...dm.attributes.length > 0 ? [
871
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
893
+ ...allAttributes.length > 0 ? [
894
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
872
895
  ] : [],
873
896
  // idFields
874
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
897
+ ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
875
898
  // uniqueFields
876
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
899
+ ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
900
+ // isDelegate
901
+ ...isDelegateModel(dm) ? [
902
+ ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
903
+ ] : [],
904
+ // subModels
905
+ ...subModels.length > 0 ? [
906
+ ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
907
+ ] : []
877
908
  ];
878
909
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
879
910
  if (computedFields.length > 0) {
@@ -881,6 +912,24 @@ var TsSchemaGenerator = class {
881
912
  }
882
913
  return ts.factory.createObjectLiteralExpression(fields, true);
883
914
  }
915
+ getSubModels(dm) {
916
+ return dm.$container.declarations.filter(isDataModel3).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
917
+ }
918
+ createTypeDefObject(td) {
919
+ const allFields = getAllFields3(td);
920
+ const allAttributes = getAllAttributes2(td);
921
+ const fields = [
922
+ // name
923
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
924
+ // fields
925
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
926
+ // attributes
927
+ ...allAttributes.length > 0 ? [
928
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
929
+ ] : []
930
+ ];
931
+ return ts.factory.createObjectLiteralExpression(fields, true);
932
+ }
884
933
  createComputedFieldsObject(fields) {
885
934
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
886
935
  ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
@@ -900,11 +949,14 @@ var TsSchemaGenerator = class {
900
949
  }
901
950
  return result;
902
951
  }
903
- createDataModelFieldObject(field) {
952
+ createDataFieldObject(field, contextModel) {
904
953
  const objectFields = [
954
+ // name
955
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
956
+ // type
905
957
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
906
958
  ];
907
- if (isIdField(field)) {
959
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
908
960
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
909
961
  }
910
962
  if (isUniqueField(field)) {
@@ -919,6 +971,13 @@ var TsSchemaGenerator = class {
919
971
  if (hasAttribute(field, "@updatedAt")) {
920
972
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
921
973
  }
974
+ if (contextModel && // id fields are duplicated in inherited models
975
+ !isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
976
+ objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
977
+ }
978
+ if (this.isDiscriminatorField(field)) {
979
+ objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
980
+ }
922
981
  if (field.attributes.length > 0) {
923
982
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
924
983
  }
@@ -953,7 +1012,7 @@ var TsSchemaGenerator = class {
953
1012
  if (hasAttribute(field, "@computed")) {
954
1013
  objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
955
1014
  }
956
- if (isDataModel2(field.type.reference?.ref)) {
1015
+ if (isDataModel3(field.type.reference?.ref)) {
957
1016
  objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
958
1017
  }
959
1018
  const fkFor = this.getForeignKeyFor(field);
@@ -962,6 +1021,10 @@ var TsSchemaGenerator = class {
962
1021
  }
963
1022
  return ts.factory.createObjectLiteralExpression(objectFields, true);
964
1023
  }
1024
+ isDiscriminatorField(field) {
1025
+ const origin = field.$container;
1026
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && isDataFieldReference(arg.value) && arg.value.target.ref === field);
1027
+ }
965
1028
  getDataSourceProvider(model) {
966
1029
  const dataSource = model.declarations.find(isDataSource);
967
1030
  invariant(dataSource, "No data source found in the model");
@@ -1006,9 +1069,9 @@ var TsSchemaGenerator = class {
1006
1069
  "Decimal",
1007
1070
  "BigInt"
1008
1071
  ].includes(fieldType.type) ? Number(lit) : lit;
1009
- } else if (isArrayExpr3(expr)) {
1072
+ } else if (isArrayExpr2(expr)) {
1010
1073
  return expr.items.map((item) => this.getMappedValue(item, fieldType));
1011
- } else if (isReferenceExpr3(expr) && isEnumField(expr.target.ref)) {
1074
+ } else if (isReferenceExpr2(expr) && isEnumField(expr.target.ref)) {
1012
1075
  return expr.target.ref.name;
1013
1076
  } else if (isInvocationExpr2(expr)) {
1014
1077
  return {
@@ -1074,7 +1137,7 @@ var TsSchemaGenerator = class {
1074
1137
  return ts.factory.createObjectLiteralExpression(relationFields);
1075
1138
  }
1076
1139
  getReferenceNames(expr) {
1077
- return isArrayExpr3(expr) && expr.items.map((item) => item.target.$refText);
1140
+ return isArrayExpr2(expr) && expr.items.map((item) => item.target.$refText);
1078
1141
  }
1079
1142
  getForeignKeyFor(field) {
1080
1143
  const result = [];
@@ -1082,7 +1145,7 @@ var TsSchemaGenerator = class {
1082
1145
  const relation = getAttribute(f, "@relation");
1083
1146
  if (relation) {
1084
1147
  for (const arg of relation.args) {
1085
- if (arg.name === "fields" && isArrayExpr3(arg.value) && arg.value.items.some((el) => isReferenceExpr3(el) && el.target.ref === field)) {
1148
+ if (arg.name === "fields" && isArrayExpr2(arg.value) && arg.value.items.some((el) => isReferenceExpr2(el) && el.target.ref === field)) {
1086
1149
  result.push(f.name);
1087
1150
  }
1088
1151
  }
@@ -1091,7 +1154,7 @@ var TsSchemaGenerator = class {
1091
1154
  return result;
1092
1155
  }
1093
1156
  getOppositeRelationField(field) {
1094
- if (!field.type.reference?.ref || !isDataModel2(field.type.reference?.ref)) {
1157
+ if (!field.type.reference?.ref || !isDataModel3(field.type.reference?.ref)) {
1095
1158
  return void 0;
1096
1159
  }
1097
1160
  const sourceModel = field.$container;
@@ -1125,27 +1188,26 @@ var TsSchemaGenerator = class {
1125
1188
  }
1126
1189
  return void 0;
1127
1190
  }
1128
- getIdFields(dm) {
1129
- return dm.fields.filter(isIdField).map((f) => f.name);
1130
- }
1131
1191
  createUniqueFieldsObject(dm) {
1132
1192
  const properties = [];
1133
- for (const field of dm.fields) {
1193
+ const allFields = getAllFields3(dm);
1194
+ for (const field of allFields) {
1134
1195
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1135
1196
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1136
1197
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1137
1198
  ])));
1138
1199
  }
1139
1200
  }
1201
+ const allAttributes = getAllAttributes2(dm);
1140
1202
  const seenKeys = /* @__PURE__ */ new Set();
1141
- for (const attr of dm.attributes) {
1203
+ for (const attr of allAttributes) {
1142
1204
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1143
1205
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1144
1206
  if (!fieldNames) {
1145
1207
  continue;
1146
1208
  }
1147
1209
  if (fieldNames.length === 1) {
1148
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1210
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1149
1211
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1150
1212
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1151
1213
  ])));
@@ -1156,7 +1218,7 @@ var TsSchemaGenerator = class {
1156
1218
  }
1157
1219
  seenKeys.add(key);
1158
1220
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1159
- const fieldDef = dm.fields.find((f) => f.name === field);
1221
+ const fieldDef = allFields.find((f) => f.name === field);
1160
1222
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1161
1223
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1162
1224
  ]));
@@ -1248,7 +1310,7 @@ var TsSchemaGenerator = class {
1248
1310
  ]);
1249
1311
  }
1250
1312
  createExpression(value) {
1251
- return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(isReferenceExpr3, (expr) => this.createRefExpression(expr)).when(isArrayExpr3, (expr) => this.createArrayExpression(expr)).when(isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(isNullExpr2, () => this.createNullExpression()).when(isThisExpr, () => this.createThisExpression()).otherwise(() => {
1313
+ 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(() => {
1252
1314
  throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1253
1315
  });
1254
1316
  }
@@ -1291,7 +1353,7 @@ var TsSchemaGenerator = class {
1291
1353
  ]);
1292
1354
  }
1293
1355
  createRefExpression(expr) {
1294
- if (isDataModelField(expr.target.ref)) {
1356
+ if (isDataField(expr.target.ref)) {
1295
1357
  return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1296
1358
  this.createLiteralNode(expr.target.$refText)
1297
1359
  ]);
@@ -1320,13 +1382,16 @@ var TsSchemaGenerator = class {
1320
1382
  throw new Error(`Unsupported literal type: ${type}`);
1321
1383
  });
1322
1384
  }
1323
- generateModels(model, outputDir) {
1385
+ generateModelsAndTypeDefs(model, outputDir) {
1324
1386
  const statements = [];
1325
- statements.push(this.generateSchemaTypeImport(true, true));
1387
+ statements.push(this.generateSchemaImport(model, true, true));
1326
1388
  statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1327
- ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`))
1389
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1390
+ ...model.declarations.some(isTypeDef2) ? [
1391
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1392
+ ] : []
1328
1393
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1329
- const dataModels = model.declarations.filter(isDataModel2);
1394
+ const dataModels = model.declarations.filter(isDataModel3);
1330
1395
  for (const dm of dataModels) {
1331
1396
  let modelType = ts.factory.createTypeAliasDeclaration([
1332
1397
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
@@ -1339,6 +1404,19 @@ var TsSchemaGenerator = class {
1339
1404
  }
1340
1405
  statements.push(modelType);
1341
1406
  }
1407
+ const typeDefs = model.declarations.filter(isTypeDef2);
1408
+ for (const td of typeDefs) {
1409
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1410
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1411
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1412
+ ts.factory.createTypeReferenceNode("$Schema"),
1413
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1414
+ ]));
1415
+ if (td.comments.length > 0) {
1416
+ typeDef = this.generateDocs(typeDef, td);
1417
+ }
1418
+ statements.push(typeDef);
1419
+ }
1342
1420
  const enums = model.declarations.filter(isEnum);
1343
1421
  for (const e of enums) {
1344
1422
  let enumDecl = ts.factory.createVariableStatement([
@@ -1365,10 +1443,12 @@ var TsSchemaGenerator = class {
1365
1443
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1366
1444
  fs.writeFileSync(outputFile, result);
1367
1445
  }
1368
- generateSchemaTypeImport(schemaObject, schemaType) {
1446
+ generateSchemaImport(model, schemaObject, schemaType) {
1369
1447
  const importSpecifiers = [];
1370
1448
  if (schemaObject) {
1371
- importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1449
+ if (model.declarations.some(isEnum)) {
1450
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1451
+ }
1372
1452
  }
1373
1453
  if (schemaType) {
1374
1454
  importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
@@ -1381,9 +1461,9 @@ var TsSchemaGenerator = class {
1381
1461
  `, true);
1382
1462
  }
1383
1463
  generateInputTypes(model, outputDir) {
1384
- const dataModels = model.declarations.filter(isDataModel2);
1464
+ const dataModels = model.declarations.filter(isDataModel3);
1385
1465
  const statements = [];
1386
- statements.push(this.generateSchemaTypeImport(false, true));
1466
+ statements.push(this.generateSchemaImport(model, false, true));
1387
1467
  const inputTypes = [
1388
1468
  "FindManyArgs",
1389
1469
  "FindUniqueArgs",
@@ -1449,7 +1529,7 @@ var TsSchemaGenerator = class {
1449
1529
  };
1450
1530
 
1451
1531
  // src/zmodel-code-generator.ts
1452
- import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataModel as DataModel2, DataModelAttribute, DataModelField, DataModelFieldAttribute, DataSource as DataSource3, Enum as Enum3, EnumField as EnumField2, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl as GeneratorDecl2, InvocationExpr, LiteralExpr, MemberAccessExpr, Model as Model2, NullExpr, NumberLiteral as NumberLiteral2, ObjectExpr, Plugin, PluginField, ReferenceArg, ReferenceExpr, StringLiteral as StringLiteral2, ThisExpr, TypeDef, TypeDefField, UnaryExpr } from "@zenstackhq/language/ast";
1532
+ 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";
1453
1533
  function _ts_decorate(decorators, target, key, desc) {
1454
1534
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1455
1535
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1537,21 +1617,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1537
1617
  return `${ast.name} = ${this.generate(ast.value)}`;
1538
1618
  }
1539
1619
  _generateDataModel(ast) {
1540
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1620
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1541
1621
  ${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") : ""}
1542
1622
  }`;
1543
1623
  }
1544
- _generateDataModelField(ast) {
1624
+ _generateDataField(ast) {
1545
1625
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1546
1626
  }
1547
1627
  fieldType(type) {
1548
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1628
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1549
1629
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1550
1630
  }
1551
1631
  _generateDataModelAttribute(ast) {
1552
1632
  return this.attribute(ast);
1553
1633
  }
1554
- _generateDataModelFieldAttribute(ast) {
1634
+ _generateDataFieldAttribute(ast) {
1555
1635
  return this.attribute(ast);
1556
1636
  }
1557
1637
  attribute(ast) {
@@ -1635,9 +1715,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1635
1715
  ${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") : ""}
1636
1716
  }`;
1637
1717
  }
1638
- _generateTypeDefField(ast) {
1639
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1640
- }
1641
1718
  argument(ast) {
1642
1719
  return this.generate(ast.value);
1643
1720
  }
@@ -1763,13 +1840,13 @@ _ts_decorate([
1763
1840
  _ts_metadata("design:returntype", void 0)
1764
1841
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1765
1842
  _ts_decorate([
1766
- gen(DataModelField),
1843
+ gen(DataField),
1767
1844
  _ts_metadata("design:type", Function),
1768
1845
  _ts_metadata("design:paramtypes", [
1769
- typeof DataModelField === "undefined" ? Object : DataModelField
1846
+ typeof DataField === "undefined" ? Object : DataField
1770
1847
  ]),
1771
1848
  _ts_metadata("design:returntype", void 0)
1772
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1849
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1773
1850
  _ts_decorate([
1774
1851
  gen(DataModelAttribute),
1775
1852
  _ts_metadata("design:type", Function),
@@ -1779,13 +1856,13 @@ _ts_decorate([
1779
1856
  _ts_metadata("design:returntype", void 0)
1780
1857
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1781
1858
  _ts_decorate([
1782
- gen(DataModelFieldAttribute),
1859
+ gen(DataFieldAttribute),
1783
1860
  _ts_metadata("design:type", Function),
1784
1861
  _ts_metadata("design:paramtypes", [
1785
- typeof DataModelFieldAttribute === "undefined" ? Object : DataModelFieldAttribute
1862
+ typeof DataFieldAttribute === "undefined" ? Object : DataFieldAttribute
1786
1863
  ]),
1787
1864
  _ts_metadata("design:returntype", void 0)
1788
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1865
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1789
1866
  _ts_decorate([
1790
1867
  gen(AttributeArg2),
1791
1868
  _ts_metadata("design:type", Function),
@@ -1950,14 +2027,6 @@ _ts_decorate([
1950
2027
  ]),
1951
2028
  _ts_metadata("design:returntype", void 0)
1952
2029
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1953
- _ts_decorate([
1954
- gen(TypeDefField),
1955
- _ts_metadata("design:type", Function),
1956
- _ts_metadata("design:paramtypes", [
1957
- typeof TypeDefField === "undefined" ? Object : TypeDefField
1958
- ]),
1959
- _ts_metadata("design:returntype", void 0)
1960
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1961
2030
  export {
1962
2031
  model_utils_exports as ModelUtils,
1963
2032
  PrismaSchemaGenerator,