@zenstackhq/sdk 3.0.0-alpha.12 → 3.0.0-alpha.14

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 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
- getModelIdFields: () => getModelIdFields,
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
- function isIdField(field) {
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 model = field.$container;
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
- if (model.fields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
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 = model.fields.find((f) => hasAttribute(f, "@unique"));
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(model);
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
  }
@@ -189,9 +128,16 @@ function getAuthDecl(model) {
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,22 @@ 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
- for (const field of decl.fields) {
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.generateModelField(model, field);
617
+ if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
618
+ this.generateModelField(model, field, decl);
619
+ }
668
620
  }
669
- for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
621
+ const allAttributes = (0, import_utils2.getAllAttributes)(decl);
622
+ for (const attr of allAttributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
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);
673
628
  }
674
629
  isPrismaAttribute(attr) {
675
630
  if (!attr.decl.ref) {
@@ -692,7 +647,7 @@ var PrismaSchemaGenerator = class {
692
647
  getStringLiteral(node) {
693
648
  return (0, import_ast2.isStringLiteral)(node) ? node.value : void 0;
694
649
  }
695
- generateModelField(model, field, addToFront = false) {
650
+ generateModelField(model, field, contextModel, addToFront = false) {
696
651
  let fieldType;
697
652
  if (field.type.type) {
698
653
  fieldType = field.type.type;
@@ -718,7 +673,7 @@ var PrismaSchemaGenerator = class {
718
673
  const type = new ModelFieldType(fieldType, isArray, field.type.optional);
719
674
  const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
720
675
  // 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")
676
+ !(model_utils_exports.isIdField(field, contextModel) && this.isInheritedFromDelegate(field, contextModel) && attr.decl.$refText === "@default")
722
677
  )).map((attr) => this.makeFieldAttribute(attr));
723
678
  const docs = [
724
679
  ...field.comments
@@ -740,16 +695,8 @@ var PrismaSchemaGenerator = class {
740
695
  const model = import_langium.AstUtils.getContainerOfType(node, import_ast2.isModel);
741
696
  return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
742
697
  }
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);
698
+ isInheritedFromDelegate(field, contextModel) {
699
+ return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
753
700
  }
754
701
  makeFieldAttribute(attr) {
755
702
  const attrName = attr.decl.ref.name;
@@ -806,12 +753,67 @@ var PrismaSchemaGenerator = class {
806
753
  ];
807
754
  _enum.addField(field.name, attributes, docs);
808
755
  }
756
+ generateDelegateRelationForBase(model, decl) {
757
+ if (!(0, import_utils2.isDelegateModel)(decl)) {
758
+ return;
759
+ }
760
+ const concreteModels = this.getConcreteModels(decl);
761
+ concreteModels.forEach((concrete) => {
762
+ const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(concrete.name)}`);
763
+ model.addField(auxName, new ModelFieldType(concrete.name, false, true));
764
+ });
765
+ }
766
+ generateDelegateRelationForConcrete(model, concreteDecl) {
767
+ const base = concreteDecl.baseModel?.ref;
768
+ if (!base) {
769
+ return;
770
+ }
771
+ const idFields = getIdFields(base);
772
+ const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(base.name)}`);
773
+ model.addField(relationField, base.name, [
774
+ new FieldAttribute("@relation", [
775
+ new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
776
+ new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
777
+ new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
778
+ new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
779
+ ])
780
+ ]);
781
+ }
782
+ getConcreteModels(dataModel) {
783
+ if (!(0, import_utils2.isDelegateModel)(dataModel)) {
784
+ return [];
785
+ }
786
+ return dataModel.$container.declarations.filter((d) => (0, import_ast2.isDataModel)(d) && d !== dataModel && d.baseModel?.ref === dataModel);
787
+ }
788
+ truncate(name) {
789
+ if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
790
+ return name;
791
+ }
792
+ const existing = this.shortNameMap.get(name);
793
+ if (existing) {
794
+ return existing;
795
+ }
796
+ const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
797
+ let index = 0;
798
+ let shortName = `${baseName}_${index}`;
799
+ while (true) {
800
+ const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
801
+ if (!conflict) {
802
+ this.shortNameMap.set(name, shortName);
803
+ break;
804
+ }
805
+ index++;
806
+ shortName = `${baseName}_${index}`;
807
+ }
808
+ return shortName;
809
+ }
809
810
  };
810
811
 
811
812
  // src/ts-schema-generator.ts
812
- var import_common_helpers = require("@zenstackhq/common-helpers");
813
+ var import_common_helpers2 = require("@zenstackhq/common-helpers");
813
814
  var import_language = require("@zenstackhq/language");
814
815
  var import_ast3 = require("@zenstackhq/language/ast");
816
+ var import_utils3 = require("@zenstackhq/language/utils");
815
817
  var import_node_fs = __toESM(require("fs"), 1);
816
818
  var import_node_path = __toESM(require("path"), 1);
817
819
  var import_ts_pattern2 = require("ts-pattern");
@@ -830,7 +832,7 @@ var TsSchemaGenerator = class {
830
832
  recursive: true
831
833
  });
832
834
  this.generateSchema(model, outputDir);
833
- this.generateModels(model, outputDir);
835
+ this.generateModelsAndTypeDefs(model, outputDir);
834
836
  this.generateInputTypes(model, outputDir);
835
837
  }
836
838
  generateSchema(model, outputDir) {
@@ -869,7 +871,11 @@ var TsSchemaGenerator = class {
869
871
  // provider
870
872
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
871
873
  // models
872
- ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
874
+ ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
875
+ // typeDefs
876
+ ...model.declarations.some(import_ast3.isTypeDef) ? [
877
+ ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
878
+ ] : []
873
879
  ];
874
880
  const enums = model.declarations.filter(import_ast3.isEnum);
875
881
  if (enums.length > 0) {
@@ -895,18 +901,43 @@ var TsSchemaGenerator = class {
895
901
  createModelsObject(model) {
896
902
  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);
897
903
  }
904
+ createTypeDefsObject(model) {
905
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => (0, import_ast3.isTypeDef)(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
906
+ }
898
907
  createDataModelObject(dm) {
908
+ const allFields = (0, import_utils3.getAllFields)(dm);
909
+ const allAttributes = (0, import_utils3.getAllAttributes)(dm).filter((attr) => {
910
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
911
+ return false;
912
+ }
913
+ return true;
914
+ });
915
+ const subModels = this.getSubModels(dm);
899
916
  const fields = [
917
+ // name
918
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
919
+ // baseModel
920
+ ...dm.baseModel ? [
921
+ ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
922
+ ] : [],
900
923
  // fields
901
- 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)),
924
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
902
925
  // attributes
903
- ...dm.attributes.length > 0 ? [
904
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
926
+ ...allAttributes.length > 0 ? [
927
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
905
928
  ] : [],
906
929
  // idFields
907
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
930
+ ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
908
931
  // uniqueFields
909
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
932
+ ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
933
+ // isDelegate
934
+ ...isDelegateModel(dm) ? [
935
+ ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
936
+ ] : [],
937
+ // subModels
938
+ ...subModels.length > 0 ? [
939
+ ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
940
+ ] : []
910
941
  ];
911
942
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
912
943
  if (computedFields.length > 0) {
@@ -914,6 +945,24 @@ var TsSchemaGenerator = class {
914
945
  }
915
946
  return ts.factory.createObjectLiteralExpression(fields, true);
916
947
  }
948
+ getSubModels(dm) {
949
+ return dm.$container.declarations.filter(import_ast3.isDataModel).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
950
+ }
951
+ createTypeDefObject(td) {
952
+ const allFields = (0, import_utils3.getAllFields)(td);
953
+ const allAttributes = (0, import_utils3.getAllAttributes)(td);
954
+ const fields = [
955
+ // name
956
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
957
+ // fields
958
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
959
+ // attributes
960
+ ...allAttributes.length > 0 ? [
961
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
962
+ ] : []
963
+ ];
964
+ return ts.factory.createObjectLiteralExpression(fields, true);
965
+ }
917
966
  createComputedFieldsObject(fields) {
918
967
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
919
968
  ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
@@ -933,11 +982,14 @@ var TsSchemaGenerator = class {
933
982
  }
934
983
  return result;
935
984
  }
936
- createDataModelFieldObject(field) {
985
+ createDataFieldObject(field, contextModel) {
937
986
  const objectFields = [
987
+ // name
988
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
989
+ // type
938
990
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
939
991
  ];
940
- if (isIdField(field)) {
992
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
941
993
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
942
994
  }
943
995
  if (isUniqueField(field)) {
@@ -952,6 +1004,13 @@ var TsSchemaGenerator = class {
952
1004
  if (hasAttribute(field, "@updatedAt")) {
953
1005
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
954
1006
  }
1007
+ if (contextModel && // id fields are duplicated in inherited models
1008
+ !isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
1009
+ objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
1010
+ }
1011
+ if (this.isDiscriminatorField(field)) {
1012
+ objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
1013
+ }
955
1014
  if (field.attributes.length > 0) {
956
1015
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
957
1016
  }
@@ -995,14 +1054,18 @@ var TsSchemaGenerator = class {
995
1054
  }
996
1055
  return ts.factory.createObjectLiteralExpression(objectFields, true);
997
1056
  }
1057
+ isDiscriminatorField(field) {
1058
+ const origin = field.$container;
1059
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && (0, import_utils3.isDataFieldReference)(arg.value) && arg.value.target.ref === field);
1060
+ }
998
1061
  getDataSourceProvider(model) {
999
1062
  const dataSource = model.declarations.find(import_ast3.isDataSource);
1000
- (0, import_common_helpers.invariant)(dataSource, "No data source found in the model");
1063
+ (0, import_common_helpers2.invariant)(dataSource, "No data source found in the model");
1001
1064
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
1002
- (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1065
+ (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1003
1066
  const type = providerExpr.value;
1004
1067
  const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
1005
- (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1068
+ (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1006
1069
  if ((0, import_ast3.isLiteralExpr)(urlExpr)) {
1007
1070
  return {
1008
1071
  type,
@@ -1010,8 +1073,8 @@ var TsSchemaGenerator = class {
1010
1073
  env: void 0
1011
1074
  };
1012
1075
  } else if ((0, import_ast3.isInvocationExpr)(urlExpr)) {
1013
- (0, import_common_helpers.invariant)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1014
- (0, import_common_helpers.invariant)(urlExpr.args.length === 1, "env function must have one argument");
1076
+ (0, import_common_helpers2.invariant)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1077
+ (0, import_common_helpers2.invariant)(urlExpr.args.length === 1, "env function must have one argument");
1015
1078
  return {
1016
1079
  type,
1017
1080
  env: urlExpr.args[0].value.value,
@@ -1027,7 +1090,7 @@ var TsSchemaGenerator = class {
1027
1090
  return void 0;
1028
1091
  }
1029
1092
  const defaultValue = defaultAttr.args[0]?.value;
1030
- (0, import_common_helpers.invariant)(defaultValue, "Expected a default value");
1093
+ (0, import_common_helpers2.invariant)(defaultValue, "Expected a default value");
1031
1094
  return this.getMappedValue(defaultValue, field.type);
1032
1095
  }
1033
1096
  getMappedValue(expr, fieldType) {
@@ -1152,33 +1215,32 @@ var TsSchemaGenerator = class {
1152
1215
  if (relation) {
1153
1216
  const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
1154
1217
  if (nameArg) {
1155
- (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1218
+ (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1156
1219
  return nameArg.value.value;
1157
1220
  }
1158
1221
  }
1159
1222
  return void 0;
1160
1223
  }
1161
- getIdFields(dm) {
1162
- return dm.fields.filter(isIdField).map((f) => f.name);
1163
- }
1164
1224
  createUniqueFieldsObject(dm) {
1165
1225
  const properties = [];
1166
- for (const field of dm.fields) {
1226
+ const allFields = (0, import_utils3.getAllFields)(dm);
1227
+ for (const field of allFields) {
1167
1228
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1168
1229
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1169
1230
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1170
1231
  ])));
1171
1232
  }
1172
1233
  }
1234
+ const allAttributes = (0, import_utils3.getAllAttributes)(dm);
1173
1235
  const seenKeys = /* @__PURE__ */ new Set();
1174
- for (const attr of dm.attributes) {
1236
+ for (const attr of allAttributes) {
1175
1237
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1176
1238
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1177
1239
  if (!fieldNames) {
1178
1240
  continue;
1179
1241
  }
1180
1242
  if (fieldNames.length === 1) {
1181
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1243
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1182
1244
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1183
1245
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1184
1246
  ])));
@@ -1189,7 +1251,7 @@ var TsSchemaGenerator = class {
1189
1251
  }
1190
1252
  seenKeys.add(key);
1191
1253
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1192
- const fieldDef = dm.fields.find((f) => f.name === field);
1254
+ const fieldDef = allFields.find((f) => f.name === field);
1193
1255
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1194
1256
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1195
1257
  ]));
@@ -1200,7 +1262,7 @@ var TsSchemaGenerator = class {
1200
1262
  return ts.factory.createObjectLiteralExpression(properties, true);
1201
1263
  }
1202
1264
  generateFieldTypeLiteral(field) {
1203
- (0, import_common_helpers.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1265
+ (0, import_common_helpers2.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1204
1266
  return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1205
1267
  }
1206
1268
  createEnumObject(e) {
@@ -1324,7 +1386,7 @@ var TsSchemaGenerator = class {
1324
1386
  ]);
1325
1387
  }
1326
1388
  createRefExpression(expr) {
1327
- if ((0, import_ast3.isDataModelField)(expr.target.ref)) {
1389
+ if ((0, import_ast3.isDataField)(expr.target.ref)) {
1328
1390
  return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1329
1391
  this.createLiteralNode(expr.target.$refText)
1330
1392
  ]);
@@ -1353,11 +1415,14 @@ var TsSchemaGenerator = class {
1353
1415
  throw new Error(`Unsupported literal type: ${type}`);
1354
1416
  });
1355
1417
  }
1356
- generateModels(model, outputDir) {
1418
+ generateModelsAndTypeDefs(model, outputDir) {
1357
1419
  const statements = [];
1358
- statements.push(this.generateSchemaTypeImport(true, true));
1420
+ statements.push(this.generateSchemaImport(model, true, true));
1359
1421
  statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1360
- ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`))
1422
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1423
+ ...model.declarations.some(import_ast3.isTypeDef) ? [
1424
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1425
+ ] : []
1361
1426
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1362
1427
  const dataModels = model.declarations.filter(import_ast3.isDataModel);
1363
1428
  for (const dm of dataModels) {
@@ -1372,6 +1437,19 @@ var TsSchemaGenerator = class {
1372
1437
  }
1373
1438
  statements.push(modelType);
1374
1439
  }
1440
+ const typeDefs = model.declarations.filter(import_ast3.isTypeDef);
1441
+ for (const td of typeDefs) {
1442
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1443
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1444
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1445
+ ts.factory.createTypeReferenceNode("$Schema"),
1446
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1447
+ ]));
1448
+ if (td.comments.length > 0) {
1449
+ typeDef = this.generateDocs(typeDef, td);
1450
+ }
1451
+ statements.push(typeDef);
1452
+ }
1375
1453
  const enums = model.declarations.filter(import_ast3.isEnum);
1376
1454
  for (const e of enums) {
1377
1455
  let enumDecl = ts.factory.createVariableStatement([
@@ -1398,10 +1476,12 @@ var TsSchemaGenerator = class {
1398
1476
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1399
1477
  import_node_fs.default.writeFileSync(outputFile, result);
1400
1478
  }
1401
- generateSchemaTypeImport(schemaObject, schemaType) {
1479
+ generateSchemaImport(model, schemaObject, schemaType) {
1402
1480
  const importSpecifiers = [];
1403
1481
  if (schemaObject) {
1404
- importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1482
+ if (model.declarations.some(import_ast3.isEnum)) {
1483
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1484
+ }
1405
1485
  }
1406
1486
  if (schemaType) {
1407
1487
  importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
@@ -1416,7 +1496,7 @@ var TsSchemaGenerator = class {
1416
1496
  generateInputTypes(model, outputDir) {
1417
1497
  const dataModels = model.declarations.filter(import_ast3.isDataModel);
1418
1498
  const statements = [];
1419
- statements.push(this.generateSchemaTypeImport(false, true));
1499
+ statements.push(this.generateSchemaImport(model, false, true));
1420
1500
  const inputTypes = [
1421
1501
  "FindManyArgs",
1422
1502
  "FindUniqueArgs",
@@ -1570,21 +1650,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1570
1650
  return `${ast.name} = ${this.generate(ast.value)}`;
1571
1651
  }
1572
1652
  _generateDataModel(ast) {
1573
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1653
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1574
1654
  ${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") : ""}
1575
1655
  }`;
1576
1656
  }
1577
- _generateDataModelField(ast) {
1657
+ _generateDataField(ast) {
1578
1658
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1579
1659
  }
1580
1660
  fieldType(type) {
1581
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1661
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1582
1662
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1583
1663
  }
1584
1664
  _generateDataModelAttribute(ast) {
1585
1665
  return this.attribute(ast);
1586
1666
  }
1587
- _generateDataModelFieldAttribute(ast) {
1667
+ _generateDataFieldAttribute(ast) {
1588
1668
  return this.attribute(ast);
1589
1669
  }
1590
1670
  attribute(ast) {
@@ -1668,9 +1748,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1668
1748
  ${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") : ""}
1669
1749
  }`;
1670
1750
  }
1671
- _generateTypeDefField(ast) {
1672
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1673
- }
1674
1751
  argument(ast) {
1675
1752
  return this.generate(ast.value);
1676
1753
  }
@@ -1796,13 +1873,13 @@ _ts_decorate([
1796
1873
  _ts_metadata("design:returntype", void 0)
1797
1874
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1798
1875
  _ts_decorate([
1799
- gen(import_ast4.DataModelField),
1876
+ gen(import_ast4.DataField),
1800
1877
  _ts_metadata("design:type", Function),
1801
1878
  _ts_metadata("design:paramtypes", [
1802
- typeof import_ast4.DataModelField === "undefined" ? Object : import_ast4.DataModelField
1879
+ typeof import_ast4.DataField === "undefined" ? Object : import_ast4.DataField
1803
1880
  ]),
1804
1881
  _ts_metadata("design:returntype", void 0)
1805
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1882
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1806
1883
  _ts_decorate([
1807
1884
  gen(import_ast4.DataModelAttribute),
1808
1885
  _ts_metadata("design:type", Function),
@@ -1812,13 +1889,13 @@ _ts_decorate([
1812
1889
  _ts_metadata("design:returntype", void 0)
1813
1890
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1814
1891
  _ts_decorate([
1815
- gen(import_ast4.DataModelFieldAttribute),
1892
+ gen(import_ast4.DataFieldAttribute),
1816
1893
  _ts_metadata("design:type", Function),
1817
1894
  _ts_metadata("design:paramtypes", [
1818
- typeof import_ast4.DataModelFieldAttribute === "undefined" ? Object : import_ast4.DataModelFieldAttribute
1895
+ typeof import_ast4.DataFieldAttribute === "undefined" ? Object : import_ast4.DataFieldAttribute
1819
1896
  ]),
1820
1897
  _ts_metadata("design:returntype", void 0)
1821
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1898
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1822
1899
  _ts_decorate([
1823
1900
  gen(import_ast4.AttributeArg),
1824
1901
  _ts_metadata("design:type", Function),
@@ -1983,14 +2060,6 @@ _ts_decorate([
1983
2060
  ]),
1984
2061
  _ts_metadata("design:returntype", void 0)
1985
2062
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1986
- _ts_decorate([
1987
- gen(import_ast4.TypeDefField),
1988
- _ts_metadata("design:type", Function),
1989
- _ts_metadata("design:paramtypes", [
1990
- typeof import_ast4.TypeDefField === "undefined" ? Object : import_ast4.TypeDefField
1991
- ]),
1992
- _ts_metadata("design:returntype", void 0)
1993
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1994
2063
  // Annotate the CommonJS export names for ESM import in node:
1995
2064
  0 && (module.exports = {
1996
2065
  ModelUtils,