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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,100 @@ 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 { invariant } from "@zenstackhq/common-helpers";
780
781
  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";
782
+ 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";
783
+ import { getAllAttributes as getAllAttributes2, getAllFields as getAllFields3, isDataFieldReference } from "@zenstackhq/language/utils";
784
+ import fs from "fs";
785
+ import path from "path";
785
786
  import { match as match2 } from "ts-pattern";
786
787
  import * as ts from "typescript";
787
788
  var TsSchemaGenerator = class {
788
789
  static {
789
790
  __name(this, "TsSchemaGenerator");
790
791
  }
791
- async generate(schemaFile, pluginModelFiles, outputFile) {
792
+ async generate(schemaFile, pluginModelFiles, outputDir) {
792
793
  const loaded = await loadDocument(schemaFile, pluginModelFiles);
793
794
  if (!loaded.success) {
794
795
  throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
795
796
  }
796
- const { model, warnings } = loaded;
797
+ const { model } = loaded;
798
+ fs.mkdirSync(outputDir, {
799
+ recursive: true
800
+ });
801
+ this.generateSchema(model, outputDir);
802
+ this.generateModelsAndTypeDefs(model, outputDir);
803
+ this.generateInputTypes(model, outputDir);
804
+ }
805
+ generateSchema(model, outputDir) {
797
806
  const statements = [];
798
807
  this.generateSchemaStatements(model, statements);
799
808
  this.generateBannerComments(statements);
800
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
809
+ const schemaOutputFile = path.join(outputDir, "schema.ts");
810
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
801
811
  const printer = ts.createPrinter();
802
812
  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
- };
813
+ fs.writeFileSync(schemaOutputFile, result);
811
814
  }
812
815
  generateSchemaStatements(model, statements) {
813
- const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
816
+ const hasComputedFields = model.declarations.some((d) => isDataModel3(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
814
817
  const runtimeImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
815
818
  ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
816
819
  ...hasComputedFields ? [
@@ -819,27 +822,6 @@ var TsSchemaGenerator = class {
819
822
  ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
820
823
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
821
824
  statements.push(runtimeImportDecl);
822
- const { type: providerType } = this.getDataSourceProvider(model);
823
- switch (providerType) {
824
- case "sqlite": {
825
- const pathImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("path"), void 0), ts.factory.createStringLiteral("node:path"));
826
- statements.push(pathImportDecl);
827
- const urlImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("url"), void 0), ts.factory.createStringLiteral("node:url"));
828
- statements.push(urlImportDecl);
829
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
830
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
831
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/sqlite-utils"));
832
- statements.push(dialectConfigImportDecl);
833
- break;
834
- }
835
- case "postgresql": {
836
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
837
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
838
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/pg-utils"));
839
- statements.push(dialectConfigImportDecl);
840
- break;
841
- }
842
- }
843
825
  const declaration = ts.factory.createVariableStatement([
844
826
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
845
827
  ], ts.factory.createVariableDeclarationList([
@@ -856,7 +838,11 @@ var TsSchemaGenerator = class {
856
838
  // provider
857
839
  ts.factory.createPropertyAssignment("provider", this.createProviderObject(model)),
858
840
  // models
859
- ts.factory.createPropertyAssignment("models", this.createModelsObject(model))
841
+ ts.factory.createPropertyAssignment("models", this.createModelsObject(model)),
842
+ // typeDefs
843
+ ...model.declarations.some(isTypeDef2) ? [
844
+ ts.factory.createPropertyAssignment("typeDefs", this.createTypeDefsObject(model))
845
+ ] : []
860
846
  ];
861
847
  const enums = model.declarations.filter(isEnum);
862
848
  if (enums.length > 0) {
@@ -876,25 +862,49 @@ var TsSchemaGenerator = class {
876
862
  createProviderObject(model) {
877
863
  const dsProvider = this.getDataSourceProvider(model);
878
864
  return ts.factory.createObjectLiteralExpression([
879
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type)),
880
- ts.factory.createPropertyAssignment("dialectConfigProvider", this.createDialectConfigProvider(dsProvider))
865
+ ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type))
881
866
  ], true);
882
867
  }
883
868
  createModelsObject(model) {
884
- return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel2(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
869
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isDataModel3(d) && !hasAttribute(d, "@@ignore")).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm))), true);
870
+ }
871
+ createTypeDefsObject(model) {
872
+ return ts.factory.createObjectLiteralExpression(model.declarations.filter((d) => isTypeDef2(d)).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td))), true);
885
873
  }
