@zenstackhq/sdk 3.0.0-alpha.3 → 3.0.0-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8,12 +8,11 @@ var __export = (target, all) => {
8
8
  // src/model-utils.ts
9
9
  var model_utils_exports = {};
10
10
  __export(model_utils_exports, {
11
+ DELEGATE_AUX_RELATION_PREFIX: () => DELEGATE_AUX_RELATION_PREFIX,
11
12
  getAttribute: () => getAttribute,
12
13
  getAuthDecl: () => getAuthDecl,
13
14
  getContainingModel: () => getContainingModel,
14
- getModelIdFields: () => getModelIdFields,
15
- getModelUniqueFields: () => getModelUniqueFields,
16
- getRecursiveBases: () => getRecursiveBases,
15
+ getIdFields: () => getIdFields,
17
16
  hasAttribute: () => hasAttribute,
18
17
  isDelegateModel: () => isDelegateModel,
19
18
  isFromStdlib: () => isFromStdlib,
@@ -21,24 +20,25 @@ __export(model_utils_exports, {
21
20
  isUniqueField: () => isUniqueField,
22
21
  resolved: () => resolved
23
22
  });
24
- import { isArrayExpr, isDataModel, isLiteralExpr, isModel, isReferenceExpr } from "@zenstackhq/language/ast";
25
- function isIdField(field) {
23
+ import { isDataModel, isLiteralExpr, isModel } from "@zenstackhq/language/ast";
24
+ import { getAllFields, getModelIdFields, getModelUniqueFields } from "@zenstackhq/language/utils";
25
+ function isIdField(field, contextModel) {
26
26
  if (hasAttribute(field, "@id")) {
27
27
  return true;
28
28
  }
29
- const model = field.$container;
30
- const modelLevelIds = getModelIdFields(model);
29
+ const modelLevelIds = getModelIdFields(contextModel);
31
30
  if (modelLevelIds.map((f) => f.name).includes(field.name)) {
32
31
  return true;
33
32
  }
34
- if (model.fields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
33
+ const allFields = getAllFields(contextModel);
34
+ if (allFields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
35
35
  return false;
36
36
  }
37
- const firstUniqueField = model.fields.find((f) => hasAttribute(f, "@unique"));
37
+ const firstUniqueField = allFields.find((f) => hasAttribute(f, "@unique"));
38
38
  if (firstUniqueField) {
39
39
  return firstUniqueField.name === field.name;
40
40
  }
41
- const modelLevelUnique = getModelUniqueFields(model);
41
+ const modelLevelUnique = getModelUniqueFields(contextModel);
42
42
  if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
43
43
  return true;
44
44
  }
@@ -53,67 +53,6 @@ function getAttribute(decl, name) {
53
53
  return decl.attributes.find((attr) => attr.decl.$refText === name);
54
54
  }
55
55
  __name(getAttribute, "getAttribute");
56
- function getModelIdFields(model) {
57
- const modelsToCheck = model.$baseMerged ? [
58
- model
59
- ] : [
60
- model,
61
- ...getRecursiveBases(model)
62
- ];
63
- for (const modelToCheck of modelsToCheck) {
64
- const idAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@id");
65
- if (!idAttr) {
66
- continue;
67
- }
68
- const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === "fields");
69
- if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {
70
- continue;
71
- }
72
- return fieldsArg.value.items.filter((item) => isReferenceExpr(item)).map((item) => item.target.ref);
73
- }
74
- return [];
75
- }
76
- __name(getModelIdFields, "getModelIdFields");
77
- function getModelUniqueFields(model) {
78
- const modelsToCheck = model.$baseMerged ? [
79
- model
80
- ] : [
81
- model,
82
- ...getRecursiveBases(model)
83
- ];
84
- for (const modelToCheck of modelsToCheck) {
85
- const uniqueAttr = modelToCheck.attributes.find((attr) => attr.decl.$refText === "@@unique");
86
- if (!uniqueAttr) {
87
- continue;
88
- }
89
- const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === "fields");
90
- if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {
91
- continue;
92
- }
93
- return fieldsArg.value.items.filter((item) => isReferenceExpr(item)).map((item) => item.target.ref);
94
- }
95
- return [];
96
- }
97
- __name(getModelUniqueFields, "getModelUniqueFields");
98
- function getRecursiveBases(dataModel, includeDelegate = true, seen = /* @__PURE__ */ new Set()) {
99
- const result = [];
100
- if (seen.has(dataModel)) {
101
- return result;
102
- }
103
- seen.add(dataModel);
104
- dataModel.superTypes.forEach((superType) => {
105
- const baseDecl = superType.ref;
106
- if (baseDecl) {
107
- if (!includeDelegate && isDelegateModel(baseDecl)) {
108
- return;
109
- }
110
- result.push(baseDecl);
111
- result.push(...getRecursiveBases(baseDecl, includeDelegate, seen));
112
- }
113
- });
114
- return result;
115
- }
116
- __name(getRecursiveBases, "getRecursiveBases");
117
56
  function isDelegateModel(node) {
118
57
  return isDataModel(node) && hasAttribute(node, "@@delegate");
119
58
  }
@@ -156,11 +95,18 @@ function getAuthDecl(model) {
156
95
  return found;
157
96
  }
158
97
  __name(getAuthDecl, "getAuthDecl");
98
+ function getIdFields(dm) {
99
+ return getAllFields(dm).filter((f) => isIdField(f, dm)).map((f) => f.name);
100
+ }
101
+ __name(getIdFields, "getIdFields");
102
+ var DELEGATE_AUX_RELATION_PREFIX = "delegate_aux";
159
103
 
160
104
  // src/prisma/prisma-schema-generator.ts
161
- import { BooleanLiteral, DataModel, DataSource as DataSource2, Enum as Enum2, GeneratorDecl, isArrayExpr as isArrayExpr2, isInvocationExpr, isLiteralExpr as isLiteralExpr2, isModel as isModel2, isNullExpr, isReferenceExpr as isReferenceExpr2, isStringLiteral, isTypeDef, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
105
+ import { lowerCaseFirst } from "@zenstackhq/common-helpers";
106
+ import { BooleanLiteral, DataModel, DataSource as DataSource2, Enum as Enum2, GeneratorDecl, isArrayExpr, isDataModel as isDataModel2, isInvocationExpr, isLiteralExpr as isLiteralExpr2, isModel as isModel2, isNullExpr, isReferenceExpr, isStringLiteral, isTypeDef, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
107
+ import { getAllAttributes, getAllFields as getAllFields2, isDelegateModel as isDelegateModel2 } from "@zenstackhq/language/utils";
162
108
  import { AstUtils } from "langium";
163
- import { match, P } from "ts-pattern";
109
+ import { match } from "ts-pattern";
164
110
 
165
111
  // src/prisma/indent-string.ts
166
112
  function indentString(string, count = 4) {
@@ -285,9 +231,9 @@ var Model = class extends ContainerDeclaration {
285
231
  }
286
232
  name;
287
233
  isView;
288
- fields;
234
+ fields = [];
289
235
  constructor(name, isView, documentations = []) {
290
- super(documentations), this.name = name, this.isView = isView, this.fields = [];
236
+ super(documentations), this.name = name, this.isView = isView;
291
237
  }
292
238
  addField(name, type, attributes = [], documentations = [], addToFront = false) {
293
239
  const field = new ModelField(name, type, attributes, documentations);
@@ -507,9 +453,9 @@ var Enum = class extends ContainerDeclaration {
507
453
  __name(this, "Enum");
508
454
  }
509
455
  name;
510
- fields;
456
+ fields = [];
511
457
  constructor(name, documentations = []) {
512
- super(documentations), this.name = name, this.fields = [];
458
+ super(documentations), this.name = name;
513
459
  }
514
460
  addField(name, attributes = [], documentations = []) {
515
461
  const field = new EnumField(name, attributes, documentations);
@@ -553,20 +499,22 @@ var EnumField = class extends DeclarationBase {
553
499
  };
554
500
 
555
501
  // src/prisma/prisma-schema-generator.ts
502
+ var IDENTIFIER_NAME_MAX_LENGTH = 50 - DELEGATE_AUX_RELATION_PREFIX.length;
556
503
  var PrismaSchemaGenerator = class {
557
504
  static {
558
505
  __name(this, "PrismaSchemaGenerator");
559
506
  }
560
507
  zmodel;
561
- PRELUDE;
562
- constructor(zmodel) {
563
- this.zmodel = zmodel;
564
- this.PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
508
+ PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
565
509
  // DO NOT MODIFY THIS FILE //
566
510
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
567
511
  //////////////////////////////////////////////////////////////////////////////////////////////
568
512
 
569
513
  `;
514
+ // a mapping from full names to shortened names
515
+ shortNameMap = /* @__PURE__ */ new Map();
516
+ constructor(zmodel) {
517
+ this.zmodel = zmodel;
570
518
  }
571
519
  async generate() {
572
520
  const prisma = new PrismaModel();
@@ -628,16 +576,22 @@ var PrismaSchemaGenerator = class {
628
576
  }
629
577
  generateModel(prisma, decl) {
630
578
  const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
631
- for (const field of decl.fields) {
579
+ const allFields = getAllFields2(decl, true);
580
+ for (const field of allFields) {
632
581
  if (model_utils_exports.hasAttribute(field, "@computed")) {
633
582
  continue;
634
583
  }
635
- this.generateModelField(model, field);
584
+ if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
585
+ this.generateModelField(model, field, decl);
586
+ }
636
587
  }
637
- for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
588
+ const allAttributes = getAllAttributes(decl);
589
+ for (const attr of allAttributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
638
590
  this.generateContainerAttribute(model, attr);
639
591
  }
640
592
  decl.comments.forEach((c) => model.addComment(c));
593
+ this.generateDelegateRelationForBase(model, decl);
594
+ this.generateDelegateRelationForConcrete(model, decl);
641
595
  }
642
596
  isPrismaAttribute(attr) {
643
597
  if (!attr.decl.ref) {
@@ -660,7 +614,7 @@ var PrismaSchemaGenerator = class {
660
614
  getStringLiteral(node) {
661
615
  return isStringLiteral(node) ? node.value : void 0;
662
616
  }
663
- generateModelField(model, field, addToFront = false) {
617
+ generateModelField(model, field, contextModel, addToFront = false) {
664
618
  let fieldType;
665
619
  if (field.type.type) {
666
620
  fieldType = field.type.type;
@@ -686,7 +640,7 @@ var PrismaSchemaGenerator = class {
686
640
  const type = new ModelFieldType(fieldType, isArray, field.type.optional);
687
641
  const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
688
642
  // when building physical schema, exclude `@default` for id fields inherited from delegate base
689
- !(model_utils_exports.isIdField(field) && this.isInheritedFromDelegate(field) && attr.decl.$refText === "@default")
643
+ !(model_utils_exports.isIdField(field, contextModel) && this.isInheritedFromDelegate(field, contextModel) && attr.decl.$refText === "@default")
690
644
  )).map((attr) => this.makeFieldAttribute(attr));
691
645
  const docs = [
692
646
  ...field.comments
@@ -708,16 +662,8 @@ var PrismaSchemaGenerator = class {
708
662
  const model = AstUtils.getContainerOfType(node, isModel2);
709
663
  return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
710
664
  }
711
- setDummyDefault(result, field) {
712
- const dummyDefaultValue = match(field.type.type).with("String", () => new AttributeArgValue("String", "")).with(P.union("Int", "BigInt", "Float", "Decimal"), () => new AttributeArgValue("Number", "0")).with("Boolean", () => new AttributeArgValue("Boolean", "false")).with("DateTime", () => new AttributeArgValue("FunctionCall", new FunctionCall("now"))).with("Json", () => new AttributeArgValue("String", "{}")).with("Bytes", () => new AttributeArgValue("String", "")).otherwise(() => {
713
- throw new Error(`Unsupported field type with default value: ${field.type.type}`);
714
- });
715
- result.attributes.push(new FieldAttribute("@default", [
716
- new AttributeArg(void 0, dummyDefaultValue)
717
- ]));
718
- }
719
- isInheritedFromDelegate(field) {
720
- return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
665
+ isInheritedFromDelegate(field, contextModel) {
666
+ return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
721
667
  }
722
668
  makeFieldAttribute(attr) {
723
669
  const attrName = attr.decl.ref.name;
@@ -730,9 +676,9 @@ var PrismaSchemaGenerator = class {
730
676
  if (isLiteralExpr2(node)) {
731
677
  const argType = match(node.$type).with(StringLiteral, () => "String").with(NumberLiteral, () => "Number").with(BooleanLiteral, () => "Boolean").exhaustive();
732
678
  return new AttributeArgValue(argType, node.value);
733
- } else if (isArrayExpr2(node)) {
679
+ } else if (isArrayExpr(node)) {
734
680
  return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
735
- } else if (isReferenceExpr2(node)) {
681
+ } else if (isReferenceExpr(node)) {
736
682
  return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
737
683
  } else if (isInvocationExpr(node)) {
738
684
  return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
@@ -774,43 +720,94 @@ var PrismaSchemaGenerator = class {
774
720
  ];
775
721
  _enum.addField(field.name, attributes, docs);
776
722
  }
723
+ generateDelegateRelationForBase(model, decl) {
724
+ if (!isDelegateModel2(decl)) {
725
+ return;
726
+ }
727
+ const concreteModels = this.getConcreteModels(decl);
728
+ concreteModels.forEach((concrete) => {
729
+ const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(concrete.name)}`);
730
+ model.addField(auxName, new ModelFieldType(concrete.name, false, true));
731
+ });
732
+ }
733
+ generateDelegateRelationForConcrete(model, concreteDecl) {
734
+ const base = concreteDecl.baseModel?.ref;
735
+ if (!base) {
736
+ return;
737
+ }
738
+ const idFields = getIdFields(base);
739
+ const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(base.name)}`);
740
+ model.addField(relationField, base.name, [
741
+ new FieldAttribute("@relation", [
742
+ new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
743
+ new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
744
+ new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
745
+ new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
746
+ ])
747
+ ]);
748
+ }
749
+ getConcreteModels(dataModel) {
750
+ if (!isDelegateModel2(dataModel)) {
751
+ return [];
752
+ }
753
+ return dataModel.$container.declarations.filter((d) => isDataModel2(d) && d !== dataModel && d.baseModel?.ref === dataModel);
754
+ }
755
+ truncate(name) {
756
+ if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
757
+ return name;
758
+ }
759
+ const existing = this.shortNameMap.get(name);
760
+ if (existing) {
761
+ return existing;
762
+ }
763
+ const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
764
+ let index = 0;
765
+ let shortName = `${baseName}_${index}`;
766
+ while (true) {
767
+ const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
768
+ if (!conflict) {
769
+ this.shortNameMap.set(name, shortName);
770
+ break;
771
+ }
772
+ index++;
773
+ shortName = `${baseName}_${index}`;
774
+ }
775
+ return shortName;
776
+ }
777
777
  };
778
778
 
779
779
  // src/ts-schema-generator.ts
780
- import { loadDocument } from "@zenstackhq/language";
781
- import { isArrayExpr as isArrayExpr3, isBinaryExpr, isDataModel as isDataModel2, isDataModelField, isDataSource, isEnum, isEnumField, isInvocationExpr as isInvocationExpr2, isLiteralExpr as isLiteralExpr3, isMemberAccessExpr, isNullExpr as isNullExpr2, isProcedure, isReferenceExpr as isReferenceExpr3, isThisExpr, isUnaryExpr } from "@zenstackhq/language/ast";
782
- import fs from "node:fs";
783
- import path from "node:path";
784
- import invariant from "tiny-invariant";
780
+ import { invariant } from "@zenstackhq/common-helpers";
781
+ import { isArrayExpr as isArrayExpr2, isBinaryExpr, isDataField, isDataModel as isDataModel3, isDataSource, isEnum, isEnumField, isInvocationExpr as isInvocationExpr2, isLiteralExpr as isLiteralExpr3, isMemberAccessExpr, isNullExpr as isNullExpr2, isProcedure, isReferenceExpr as isReferenceExpr2, isThisExpr, isTypeDef as isTypeDef2, isUnaryExpr } from "@zenstackhq/language/ast";
782
+ import { getAllAttributes as getAllAttributes2, getAllFields as getAllFields3, isDataFieldReference } from "@zenstackhq/language/utils";
783
+ import fs from "fs";
784
+ import path from "path";
785
785
  import { match as match2 } from "ts-pattern";
786
786
  import * as ts from "typescript";
787
787
  var TsSchemaGenerator = class {
788
788
  static {
789
789
  __name(this, "TsSchemaGenerator");
790
790
  }
791
- async generate(schemaFile, pluginModelFiles, outputFile) {
792
- const loaded = await loadDocument(schemaFile, pluginModelFiles);
793
- if (!loaded.success) {
794
- throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
795
- }
796
- const { model, warnings } = loaded;
791
+ async generate(model, outputDir) {
792
+ fs.mkdirSync(outputDir, {
793
+ recursive: true
794
+ });
795
+ this.generateSchema(model, outputDir);
796
+ this.generateModelsAndTypeDefs(model, outputDir);
797
+ this.generateInputTypes(model, outputDir);
798
+ }
799
+ generateSchema(model, outputDir) {
797
800
  const statements = [];
798
801
  this.generateSchemaStatements(model, statements);
799
802
  this.generateBannerComments(statements);
800
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
803
+ const schemaOutputFile = path.join(outputDir, "schema.ts");
804
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
801
805
  const printer = ts.createPrinter();
802
806
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
803
- fs.mkdirSync(path.dirname(outputFile), {
804
- recursive: true
805
- });
806
- fs.writeFileSync(outputFile, result);
807
- return {
808
- model,
809
- warnings
810
- };
807
+ fs.writeFileSync(schemaOutputFile, result);
811
808
  }
812
809
  generateSchemaStatements(model, statements) {
813
- const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
810
+ const hasComputedFields = model.declarations.some((d) => isDataModel3(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
814
811
  const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
815
812
  ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
816
813
  ...hasComputedFields ? [
@@ -835,7 +832,11 @@ var TsSchemaGenerator = class {
835
832
  // provider
836
833
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
837
834
  // models
838
- ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
835
+ ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
836
+ // typeDefs
837
+ ...model.declarations.some(isTypeDef2) ? [
838
+ ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
839
+ ] : []
839
840
  ];
840
841
  const enums = model.declarations.filter(isEnum);
841
842
  if (enums.length > 0) {
@@ -859,20 +860,45 @@ var TsSchemaGenerator = class {
859
860
  ], true);
860
861
  }
861
862
  createModelsObject(model) {
862
- return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel2(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
863
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel3(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
864
+ }
865
+ createTypeDefsObject(model) {
866
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isTypeDef2(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
863
867
  }
864
868
  createDataModelObject(dm) {
869
+ const allFields = getAllFields3(dm);
870
+ const allAttributes = getAllAttributes2(dm).filter((attr) => {
871
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
872
+ return false;
873
+ }
874
+ return true;
875
+ });
876
+ const subModels = this.getSubModels(dm);
865
877
  const fields = [
878
+ // name
879
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
880
+ // baseModel
881
+ ...dm.baseModel ? [
882
+ ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
883
+ ] : [],
866
884
  // fields
867
- 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)),
885
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
868
886
  // attributes
869
- ...dm.attributes.length > 0 ? [
870
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
887
+ ...allAttributes.length > 0 ? [
888
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
871
889
  ] : [],
872
890
  // idFields
873
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
891
+ ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
874
892
  // uniqueFields
875
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
893
+ ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
894
+ // isDelegate
895
+ ...isDelegateModel(dm) ? [
896
+ ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
897
+ ] : [],
898
+ // subModels
899
+ ...subModels.length > 0 ? [
900
+ ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
901
+ ] : []
876
902
  ];
877
903
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
878
904
  if (computedFields.length > 0) {
@@ -880,23 +906,56 @@ var TsSchemaGenerator = class {
880
906
  }
881
907
  return ts.factory.createObjectLiteralExpression(fields, true);
882
908
  }
909
+ getSubModels(dm) {
910
+ return dm.$container.declarations.filter(isDataModel3).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
911
+ }
912
+ createTypeDefObject(td) {
913
+ const allFields = getAllFields3(td);
914
+ const allAttributes = getAllAttributes2(td);
915
+ const fields = [
916
+ // name
917
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
918
+ // fields
919
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
920
+ // attributes
921
+ ...allAttributes.length > 0 ? [
922
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
923
+ ] : []
924
+ ];
925
+ return ts.factory.createObjectLiteralExpression(fields, true);
926
+ }
883
927
  createComputedFieldsObject(fields) {
884
- return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
885
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
928
+ return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
929
+ // parameter: `context: { currentModel: string }`
930
+ ts.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, ts.factory.createTypeLiteralNode([
931
+ ts.factory.createPropertySignature(void 0, "currentModel", void 0, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
932
+ ]), void 0)
933
+ ], ts.factory.createTypeReferenceNode("OperandExpression", [
934
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
886
935
  ]), ts.factory.createBlock([
887
936
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
888
937
  ts.factory.createStringLiteral("This is a stub for computed field")
889
938
  ]))
890
939
  ], true))), true);
891
940
  }
892
- mapTypeToTSSyntaxKeyword(type) {
893
- return match2(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);
941
+ mapFieldTypeToTSType(type) {
942
+ let result = match2(type.type).with("String", () => "string").with("Boolean", () => "boolean").with("Int", () => "number").with("Float", () => "number").with("BigInt", () => "bigint").with("Decimal", () => "number").otherwise(() => "unknown");
943
+ if (type.array) {
944
+ result = `${result}[]`;
945
+ }
946
+ if (type.optional) {
947
+ result = `${result} | null`;
948
+ }
949
+ return result;
894
950
  }
895
- createDataModelFieldObject(field) {
951
+ createDataFieldObject(field, contextModel) {
896
952
  const objectFields = [
897
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
953
+ // name
954
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
955
+ // type
956
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
898
957
  ];
899
- if (isIdField(field)) {
958
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
900
959
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
901
960
  }
902
961
  if (isUniqueField(field)) {
@@ -911,12 +970,19 @@ var TsSchemaGenerator = class {
911
970
  if (hasAttribute(field, "@updatedAt")) {
912
971
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
913
972
  }
973
+ if (contextModel && // id fields are duplicated in inherited models
974
+ !isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
975
+ objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
976
+ }
977
+ if (this.isDiscriminatorField(field)) {
978
+ objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
979
+ }
914
980
  if (field.attributes.length > 0) {
915
981
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
916
982
  }
917
- const defaultValue = this.getMappedDefault(field);
983
+ const defaultValue = this.getFieldMappedDefault(field);
918
984
  if (defaultValue !== void 0) {
919
- if (typeof defaultValue === "object") {
985
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
920
986
  if ("call" in defaultValue) {
921
987
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
922
988
  ts.factory.createStringLiteral(defaultValue.call),
@@ -935,13 +1001,17 @@ var TsSchemaGenerator = class {
935
1001
  throw new Error(`Unsupported default value type for field ${field.name}`);
936
1002
  }
937
1003
  } else {
938
- 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()));
1004
+ if (Array.isArray(defaultValue)) {
1005
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
1006
+ } else {
1007
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
1008
+ }
939
1009
  }
940
1010
  }
941
1011
  if (hasAttribute(field, "@computed")) {
942
1012
  objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
943
1013
  }
944
- if (isDataModel2(field.type.reference?.ref)) {
1014
+ if (isDataModel3(field.type.reference?.ref)) {
945
1015
  objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
946
1016
  }
947
1017
  const fkFor = this.getForeignKeyFor(field);
@@ -950,60 +1020,53 @@ var TsSchemaGenerator = class {
950
1020
  }
951
1021
  return ts.factory.createObjectLiteralExpression(objectFields, true);
952
1022
  }
1023
+ isDiscriminatorField(field) {
1024
+ const origin = field.$container;
1025
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && isDataFieldReference(arg.value) && arg.value.target.ref === field);
1026
+ }
953
1027
  getDataSourceProvider(model) {
954
1028
  const dataSource = model.declarations.find(isDataSource);
955
1029
  invariant(dataSource, "No data source found in the model");
956
1030
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
957
1031
  invariant(isLiteralExpr3(providerExpr), "Provider must be a literal");
958
1032
  const type = providerExpr.value;
959
- const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
960
- invariant(isLiteralExpr3(urlExpr) || isInvocationExpr2(urlExpr), "URL must be a literal or env function");
961
- if (isLiteralExpr3(urlExpr)) {
962
- return {
963
- type,
964
- url: urlExpr.value,
965
- env: void 0
966
- };
967
- } else if (isInvocationExpr2(urlExpr)) {
968
- invariant(urlExpr.function.$refText === "env", 'only "env" function is supported');
969
- invariant(urlExpr.args.length === 1, "env function must have one argument");
970
- return {
971
- type,
972
- env: urlExpr.args[0].value.value,
973
- url: void 0
974
- };
975
- } else {
976
- throw new Error("Unsupported URL type");
977
- }
1033
+ return {
1034
+ type
1035
+ };
978
1036
  }
979
- getMappedDefault(field) {
1037
+ getFieldMappedDefault(field) {
980
1038
  const defaultAttr = getAttribute(field, "@default");
981
1039
  if (!defaultAttr) {
982
1040
  return void 0;
983
1041
  }
984
1042
  const defaultValue = defaultAttr.args[0]?.value;
985
1043
  invariant(defaultValue, "Expected a default value");
986
- if (isLiteralExpr3(defaultValue)) {
987
- const lit = defaultValue.value;
988
- return field.type.type === "Boolean" ? lit : [
1044
+ return this.getMappedValue(defaultValue, field.type);
1045
+ }
1046
+ getMappedValue(expr, fieldType) {
1047
+ if (isLiteralExpr3(expr)) {
1048
+ const lit = expr.value;
1049
+ return fieldType.type === "Boolean" ? lit : [
989
1050
  "Int",
990
1051
  "Float",
991
1052
  "Decimal",
992
1053
  "BigInt"
993
- ].includes(field.type.type) ? Number(lit) : lit;
994
- } else if (isReferenceExpr3(defaultValue) && isEnumField(defaultValue.target.ref)) {
995
- return defaultValue.target.ref.name;
996
- } else if (isInvocationExpr2(defaultValue)) {
1054
+ ].includes(fieldType.type) ? Number(lit) : lit;
1055
+ } else if (isArrayExpr2(expr)) {
1056
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1057
+ } else if (isReferenceExpr2(expr) && isEnumField(expr.target.ref)) {
1058
+ return expr.target.ref.name;
1059
+ } else if (isInvocationExpr2(expr)) {
997
1060
  return {
998
- call: defaultValue.function.$refText,
999
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1061
+ call: expr.function.$refText,
1062
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1000
1063
  };
1001
- } else if (this.isAuthMemberAccess(defaultValue)) {
1064
+ } else if (this.isAuthMemberAccess(expr)) {
1002
1065
  return {
1003
- authMember: this.getMemberAccessChain(defaultValue)
1066
+ authMember: this.getMemberAccessChain(expr)
1004
1067
  };
1005
1068
  } else {
1006
- throw new Error(`Unsupported default value type for field ${field.name}`);
1069
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1007
1070
  }
1008
1071
  }
1009
1072
  getMemberAccessChain(expr) {
@@ -1057,7 +1120,7 @@ var TsSchemaGenerator = class {
1057
1120
  return ts.factory.createObjectLiteralExpression(relationFields);
1058
1121
  }
1059
1122
  getReferenceNames(expr) {
1060
- return isArrayExpr3(expr) && expr.items.map((item) => item.target.$refText);
1123
+ return isArrayExpr2(expr) && expr.items.map((item) => item.target.$refText);
1061
1124
  }
1062
1125
  getForeignKeyFor(field) {
1063
1126
  const result = [];
@@ -1065,7 +1128,7 @@ var TsSchemaGenerator = class {
1065
1128
  const relation = getAttribute(f, "@relation");
1066
1129
  if (relation) {
1067
1130
  for (const arg of relation.args) {
1068
- if (arg.name === "fields" && isArrayExpr3(arg.value) && arg.value.items.some((el) => isReferenceExpr3(el) && el.target.ref === field)) {
1131
+ if (arg.name === "fields" && isArrayExpr2(arg.value) && arg.value.items.some((el) => isReferenceExpr2(el) && el.target.ref === field)) {
1069
1132
  result.push(f.name);
1070
1133
  }
1071
1134
  }
@@ -1074,7 +1137,7 @@ var TsSchemaGenerator = class {
1074
1137
  return result;
1075
1138
  }
1076
1139
  getOppositeRelationField(field) {
1077
- if (!field.type.reference?.ref || !isDataModel2(field.type.reference?.ref)) {
1140
+ if (!field.type.reference?.ref || !isDataModel3(field.type.reference?.ref)) {
1078
1141
  return void 0;
1079
1142
  }
1080
1143
  const sourceModel = field.$container;
@@ -1108,34 +1171,39 @@ var TsSchemaGenerator = class {
1108
1171
  }
1109
1172
  return void 0;
1110
1173
  }
1111
- getIdFields(dm) {
1112
- return dm.fields.filter(isIdField).map((f) => f.name);
1113
- }
1114
1174
  createUniqueFieldsObject(dm) {
1115
1175
  const properties = [];
1116
- for (const field of dm.fields) {
1176
+ const allFields = getAllFields3(dm);
1177
+ for (const field of allFields) {
1117
1178
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1118
1179
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1119
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1180
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1120
1181
  ])));
1121
1182
  }
1122
1183
  }
1123
- for (const attr of dm.attributes) {
1184
+ const allAttributes = getAllAttributes2(dm);
1185
+ const seenKeys = /* @__PURE__ */ new Set();
1186
+ for (const attr of allAttributes) {
1124
1187
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1125
1188
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1126
1189
  if (!fieldNames) {
1127
1190
  continue;
1128
1191
  }
1129
1192
  if (fieldNames.length === 1) {
1130
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1193
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1131
1194
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1132
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1195
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1133
1196
  ])));
1134
1197
  } else {
1198
+ const key = fieldNames.join("_");
1199
+ if (seenKeys.has(key)) {
1200
+ continue;
1201
+ }
1202
+ seenKeys.add(key);
1135
1203
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1136
- const fieldDef = dm.fields.find((f) => f.name === field);
1204
+ const fieldDef = allFields.find((f) => f.name === field);
1137
1205
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1138
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1206
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1139
1207
  ]));
1140
1208
  }))));
1141
1209
  }
@@ -1143,6 +1211,10 @@ var TsSchemaGenerator = class {
1143
1211
  }
1144
1212
  return ts.factory.createObjectLiteralExpression(properties, true);
1145
1213
  }
1214
+ generateFieldTypeLiteral(field) {
1215
+ invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1216
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1217
+ }
1146
1218
  createEnumObject(e) {
1147
1219
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1148
1220
  }
@@ -1197,6 +1269,8 @@ var TsSchemaGenerator = class {
1197
1269
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1198
1270
  //////////////////////////////////////////////////////////////////////////////////////////////
1199
1271
 
1272
+ /* eslint-disable */
1273
+
1200
1274
  `;
1201
1275
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1202
1276
  }
@@ -1219,7 +1293,7 @@ var TsSchemaGenerator = class {
1219
1293
  ]);
1220
1294
  }
1221
1295
  createExpression(value) {
1222
- return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(isReferenceExpr3, (expr) => this.createRefExpression(expr)).when(isArrayExpr3, (expr) => this.createArrayExpression(expr)).when(isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(isNullExpr2, () => this.createNullExpression()).when(isThisExpr, () => this.createThisExpression()).otherwise(() => {
1296
+ return match2(value).when(isLiteralExpr3, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(isInvocationExpr2, (expr) => this.createCallExpression(expr)).when(isReferenceExpr2, (expr) => this.createRefExpression(expr)).when(isArrayExpr2, (expr) => this.createArrayExpression(expr)).when(isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(isNullExpr2, () => this.createNullExpression()).when(isThisExpr, () => this.createThisExpression()).otherwise(() => {
1223
1297
  throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1224
1298
  });
1225
1299
  }
@@ -1262,7 +1336,7 @@ var TsSchemaGenerator = class {
1262
1336
  ]);
1263
1337
  }
1264
1338
  createRefExpression(expr) {
1265
- if (isDataModelField(expr.target.ref)) {
1339
+ if (isDataField(expr.target.ref)) {
1266
1340
  return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1267
1341
  this.createLiteralNode(expr.target.$refText)
1268
1342
  ]);
@@ -1291,10 +1365,154 @@ var TsSchemaGenerator = class {
1291
1365
  throw new Error(`Unsupported literal type: ${type}`);
1292
1366
  });
1293
1367
  }
1368
+ generateModelsAndTypeDefs(model, outputDir) {
1369
+ const statements = [];
1370
+ statements.push(this.generateSchemaImport(model, true, true));
1371
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1372
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1373
+ ...model.declarations.some(isTypeDef2) ? [
1374
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1375
+ ] : []
1376
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1377
+ const dataModels = model.declarations.filter(isDataModel3);
1378
+ for (const dm of dataModels) {
1379
+ let modelType = ts.factory.createTypeAliasDeclaration([
1380
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1381
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1382
+ ts.factory.createTypeReferenceNode("$Schema"),
1383
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1384
+ ]));
1385
+ if (dm.comments.length > 0) {
1386
+ modelType = this.generateDocs(modelType, dm);
1387
+ }
1388
+ statements.push(modelType);
1389
+ }
1390
+ const typeDefs = model.declarations.filter(isTypeDef2);
1391
+ for (const td of typeDefs) {
1392
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1393
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1394
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1395
+ ts.factory.createTypeReferenceNode("$Schema"),
1396
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1397
+ ]));
1398
+ if (td.comments.length > 0) {
1399
+ typeDef = this.generateDocs(typeDef, td);
1400
+ }
1401
+ statements.push(typeDef);
1402
+ }
1403
+ const enums = model.declarations.filter(isEnum);
1404
+ for (const e of enums) {
1405
+ let enumDecl = ts.factory.createVariableStatement([
1406
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1407
+ ], ts.factory.createVariableDeclarationList([
1408
+ 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)))
1409
+ ], ts.NodeFlags.Const));
1410
+ if (e.comments.length > 0) {
1411
+ enumDecl = this.generateDocs(enumDecl, e);
1412
+ }
1413
+ statements.push(enumDecl);
1414
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1415
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1416
+ ], 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)))));
1417
+ if (e.comments.length > 0) {
1418
+ typeAlias = this.generateDocs(typeAlias, e);
1419
+ }
1420
+ statements.push(typeAlias);
1421
+ }
1422
+ this.generateBannerComments(statements);
1423
+ const outputFile = path.join(outputDir, "models.ts");
1424
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1425
+ const printer = ts.createPrinter();
1426
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1427
+ fs.writeFileSync(outputFile, result);
1428
+ }
1429
+ generateSchemaImport(model, schemaObject, schemaType) {
1430
+ const importSpecifiers = [];
1431
+ if (schemaObject) {
1432
+ if (model.declarations.some(isEnum)) {
1433
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1434
+ }
1435
+ }
1436
+ if (schemaType) {
1437
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1438
+ }
1439
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1440
+ }
1441
+ generateDocs(tsDecl, decl) {
1442
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1443
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1444
+ `, true);
1445
+ }
1446
+ generateInputTypes(model, outputDir) {
1447
+ const dataModels = model.declarations.filter(isDataModel3);
1448
+ const statements = [];
1449
+ statements.push(this.generateSchemaImport(model, false, true));
1450
+ const inputTypes = [
1451
+ "FindManyArgs",
1452
+ "FindUniqueArgs",
1453
+ "FindFirstArgs",
1454
+ "CreateArgs",
1455
+ "CreateManyArgs",
1456
+ "CreateManyAndReturnArgs",
1457
+ "UpdateArgs",
1458
+ "UpdateManyArgs",
1459
+ "UpdateManyAndReturnArgs",
1460
+ "UpsertArgs",
1461
+ "DeleteArgs",
1462
+ "DeleteManyArgs",
1463
+ "CountArgs",
1464
+ "AggregateArgs",
1465
+ "GroupByArgs",
1466
+ "WhereInput",
1467
+ "SelectInput",
1468
+ "IncludeInput",
1469
+ "OmitInput"
1470
+ ];
1471
+ const inputTypeNameFixes = {
1472
+ SelectInput: "Select",
1473
+ IncludeInput: "Include",
1474
+ OmitInput: "Omit"
1475
+ };
1476
+ 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")));
1477
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1478
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1479
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1480
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1481
+ for (const dm of dataModels) {
1482
+ for (const inputType of inputTypes) {
1483
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1484
+ statements.push(ts.factory.createTypeAliasDeclaration([
1485
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1486
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1487
+ ts.factory.createTypeReferenceNode("$Schema"),
1488
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1489
+ ])));
1490
+ }
1491
+ statements.push(ts.factory.createTypeAliasDeclaration([
1492
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1493
+ ], `${dm.name}GetPayload`, [
1494
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1495
+ ts.factory.createTypeReferenceNode("$Schema"),
1496
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1497
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1498
+ ]))
1499
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1500
+ ts.factory.createTypeReferenceNode("$Schema"),
1501
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1502
+ ts.factory.createTypeReferenceNode("Args")
1503
+ ])));
1504
+ }
1505
+ this.generateBannerComments(statements);
1506
+ const outputFile = path.join(outputDir, "input.ts");
1507
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1508
+ const printer = ts.createPrinter();
1509
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1510
+ fs.writeFileSync(outputFile, result);
1511
+ }
1294
1512
  };
1295
1513
 
1296
1514
  // src/zmodel-code-generator.ts
1297
- import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataModel as DataModel2, DataModelAttribute, DataModelField, DataModelFieldAttribute, DataSource as DataSource3, Enum as Enum3, EnumField as EnumField2, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl as GeneratorDecl2, InvocationExpr, LiteralExpr, MemberAccessExpr, Model as Model2, NullExpr, NumberLiteral as NumberLiteral2, ObjectExpr, Plugin, PluginField, ReferenceArg, ReferenceExpr, StringLiteral as StringLiteral2, ThisExpr, TypeDef, TypeDefField, UnaryExpr } from "@zenstackhq/language/ast";
1515
+ import { ArrayExpr, Attribute, AttributeArg as AttributeArg2, AttributeParam, AttributeParamType, BinaryExpr, BinaryExprOperatorPriority, BooleanLiteral as BooleanLiteral2, ConfigArrayExpr, ConfigField, ConfigInvocationExpr, DataField, DataFieldAttribute, DataModel as DataModel2, DataModelAttribute, DataSource as DataSource3, Enum as Enum3, EnumField as EnumField2, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl as GeneratorDecl2, InvocationExpr, LiteralExpr, MemberAccessExpr, Model as Model2, NullExpr, NumberLiteral as NumberLiteral2, ObjectExpr, Plugin, PluginField, ReferenceArg, ReferenceExpr, StringLiteral as StringLiteral2, ThisExpr, TypeDef, UnaryExpr } from "@zenstackhq/language/ast";
1298
1516
  function _ts_decorate(decorators, target, key, desc) {
1299
1517
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1300
1518
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1382,21 +1600,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1382
1600
  return `${ast.name} = ${this.generate(ast.value)}`;
1383
1601
  }
1384
1602
  _generateDataModel(ast) {
1385
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1603
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1386
1604
  ${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") : ""}
1387
1605
  }`;
1388
1606
  }
