@zenstackhq/sdk 3.0.0-alpha.1 → 3.0.0-alpha.11

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.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as _zenstackhq_language_ast from '@zenstackhq/language/ast';
2
2
  import { DataModelField, DataModel, TypeDef, Enum, EnumField, FunctionDecl, Attribute, AttributeParam, TypeDefField, DataModelFieldAttribute, DataModelAttribute, AstNode, Model, Reference, InvocationExpr } from '@zenstackhq/language/ast';
3
+ import { MaybePromise } from 'langium';
3
4
 
4
5
  declare function isIdField(field: DataModelField): boolean;
5
6
  declare function hasAttribute(decl: DataModel | TypeDef | DataModelField | Enum | EnumField | FunctionDecl | Attribute | AttributeParam, name: string): boolean;
@@ -36,6 +37,13 @@ declare namespace modelUtils {
36
37
  export { modelUtils_getAttribute as getAttribute, modelUtils_getAuthDecl as getAuthDecl, modelUtils_getContainingModel as getContainingModel, modelUtils_getModelIdFields as getModelIdFields, modelUtils_getModelUniqueFields as getModelUniqueFields, modelUtils_getRecursiveBases as getRecursiveBases, modelUtils_hasAttribute as hasAttribute, modelUtils_isDelegateModel as isDelegateModel, modelUtils_isFromStdlib as isFromStdlib, modelUtils_isIdField as isIdField, modelUtils_isUniqueField as isUniqueField, modelUtils_resolved as resolved };
37
38
  }
38
39
 