886
874
  createDataModelObject(dm) {
875
+ const allFields = getAllFields3(dm);
876
+ const allAttributes = getAllAttributes2(dm).filter((attr) => {
877
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
878
+ return false;
879
+ }
880
+ return true;
881
+ });
882
+ const subModels = this.getSubModels(dm);
887
883
  const fields = [
884
+ // name
885
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
886
+ // baseModel
887
+ ...dm.baseModel ? [
888
+ ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
889
+ ] : [],
888
890
  // fields
889
- 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)),
891
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm))), true)),
890
892
  // attributes
891
- ...dm.attributes.length > 0 ? [
892
- ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(dm.attributes.map((attr) => this.createAttributeObject(attr)), true))
893
+ ...allAttributes.length > 0 ? [
894
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
893
895
  ] : [],
894
896
  // idFields
895
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(this.getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
897
+ ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
896
898
  // uniqueFields
897
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm))
899
+ ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
900
+ // isDelegate
901
+ ...isDelegateModel(dm) ? [
902
+ ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
903
+ ] : [],
904
+ // subModels
905
+ ...subModels.length > 0 ? [
906
+ ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
907
+ ] : []
898
908
  ];
899
909
  const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
900
910
  if (computedFields.length > 0) {
@@ -902,23 +912,51 @@ var TsSchemaGenerator = class {
902
912
  }
903
913
  return ts.factory.createObjectLiteralExpression(fields, true);
904
914
  }
915
+ getSubModels(dm) {
916
+ return dm.$container.declarations.filter(isDataModel3).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
917
+ }
918
+ createTypeDefObject(td) {
919
+ const allFields = getAllFields3(td);
920
+ const allAttributes = getAllAttributes2(td);
921
+ const fields = [
922
+ // name
923
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
924
+ // fields
925
+ ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0))), true)),
926
+ // attributes
927
+ ...allAttributes.length > 0 ? [
928
+ ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true))
929
+ ] : []
930
+ ];
931
+ return ts.factory.createObjectLiteralExpression(fields, true);
932
+ }
905
933
  createComputedFieldsObject(fields) {
906
934
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
907
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
935
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
908
936
  ]), ts.factory.createBlock([
909
937
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
910
938
  ts.factory.createStringLiteral("This is a stub for computed field")
911
939
  ]))
912
940
  ], true))), true);
913
941
  }
914
- mapTypeToTSSyntaxKeyword(type) {
915
- 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);
942
+ mapFieldTypeToTSType(type) {
943
+ 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");
944
+ if (type.array) {
945
+ result = `${result}[]`;
946
+ }
947
+ if (type.optional) {
948
+ result = `${result} | null`;
949
+ }
950
+ return result;
916
951
  }
917
- createDataModelFieldObject(field) {
952
+ createDataFieldObject(field, contextModel) {
918
953
  const objectFields = [
919
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
954
+ // name
955
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
956
+ // type
957
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
920
958
  ];
921
- if (isIdField(field)) {
959
+ if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
922
960
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
923
961
  }
924
962
  if (isUniqueField(field)) {
@@ -933,12 +971,19 @@ var TsSchemaGenerator = class {
933
971
  if (hasAttribute(field, "@updatedAt")) {
934
972
  objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ts.factory.createTrue()));
935
973
  }
974
+ if (contextModel && // id fields are duplicated in inherited models
975
+ !isIdField(field, contextModel) && field.$container !== contextModel && isDelegateModel(field.$container)) {
976
+ objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(field.$container.name)));
977
+ }
978
+ if (this.isDiscriminatorField(field)) {
979
+ objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
980
+ }
936
981
  if (field.attributes.length > 0) {
937
982
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
938
983
  }