1389
- _generateDataModelField(ast) {
1607
+ _generateDataField(ast) {
1390
1608
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1391
1609
  }
1392
1610
  fieldType(type) {
1393
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1611
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1394
1612
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1395
1613
  }
1396
1614
  _generateDataModelAttribute(ast) {
1397
1615
  return this.attribute(ast);
1398
1616
  }
1399
- _generateDataModelFieldAttribute(ast) {
1617
+ _generateDataFieldAttribute(ast) {
1400
1618
  return this.attribute(ast);
1401
1619
  }
1402
1620
  attribute(ast) {
@@ -1480,9 +1698,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1480
1698
  ${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") : ""}
1481
1699
  }`;
1482
1700
  }
1483
- _generateTypeDefField(ast) {
1484
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1485
- }
1486
1701
  argument(ast) {
1487
1702
  return this.generate(ast.value);
1488
1703
  }
@@ -1608,13 +1823,13 @@ _ts_decorate([
1608
1823
  _ts_metadata("design:returntype", void 0)
1609
1824
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1610
1825
  _ts_decorate([
1611
- gen(DataModelField),
1826
+ gen(DataField),
1612
1827
  _ts_metadata("design:type", Function),
1613
1828
  _ts_metadata("design:paramtypes", [
1614
- typeof DataModelField === "undefined" ? Object : DataModelField
1829
+ typeof DataField === "undefined" ? Object : DataField
1615
1830
  ]),
1616
1831
  _ts_metadata("design:returntype", void 0)
1617
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1832
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1618
1833
  _ts_decorate([
1619
1834
  gen(DataModelAttribute),
1620
1835
  _ts_metadata("design:type", Function),
@@ -1624,13 +1839,13 @@ _ts_decorate([
1624
1839
  _ts_metadata("design:returntype", void 0)
1625
1840
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1626
1841
  _ts_decorate([
1627
- gen(DataModelFieldAttribute),
1842
+ gen(DataFieldAttribute),
1628
1843
  _ts_metadata("design:type", Function),
1629
1844
  _ts_metadata("design:paramtypes", [
1630
- typeof DataModelFieldAttribute === "undefined" ? Object : DataModelFieldAttribute
1845
+ typeof DataFieldAttribute === "undefined" ? Object : DataFieldAttribute
1631
1846
  ]),
1632
1847
  _ts_metadata("design:returntype", void 0)
1633
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1848
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1634
1849
  _ts_decorate([
1635
1850
  gen(AttributeArg2),
1636
1851
  _ts_metadata("design:type", Function),
@@ -1795,14 +2010,6 @@ _ts_decorate([
1795
2010
  ]),
1796
2011
  _ts_metadata("design:returntype", void 0)
1797
2012
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1798
- _ts_decorate([
1799
- gen(TypeDefField),
1800
- _ts_metadata("design:type", Function),
1801
- _ts_metadata("design:paramtypes", [
1802
- typeof TypeDefField === "undefined" ? Object : TypeDefField
1803
- ]),
1804
- _ts_metadata("design:returntype", void 0)
1805
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1806
2013
  export {
1807
2014
  model_utils_exports as ModelUtils,
1808
2015
  PrismaSchemaGenerator,