@zenstackhq/sdk 3.0.0-alpha.2 → 3.0.0-alpha.20

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
 
@@ -318,9 +264,9 @@ var Model = class extends ContainerDeclaration {
318
264
  }
319
265
  name;
320
266
  isView;
321
- fields;
267
+ fields = [];
322
268
  constructor(name, isView, documentations = []) {
323
- super(documentations), this.name = name, this.isView = isView, this.fields = [];
269
+ super(documentations), this.name = name, this.isView = isView;
324
270
  }
325
271
  addField(name, type, attributes = [], documentations = [], addToFront = false) {
326
272
  const field = new ModelField(name, type, attributes, documentations);
@@ -540,9 +486,9 @@ var Enum = class extends ContainerDeclaration {
540
486
  __name(this, "Enum");
541
487
  }
542
488
  name;
543
- fields;
489
+ fields = [];
544
490
  constructor(name, documentations = []) {
545
- super(documentations), this.name = name, this.fields = [];
491
+ super(documentations), this.name = name;
546
492
  }
547
493
  addField(name, attributes = [], documentations = []) {
548
494
  const field = new EnumField(name, attributes, documentations);
@@ -586,20 +532,22 @@ 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");
592
539
  }
593
540
  zmodel;
594
- PRELUDE;
595
- constructor(zmodel) {
596
- this.zmodel = zmodel;
597
- this.PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
541
+ PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
598
542
  // DO NOT MODIFY THIS FILE //
599
543
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
600
544
  //////////////////////////////////////////////////////////////////////////////////////////////
601
545
 
602
546
  `;
547
+ // a mapping from full names to shortened names
548
+ shortNameMap = /* @__PURE__ */ new Map();
549
+ constructor(zmodel) {
550
+ this.zmodel = zmodel;
603
551
  }
604
552
  async generate() {
605
553
  const prisma = new PrismaModel();
@@ -661,16 +609,22 @@ var PrismaSchemaGenerator = class {
661
609
  }
662
610
  generateModel(prisma, decl) {
663
611
  const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
664
- for (const field of decl.fields) {
612
+ const allFields = (0, import_utils2.getAllFields)(decl, true);
613
+ for (const field of allFields) {
665
614
  if (model_utils_exports.hasAttribute(field, "@computed")) {
666
615
  continue;
667
616
  }
668
- this.generateModelField(model, field);
617
+ if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
618
+ this.generateModelField(model, field, decl);
619
+ }
669
620
  }
670
- 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))) {
671
623
  this.generateContainerAttribute(model, attr);
672
624
  }
673
625
  decl.comments.forEach((c) => model.addComment(c));
626
+ this.generateDelegateRelationForBase(model, decl);
627
+ this.generateDelegateRelationForConcrete(model, decl);
674
628
  }
675
629
  isPrismaAttribute(attr) {
676
630
  if (!attr.decl.ref) {
@@ -693,7 +647,7 @@ var PrismaSchemaGenerator = class {
693
647
  getStringLiteral(node) {
694
648
  return (0, import_ast2.isStringLiteral)(node) ? node.value : void 0;
695
649
  }
696
- generateModelField(model, field, addToFront = false) {
650
+ generateModelField(model, field, contextModel, addToFront = false) {
697
651
  let fieldType;
698
652
  if (field.type.type) {
699
653
  fieldType = field.type.type;
@@ -719,7 +673,7 @@ var PrismaSchemaGenerator = class {
719
673
  const type = new ModelFieldType(fieldType, isArray, field.type.optional);
720
674
  const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
721
675
  // when building physical schema, exclude `@default` for id fields inherited from delegate base
722
- !(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")
723
677
  )).map((attr) => this.makeFieldAttribute(attr));
724
678
  const docs = [
725
679
  ...field.comments
@@ -741,16 +695,8 @@ var PrismaSchemaGenerator = class {
741
695
  const model = import_langium.AstUtils.getContainerOfType(node, import_ast2.isModel);
742
696
  return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
743
697
  }
744
- setDummyDefault(result, field) {
745
- 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(() => {
746
- throw new Error(`Unsupported field type with default value: ${field.type.type}`);
747
- });
748
- result.attributes.push(new FieldAttribute("@default", [
749
- new AttributeArg(void 0, dummyDefaultValue)
750
- ]));
751
- }
752
- isInheritedFromDelegate(field) {
753
- return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
698
+ isInheritedFromDelegate(field, contextModel) {
699
+ return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
754
700
  }
755
701
  makeFieldAttribute(attr) {
756
702
  const attrName = attr.decl.ref.name;
@@ -807,40 +753,97 @@ var PrismaSchemaGenerator = class {
807
753
  ];
808
754
  _enum.addField(field.name, attributes, docs);
809
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
+ }
810
810
  };
811
811
 
812
812
  // src/ts-schema-generator.ts
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
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
818
819
  var import_ts_pattern2 = require("ts-pattern");
819
820
  var ts = __toESM(require("typescript"), 1);
820
821
  var TsSchemaGenerator = class {
821
822
  static {
822
823
  __name(this, "TsSchemaGenerator");
823
824
  }
824
- async generate(schemaFile, pluginModelFiles, outputFile) {
825
+ async generate(schemaFile, pluginModelFiles, outputDir) {
825
826
  const loaded = await (0, import_language.loadDocument)(schemaFile, pluginModelFiles);
826
827
  if (!loaded.success) {
827
828
  throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
828
829
  }
829
- const { model, warnings } = loaded;
830
+ const { model } = loaded;
831
+ import_node_fs.default.mkdirSync(outputDir, {
832
+ recursive: true
833
+ });
834
+ this.generateSchema(model, outputDir);
835
+ this.generateModelsAndTypeDefs(model, outputDir);
836
+ this.generateInputTypes(model, outputDir);
837
+ }
838
+ generateSchema(model, outputDir) {
830
839
  const statements = [];
831
840
  this.generateSchemaStatements(model, statements);
832
841
  this.generateBannerComments(statements);
833
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
842
+ const schemaOutputFile = import_node_path.default.join(outputDir, "schema.ts");
843
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
834
844
  const printer = ts.createPrinter();
835
845
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
836
- import_node_fs.default.mkdirSync(import_node_path.default.dirname(outputFile), {
837
- recursive: true
838
- });
839
- import_node_fs.default.writeFileSync(outputFile, result);
840
- return {
841
- model,
842
- warnings
843
- };
846
+ import_node_fs.default.writeFileSync(schemaOutputFile, result);
844
847
  }
845
848
  generateSchemaStatements(model, statements) {
846
849
  const hasComputedFields = model.declarations.some((d) => (0, import_ast3.isDataModel)(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
@@ -852,27 +855,6 @@ var TsSchemaGenerator = class {
852
855
  ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
853
856
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
854
857
  statements.push(runtimeImportDecl);
855
- const { type: providerType } = this.getDataSourceProvider(model);
856
- switch (providerType) {
857
- case "sqlite": {
858
- const pathImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("path"), void 0), ts.factory.createStringLiteral("node:path"));
859
- statements.push(pathImportDecl);
860
- const urlImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("url"), void 0), ts.factory.createStringLiteral("node:url"));
861
- statements.push(urlImportDecl);
862
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
863
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
864
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/sqlite-utils"));
865
- statements.push(dialectConfigImportDecl);
866
- break;
867
- }
868
- case "postgresql": {
869
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
870
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
871
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/pg-utils"));
872
- statements.push(dialectConfigImportDecl);
873
- break;
874
- }
875
- }
876
858
  const declaration = ts.factory.createVariableStatement([
877
859
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
878
860
  ], ts.factory.createVariableDeclarationList([
@@ -889,7 +871,11 @@ var TsSchemaGenerator = class {
889
871
  // provider
890
872
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
891
873
  // models
892
- 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
+ ] : []
893
879
  ];
894
880
  const enums = model.declarations.filter(import_ast3.isEnum);
895
881
  if (enums.length > 0) {
@@ -909,25 +895,49 @@ var TsSchemaGenerator = class {
909
895
  createProviderObject(model) {
910
896
  const dsProvider = this.getDataSourceProvider(model);
911
897
  return ts.factory.createObjectLiteralExpression([
912
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type)),
913
- ts.factory.createPropertyAssignment("dialectConfigProvider", this.createDialectConfigProvider(dsProvider))
898
+ ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type))
914
899
  ], true);
915
900
  }
916
901
  createModelsObject(model) {
917
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);
918
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
+ }
919
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);
920
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
+ ] : [],
921
923
  // fields
922
- 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)),
923
925
  // attributes
924
- ...dm.attributes.length > 0 ? [
925
- 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))
926
928
  ] : [],
927
929
  // idFields
928
- 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)))),
929
931
  // uniqueFields
930
- 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
+ ] : []
931
941
  ];
932
942
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
933
943
  if (computedFields.length > 0) {
@@ -935,23 +945,51 @@ var TsSchemaGenerator = class {
935
945
  }
936
946
  return ts.factory.createObjectLiteralExpression(fields, true);
937
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
+ }
938
966
  createComputedFieldsObject(fields) {
939
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", [
940
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
968
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
941
969
  ]), ts.factory.createBlock([
942
970
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
943
971
  ts.factory.createStringLiteral("This is a stub for computed field")
944
972
  ]))
945
973
  ], true))), true);
946
974
  }
947
- mapTypeToTSSyntaxKeyword(type) {
948
- return (0, import_ts_pattern2.match)(type).with("String", () => ts.SyntaxKind.StringKeyword).with("Boolean", () => ts.SyntaxKind.BooleanKeyword).with("Int", () => ts.SyntaxKind.NumberKeyword).with("Float", () => ts.SyntaxKind.NumberKeyword).with("BigInt", () => ts.SyntaxKind.BigIntKeyword).with("Decimal", () => ts.SyntaxKind.NumberKeyword).otherwise(() => ts.SyntaxKind.UnknownKeyword);
975
+ mapFieldTypeToTSType(type) {
976
+ let result = (0, import_ts_pattern2.match)(type.type).with("String", () => "string").with("Boolean", () => "boolean").with("Int", () => "number").with("Float", () => "number").with("BigInt", () => "bigint").with("Decimal", () => "number").otherwise(() => "unknown");
977
+ if (type.array) {
978
+ result = `${result}[]`;
979
+ }
980
+ if (type.optional) {
981
+ result = `${result} | null`;
982
+ }
983
+ return result;
949
984
  }
950
- createDataModelFieldObject(field) {
985
+ createDataFieldObject(field, contextModel) {
951
986
  const objectFields = [
952
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
987
+ // name
988
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
989
+ // type
990
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
953
991
  ];
954
- if (isIdField(field)) {
992
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
955
993
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
956
994
  }
957
995
  if (isUniqueField(field)) {
@@ -966,12 +1004,19 @@ var TsSchemaGenerator = class {
966
1004
  if (hasAttribute(field, "@updatedAt")) {
967
1005
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
968
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
+ }
969
1014
  if (field.attributes.length > 0) {
970
1015
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
971
1016
  }
972
- const defaultValue = this.getMappedDefault(field);
1017
+ const defaultValue = this.getFieldMappedDefault(field);
973
1018
  if (defaultValue !== void 0) {
974
- if (typeof defaultValue === "object") {
1019
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
975
1020
  if ("call" in defaultValue) {
976
1021
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
977
1022
  ts.factory.createStringLiteral(defaultValue.call),
@@ -990,7 +1035,11 @@ var TsSchemaGenerator = class {
990
1035
  throw new Error(`Unsupported default value type for field ${field.name}`);
991
1036
  }
992
1037
  } else {
993
- objectFields.push(ts.factory.createPropertyAssignment("default", typeof defaultValue === "string" ? ts.factory.createStringLiteral(defaultValue) : typeof defaultValue === "number" ? ts.factory.createNumericLiteral(defaultValue) : defaultValue === true ? ts.factory.createTrue() : ts.factory.createFalse()));
1038
+ if (Array.isArray(defaultValue)) {
1039
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
1040
+ } else {
1041
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
1042
+ }
994
1043
  }
995
1044
  }
996
1045
  if (hasAttribute(field, "@computed")) {
@@ -1005,60 +1054,53 @@ var TsSchemaGenerator = class {
1005
1054
  }
1006
1055
  return ts.factory.createObjectLiteralExpression(objectFields, true);
1007
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
+ }
1008
1061
  getDataSourceProvider(model) {
1009
1062
  const dataSource = model.declarations.find(import_ast3.isDataSource);
1010
- (0, import_tiny_invariant.default)(dataSource, "No data source found in the model");
1063
+ (0, import_common_helpers2.invariant)(dataSource, "No data source found in the model");
1011
1064
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
1012
- (0, import_tiny_invariant.default)((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");
1013
1066
  const type = providerExpr.value;
1014
- const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
1015
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1016
- if ((0, import_ast3.isLiteralExpr)(urlExpr)) {
1017
- return {
1018
- type,
1019
- url: urlExpr.value,
1020
- env: void 0
1021
- };
1022
- } else if ((0, import_ast3.isInvocationExpr)(urlExpr)) {
1023
- (0, import_tiny_invariant.default)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1024
- (0, import_tiny_invariant.default)(urlExpr.args.length === 1, "env function must have one argument");
1025
- return {
1026
- type,
1027
- env: urlExpr.args[0].value.value,
1028
- url: void 0
1029
- };
1030
- } else {
1031
- throw new Error("Unsupported URL type");
1032
- }
1067
+ return {
1068
+ type
1069
+ };
1033
1070
  }
1034
- getMappedDefault(field) {
1071
+ getFieldMappedDefault(field) {
1035
1072
  const defaultAttr = getAttribute(field, "@default");
1036
1073
  if (!defaultAttr) {
1037
1074
  return void 0;
1038
1075
  }
1039
1076
  const defaultValue = defaultAttr.args[0]?.value;
1040
- (0, import_tiny_invariant.default)(defaultValue, "Expected a default value");
1041
- if ((0, import_ast3.isLiteralExpr)(defaultValue)) {
1042
- const lit = defaultValue.value;
1043
- return field.type.type === "Boolean" ? lit : [
1077
+ (0, import_common_helpers2.invariant)(defaultValue, "Expected a default value");
1078
+ return this.getMappedValue(defaultValue, field.type);
1079
+ }
1080
+ getMappedValue(expr, fieldType) {
1081
+ if ((0, import_ast3.isLiteralExpr)(expr)) {
1082
+ const lit = expr.value;
1083
+ return fieldType.type === "Boolean" ? lit : [
1044
1084
  "Int",
1045
1085
  "Float",
1046
1086
  "Decimal",
1047
1087
  "BigInt"
1048
- ].includes(field.type.type) ? Number(lit) : lit;
1049
- } else if ((0, import_ast3.isReferenceExpr)(defaultValue) && (0, import_ast3.isEnumField)(defaultValue.target.ref)) {
1050
- return defaultValue.target.ref.name;
1051
- } else if ((0, import_ast3.isInvocationExpr)(defaultValue)) {
1088
+ ].includes(fieldType.type) ? Number(lit) : lit;
1089
+ } else if ((0, import_ast3.isArrayExpr)(expr)) {
1090
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1091
+ } else if ((0, import_ast3.isReferenceExpr)(expr) && (0, import_ast3.isEnumField)(expr.target.ref)) {
1092
+ return expr.target.ref.name;
1093
+ } else if ((0, import_ast3.isInvocationExpr)(expr)) {
1052
1094
  return {
1053
- call: defaultValue.function.$refText,
1054
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1095
+ call: expr.function.$refText,
1096
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1055
1097
  };
1056
- } else if (this.isAuthMemberAccess(defaultValue)) {
1098
+ } else if (this.isAuthMemberAccess(expr)) {
1057
1099
  return {
1058
- authMember: this.getMemberAccessChain(defaultValue)
1100
+ authMember: this.getMemberAccessChain(expr)
1059
1101
  };
1060
1102
  } else {
1061
- throw new Error(`Unsupported default value type for field ${field.name}`);
1103
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1062
1104
  }
1063
1105
  }
1064
1106
  getMemberAccessChain(expr) {
@@ -1157,40 +1199,45 @@ var TsSchemaGenerator = class {
1157
1199
  if (relation) {
1158
1200
  const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
1159
1201
  if (nameArg) {
1160
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1202
+ (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1161
1203
  return nameArg.value.value;
1162
1204
  }
1163
1205
  }
1164
1206
  return void 0;
1165
1207
  }
1166
- getIdFields(dm) {
1167
- return dm.fields.filter(isIdField).map((f) => f.name);
1168
- }
1169
1208
  createUniqueFieldsObject(dm) {
1170
1209
  const properties = [];
1171
- for (const field of dm.fields) {
1210
+ const allFields = (0, import_utils3.getAllFields)(dm);
1211
+ for (const field of allFields) {
1172
1212
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1173
1213
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1174
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1214
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1175
1215
  ])));
1176
1216
  }
1177
1217
  }
1178
- for (const attr of dm.attributes) {
1218
+ const allAttributes = (0, import_utils3.getAllAttributes)(dm);
1219
+ const seenKeys = /* @__PURE__ */ new Set();
1220
+ for (const attr of allAttributes) {
1179
1221
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1180
1222
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1181
1223
  if (!fieldNames) {
1182
1224
  continue;
1183
1225
  }
1184
1226
  if (fieldNames.length === 1) {
1185
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1227
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1186
1228
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1187
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1229
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1188
1230
  ])));
1189
1231
  } else {
1232
+ const key = fieldNames.join("_");
1233
+ if (seenKeys.has(key)) {
1234
+ continue;
1235
+ }
1236
+ seenKeys.add(key);
1190
1237
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1191
- const fieldDef = dm.fields.find((f) => f.name === field);
1238
+ const fieldDef = allFields.find((f) => f.name === field);
1192
1239
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1193
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1240
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1194
1241
  ]));
1195
1242
  }))));
1196
1243
  }
@@ -1198,6 +1245,10 @@ var TsSchemaGenerator = class {
1198
1245
  }
1199
1246
  return ts.factory.createObjectLiteralExpression(properties, true);
1200
1247
  }
1248
+ generateFieldTypeLiteral(field) {
1249
+ (0, import_common_helpers2.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1250
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1251
+ }
1201
1252
  createEnumObject(e) {
1202
1253
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1203
1254
  }
@@ -1218,44 +1269,6 @@ var TsSchemaGenerator = class {
1218
1269
  createLiteralNode(arg) {
1219
1270
  return arg === null ? ts.factory.createNull() : typeof arg === "string" ? ts.factory.createStringLiteral(arg) : typeof arg === "number" ? ts.factory.createNumericLiteral(arg) : arg === true ? ts.factory.createTrue() : arg === false ? ts.factory.createFalse() : void 0;
1220
1271
  }
1221
- createDialectConfigProvider(dsProvider) {
1222
- const type = dsProvider.type;
1223
- let urlExpr;
1224
- if (dsProvider.env !== void 0) {
1225
- urlExpr = ts.factory.createIdentifier(`process.env['${dsProvider.env}']`);
1226
- } else {
1227
- urlExpr = ts.factory.createStringLiteral(dsProvider.url);
1228
- if (type === "sqlite") {
1229
- let parsedUrl;
1230
- try {
1231
- parsedUrl = new URL(dsProvider.url);
1232
- } catch {
1233
- }
1234
- if (parsedUrl) {
1235
- if (parsedUrl.protocol !== "file:") {
1236
- throw new Error("Invalid SQLite URL: only file protocol is supported");
1237
- }
1238
- urlExpr = ts.factory.createStringLiteral(dsProvider.url.replace(/^file:/, ""));
1239
- }
1240
- }
1241
- }
1242
- return (0, import_ts_pattern2.match)(type).with("sqlite", () => {
1243
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1244
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1245
- urlExpr,
1246
- ts.factory.createIdentifier(`typeof __dirname !== 'undefined' ? __dirname : path.dirname(url.fileURLToPath(import.meta.url))`)
1247
- ]))
1248
- ], true));
1249
- }).with("postgresql", () => {
1250
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1251
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1252
- urlExpr
1253
- ]))
1254
- ], true));
1255
- }).otherwise(() => {
1256
- throw new Error(`Unsupported provider: ${type}`);
1257
- });
1258
- }
1259
1272
  createProceduresObject(procedures) {
1260
1273
  return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
1261
1274
  }
@@ -1290,6 +1303,8 @@ var TsSchemaGenerator = class {
1290
1303
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1291
1304
  //////////////////////////////////////////////////////////////////////////////////////////////
1292
1305
 
1306
+ /* eslint-disable */
1307
+
1293
1308
  `;
1294
1309
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1295
1310
  }
@@ -1355,7 +1370,7 @@ var TsSchemaGenerator = class {
1355
1370
  ]);