939
- const defaultValue = this.getMappedDefault(field);
984
+ const defaultValue = this.getFieldMappedDefault(field);
940
985
  if (defaultValue !== void 0) {
941
- if (typeof defaultValue === "object") {
986
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
942
987
  if ("call" in defaultValue) {
943
988
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
944
989
  ts.factory.createStringLiteral(defaultValue.call),
@@ -957,13 +1002,17 @@ var TsSchemaGenerator = class {
957
1002
  throw new Error(`Unsupported default value type for field ${field.name}`);
958
1003
  }
959
1004
  } else {
960
- 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()));
1005
+ if (Array.isArray(defaultValue)) {
1006
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
1007
+ } else {
1008
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
1009
+ }
961
1010
  }
962
1011
  }
963
1012
  if (hasAttribute(field, "@computed")) {
964
1013
  objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
965
1014
  }
966
- if (isDataModel2(field.type.reference?.ref)) {
1015
+ if (isDataModel3(field.type.reference?.ref)) {
967
1016
  objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
968
1017
  }
969
1018
  const fkFor = this.getForeignKeyFor(field);
@@ -972,60 +1021,53 @@ var TsSchemaGenerator = class {
972
1021
  }
973
1022
  return ts.factory.createObjectLiteralExpression(objectFields, true);
974
1023
  }
1024
+ isDiscriminatorField(field) {
1025
+ const origin = field.$container;
1026
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && isDataFieldReference(arg.value) && arg.value.target.ref === field);
1027
+ }
975
1028
  getDataSourceProvider(model) {
976
1029
  const dataSource = model.declarations.find(isDataSource);
977
1030
  invariant(dataSource, "No data source found in the model");
978
1031
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
979
1032
  invariant(isLiteralExpr3(providerExpr), "Provider must be a literal");
980
1033
  const type = providerExpr.value;
981
- const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
982
- invariant(isLiteralExpr3(urlExpr) || isInvocationExpr2(urlExpr), "URL must be a literal or env function");
983
- if (isLiteralExpr3(urlExpr)) {
984
- return {
985
- type,
986
- url: urlExpr.value,
987
- env: void 0
988
- };
989
- } else if (isInvocationExpr2(urlExpr)) {
990
- invariant(urlExpr.function.$refText === "env", 'only "env" function is supported');
991
- invariant(urlExpr.args.length === 1, "env function must have one argument");
992
- return {
993
- type,
994
- env: urlExpr.args[0].value.value,
995
- url: void 0
996
- };
997
- } else {
998
- throw new Error("Unsupported URL type");
999
- }
1034
+ return {
1035
+ type
1036
+ };
1000
1037
  }