40
+ type CliGeneratorContext = {
41
+ model: Model;
42
+ outputPath: string;
43
+ tsSchemaFile: string;
44
+ };
45
+ type CliGenerator = (context: CliGeneratorContext) => MaybePromise<void>;
46
+
39
47
  declare class FunctionCall {
40
48
  func: string;
41
49
  args: FunctionCallArg[];
@@ -82,20 +90,19 @@ declare class PrismaSchemaGenerator {
82
90
  }
83
91
 
84
92
  declare class TsSchemaGenerator {
85
- generate(schemaFile: string, pluginModelFiles: string[], outputFile: string): Promise<{
86
- model: Model;
87
- warnings: string[];
88
- }>;
93
+ generate(schemaFile: string, pluginModelFiles: string[], outputDir: string): Promise<void>;
94
+ private generateSchema;
89
95
  private generateSchemaStatements;
90
96
  private createSchemaObject;
91
97
  private createProviderObject;
92
98
  private createModelsObject;
93
99
  private createDataModelObject;
94
100
  private createComputedFieldsObject;
95
- private mapTypeToTSSyntaxKeyword;
101
+ private mapFieldTypeToTSType;
96
102
  private createDataModelFieldObject;
97
103
  private getDataSourceProvider;
98
- private getMappedDefault;
104
+ private getFieldMappedDefault;
105
+ private getMappedValue;
99
106
  private getMemberAccessChain;
100
107
  private isAuthMemberAccess;
101
108
  private isAuthInvocation;
@@ -106,10 +113,10 @@ declare class TsSchemaGenerator {
106
113
  private getRelationName;
107
114
  private getIdFields;
108
115
  private createUniqueFieldsObject;
116
+ private generateFieldTypeLiteral;
109
117
  private createEnumObject;
110
118
  private getLiteral;
111
119
  private createLiteralNode;
112
- private createDialectConfigProvider;
113
120
  private createProceduresObject;
114
121
  private createProcedureObject;
115
122
  private generateBannerComments;
@@ -125,6 +132,10 @@ declare class TsSchemaGenerator {
125
132
  private createRefExpression;
126
133
  private createCallExpression;
127
134
  private createLiteralExpression;
135
+ private generateModels;
136
+ private generateSchemaTypeImport;
137
+ private generateDocs;
138
+ private generateInputTypes;
128
139
  }
129
140
 
130
141
  /**
@@ -193,4 +204,4 @@ declare class ZModelCodeGenerator {
193
204
  private isCollectionPredicateOperator;
194
205
  }
195
206
 
196
- export { modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
207
+ export { type CliGenerator, type CliGeneratorContext, modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as _zenstackhq_language_ast from '@zenstackhq/language/ast';
2
2
  import { DataModelField, DataModel, TypeDef, Enum, EnumField, FunctionDecl, Attribute, AttributeParam, TypeDefField, DataModelFieldAttribute, DataModelAttribute, AstNode, Model, Reference, InvocationExpr } from '@zenstackhq/language/ast';
3
+ import { MaybePromise } from 'langium';
3
4
 
4
5
  declare function isIdField(field: DataModelField): boolean;
5
6
  declare function hasAttribute(decl: DataModel | TypeDef | DataModelField | Enum | EnumField | FunctionDecl | Attribute | AttributeParam, name: string): boolean;
@@ -36,6 +37,13 @@ declare namespace modelUtils {
36
37
  export { modelUtils_getAttribute as getAttribute, modelUtils_getAuthDecl as getAuthDecl, modelUtils_getContainingModel as getContainingModel, modelUtils_getModelIdFields as getModelIdFields, modelUtils_getModelUniqueFields as getModelUniqueFields, modelUtils_getRecursiveBases as getRecursiveBases, modelUtils_hasAttribute as hasAttribute, modelUtils_isDelegateModel as isDelegateModel, modelUtils_isFromStdlib as isFromStdlib, modelUtils_isIdField as isIdField, modelUtils_isUniqueField as isUniqueField, modelUtils_resolved as resolved };
37
38
  }
38
39
 
40
+ type CliGeneratorContext = {
41
+ model: Model;
42
+ outputPath: string;
43
+ tsSchemaFile: string;
44
+ };
45
+ type CliGenerator = (context: CliGeneratorContext) => MaybePromise<void>;
46
+
39
47
  declare class FunctionCall {
40
48
  func: string;
41
49
  args: FunctionCallArg[];
@@ -82,20 +90,19 @@ declare class PrismaSchemaGenerator {
82
90
  }
83
91
 
84
92
  declare class TsSchemaGenerator {
85
- generate(schemaFile: string, pluginModelFiles: string[], outputFile: string): Promise<{
86
- model: Model;
87
- warnings: string[];
88
- }>;
93
+ generate(schemaFile: string, pluginModelFiles: string[], outputDir: string): Promise<void>;
94
+ private generateSchema;
89
95
  private generateSchemaStatements;
90
96
  private createSchemaObject;
91
97
  private createProviderObject;
92
98
  private createModelsObject;
93
99
  private createDataModelObject;
94
100
  private createComputedFieldsObject;
95
- private mapTypeToTSSyntaxKeyword;
101
+ private mapFieldTypeToTSType;
96
102
  private createDataModelFieldObject;
97
103
  private getDataSourceProvider;
98
- private getMappedDefault;
104
+ private getFieldMappedDefault;
105
+ private getMappedValue;
99
106
  private getMemberAccessChain;
100
107
  private isAuthMemberAccess;
101
108
  private isAuthInvocation;
@@ -106,10 +113,10 @@ declare class TsSchemaGenerator {
106
113
  private getRelationName;
107
114
  private getIdFields;
108
115
  private createUniqueFieldsObject;
116
+ private generateFieldTypeLiteral;
109
117
  private createEnumObject;
110
118
  private getLiteral;
111
119
  private createLiteralNode;
112
- private createDialectConfigProvider;
113
120
  private createProceduresObject;
114
121
  private createProcedureObject;
115
122
  private generateBannerComments;
@@ -125,6 +132,10 @@ declare class TsSchemaGenerator {
125
132
  private createRefExpression;
126
133
  private createCallExpression;
127
134
  private createLiteralExpression;
135
+ private generateModels;
136
+ private generateSchemaTypeImport;
137
+ private generateDocs;
138
+ private generateInputTypes;
128
139
  }
129
140
 
130
141
  /**
@@ -193,4 +204,4 @@ declare class ZModelCodeGenerator {
193
204
  private isCollectionPredicateOperator;
194
205
  }
195
206
 
196
- export { modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
207
+ export { type CliGenerator, type CliGeneratorContext, modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
package/dist/index.js CHANGED
@@ -285,9 +285,9 @@ var Model = class extends ContainerDeclaration {
285
285
  }
286
286
  name;
287
287
  isView;
288
- fields;
288
+ fields = [];
289
289
  constructor(name, isView, documentations = []) {
290
- super(documentations), this.name = name, this.isView = isView, this.fields = [];
290
+ super(documentations), this.name = name, this.isView = isView;
291
291
  }
292
292
  addField(name, type, attributes = [], documentations = [], addToFront = false) {
293
293
  const field = new ModelField(name, type, attributes, documentations);
@@ -507,9 +507,9 @@ var Enum = class extends ContainerDeclaration {
507
507
  __name(this, "Enum");
508
508
  }
509
509
  name;
510
- fields;
510
+ fields = [];
511
511
  constructor(name, documentations = []) {
512
- super(documentations), this.name = name, this.fields = [];
512
+ super(documentations), this.name = name;
513
513
  }
514
514
  addField(name, attributes = [], documentations = []) {
515
515
  const field = new EnumField(name, attributes, documentations);
@@ -558,15 +558,14 @@ var PrismaSchemaGenerator = class {
558
558
  __name(this, "PrismaSchemaGenerator");
559
559
  }
560
560
  zmodel;
561
- PRELUDE;
562
- constructor(zmodel) {
563
- this.zmodel = zmodel;
564
- this.PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
561
+ PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
565
562
  // DO NOT MODIFY THIS FILE //
566
563
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
567
564
  //////////////////////////////////////////////////////////////////////////////////////////////
568
565
 
569
566
  `;
567
+ constructor(zmodel) {
568
+ this.zmodel = zmodel;
570
569
  }
571
570
  async generate() {
572
571
  const prisma = new PrismaModel();
@@ -777,37 +776,39 @@ var PrismaSchemaGenerator = class {
777
776
  };
778
777
 
779
778
  // src/ts-schema-generator.ts
779
+ import { invariant } from "@zenstackhq/common-helpers";
780
780
  import { loadDocument } from "@zenstackhq/language";
781
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 fs from "fs";
783
+ import path from "path";
785
784
  import { match as match2 } from "ts-pattern";
786
785
  import * as ts from "typescript";
787
786
  var TsSchemaGenerator = class {
788
787
  static {
789
788
  __name(this, "TsSchemaGenerator");
790
789
  }
791
- async generate(schemaFile, pluginModelFiles, outputFile) {
790
+ async generate(schemaFile, pluginModelFiles, outputDir) {
792
791
  const loaded = await loadDocument(schemaFile, pluginModelFiles);
793
792
  if (!loaded.success) {
794
793
  throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
795
794
  }
796
- const { model, warnings } = loaded;
795
+ const { model } = loaded;
796
+ fs.mkdirSync(outputDir, {
797
+ recursive: true
798
+ });
799
+ this.generateSchema(model, outputDir);
800
+ this.generateModels(model, outputDir);
801
+ this.generateInputTypes(model, outputDir);
802
+ }
803
+ generateSchema(model, outputDir) {
797
804
  const statements = [];
798
805
  this.generateSchemaStatements(model, statements);
799
806
  this.generateBannerComments(statements);
800
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
807
+ const schemaOutputFile = path.join(outputDir, "schema.ts");
808
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
801
809
  const printer = ts.createPrinter();
802
810
  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
- };
811
+ fs.writeFileSync(schemaOutputFile, result);
811
812
  }
812
813
  generateSchemaStatements(model, statements) {
813
814
  const hasComputedFields = model.declarations.some((d) => isDataModel2(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
@@ -819,27 +820,6 @@ var TsSchemaGenerator = class {
819
820
  ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
820
821
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
821
822
  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
823
  const declaration = ts.factory.createVariableStatement([
844
824
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
845
825
  ], ts.factory.createVariableDeclarationList([
@@ -876,8 +856,7 @@ var TsSchemaGenerator = class {
876
856
  createProviderObject(model) {
877
857
  const dsProvider = this.getDataSourceProvider(model);
878
858
  return ts.factory.createObjectLiteralExpression([
879
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type)),
880
- ts.factory.createPropertyAssignment("dialectConfigProvider", this.createDialectConfigProvider(dsProvider))
859
+ ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type))
881
860
  ], true);
882
861
  }
883
862
  createModelsObject(model) {
@@ -904,19 +883,26 @@ var TsSchemaGenerator = class {
904
883
  }
905
884
  createComputedFieldsObject(fields) {
906
885
  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))
886
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
908
887
  ]), ts.factory.createBlock([
909
888
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
910
889
  ts.factory.createStringLiteral("This is a stub for computed field")
911
890
  ]))
912
891
  ], true))), true);
913
892
  }
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);
893
+ mapFieldTypeToTSType(type) {
894
+ 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");
895
+ if (type.array) {
896
+ result = `${result}[]`;
897
+ }
898
+ if (type.optional) {
899
+ result = `${result} | null`;
900
+ }
901
+ return result;
916
902
  }
917
903
  createDataModelFieldObject(field) {
918
904
  const objectFields = [
919
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
905
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
920
906
  ];
921
907
  if (isIdField(field)) {
922
908
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
@@ -936,9 +922,9 @@ var TsSchemaGenerator = class {
936
922
  if (field.attributes.length > 0) {
937
923
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
938
924
  }
939
- const defaultValue = this.getMappedDefault(field);
925
+ const defaultValue = this.getFieldMappedDefault(field);
940
926
  if (defaultValue !== void 0) {
941
- if (typeof defaultValue === "object") {
927
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
942
928
  if ("call" in defaultValue) {
943
929
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
944
930
  ts.factory.createStringLiteral(defaultValue.call),
@@ -957,7 +943,11 @@ var TsSchemaGenerator = class {
957
943
  throw new Error(`Unsupported default value type for field ${field.name}`);
958
944
  }
959
945
  } 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()));
946
+ if (Array.isArray(defaultValue)) {
947
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
948
+ } else {
949
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
950
+ }
961
951
  }
962
952
  }
963
953
  if (hasAttribute(field, "@computed")) {
@@ -998,34 +988,39 @@ var TsSchemaGenerator = class {
998
988
  throw new Error("Unsupported URL type");
999
989
  }
1000
990
  }
1001
- getMappedDefault(field) {
991
+ getFieldMappedDefault(field) {
1002
992
  const defaultAttr = getAttribute(field, "@default");
1003
993
  if (!defaultAttr) {
1004
994
  return void 0;
1005
995
  }
1006
996
  const defaultValue = defaultAttr.args[0]?.value;
1007
997
  invariant(defaultValue, "Expected a default value");
1008
- if (isLiteralExpr3(defaultValue)) {
1009
- const lit = defaultValue.value;
1010
- return field.type.type === "Boolean" ? lit : [
998
+ return this.getMappedValue(defaultValue, field.type);
999
+ }
1000
+ getMappedValue(expr, fieldType) {
1001
+ if (isLiteralExpr3(expr)) {
1002
+ const lit = expr.value;
1003
+ return fieldType.type === "Boolean" ? lit : [
1011
1004
  "Int",
1012
1005
  "Float",
1013
1006
  "Decimal",
1014
1007
  "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)) {
1008
+ ].includes(fieldType.type) ? Number(lit) : lit;
1009
+ } else if (isArrayExpr3(expr)) {
1010
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1011
+ } else if (isReferenceExpr3(expr) && isEnumField(expr.target.ref)) {
1012
+ return expr.target.ref.name;
1013
+ } else if (isInvocationExpr2(expr)) {
1019
1014
  return {
1020
- call: defaultValue.function.$refText,
1021
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1015
+ call: expr.function.$refText,
1016
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1022
1017
  };
1023
- } else if (this.isAuthMemberAccess(defaultValue)) {
1018
+ } else if (this.isAuthMemberAccess(expr)) {
1024
1019
  return {
1025
- authMember: this.getMemberAccessChain(defaultValue)
1020
+ authMember: this.getMemberAccessChain(expr)
1026
1021
  };
1027
1022
  } else {
1028
- throw new Error(`Unsupported default value type for field ${field.name}`);
1023
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1029
1024
  }
1030
1025
  }
1031
1026
  getMemberAccessChain(expr) {
@@ -1138,10 +1133,11 @@ var TsSchemaGenerator = class {
1138
1133
  for (const field of dm.fields) {
1139
1134
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1140
1135
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1141
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1136
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1142
1137
  ])));
1143
1138
  }
1144
1139
  }
1140
+ const seenKeys = /* @__PURE__ */ new Set();
1145
1141
  for (const attr of dm.attributes) {
1146
1142
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1147
1143
  const fieldNames = this.getReferenceNames(attr.args[0].value);
@@ -1151,13 +1147,18 @@ var TsSchemaGenerator = class {
1151
1147
  if (fieldNames.length === 1) {
1152
1148
  const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1153
1149
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1154
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1150
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1155
1151
  ])));
1156
1152
  } else {
1153
+ const key = fieldNames.join("_");
1154
+ if (seenKeys.has(key)) {
1155
+ continue;
1156
+ }
1157
+ seenKeys.add(key);
1157
1158
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1158
1159
  const fieldDef = dm.fields.find((f) => f.name === field);
1159
1160
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1160
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1161
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1161
1162
  ]));