1356
1371
  }
1357
1372
  createRefExpression(expr) {
1358
- if ((0, import_ast3.isDataModelField)(expr.target.ref)) {
1373
+ if ((0, import_ast3.isDataField)(expr.target.ref)) {
1359
1374
  return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1360
1375
  this.createLiteralNode(expr.target.$refText)
1361
1376
  ]);
@@ -1384,6 +1399,150 @@ var TsSchemaGenerator = class {
1384
1399
  throw new Error(`Unsupported literal type: ${type}`);
1385
1400
  });
1386
1401
  }
1402
+ generateModelsAndTypeDefs(model, outputDir) {
1403
+ const statements = [];
1404
+ statements.push(this.generateSchemaImport(model, true, true));
1405
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1406
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1407
+ ...model.declarations.some(import_ast3.isTypeDef) ? [
1408
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1409
+ ] : []
1410
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1411
+ const dataModels = model.declarations.filter(import_ast3.isDataModel);
1412
+ for (const dm of dataModels) {
1413
+ let modelType = ts.factory.createTypeAliasDeclaration([
1414
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1415
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1416
+ ts.factory.createTypeReferenceNode("$Schema"),
1417
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1418
+ ]));
1419
+ if (dm.comments.length > 0) {
1420
+ modelType = this.generateDocs(modelType, dm);
1421
+ }
1422
+ statements.push(modelType);
1423
+ }
1424
+ const typeDefs = model.declarations.filter(import_ast3.isTypeDef);
1425
+ for (const td of typeDefs) {
1426
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1427
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1428
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1429
+ ts.factory.createTypeReferenceNode("$Schema"),
1430
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1431
+ ]));
1432
+ if (td.comments.length > 0) {
1433
+ typeDef = this.generateDocs(typeDef, td);
1434
+ }
1435
+ statements.push(typeDef);
1436
+ }
1437
+ const enums = model.declarations.filter(import_ast3.isEnum);
1438
+ for (const e of enums) {
1439
+ let enumDecl = ts.factory.createVariableStatement([
1440
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1441
+ ], ts.factory.createVariableDeclarationList([
1442
+ 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)))
1443
+ ], ts.NodeFlags.Const));
1444
+ if (e.comments.length > 0) {
1445
+ enumDecl = this.generateDocs(enumDecl, e);
1446
+ }
1447
+ statements.push(enumDecl);
1448
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1449
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1450
+ ], 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)))));
1451
+ if (e.comments.length > 0) {
1452
+ typeAlias = this.generateDocs(typeAlias, e);
1453
+ }
1454
+ statements.push(typeAlias);
1455
+ }
1456
+ this.generateBannerComments(statements);
1457
+ const outputFile = import_node_path.default.join(outputDir, "models.ts");
1458
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1459
+ const printer = ts.createPrinter();
1460
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1461
+ import_node_fs.default.writeFileSync(outputFile, result);
1462
+ }
1463
+ generateSchemaImport(model, schemaObject, schemaType) {
1464
+ const importSpecifiers = [];
1465
+ if (schemaObject) {
1466
+ if (model.declarations.some(import_ast3.isEnum)) {
1467
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1468
+ }
1469
+ }
1470
+ if (schemaType) {
1471
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1472
+ }
1473
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1474
+ }
1475
+ generateDocs(tsDecl, decl) {
1476
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1477
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1478
+ `, true);
1479
+ }
1480
+ generateInputTypes(model, outputDir) {
1481
+ const dataModels = model.declarations.filter(import_ast3.isDataModel);
1482
+ const statements = [];
1483
+ statements.push(this.generateSchemaImport(model, false, true));
1484
+ const inputTypes = [
1485
+ "FindManyArgs",
1486
+ "FindUniqueArgs",
1487
+ "FindFirstArgs",
1488
+ "CreateArgs",
1489
+ "CreateManyArgs",
1490
+ "CreateManyAndReturnArgs",
1491
+ "UpdateArgs",
1492
+ "UpdateManyArgs",
1493
+ "UpdateManyAndReturnArgs",
1494
+ "UpsertArgs",
1495
+ "DeleteArgs",
1496
+ "DeleteManyArgs",
1497
+ "CountArgs",
1498
+ "AggregateArgs",
1499
+ "GroupByArgs",
1500
+ "WhereInput",
1501
+ "SelectInput",
1502
+ "IncludeInput",
1503
+ "OmitInput"
1504
+ ];
1505
+ const inputTypeNameFixes = {
1506
+ SelectInput: "Select",
1507
+ IncludeInput: "Include",
1508
+ OmitInput: "Omit"
1509
+ };
1510
+ 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")));
1511
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1512
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1513
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1514
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1515
+ for (const dm of dataModels) {
1516
+ for (const inputType of inputTypes) {
1517
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1518
+ statements.push(ts.factory.createTypeAliasDeclaration([
1519
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1520
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1521
+ ts.factory.createTypeReferenceNode("$Schema"),
1522
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1523
+ ])));
1524
+ }
1525
+ statements.push(ts.factory.createTypeAliasDeclaration([
1526
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1527
+ ], `${dm.name}GetPayload`, [
1528
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1529
+ ts.factory.createTypeReferenceNode("$Schema"),
1530
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1531
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1532
+ ]))
1533
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1534
+ ts.factory.createTypeReferenceNode("$Schema"),
1535
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1536
+ ts.factory.createTypeReferenceNode("Args")
1537
+ ])));
1538
+ }
1539
+ this.generateBannerComments(statements);
1540
+ const outputFile = import_node_path.default.join(outputDir, "input.ts");
1541
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1542
+ const printer = ts.createPrinter();
1543
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1544
+ import_node_fs.default.writeFileSync(outputFile, result);
1545
+ }
1387
1546
  };
1388
1547
 
1389
1548
  // src/zmodel-code-generator.ts
@@ -1475,21 +1634,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1475
1634
  return `${ast.name} = ${this.generate(ast.value)}`;
1476
1635
  }
1477
1636
  _generateDataModel(ast) {
1478
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1637
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1479
1638
  ${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") : ""}
1480
1639
  }`;
1481
1640
  }