1001
- getMappedDefault(field) {
1038
+ getFieldMappedDefault(field) {
1002
1039
  const defaultAttr = getAttribute(field, "@default");
1003
1040
  if (!defaultAttr) {
1004
1041
  return void 0;
1005
1042
  }
1006
1043
  const defaultValue = defaultAttr.args[0]?.value;
1007
1044
  invariant(defaultValue, "Expected a default value");
1008
- if (isLiteralExpr3(defaultValue)) {
1009
- const lit = defaultValue.value;
1010
- return field.type.type === "Boolean" ? lit : [
1045
+ return this.getMappedValue(defaultValue, field.type);
1046
+ }
1047
+ getMappedValue(expr, fieldType) {
1048
+ if (isLiteralExpr3(expr)) {
1049
+ const lit = expr.value;
1050
+ return fieldType.type === "Boolean" ? lit : [
1011
1051
  "Int",
1012
1052
  "Float",
1013
1053
  "Decimal",
1014
1054
  "BigInt"
1015
- ].includes(field.type.type) ? Number(lit) : lit;
1016
- } else if (isReferenceExpr3(defaultValue) && isEnumField(defaultValue.target.ref)) {
1017
- return defaultValue.target.ref.name;
1018
- } else if (isInvocationExpr2(defaultValue)) {
1055
+ ].includes(fieldType.type) ? Number(lit) : lit;
1056
+ } else if (isArrayExpr2(expr)) {
1057
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1058
+ } else if (isReferenceExpr2(expr) && isEnumField(expr.target.ref)) {
1059
+ return expr.target.ref.name;
1060
+ } else if (isInvocationExpr2(expr)) {
1019
1061
  return {
1020
- call: defaultValue.function.$refText,
1021
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1062
+ call: expr.function.$refText,
1063
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1022
1064
  };
1023
- } else if (this.isAuthMemberAccess(defaultValue)) {
1065
+ } else if (this.isAuthMemberAccess(expr)) {
1024
1066
  return {
1025
- authMember: this.getMemberAccessChain(defaultValue)
1067
+ authMember: this.getMemberAccessChain(expr)
1026
1068
  };
1027
1069
  } else {
1028
- throw new Error(`Unsupported default value type for field ${field.name}`);
1070
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1029
1071
  }
1030
1072
  }
1031
1073
  getMemberAccessChain(expr) {
@@ -1079,7 +1121,7 @@ var TsSchemaGenerator = class {
1079
1121
  return ts.factory.createObjectLiteralExpression(relationFields);
1080
1122
  }
1081
1123
  getReferenceNames(expr) {
1082
- return isArrayExpr3(expr) && expr.items.map((item) => item.target.$refText);
1124
+ return isArrayExpr2(expr) && expr.items.map((item) => item.target.$refText);
1083
1125
  }
1084
1126
  getForeignKeyFor(field) {
1085
1127
  const result = [];
@@ -1087,7 +1129,7 @@ var TsSchemaGenerator = class {
1087
1129
  const relation = getAttribute(f, "@relation");
1088
1130
  if (relation) {
1089
1131
  for (const arg of relation.args) {
1090
- if (arg.name === "fields" && isArrayExpr3(arg.value) && arg.value.items.some((el) => isReferenceExpr3(el) && el.target.ref === field)) {
1132
+ if (arg.name === "fields" && isArrayExpr2(arg.value) && arg.value.items.some((el) => isReferenceExpr2(el) && el.target.ref === field)) {
1091
1133
  result.push(f.name);
1092
1134
  }
1093
1135
  }
@@ -1096,7 +1138,7 @@ var TsSchemaGenerator = class {
1096
1138
  return result;
1097
1139
  }
1098
1140
  getOppositeRelationField(field) {
1099
- if (!field.type.reference?.ref || !isDataModel2(field.type.reference?.ref)) {
1141
+ if (!field.type.reference?.ref || !isDataModel3(field.type.reference?.ref)) {
1100
1142
  return void 0;
1101
1143
  }
1102
1144
  const sourceModel = field.$container;
@@ -1130,34 +1172,39 @@ var TsSchemaGenerator = class {
1130
1172
  }
1131
1173
  return void 0;
1132
1174
  }
1133
- getIdFields(dm) {
1134
- return dm.fields.filter(isIdField).map((f) => f.name);
1135
- }
1136
1175
  createUniqueFieldsObject(dm) {
1137
1176
  const properties = [];
1138
- for (const field of dm.fields) {
1177
+ const allFields = getAllFields3(dm);
1178
+ for (const field of allFields) {
1139
1179
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1140
1180
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1141
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1181
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1142
1182
  ])));
1143
1183
  }
1144
1184
  }
1145
- for (const attr of dm.attributes) {
1185
+ const allAttributes = getAllAttributes2(dm);
1186
+ const seenKeys = /* @__PURE__ */ new Set();
1187
+ for (const attr of allAttributes) {
1146
1188
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1147
1189
  const fieldNames = this.getReferenceNames(attr.args[0].value);
1148
1190
  if (!fieldNames) {
1149
1191
  continue;
1150
1192
  }
1151
1193
  if (fieldNames.length === 1) {
1152
- const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1194
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1153
1195
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1154
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1196
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1155
1197
  ])));
1156
1198
  } else {
1199
+ const key = fieldNames.join("_");
1200
+ if (seenKeys.has(key)) {
1201
+ continue;
1202
+ }
1203
+ seenKeys.add(key);
1157
1204
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1158
- const fieldDef = dm.fields.find((f) => f.name === field);
1205
+ const fieldDef = allFields.find((f) => f.name === field);
1159
1206
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1160
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1207
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1161
1208
  ]));
1162
1209
  }))));