1162
1163
  }))));
1163
1164
  }
@@ -1165,6 +1166,10 @@ var TsSchemaGenerator = class {
1165
1166
  }
1166
1167
  return ts.factory.createObjectLiteralExpression(properties, true);
1167
1168
  }
1169
+ generateFieldTypeLiteral(field) {
1170
+ invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1171
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1172
+ }
1168
1173
  createEnumObject(e) {
1169
1174
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1170
1175
  }
@@ -1185,44 +1190,6 @@ var TsSchemaGenerator = class {
1185
1190
  createLiteralNode(arg) {
1186
1191
  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
1192
  }
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
1193
  createProceduresObject(procedures) {
1227
1194
  return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
1228
1195
  }
@@ -1257,6 +1224,8 @@ var TsSchemaGenerator = class {
1257
1224
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1258
1225
  //////////////////////////////////////////////////////////////////////////////////////////////
1259
1226
 
1227
+ /* eslint-disable */
1228
+
1260
1229
  `;
1261
1230
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1262
1231
  }
@@ -1351,6 +1320,132 @@ var TsSchemaGenerator = class {
1351
1320
  throw new Error(`Unsupported literal type: ${type}`);
1352
1321
  });
1353
1322
  }
1323
+ generateModels(model, outputDir) {
1324
+ const statements = [];
1325
+ statements.push(this.generateSchemaTypeImport(true, true));
1326
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1327
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`))
1328
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1329
+ const dataModels = model.declarations.filter(isDataModel2);
1330
+ for (const dm of dataModels) {
1331
+ let modelType = ts.factory.createTypeAliasDeclaration([
1332
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1333
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1334
+ ts.factory.createTypeReferenceNode("$Schema"),
1335
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1336
+ ]));
1337
+ if (dm.comments.length > 0) {
1338
+ modelType = this.generateDocs(modelType, dm);
1339
+ }
1340
+ statements.push(modelType);
1341
+ }
1342
+ const enums = model.declarations.filter(isEnum);
1343
+ for (const e of enums) {
1344
+ let enumDecl = ts.factory.createVariableStatement([
1345
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1346
+ ], ts.factory.createVariableDeclarationList([
1347
+ 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)))
1348
+ ], ts.NodeFlags.Const));
1349
+ if (e.comments.length > 0) {
1350
+ enumDecl = this.generateDocs(enumDecl, e);
1351
+ }
1352
+ statements.push(enumDecl);
1353
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1354
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1355
+ ], 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)))));
1356
+ if (e.comments.length > 0) {
1357
+ typeAlias = this.generateDocs(typeAlias, e);
1358
+ }
1359
+ statements.push(typeAlias);
1360
+ }
1361
+ this.generateBannerComments(statements);
1362
+ const outputFile = path.join(outputDir, "models.ts");
1363
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1364
+ const printer = ts.createPrinter();
1365
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1366
+ fs.writeFileSync(outputFile, result);
1367
+ }
1368
+ generateSchemaTypeImport(schemaObject, schemaType) {
1369
+ const importSpecifiers = [];
1370
+ if (schemaObject) {
1371
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1372
+ }
1373
+ if (schemaType) {
1374
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1375
+ }
1376
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1377
+ }
1378
+ generateDocs(tsDecl, decl) {
1379
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1380
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1381
+ `, true);
1382
+ }
1383
+ generateInputTypes(model, outputDir) {
1384
+ const dataModels = model.declarations.filter(isDataModel2);
1385
+ const statements = [];
1386
+ statements.push(this.generateSchemaTypeImport(false, true));
1387
+ const inputTypes = [
1388
+ "FindManyArgs",
1389
+ "FindUniqueArgs",
1390
+ "FindFirstArgs",
1391
+ "CreateArgs",
1392
+ "CreateManyArgs",
1393
+ "CreateManyAndReturnArgs",
1394
+ "UpdateArgs",
1395
+ "UpdateManyArgs",
1396
+ "UpdateManyAndReturnArgs",
1397
+ "UpsertArgs",
1398
+ "DeleteArgs",
1399
+ "DeleteManyArgs",
1400
+ "CountArgs",
1401
+ "AggregateArgs",
1402
+ "GroupByArgs",
1403
+ "WhereInput",
1404
+ "SelectInput",
1405
+ "IncludeInput",
1406
+ "OmitInput"
1407
+ ];
1408
+ const inputTypeNameFixes = {
1409
+ SelectInput: "Select",
1410
+ IncludeInput: "Include",
1411
+ OmitInput: "Omit"
1412
+ };
1413
+ 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")));
1414
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1415
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1416
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1417
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1418
+ for (const dm of dataModels) {
1419
+ for (const inputType of inputTypes) {
1420
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1421
+ statements.push(ts.factory.createTypeAliasDeclaration([
1422
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1423
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1424
+ ts.factory.createTypeReferenceNode("$Schema"),
1425
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1426
+ ])));
1427
+ }
1428
+ statements.push(ts.factory.createTypeAliasDeclaration([
1429
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1430
+ ], `${dm.name}GetPayload`, [
1431
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1432
+ ts.factory.createTypeReferenceNode("$Schema"),
1433
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1434
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1435
+ ]))
1436
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1437
+ ts.factory.createTypeReferenceNode("$Schema"),
1438
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1439
+ ts.factory.createTypeReferenceNode("Args")
1440
+ ])));
1441
+ }
1442
+ this.generateBannerComments(statements);
1443
+ const outputFile = path.join(outputDir, "input.ts");
1444
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1445
+ const printer = ts.createPrinter();
1446
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1447
+ fs.writeFileSync(outputFile, result);
1448
+ }
1354
1449
  };
1355
1450
 
1356
1451
  // src/zmodel-code-generator.ts