1482
- _generateDataModelField(ast) {
1641
+ _generateDataField(ast) {
1483
1642
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1484
1643
  }
1485
1644
  fieldType(type) {
1486
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1645
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1487
1646
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1488
1647
  }
1489
1648
  _generateDataModelAttribute(ast) {
1490
1649
  return this.attribute(ast);
1491
1650
  }
1492
- _generateDataModelFieldAttribute(ast) {
1651
+ _generateDataFieldAttribute(ast) {
1493
1652
  return this.attribute(ast);
1494
1653
  }
1495
1654
  attribute(ast) {
@@ -1573,9 +1732,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1573
1732
  ${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") : ""}
1574
1733
  }`;
1575
1734
  }
1576
- _generateTypeDefField(ast) {
1577
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1578
- }
1579
1735
  argument(ast) {
1580
1736
  return this.generate(ast.value);
1581
1737
  }
@@ -1701,13 +1857,13 @@ _ts_decorate([
1701
1857
  _ts_metadata("design:returntype", void 0)
1702
1858
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1703
1859
  _ts_decorate([
1704
- gen(import_ast4.DataModelField),
1860
+ gen(import_ast4.DataField),
1705
1861
  _ts_metadata("design:type", Function),
1706
1862
  _ts_metadata("design:paramtypes", [
1707
- typeof import_ast4.DataModelField === "undefined" ? Object : import_ast4.DataModelField
1863
+ typeof import_ast4.DataField === "undefined" ? Object : import_ast4.DataField
1708
1864
  ]),
1709
1865
  _ts_metadata("design:returntype", void 0)
1710
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1866
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1711
1867
  _ts_decorate([
1712
1868
  gen(import_ast4.DataModelAttribute),
1713
1869
  _ts_metadata("design:type", Function),
@@ -1717,13 +1873,13 @@ _ts_decorate([
1717
1873
  _ts_metadata("design:returntype", void 0)
1718
1874
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1719
1875
  _ts_decorate([
1720
- gen(import_ast4.DataModelFieldAttribute),
1876
+ gen(import_ast4.DataFieldAttribute),
1721
1877
  _ts_metadata("design:type", Function),
1722
1878
  _ts_metadata("design:paramtypes", [
1723
- typeof import_ast4.DataModelFieldAttribute === "undefined" ? Object : import_ast4.DataModelFieldAttribute
1879
+ typeof import_ast4.DataFieldAttribute === "undefined" ? Object : import_ast4.DataFieldAttribute
1724
1880
  ]),
1725
1881
  _ts_metadata("design:returntype", void 0)
1726
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1882
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1727
1883
  _ts_decorate([
1728
1884
  gen(import_ast4.AttributeArg),
1729
1885
  _ts_metadata("design:type", Function),
@@ -1888,14 +2044,6 @@ _ts_decorate([
1888
2044
  ]),
1889
2045
  _ts_metadata("design:returntype", void 0)
1890
2046
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1891
- _ts_decorate([
1892
- gen(import_ast4.TypeDefField),
1893
- _ts_metadata("design:type", Function),
1894
- _ts_metadata("design:paramtypes", [
1895
- typeof import_ast4.TypeDefField === "undefined" ? Object : import_ast4.TypeDefField
1896
- ]),
1897
- _ts_metadata("design:returntype", void 0)
1898
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1899
2047
  // Annotate the CommonJS export names for ESM import in node:
1900
2048
  0 && (module.exports = {
1901
2049
  ModelUtils,