1163
1210
  }
@@ -1165,6 +1212,10 @@ var TsSchemaGenerator = class {
1165
1212
  }
1166
1213
  return ts.factory.createObjectLiteralExpression(properties, true);
1167
1214
  }
1215
+ generateFieldTypeLiteral(field) {
1216
+ invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1217
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1218
+ }
1168
1219
  createEnumObject(e) {
1169
1220
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1170
1221
  }
@@ -1185,44 +1236,6 @@ var TsSchemaGenerator = class {
1185
1236
  createLiteralNode(arg) {
1186
1237
  return arg === null ? ts.factory.createNull() : typeof arg === "string" ? ts.factory.createStringLiteral(arg) : typeof arg === "number" ? ts.factory.createNumericLiteral(arg) : arg === true ? ts.factory.createTrue() : arg === false ? ts.factory.createFalse() : void 0;
1187
1238
  }
1188
- createDialectConfigProvider(dsProvider) {
1189
- const type = dsProvider.type;
1190
- let urlExpr;
1191
- if (dsProvider.env !== void 0) {
1192
- urlExpr = ts.factory.createIdentifier(`process.env['${dsProvider.env}']`);
1193
- } else {
1194
- urlExpr = ts.factory.createStringLiteral(dsProvider.url);
1195
- if (type === "sqlite") {
1196
- let parsedUrl;
1197
- try {
1198
- parsedUrl = new URL(dsProvider.url);
1199
- } catch {
1200
- }
1201
- if (parsedUrl) {
1202
- if (parsedUrl.protocol !== "file:") {
1203
- throw new Error("Invalid SQLite URL: only file protocol is supported");
1204
- }
1205
- urlExpr = ts.factory.createStringLiteral(dsProvider.url.replace(/^file:/, ""));
1206
- }
1207
- }
1208
- }
1209
- return match2(type).with("sqlite", () => {
1210
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1211
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1212
- urlExpr,
1213
- ts.factory.createIdentifier(`typeof __dirname !== 'undefined' ? __dirname : path.dirname(url.fileURLToPath(import.meta.url))`)
1214
- ]))
1215
- ], true));
1216
- }).with("postgresql", () => {
1217
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1218
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1219
- urlExpr
1220
- ]))
1221
- ], true));
1222
- }).otherwise(() => {
1223
- throw new Error(`Unsupported provider: ${type}`);
1224
- });
1225
- }
1226
1239
  createProceduresObject(procedures) {
1227
1240
  return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
1228
1241
  }
