@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 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
  }
@@ -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
- 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) && !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.isDefaultWithPluginInvocation(attr)).filter((attr) => (
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
- isDefaultWithPluginInvocation(attr) {
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((node) => (0, import_ast2.isInvocationExpr)(node) && this.isFromPlugin(node.function.ref));
699
+ return import_langium.AstUtils.streamAst(expr).some(import_utils2.isAuthInvocation);
738
700
  }
739
- isFromPlugin(node) {
740
- const model = import_langium.AstUtils.getContainerOfType(node, import_ast2.isModel);
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 import_common_helpers = require("@zenstackhq/common-helpers");
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
- async generate(schemaFile, pluginModelFiles, outputFile) {
824
- const loaded = await (0, import_language.loadDocument)(schemaFile, pluginModelFiles);
825
- if (!loaded.success) {
826
- throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
827
- }
828
- const { model, warnings } = loaded;
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 sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
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.mkdirSync(import_node_path.default.dirname(outputFile), {
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
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
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(this.createSchemaObject(model), ts.factory.createTypeReferenceNode("const")), ts.factory.createTypeReferenceNode("SchemaDef")))
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(dm.fields.filter((field) => !hasAttribute(field, "@ignore")).map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataModelFieldObject(field))), true)),
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
- ...dm.attributes.length > 0 ? [
902
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
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(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
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, [], ts.factory.createTypeReferenceNode("OperandExpression", [
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
- createDataModelFieldObject(field) {
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", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
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.createLiteralNode(arg)))
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", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, [
968
- ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
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, import_common_helpers.invariant)(dataSource, "No data source found in the model");
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, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1081
+ (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1001
1082
  const type = providerExpr.value;
1002
- const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
1003
- (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1004
- if ((0, import_ast3.isLiteralExpr)(urlExpr)) {
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, import_common_helpers.invariant)(defaultValue, "Expected a default value");
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, 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");
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
- for (const field of dm.fields) {
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 dm.attributes) {
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 = dm.fields.find((f) => f.name === fieldNames[0]);
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 = fieldNames.join("_");
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(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1190
- const fieldDef = dm.fields.find((f) => f.name === field);
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, import_common_helpers.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
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 ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._this"), void 0, []);
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 ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, args);
1373
+ return this.createExpressionUtilsCall("member", args);
1302
1374
  }
1303
1375
  createNullExpression() {
1304
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._null"), void 0, []);
1376
+ return this.createExpressionUtilsCall("_null");
1305
1377
  }
1306
1378
  createBinaryExpression(expr) {
1307
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.binary"), void 0, [
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 ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.unary"), void 0, [
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 ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.array"), void 0, [
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.isDataModelField)(expr.target.ref)) {
1326
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
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 ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
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", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
1416
+ return (0, import_ts_pattern2.match)(type).with("BooleanLiteral", () => this.createExpressionUtilsCall("literal", [
1345
1417
  this.createLiteralNode(value)
1346
- ])).with("NumberLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
1418
+ ])).with("NumberLiteral", () => this.createExpressionUtilsCall("literal", [
1347
1419
  ts.factory.createIdentifier(value)
1348
- ])).with("StringLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
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.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
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
- _generateDataModelField(ast) {
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 == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
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
- _generateDataModelFieldAttribute(ast) {
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.DataModelField),
1884
+ gen(import_ast4.DataField),
1672
1885
  _ts_metadata("design:type", Function),
1673
1886
  _ts_metadata("design:paramtypes", [
1674
- typeof import_ast4.DataModelField === "undefined" ? Object : import_ast4.DataModelField
1887
+ typeof import_ast4.DataField === "undefined" ? Object : import_ast4.DataField
1675
1888
  ]),
1676
1889
  _ts_metadata("design:returntype", void 0)
1677
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
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.DataModelFieldAttribute),
1900
+ gen(import_ast4.DataFieldAttribute),
1688
1901
  _ts_metadata("design:type", Function),
1689
1902
  _ts_metadata("design:paramtypes", [
1690
- typeof import_ast4.DataModelFieldAttribute === "undefined" ? Object : import_ast4.DataModelFieldAttribute
1903
+ typeof import_ast4.DataFieldAttribute === "undefined" ? Object : import_ast4.DataFieldAttribute
1691
1904
  ]),
1692
1905
  _ts_metadata("design:returntype", void 0)
1693
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
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,