@zenstackhq/sdk 3.0.0-alpha.9 → 3.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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, isTypeDef } 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
  }
@@ -149,18 +88,25 @@ function resolved(ref) {
149
88
  }
150
89
  __name(resolved, "resolved");
151
90
  function getAuthDecl(model) {
152
- let found = model.declarations.find((d) => isDataModel(d) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
91
+ let found = model.declarations.find((d) => (isDataModel(d) || isTypeDef(d)) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
153
92
  if (!found) {
154
93
  found = model.declarations.find((d) => isDataModel(d) && d.name === "User");
155
94
  }
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, isNullExpr, isReferenceExpr, isStringLiteral, isTypeDef as isTypeDef2, NumberLiteral, StringLiteral } from "@zenstackhq/language/ast";
107
+ import { getAllAttributes, getAllFields as getAllFields2, isAuthInvocation, isDelegateModel as isDelegateModel2 } from "@zenstackhq/language/utils";
162
108
  import { AstUtils } from "langium";
163
- import { match, P } from "ts-pattern";
109
+ import { match } from "ts-pattern";
164
110
 
165
111
  // src/prisma/indent-string.ts
166
112
  function indentString(string, count = 4) {
@@ -553,6 +499,7 @@ var EnumField = class extends DeclarationBase {
553
499
  };
554
500
 
555
501
  // src/prisma/prisma-schema-generator.ts
502
+ var IDENTIFIER_NAME_MAX_LENGTH = 50 - DELEGATE_AUX_RELATION_PREFIX.length;
556
503
  var PrismaSchemaGenerator = class {
557
504
  static {
558
505
  __name(this, "PrismaSchemaGenerator");
@@ -564,6 +511,8 @@ var PrismaSchemaGenerator = class {
564
511
  //////////////////////////////////////////////////////////////////////////////////////////////
565
512
 
566
513
  `;
514
+ // a mapping from full names to shortened names
515
+ shortNameMap = /* @__PURE__ */ new Map();
567
516
  constructor(zmodel) {
568
517
  this.zmodel = zmodel;
569
518
  }
@@ -627,16 +576,29 @@ var PrismaSchemaGenerator = class {
627
576
  }
628
577
  generateModel(prisma, decl) {
629
578
  const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
630
- for (const field of decl.fields) {
579
+ const allFields = getAllFields2(decl, true);
580
+ for (const field of allFields) {
631
581
  if (model_utils_exports.hasAttribute(field, "@computed")) {
632
582
  continue;
633
583
  }
634
- this.generateModelField(model, field);
584
+ if (model_utils_exports.isIdField(field, decl) || !this.isInheritedFromDelegate(field, decl)) {
585
+ this.generateModelField(model, field, decl);
586
+ }
635
587
  }
636
- for (const attr of decl.attributes.filter((attr2) => this.isPrismaAttribute(attr2))) {
588
+ const allAttributes = getAllAttributes(decl);
589
+ for (const attr of allAttributes.filter((attr2) => this.isPrismaAttribute(attr2) && !this.isInheritedMapAttribute(attr2, decl))) {
637
590
  this.generateContainerAttribute(model, attr);
638
591
  }
639
592
  decl.comments.forEach((c) => model.addComment(c));
593
+ this.generateDelegateRelationForBase(model, decl);
594
+ this.generateDelegateRelationForConcrete(model, decl);
595
+ }
596
+ isInheritedMapAttribute(attr, contextModel) {
597
+ if (attr.$container === contextModel) {
598
+ return false;
599
+ }
600
+ const attrName = attr.decl.ref?.name ?? attr.decl.$refText;
601
+ return attrName === "@@map";
640
602
  }
641
603
  isPrismaAttribute(attr) {
642
604
  if (!attr.decl.ref) {
@@ -659,12 +621,12 @@ var PrismaSchemaGenerator = class {
659
621
  getStringLiteral(node) {
660
622
  return isStringLiteral(node) ? node.value : void 0;
661
623
  }
662
- generateModelField(model, field, addToFront = false) {
624
+ generateModelField(model, field, contextModel, addToFront = false) {
663
625
  let fieldType;
664
626
  if (field.type.type) {
665
627
  fieldType = field.type.type;
666
628
  } else if (field.type.reference?.ref) {
667
- if (isTypeDef(field.type.reference.ref)) {
629
+ if (isTypeDef2(field.type.reference.ref)) {
668
630
  fieldType = "Json";
669
631
  } else {
670
632
  fieldType = field.type.reference.ref.name;
@@ -680,12 +642,12 @@ var PrismaSchemaGenerator = class {
680
642
  }
681
643
  const isArray = (
682
644
  // typed-JSON fields should be translated to scalar Json type
683
- isTypeDef(field.type.reference?.ref) ? false : field.type.array
645
+ isTypeDef2(field.type.reference?.ref) ? false : field.type.array
684
646
  );
685
647
  const type = new ModelFieldType(fieldType, isArray, field.type.optional);
686
- const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithPluginInvocation(attr)).filter((attr) => (
648
+ const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithAuthInvocation(attr)).filter((attr) => (
687
649
  // when building physical schema, exclude `@default` for id fields inherited from delegate base
688
- !(model_utils_exports.isIdField(field) && this.isInheritedFromDelegate(field) && attr.decl.$refText === "@default")
650
+ !(model_utils_exports.isIdField(field, contextModel) && this.isInheritedFromDelegate(field, contextModel) && attr.decl.$refText === "@default")
689
651
  )).map((attr) => this.makeFieldAttribute(attr));
690
652
  const docs = [
691
653
  ...field.comments
@@ -693,7 +655,7 @@ var PrismaSchemaGenerator = class {
693
655
  const result = model.addField(field.name, type, attributes, docs, addToFront);
694
656
  return result;
695
657
  }
696
- isDefaultWithPluginInvocation(attr) {
658
+ isDefaultWithAuthInvocation(attr) {
697
659
  if (attr.decl.ref?.name !== "@default") {
698
660
  return false;
699
661
  }
@@ -701,22 +663,10 @@ var PrismaSchemaGenerator = class {
701
663
  if (!expr) {
702
664
  return false;
703
665
  }
704
- return AstUtils.streamAst(expr).some((node) => isInvocationExpr(node) && this.isFromPlugin(node.function.ref));
705
- }
706
- isFromPlugin(node) {
707
- const model = AstUtils.getContainerOfType(node, isModel2);
708
- return !!model && !!model.$document && model.$document.uri.path.endsWith("plugin.zmodel");
666
+ return AstUtils.streamAst(expr).some(isAuthInvocation);
709
667
  }
710
- setDummyDefault(result, field) {
711
- const dummyDefaultValue = match(field.type.type).with("String", () => new AttributeArgValue("String", "")).with(P.union("Int", "BigInt", "Float", "Decimal"), () => new AttributeArgValue("Number", "0")).with("Boolean", () => new AttributeArgValue("Boolean", "false")).with("DateTime", () => new AttributeArgValue("FunctionCall", new FunctionCall("now"))).with("Json", () => new AttributeArgValue("String", "{}")).with("Bytes", () => new AttributeArgValue("String", "")).otherwise(() => {
712
- throw new Error(`Unsupported field type with default value: ${field.type.type}`);
713
- });
714
- result.attributes.push(new FieldAttribute("@default", [
715
- new AttributeArg(void 0, dummyDefaultValue)
716
- ]));
717
- }
718
- isInheritedFromDelegate(field) {
719
- return field.$inheritedFrom && model_utils_exports.isDelegateModel(field.$inheritedFrom);
668
+ isInheritedFromDelegate(field, contextModel) {
669
+ return field.$container !== contextModel && model_utils_exports.isDelegateModel(field.$container);
720
670
  }
721
671
  makeFieldAttribute(attr) {
722
672
  const attrName = attr.decl.ref.name;
@@ -729,9 +679,9 @@ var PrismaSchemaGenerator = class {
729
679
  if (isLiteralExpr2(node)) {
730
680
  const argType = match(node.$type).with(StringLiteral, () => "String").with(NumberLiteral, () => "Number").with(BooleanLiteral, () => "Boolean").exhaustive();
731
681
  return new AttributeArgValue(argType, node.value);
732
- } else if (isArrayExpr2(node)) {
682
+ } else if (isArrayExpr(node)) {
733
683
  return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
734
- } else if (isReferenceExpr2(node)) {
684
+ } else if (isReferenceExpr(node)) {
735
685
  return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
736
686
  } else if (isInvocationExpr(node)) {
737
687
  return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
@@ -773,12 +723,66 @@ var PrismaSchemaGenerator = class {
773
723
  ];
774
724
  _enum.addField(field.name, attributes, docs);
775
725
  }
726
+ generateDelegateRelationForBase(model, decl) {
727
+ if (!isDelegateModel2(decl)) {
728
+ return;
729
+ }
730
+ const concreteModels = this.getConcreteModels(decl);
731
+ concreteModels.forEach((concrete) => {
732
+ const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(concrete.name)}`);
733
+ model.addField(auxName, new ModelFieldType(concrete.name, false, true));
734
+ });
735
+ }
736
+ generateDelegateRelationForConcrete(model, concreteDecl) {
737
+ const base = concreteDecl.baseModel?.ref;
738
+ if (!base) {
739
+ return;
740
+ }
741
+ const idFields = getIdFields(base);
742
+ const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${lowerCaseFirst(base.name)}`);
743
+ model.addField(relationField, base.name, [
744
+ new FieldAttribute("@relation", [
745
+ new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
746
+ new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
747
+ new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
748
+ new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
749
+ ])
750
+ ]);
751
+ }
752
+ getConcreteModels(dataModel) {
753
+ if (!isDelegateModel2(dataModel)) {
754
+ return [];
755
+ }
756
+ return dataModel.$container.declarations.filter((d) => isDataModel2(d) && d !== dataModel && d.baseModel?.ref === dataModel);
757
+ }
758
+ truncate(name) {
759
+ if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
760
+ return name;
761
+ }
762
+ const existing = this.shortNameMap.get(name);
763
+ if (existing) {
764
+ return existing;
765
+ }
766
+ const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
767
+ let index = 0;
768
+ let shortName = `${baseName}_${index}`;
769
+ while (true) {
770
+ const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
771
+ if (!conflict) {
772
+ this.shortNameMap.set(name, shortName);
773
+ break;
774
+ }
775
+ index++;
776
+ shortName = `${baseName}_${index}`;
777
+ }
778
+ return shortName;
779
+ }
776
780
  };
777
781
 
778
782
  // src/ts-schema-generator.ts
779
783
  import { invariant } from "@zenstackhq/common-helpers";
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";
784
+ 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 isTypeDef3, isUnaryExpr } from "@zenstackhq/language/ast";
785
+ import { getAllAttributes as getAllAttributes2, getAllFields as getAllFields3, isDataFieldReference } from "@zenstackhq/language/utils";
782
786
  import fs from "fs";
783
787
  import path from "path";
784
788
  import { match as match2 } from "ts-pattern";
@@ -787,41 +791,43 @@ var TsSchemaGenerator = class {
787
791
  static {
788
792
  __name(this, "TsSchemaGenerator");
789
793
  }
790
- async generate(schemaFile, pluginModelFiles, outputFile) {
791
- const loaded = await loadDocument(schemaFile, pluginModelFiles);
792
- if (!loaded.success) {
793
- throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
794
- }
795
- const { model, warnings } = loaded;
794
+ usedExpressionUtils = false;
795
+ async generate(model, outputDir) {
796
+ fs.mkdirSync(outputDir, {
797
+ recursive: true
798
+ });
799
+ this.usedExpressionUtils = false;
800
+ this.generateSchema(model, outputDir);
801
+ this.generateModelsAndTypeDefs(model, outputDir);
802
+ this.generateInputTypes(model, outputDir);
803
+ }
804
+ generateSchema(model, outputDir) {
796
805
  const statements = [];
797
806
  this.generateSchemaStatements(model, statements);
798
807
  this.generateBannerComments(statements);
799
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
808
+ const schemaOutputFile = path.join(outputDir, "schema.ts");
809
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
800
810
  const printer = ts.createPrinter();
801
811
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
802
- fs.mkdirSync(path.dirname(outputFile), {
803
- recursive: true
804
- });
805
- fs.writeFileSync(outputFile, result);
806
- return {
807
- model,
808
- warnings
809
- };
812
+ fs.writeFileSync(schemaOutputFile, result);
810
813
  }
811
814
  generateSchemaStatements(model, statements) {
812
- const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
815
+ const hasComputedFields = model.declarations.some((d) => isDataModel3(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
816
+ const schemaObject = this.createSchemaObject(model);
813
817
  const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
814
818
  ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
815
819
  ...hasComputedFields ? [
816
820
  ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("OperandExpression"))
817
821
  ] : [],
818
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
822
+ ...this.usedExpressionUtils ? [
823
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
824
+ ] : []
819
825
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
820
826
  statements.push(runtimeImportDecl);
821
827
  const declaration = ts.factory.createVariableStatement([
822
828
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
823
829
  ], ts.factory.createVariableDeclarationList([
824
- ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createSatisfiesExpression(ts.factory.createAsExpression(this.createSchemaObject(model), ts.factory.createTypeReferenceNode("const")), ts.factory.createTypeReferenceNode("SchemaDef")))
830
+ ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createSatisfiesExpression(ts.factory.createAsExpression(schemaObject, ts.factory.createTypeReferenceNode("const")), ts.factory.createTypeReferenceNode("SchemaDef")))
825
831
  ], ts.NodeFlags.Const));
826
832
  statements.push(declaration);
827
833
  const typeDeclaration = ts.factory.createTypeAliasDeclaration([
@@ -829,12 +835,20 @@ var TsSchemaGenerator = class {
829
835
  ], "SchemaType", void 0, ts.factory.createTypeReferenceNode("typeof schema"));
830
836
  statements.push(typeDeclaration);
831
837
  }
838
+ createExpressionUtilsCall(method, args) {
839
+ this.usedExpressionUtils = true;
840
+ return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("ExpressionUtils"), method), void 0, args || []);
841
+ }
832
842
  createSchemaObject(model) {
833
843
  const properties = [
834
844
  // provider
835
845
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
836
846
  // models
837
- ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
847
+ ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
848
+ // typeDefs
849
+ ...model.declarations.some(isTypeDef3) ? [
850
+ ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
851
+ ] : []
838
852
  ];
839
853
  const enums = model.declarations.filter(isEnum);
840
854
  if (enums.length > 0) {
@@ -858,20 +872,48 @@ var TsSchemaGenerator = class {
858
872
  ], true);
859
873
  }
860
874
  createModelsObject(model) {
861
- return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel2(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
875
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel3(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
876
+ }
877
+ createTypeDefsObject(model) {
878
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isTypeDef3(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
862
879
  }
863
880
  createDataModelObject(dm) {
881
+ const allFields = getAllFields3(dm);
882
+ const allAttributes = getAllAttributes2(dm).filter((attr) => {
883
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
884
+ return false;
885
+ }
886
+ return true;
887
+ });
888
+ const subModels = this.getSubModels(dm);
864
889
  const fields = [
890
+ // name
891
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
892
+ // baseModel
893
+ ...dm.baseModel ? [
894
+ ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
895
+ ] : [],
865
896
  // fields
866
- 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)),
897
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
867
898
  // attributes
868
- ...dm.attributes.length > 0 ? [
869
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
899
+ ...allAttributes.length > 0 ? [
900
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
870
901
  ] : [],
871
902
  // idFields
872
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
903
+ ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
873
904
  // uniqueFields
874
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
905
+ ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
906
+ // isDelegate
907
+ ...isDelegateModel(dm) ? [
908
+ ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
909
+ ] : [],
910
+ // subModels
911
+ ...subModels.length > 0 ? [
912
+ ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
913
+ ] : [],
914
+ ...dm.isView ? [
915
+ ts.factory.createPropertyAssignment("isView", ts.factory.createTrue())
916
+ ] : []
875
917
  ];
876
918
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
877
919
  if (computedFields.length > 0) {
@@ -879,8 +921,31 @@ var TsSchemaGenerator = class {
879
921
  }
880
922
  return ts.factory.createObjectLiteralExpression(fields, true);
881
923
  }
924
+ getSubModels(dm) {
925
+ return dm.$container.declarations.filter(isDataModel3).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
926
+ }
927
+ createTypeDefObject(td) {
928
+ const allFields = getAllFields3(td);
929
+ const allAttributes = getAllAttributes2(td);
930
+ const fields = [
931
+ // name
932
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
933
+ // fields
934
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
935
+ // attributes
936
+ ...allAttributes.length > 0 ? [
937
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
938
+ ] : []
939
+ ];
940
+ return ts.factory.createObjectLiteralExpression(fields, true);
941
+ }
882
942
  createComputedFieldsObject(fields) {
883
- return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
943
+ return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
944
+ // parameter: `context: { modelAlias: string }`
945
+ ts.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, ts.factory.createTypeLiteralNode([
946
+ ts.factory.createPropertySignature(void 0, "modelAlias", void 0, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
947
+ ]), void 0)
948
+ ], ts.factory.createTypeReferenceNode("OperandExpression", [
884
949
  ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
885
950
  ]), ts.factory.createBlock([
886
951
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
@@ -898,11 +963,14 @@ var TsSchemaGenerator = class {
898
963
  }
899
964
  return result;
900
965
  }
901
- createDataModelFieldObject(field) {
966
+ createDataFieldObject(field, contextModel) {
902
967
  const objectFields = [
968
+ // name
969
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
970
+ // type
903
971
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
904
972
  ];
905
- if (isIdField(field)) {
973
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
906
974
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
907
975
  }
908
976
  if (isUniqueField(field)) {
@@ -917,6 +985,13 @@ var TsSchemaGenerator = class {
917
985
  if (hasAttribute(field, "@updatedAt")) {
918
986
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
919
987
  }
988
+ if (contextModel && // id fields are duplicated in inherited models
989
+ !isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
990
+ objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
991
+ }
992
+ if (this.isDiscriminatorField(field)) {
993
+ objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
994
+ }
920
995
  if (field.attributes.length > 0) {
921
996
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
922
997
  }
@@ -924,15 +999,17 @@ var TsSchemaGenerator = class {
924
999
  if (defaultValue !== void 0) {
925
1000
  if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
926
1001
  if ("call" in defaultValue) {
927
- objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
1002
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createExpressionUtilsCall("call", [
928
1003
  ts.factory.createStringLiteral(defaultValue.call),
929
1004
  ...defaultValue.args.length > 0 ? [
930
- ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createLiteralNode(arg)))
1005
+ ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createExpressionUtilsCall("literal", [
1006
+ this.createLiteralNode(arg)
1007
+ ])))
931
1008
  ] : []
932
1009
  ])));
933
1010
  } else if ("authMember" in defaultValue) {
934
- objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, [
935
- ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
1011
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createExpressionUtilsCall("member", [
1012
+ this.createExpressionUtilsCall("call", [
936
1013
  ts.factory.createStringLiteral("auth")
937
1014
  ]),
938
1015
  ts.factory.createArrayLiteralExpression(defaultValue.authMember.map((m) => ts.factory.createStringLiteral(m)))
@@ -951,7 +1028,7 @@ var TsSchemaGenerator = class {
951
1028
  if (hasAttribute(field, "@computed")) {
952
1029
  objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
953
1030
  }
954
- if (isDataModel2(field.type.reference?.ref)) {
1031
+ if (isDataModel3(field.type.reference?.ref)) {
955
1032
  objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
956
1033
  }
957
1034
  const fkFor = this.getForeignKeyFor(field);
@@ -960,31 +1037,19 @@ var TsSchemaGenerator = class {
960
1037
  }
961
1038
  return ts.factory.createObjectLiteralExpression(objectFields, true);
962
1039
  }
1040
+ isDiscriminatorField(field) {
1041
+ const origin = field.$container;
1042
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && isDataFieldReference(arg.value) && arg.value.target.ref === field);
1043
+ }
963
1044
  getDataSourceProvider(model) {
964
1045
  const dataSource = model.declarations.find(isDataSource);
965
1046
  invariant(dataSource, "No data source found in the model");
966
1047
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
967
1048
  invariant(isLiteralExpr3(providerExpr), "Provider must be a literal");
968
1049
  const type = providerExpr.value;
969
- const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
970
- invariant(isLiteralExpr3(urlExpr) || isInvocationExpr2(urlExpr), "URL must be a literal or env function");
971
- if (isLiteralExpr3(urlExpr)) {
972
- return {
973
- type,
974
- url: urlExpr.value,
975
- env: void 0
976
- };
977
- } else if (isInvocationExpr2(urlExpr)) {
978
- invariant(urlExpr.function.$refText === "env", 'only "env" function is supported');
979
- invariant(urlExpr.args.length === 1, "env function must have one argument");
980
- return {
981
- type,
982
- env: urlExpr.args[0].value.value,
983
- url: void 0
984
- };
985
- } else {
986
- throw new Error("Unsupported URL type");
987
- }
1050
+ return {
1051
+ type
1052
+ };
988
1053
  }
989
1054
  getFieldMappedDefault(field) {
990
1055
  const defaultAttr = getAttribute(field, "@default");
@@ -1004,9 +1069,9 @@ var TsSchemaGenerator = class {
1004
1069
  "Decimal",
1005
1070
  "BigInt"
1006
1071
  ].includes(fieldType.type) ? Number(lit) : lit;
1007
- } else if (isArrayExpr3(expr)) {
1072
+ } else if (isArrayExpr2(expr)) {
1008
1073
  return expr.items.map((item) => this.getMappedValue(item, fieldType));
1009
- } else if (isReferenceExpr3(expr) && isEnumField(expr.target.ref)) {
1074
+ } else if (isReferenceExpr2(expr) && isEnumField(expr.target.ref)) {
1010
1075
  return expr.target.ref.name;
1011
1076
  } else if (isInvocationExpr2(expr)) {
1012
1077
  return {
@@ -1072,7 +1137,7 @@ var TsSchemaGenerator = class {
1072
1137
  return ts.factory.createObjectLiteralExpression(relationFields);
1073
1138
  }
1074
1139
  getReferenceNames(expr) {
1075
- return isArrayExpr3(expr) && expr.items.map((item) => item.target.$refText);
1140
+ return isArrayExpr2(expr) && expr.items.map((item) => item.target.$refText);
1076
1141
  }
1077
1142
  getForeignKeyFor(field) {
1078
1143
  const result = [];
@@ -1080,7 +1145,7 @@ var TsSchemaGenerator = class {
1080
1145
  const relation = getAttribute(f, "@relation");
1081
1146
  if (relation) {
1082
1147
  for (const arg of relation.args) {
1083
- if (arg.name === "fields" && isArrayExpr3(arg.value) && arg.value.items.some((el) => isReferenceExpr3(el) && el.target.ref === field)) {
1148
+ if (arg.name === "fields" && isArrayExpr2(arg.value) && arg.value.items.some((el) => isReferenceExpr2(el) && el.target.ref === field)) {
1084
1149
  result.push(f.name);
1085
1150
  }
1086
1151
  }
@@ -1089,7 +1154,7 @@ var TsSchemaGenerator = class {
1089
1154
  return result;
1090
1155
  }
1091
1156
  getOppositeRelationField(field) {
1092
- if (!field.type.reference?.ref || !isDataModel2(field.type.reference?.ref)) {
1157
+ if (!field.type.reference?.ref || !isDataModel3(field.type.reference?.ref)) {
1093
1158
  return void 0;
1094
1159
  }
1095
1160
  const sourceModel = field.$container;
@@ -1123,38 +1188,37 @@ var TsSchemaGenerator = class {
1123
1188
  }
1124
1189
  return void 0;
1125
1190
  }
1126
- getIdFields(dm) {
1127
- return dm.fields.filter(isIdField).map((f) => f.name);
1128
- }
1129
1191
  createUniqueFieldsObject(dm) {
1130
1192
  const properties = [];
1131
- for (const field of dm.fields) {
1193
+ const allFields = getAllFields3(dm);
1194
+ for (const field of allFields) {
1132
1195
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1133
1196
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1134
1197
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1135
1198
  ])));
1136
1199
  }
1137
1200
  }
1201
+ const allAttributes = getAllAttributes2(dm);
1138
1202
  const seenKeys = /* @__PURE__ */ new Set();
1139
- for (const attr of dm.attributes) {
1203
+ for (const attr of allAttributes) {
1140
1204
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1141
1205
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1142
1206
  if (!fieldNames) {
1143
1207
  continue;
1144
1208
  }
1145
1209
  if (fieldNames.length === 1) {
1146
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1210
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1147
1211
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1148
1212
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1149
1213
  ])));
1150
1214
  } else {
1151
- const key = fieldNames.join("_");
1215
+ const key = this.getCompoundUniqueKey(attr, fieldNames);
1152
1216
  if (seenKeys.has(key)) {
1153
1217
  continue;
1154
1218
  }
1155
1219
  seenKeys.add(key);
1156
- properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1157
- const fieldDef = dm.fields.find((f) => f.name === field);
1220
+ properties.push(ts.factory.createPropertyAssignment(key, ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1221
+ const fieldDef = allFields.find((f) => f.name === field);
1158
1222
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1159
1223
  ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1160
1224
  ]));
@@ -1164,6 +1228,14 @@ var TsSchemaGenerator = class {
1164
1228
  }
1165
1229
  return ts.factory.createObjectLiteralExpression(properties, true);
1166
1230
  }
1231
+ getCompoundUniqueKey(attr, fieldNames) {
1232
+ const nameArg = attr.args.find((arg) => arg.$resolvedParam.name === "name");
1233
+ if (nameArg && isLiteralExpr3(nameArg.value)) {
1234
+ return nameArg.value.value;
1235
+ } else {
1236
+ return fieldNames.join("_");
1237
+ }
1238
+ }
1167
1239
  generateFieldTypeLiteral(field) {
1168
1240
  invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1169
1241
  return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
@@ -1246,12 +1318,12 @@ var TsSchemaGenerator = class {
1246
1318
  ]);
1247
1319
  }
1248
1320
  createExpression(value) {
1249
- 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(() => {
1321
+ 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(() => {
1250
1322
  throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1251
1323
  });
1252
1324
  }
1253
1325
  createThisExpression() {
1254
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._this"), void 0, []);
1326
+ return this.createExpressionUtilsCall("_this");
1255
1327
  }
1256
1328
  createMemberExpression(expr) {
1257
1329
  const members = [];
@@ -1265,32 +1337,32 @@ var TsSchemaGenerator = class {
1265
1337
  this.createExpression(receiver),
1266
1338
  ts.factory.createArrayLiteralExpression(members.map((m) => ts.factory.createStringLiteral(m)))
1267
1339
  ];
1268
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.member"), void 0, args);
1340
+ return this.createExpressionUtilsCall("member", args);
1269
1341
  }
1270
1342
  createNullExpression() {
1271
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils._null"), void 0, []);
1343
+ return this.createExpressionUtilsCall("_null");
1272
1344
  }
1273
1345
  createBinaryExpression(expr) {
1274
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.binary"), void 0, [
1346
+ return this.createExpressionUtilsCall("binary", [
1275
1347
  this.createExpression(expr.left),
1276
1348
  this.createLiteralNode(expr.operator),
1277
1349
  this.createExpression(expr.right)
1278
1350
  ]);
1279
1351
  }
1280
1352
  createUnaryExpression(expr) {
1281
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.unary"), void 0, [
1353
+ return this.createExpressionUtilsCall("unary", [
1282
1354
  this.createLiteralNode(expr.operator),
1283
1355
  this.createExpression(expr.operand)
1284
1356
  ]);
1285
1357
  }
1286
1358
  createArrayExpression(expr) {
1287
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.array"), void 0, [
1359
+ return this.createExpressionUtilsCall("array", [
1288
1360
  ts.factory.createArrayLiteralExpression(expr.items.map((item) => this.createExpression(item)))
1289
1361
  ]);
1290
1362
  }
1291
1363
  createRefExpression(expr) {
1292
- if (isDataModelField(expr.target.ref)) {
1293
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1364
+ if (isDataField(expr.target.ref)) {
1365
+ return this.createExpressionUtilsCall("field", [
1294
1366
  this.createLiteralNode(expr.target.$refText)
1295
1367
  ]);
1296
1368
  } else if (isEnumField(expr.target.ref)) {
@@ -1300,7 +1372,7 @@ var TsSchemaGenerator = class {
1300
1372
  }
1301
1373
  }
1302
1374
  createCallExpression(expr) {
1303
- return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
1375
+ return this.createExpressionUtilsCall("call", [
1304
1376
  ts.factory.createStringLiteral(expr.function.$refText),
1305
1377
  ...expr.args.length > 0 ? [
1306
1378
  ts.factory.createArrayLiteralExpression(expr.args.map((arg) => this.createExpression(arg.value)))
@@ -1308,20 +1380,164 @@ var TsSchemaGenerator = class {
1308
1380
  ]);
1309
1381
  }
1310
1382
  createLiteralExpression(type, value) {
1311
- return match2(type).with("BooleanLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
1383
+ return match2(type).with("BooleanLiteral", () => this.createExpressionUtilsCall("literal", [
1312
1384
  this.createLiteralNode(value)
1313
- ])).with("NumberLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
1385
+ ])).with("NumberLiteral", () => this.createExpressionUtilsCall("literal", [
1314
1386
  ts.factory.createIdentifier(value)
1315
- ])).with("StringLiteral", () => ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.literal"), void 0, [
1387
+ ])).with("StringLiteral", () => this.createExpressionUtilsCall("literal", [
1316
1388
  this.createLiteralNode(value)
1317
1389
  ])).otherwise(() => {
1318
1390
  throw new Error(`Unsupported literal type: ${type}`);
1319
1391
  });
1320
1392
  }
1393
+ generateModelsAndTypeDefs(model, outputDir) {
1394
+ const statements = [];
1395
+ statements.push(this.generateSchemaImport(model, true, true));
1396
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1397
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1398
+ ...model.declarations.some(isTypeDef3) ? [
1399
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1400
+ ] : []
1401
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1402
+ const dataModels = model.declarations.filter(isDataModel3);
1403
+ for (const dm of dataModels) {
1404
+ let modelType = ts.factory.createTypeAliasDeclaration([
1405
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1406
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1407
+ ts.factory.createTypeReferenceNode("$Schema"),
1408
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1409
+ ]));
1410
+ if (dm.comments.length > 0) {
1411
+ modelType = this.generateDocs(modelType, dm);
1412
+ }
1413
+ statements.push(modelType);
1414
+ }
1415
+ const typeDefs = model.declarations.filter(isTypeDef3);
1416
+ for (const td of typeDefs) {
1417
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1418
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1419
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1420
+ ts.factory.createTypeReferenceNode("$Schema"),
1421
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1422
+ ]));
1423
+ if (td.comments.length > 0) {
1424
+ typeDef = this.generateDocs(typeDef, td);
1425
+ }
1426
+ statements.push(typeDef);
1427
+ }
1428
+ const enums = model.declarations.filter(isEnum);
1429
+ for (const e of enums) {
1430
+ let enumDecl = ts.factory.createVariableStatement([
1431
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1432
+ ], ts.factory.createVariableDeclarationList([
1433
+ 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)))
1434
+ ], ts.NodeFlags.Const));
1435
+ if (e.comments.length > 0) {
1436
+ enumDecl = this.generateDocs(enumDecl, e);
1437
+ }
1438
+ statements.push(enumDecl);
1439
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1440
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1441
+ ], 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)))));
1442
+ if (e.comments.length > 0) {
1443
+ typeAlias = this.generateDocs(typeAlias, e);
1444
+ }
1445
+ statements.push(typeAlias);
1446
+ }
1447
+ this.generateBannerComments(statements);
1448
+ const outputFile = path.join(outputDir, "models.ts");
1449
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1450
+ const printer = ts.createPrinter();
1451
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1452
+ fs.writeFileSync(outputFile, result);
1453
+ }
1454
+ generateSchemaImport(model, schemaObject, schemaType) {
1455
+ const importSpecifiers = [];
1456
+ if (schemaObject) {
1457
+ if (model.declarations.some(isEnum)) {
1458
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1459
+ }
1460
+ }
1461
+ if (schemaType) {
1462
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1463
+ }
1464
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1465
+ }
1466
+ generateDocs(tsDecl, decl) {
1467
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1468
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1469
+ `, true);
1470
+ }
1471
+ generateInputTypes(model, outputDir) {
1472
+ const dataModels = model.declarations.filter(isDataModel3);
1473
+ const statements = [];
1474
+ statements.push(this.generateSchemaImport(model, false, true));
1475
+ const inputTypes = [
1476
+ "FindManyArgs",
1477
+ "FindUniqueArgs",
1478
+ "FindFirstArgs",
1479
+ "CreateArgs",
1480
+ "CreateManyArgs",
1481
+ "CreateManyAndReturnArgs",
1482
+ "UpdateArgs",
1483
+ "UpdateManyArgs",
1484
+ "UpdateManyAndReturnArgs",
1485
+ "UpsertArgs",
1486
+ "DeleteArgs",
1487
+ "DeleteManyArgs",
1488
+ "CountArgs",
1489
+ "AggregateArgs",
1490
+ "GroupByArgs",
1491
+ "WhereInput",
1492
+ "SelectInput",
1493
+ "IncludeInput",
1494
+ "OmitInput"
1495
+ ];
1496
+ const inputTypeNameFixes = {
1497
+ SelectInput: "Select",
1498
+ IncludeInput: "Include",
1499
+ OmitInput: "Omit"
1500
+ };
1501
+ 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")));
1502
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1503
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1504
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1505
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1506
+ for (const dm of dataModels) {
1507
+ for (const inputType of inputTypes) {
1508
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1509
+ statements.push(ts.factory.createTypeAliasDeclaration([
1510
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1511
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1512
+ ts.factory.createTypeReferenceNode("$Schema"),
1513
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1514
+ ])));
1515
+ }
1516
+ statements.push(ts.factory.createTypeAliasDeclaration([
1517
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1518
+ ], `${dm.name}GetPayload`, [
1519
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1520
+ ts.factory.createTypeReferenceNode("$Schema"),
1521
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1522
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1523
+ ]))
1524
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1525
+ ts.factory.createTypeReferenceNode("$Schema"),
1526
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1527
+ ts.factory.createTypeReferenceNode("Args")
1528
+ ])));
1529
+ }
1530
+ this.generateBannerComments(statements);
1531
+ const outputFile = path.join(outputDir, "input.ts");
1532
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1533
+ const printer = ts.createPrinter();
1534
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1535
+ fs.writeFileSync(outputFile, result);
1536
+ }
1321
1537
  };