@@ -1257,6 +1270,8 @@ var TsSchemaGenerator = class {
1257
1270
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1258
1271
  //////////////////////////////////////////////////////////////////////////////////////////////
1259
1272
 
1273
+ /* eslint-disable */
1274
+
1260
1275
  `;
1261
1276
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1262
1277
  }
@@ -1279,7 +1294,7 @@ var TsSchemaGenerator = class {
1279
1294
  ]);
1280
1295
  }
1281
1296
  createExpression(value) {
1282
- 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(() => {
1297
+ 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(() => {
1283
1298
  throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1284
1299
  });
1285
1300
  }
@@ -1322,7 +1337,7 @@ var TsSchemaGenerator = class {
1322
1337
  ]);
1323
1338
  }
1324
1339
  createRefExpression(expr) {
1325
- if (isDataModelField(expr.target.ref)) {
1340
+ if (isDataField(expr.target.ref)) {
1326
1341
  return ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.field"), void 0, [
1327
1342
  this.createLiteralNode(expr.target.$refText)
1328
1343
  ]);
@@ -1351,10 +1366,154 @@ var TsSchemaGenerator = class {
1351
1366
  throw new Error(`Unsupported literal type: ${type}`);
1352
1367
  });
1353
1368
  }
1369
+ generateModelsAndTypeDefs(model, outputDir) {
1370
+ const statements = [];
1371
+ statements.push(this.generateSchemaImport(model, true, true));
1372
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1373
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1374
+ ...model.declarations.some(isTypeDef2) ? [
1375
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1376
+ ] : []
1377
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1378
+ const dataModels = model.declarations.filter(isDataModel3);
1379
+ for (const dm of dataModels) {
1380
+ let modelType = ts.factory.createTypeAliasDeclaration([
1381
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1382
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1383
+ ts.factory.createTypeReferenceNode("$Schema"),
1384
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1385
+ ]));
1386
+ if (dm.comments.length > 0) {
1387
+ modelType = this.generateDocs(modelType, dm);
1388
+ }
1389
+ statements.push(modelType);
1390
+ }
1391
+ const typeDefs = model.declarations.filter(isTypeDef2);
1392
+ for (const td of typeDefs) {
1393
+ let typeDef = ts.factory.createTypeAliasDeclaration([
1394
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1395
+ ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1396
+ ts.factory.createTypeReferenceNode("$Schema"),
1397
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1398
+ ]));
1399
+ if (td.comments.length > 0) {
1400
+ typeDef = this.generateDocs(typeDef, td);
1401
+ }
1402
+ statements.push(typeDef);
1403
+ }
1404
+ const enums = model.declarations.filter(isEnum);
1405
+ for (const e of enums) {
1406
+ let enumDecl = ts.factory.createVariableStatement([
1407
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1408
+ ], ts.factory.createVariableDeclarationList([
1409
+ 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)))
1410
+ ], ts.NodeFlags.Const));
1411
+ if (e.comments.length > 0) {
1412
+ enumDecl = this.generateDocs(enumDecl, e);
1413
+ }
1414
+ statements.push(enumDecl);
1415
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1416
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1417
+ ], 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)))));
1418
+ if (e.comments.length > 0) {
1419
+ typeAlias = this.generateDocs(typeAlias, e);
1420
+ }
1421
+ statements.push(typeAlias);
1422
+ }
1423
+ this.generateBannerComments(statements);
1424
+ const outputFile = path.join(outputDir, "models.ts");
1425
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1426
+ const printer = ts.createPrinter();
1427
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1428
+ fs.writeFileSync(outputFile, result);
1429
+ }
1430
+ generateSchemaImport(model, schemaObject, schemaType) {
1431
+ const importSpecifiers = [];
1432
+ if (schemaObject) {
1433
+ if (model.declarations.some(isEnum)) {
1434
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1435
+ }
1436
+ }
1437
+ if (schemaType) {
1438
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1439
+ }
1440
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1441
+ }
1442
+ generateDocs(tsDecl, decl) {
1443
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1444
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1445
+ `, true);
1446
+ }
1447
+ generateInputTypes(model, outputDir) {
1448
+ const dataModels = model.declarations.filter(isDataModel3);
1449
+ const statements = [];
1450
+ statements.push(this.generateSchemaImport(model, false, true));
1451
+ const inputTypes = [
1452
+ "FindManyArgs",
1453
+ "FindUniqueArgs",
1454
+ "FindFirstArgs",
1455
+ "CreateArgs",
1456
+ "CreateManyArgs",
1457
+ "CreateManyAndReturnArgs",
1458
+ "UpdateArgs",
1459
+ "UpdateManyArgs",
1460
+ "UpdateManyAndReturnArgs",
1461
+ "UpsertArgs",
1462
+ "DeleteArgs",
1463
+ "DeleteManyArgs",
1464
+ "CountArgs",
1465
+ "AggregateArgs",
1466
+ "GroupByArgs",
1467
+ "WhereInput",
1468
+ "SelectInput",
1469
+ "IncludeInput",
1470
+ "OmitInput"
1471
+ ];
1472
+ const inputTypeNameFixes = {
1473
+ SelectInput: "Select",
1474
+ IncludeInput: "Include",
1475
+ OmitInput: "Omit"
1476
+ };
1477
+ 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")));
1478
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1479
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1480
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1481
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1482
+ for (const dm of dataModels) {
1483
+ for (const inputType of inputTypes) {
1484
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1485
+ statements.push(ts.factory.createTypeAliasDeclaration([
1486
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1487
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1488
+ ts.factory.createTypeReferenceNode("$Schema"),
1489
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1490
+ ])));
1491
+ }
1492
+ statements.push(ts.factory.createTypeAliasDeclaration([
1493
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1494
+ ], `${dm.name}GetPayload`, [
1495
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1496
+ ts.factory.createTypeReferenceNode("$Schema"),
1497
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1498
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1499
+ ]))
1500
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1501
+ ts.factory.createTypeReferenceNode("$Schema"),
1502
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1503
+ ts.factory.createTypeReferenceNode("Args")
1504
+ ])));
1505
+ }
1506
+ this.generateBannerComments(statements);
1507
+ const outputFile = path.join(outputDir, "input.ts");
1508
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1509
+ const printer = ts.createPrinter();
1510
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1511
+ fs.writeFileSync(outputFile, result);
1512
+ }
1354
1513
  };
1355
1514
 
1356
1515
  // src/zmodel-code-generator.ts
1357
- 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";
1516
+ 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";
1358
1517
  function _ts_decorate(decorators, target, key, desc) {
1359
1518
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1360
1519
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1442,21 +1601,21 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}
1442
1601
  return `${ast.name} = ${this.generate(ast.value)}`;
1443
1602
  }
1444
1603
  _generateDataModel(ast) {
1445
- return `${ast.isAbstract ? "abstract " : ""}${ast.isView ? "view" : "model"} ${ast.name}${ast.superTypes.length > 0 ? " extends " + ast.superTypes.map((x) => x.ref?.name).join(", ") : ""} {
1604
+ return `${ast.isView ? "view" : "model"} ${ast.name}${ast.mixins.length > 0 ? " mixes " + ast.mixins.map((x) => x.ref?.name).join(", ") : ""} {
1446
1605
  ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attributes.length > 0 ? "\n\n" + ast.attributes.map((x) => this.indent + this.generate(x)).join("\n") : ""}
1447
1606
  }`;
1448
1607
  }
1449
- _generateDataModelField(ast) {
1608
+ _generateDataField(ast) {
1450
1609
  return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1451
1610
  }
1452
1611
  fieldType(type) {
1453
- const baseType = type.type ? type.type : type.$type == "DataModelFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1612
+ const baseType = type.type ? type.type : type.$type == "DataFieldType" && type.unsupported ? "Unsupported(" + this.generate(type.unsupported.value) + ")" : type.reference?.$refText;
1454
1613
  return `${baseType}${type.array ? "[]" : ""}${type.optional ? "?" : ""}`;
1455
1614
  }
1456
1615
  _generateDataModelAttribute(ast) {
1457
1616
  return this.attribute(ast);
1458
1617
  }
1459
- _generateDataModelFieldAttribute(ast) {
1618
+ _generateDataFieldAttribute(ast) {
1460
1619
  return this.attribute(ast);
1461
1620
  }
1462
1621
  attribute(ast) {
@@ -1540,9 +1699,6 @@ ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attribu
1540
1699
  ${ast.fields.map((x) => this.indent + this.generate(x)).join("\n")}${ast.attributes.length > 0 ? "\n\n" + ast.attributes.map((x) => this.indent + this.generate(x)).join("\n") : ""}
1541
1700
  }`;