1322
1538
 
1323
1539
  // src/zmodel-code-generator.ts
1324
- 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";
1540
+ 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";
1325
1541
  function _ts_decorate(decorators, target, key, desc) {
1326
1542
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1327
1543
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1409,21 +1625,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1409
1625
  return `${ast.name} = ${this.generate(ast.value)}`;
1410
1626
  }
1411
1627
  _generateDataModel(ast) {
1412
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1628
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1413
1629
  ${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") : ""}
1414
1630
  }`;
1415
1631
  }
1416
- _generateDataModelField(ast) {
1632
+ _generateDataField(ast) {
1417
1633
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1418
1634
  }
1419
1635
  fieldType(type) {
1420
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1636
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1421
1637
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1422
1638
  }
1423
1639
  _generateDataModelAttribute(ast) {
1424
1640
  return this.attribute(ast);
1425
1641
  }
1426
- _generateDataModelFieldAttribute(ast) {
1642
+ _generateDataFieldAttribute(ast) {
1427
1643
  return this.attribute(ast);
1428
1644
  }
1429
1645
  attribute(ast) {
@@ -1507,9 +1723,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1507
1723
  ${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") : ""}
1508
1724
  }`;
1509
1725
  }
1510
- _generateTypeDefField(ast) {
1511
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1512
- }
1513
1726
  argument(ast) {
1514
1727
  return this.generate(ast.value);
1515
1728
  }