1542
1701
  }
1543
- _generateTypeDefField(ast) {
1544
- return `${ast.name} ${this.fieldType(ast.type)}${ast.attributes.length > 0 ? " " + ast.attributes.map((x) => this.generate(x)).join(" ") : ""}`;
1545
- }
1546
1702
  argument(ast) {
1547
1703
  return this.generate(ast.value);
1548
1704
  }
@@ -1668,13 +1824,13 @@ _ts_decorate([
1668
1824
  _ts_metadata("design:returntype", void 0)
1669
1825
  ], ZModelCodeGenerator.prototype, "_generateDataModel", null);
1670
1826
  _ts_decorate([
1671
- gen(DataModelField),
1827
+ gen(DataField),
1672
1828
  _ts_metadata("design:type", Function),
1673
1829
  _ts_metadata("design:paramtypes", [
1674
- typeof DataModelField === "undefined" ? Object : DataModelField
1830
+ typeof DataField === "undefined" ? Object : DataField
1675
1831
  ]),
1676
1832
  _ts_metadata("design:returntype", void 0)
1677
- ], ZModelCodeGenerator.prototype, "_generateDataModelField", null);
1833
+ ], ZModelCodeGenerator.prototype, "_generateDataField", null);
1678
1834
  _ts_decorate([
1679
1835
  gen(DataModelAttribute),
1680
1836
  _ts_metadata("design:type", Function),
@@ -1684,13 +1840,13 @@ _ts_decorate([
1684
1840
  _ts_metadata("design:returntype", void 0)
1685
1841
  ], ZModelCodeGenerator.prototype, "_generateDataModelAttribute", null);
1686
1842
  _ts_decorate([
1687
- gen(DataModelFieldAttribute),
1843
+ gen(DataFieldAttribute),
1688
1844
  _ts_metadata("design:type", Function),
1689
1845
  _ts_metadata("design:paramtypes", [
1690
- typeof DataModelFieldAttribute === "undefined" ? Object : DataModelFieldAttribute
1846
+ typeof DataFieldAttribute === "undefined" ? Object : DataFieldAttribute
1691
1847
  ]),
1692
1848
  _ts_metadata("design:returntype", void 0)
1693
- ], ZModelCodeGenerator.prototype, "_generateDataModelFieldAttribute", null);
1849
+ ], ZModelCodeGenerator.prototype, "_generateDataFieldAttribute", null);
1694
1850
  _ts_decorate([
1695
1851
  gen(AttributeArg2),
1696
1852
  _ts_metadata("design:type", Function),
@@ -1855,14 +2011,6 @@ _ts_decorate([
1855
2011
  ]),
1856
2012
  _ts_metadata("design:returntype", void 0)
1857
2013
  ], ZModelCodeGenerator.prototype, "_generateTypeDef", null);
1858
- _ts_decorate([
1859
- gen(TypeDefField),
1860
- _ts_metadata("design:type", Function),
1861
- _ts_metadata("design:paramtypes", [
1862
- typeof TypeDefField === "undefined" ? Object : TypeDefField
1863
- ]),
1864
- _ts_metadata("design:returntype", void 0)
1865
- ], ZModelCodeGenerator.prototype, "_generateTypeDefField", null);
1866
2014
  export {
1867
2015
  model_utils_exports as ModelUtils,
1868
2016
  PrismaSchemaGenerator,