@@ -1635,13 +1848,13 @@ _ts_decorate([
1635
1848
  _ts_metadata("design:returntype", void 0)
1636
1849
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1637
1850
  _ts_decorate([
1638
- gen(DataModelField),
1851
+ gen(DataField),
1639
1852
  _ts_metadata("design:type", Function),
1640
1853
  _ts_metadata("design:paramtypes", [
1641
- typeof DataModelField === "undefined" ? Object : DataModelField
1854
+ typeof DataField === "undefined" ? Object : DataField
1642
1855
  ]),
1643
1856
  _ts_metadata("design:returntype", void 0)
1644
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1857
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1645
1858
  _ts_decorate([
1646
1859
  gen(DataModelAttribute),
1647
1860
  _ts_metadata("design:type", Function),
@@ -1651,13 +1864,13 @@ _ts_decorate([
1651
1864
  _ts_metadata("design:returntype", void 0)
1652
1865
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1653
1866
  _ts_decorate([
1654
- gen(DataModelFieldAttribute),
1867
+ gen(DataFieldAttribute),
1655
1868
  _ts_metadata("design:type", Function),
1656
1869
  _ts_metadata("design:paramtypes", [
1657
- typeof DataModelFieldAttribute === "undefined" ? Object : DataModelFieldAttribute
1870
+ typeof DataFieldAttribute === "undefined" ? Object : DataFieldAttribute
1658
1871
  ]),
1659
1872
  _ts_metadata("design:returntype", void 0)
1660
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1873
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1661
1874
  _ts_decorate([
1662
1875
  gen(AttributeArg2),
1663
1876
  _ts_metadata("design:type", Function),
@@ -1822,14 +2035,6 @@ _ts_decorate([
1822
2035
  ]),
1823
2036
  _ts_metadata("design:returntype", void 0)
1824
2037
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1825
- _ts_decorate([
1826
- gen(TypeDefField),
1827
- _ts_metadata("design:type", Function),
1828
- _ts_metadata("design:paramtypes", [
1829
- typeof TypeDefField === "undefined" ? Object : TypeDefField
1830
- ]),
1831
- _ts_metadata("design:returntype", void 0)
1832
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1833
2038
  export {
1834
2039
  model_utils_exports as ModelUtils,
1835
2040
  PrismaSchemaGenerator,