@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.cjs CHANGED
@@ -318,9 +318,9 @@ var Model = class extends ContainerDeclaration {
318
318
  }
319
319
  name;
320
320
  isView;
321
- fields;
321
+ fields = [];
322
322
  constructor(name, isView, documentations = []) {
323
- super(documentations), this.name = name, this.isView = isView, this.fields = [];
323
+ super(documentations), this.name = name, this.isView = isView;
324
324
  }
325
325
  addField(name, type, attributes = [], documentations = [], addToFront = false) {
326
326
  const field = new ModelField(name, type, attributes, documentations);
@@ -540,9 +540,9 @@ var Enum = class extends ContainerDeclaration {
540
540
  __name(this, "Enum");
541
541
  }
542
542
  name;
543
- fields;
543
+ fields = [];
544
544
  constructor(name, documentations = []) {
545
- super(documentations), this.name = name, this.fields = [];
545
+ super(documentations), this.name = name;
546
546
  }
547
547
  addField(name, attributes = [], documentations = []) {
548
548
  const field = new EnumField(name, attributes, documentations);
@@ -591,15 +591,14 @@ var PrismaSchemaGenerator = class {
591
591
  __name(this, "PrismaSchemaGenerator");
592
592
  }
593
593
  zmodel;
594
- PRELUDE;
595
- constructor(zmodel) {
596
- this.zmodel = zmodel;
597
- this.PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
594
+ PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
598
595
  // DO NOT MODIFY THIS FILE //
599
596
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
600
597
  //////////////////////////////////////////////////////////////////////////////////////////////
601
598
 
602
599
  `;
600
+ constructor(zmodel) {
601
+ this.zmodel = zmodel;
603
602
  }
604
603
  async generate() {
605
604
  const prisma = new PrismaModel();
@@ -810,37 +809,39 @@ var PrismaSchemaGenerator = class {
810
809
  };
811
810
 
812
811
  // src/ts-schema-generator.ts
812
+ var import_common_helpers = require("@zenstackhq/common-helpers");
813
813
  var import_language = require("@zenstackhq/language");
814
814
  var import_ast3 = require("@zenstackhq/language/ast");
815
815
  var import_node_fs = __toESM(require("fs"), 1);
816
816
  var import_node_path = __toESM(require("path"), 1);
817
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
818
817
  var import_ts_pattern2 = require("ts-pattern");
819
818
  var ts = __toESM(require("typescript"), 1);
820
819
  var TsSchemaGenerator = class {
821
820
  static {
822
821
  __name(this, "TsSchemaGenerator");
823
822
  }
824
- async generate(schemaFile, pluginModelFiles, outputFile) {
823
+ async generate(schemaFile, pluginModelFiles, outputDir) {
825
824
  const loaded = await (0, import_language.loadDocument)(schemaFile, pluginModelFiles);
826
825
  if (!loaded.success) {
827
826
  throw new Error(`Error loading schema:${loaded.errors.join("\n")}`);
828
827
  }
829
- const { model, warnings } = loaded;
828
+ const { model } = loaded;
829
+ import_node_fs.default.mkdirSync(outputDir, {
830
+ recursive: true
831
+ });
832
+ this.generateSchema(model, outputDir);
833
+ this.generateModels(model, outputDir);
834
+ this.generateInputTypes(model, outputDir);
835
+ }
836
+ generateSchema(model, outputDir) {
830
837
  const statements = [];
831
838
  this.generateSchemaStatements(model, statements);
832
839
  this.generateBannerComments(statements);
833
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
840
+ const schemaOutputFile = import_node_path.default.join(outputDir, "schema.ts");
841
+ const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
834
842
  const printer = ts.createPrinter();
835
843
  const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
836
- import_node_fs.default.mkdirSync(import_node_path.default.dirname(outputFile), {
837
- recursive: true
838
- });
839
- import_node_fs.default.writeFileSync(outputFile, result);
840
- return {
841
- model,
842
- warnings
843
- };
844
+ import_node_fs.default.writeFileSync(schemaOutputFile, result);
844
845
  }
845
846
  generateSchemaStatements(model, statements) {
846
847
  const hasComputedFields = model.declarations.some((d) => (0, import_ast3.isDataModel)(d) && d.fields.some((f) => hasAttribute(f, "@computed")));
@@ -852,27 +853,6 @@ var TsSchemaGenerator = class {
852
853
  ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
853
854
  ])), ts.factory.createStringLiteral("@zenstackhq/runtime/schema"));
854
855
  statements.push(runtimeImportDecl);
855
- const { type: providerType } = this.getDataSourceProvider(model);
856
- switch (providerType) {
857
- case "sqlite": {
858
- const pathImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("path"), void 0), ts.factory.createStringLiteral("node:path"));
859
- statements.push(pathImportDecl);
860
- const urlImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("url"), void 0), ts.factory.createStringLiteral("node:url"));
861
- statements.push(urlImportDecl);
862
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
863
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
864
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/sqlite-utils"));
865
- statements.push(dialectConfigImportDecl);
866
- break;
867
- }
868
- case "postgresql": {
869
- const dialectConfigImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
870
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("toDialectConfig"))
871
- ])), ts.factory.createStringLiteral("@zenstackhq/runtime/utils/pg-utils"));
872
- statements.push(dialectConfigImportDecl);
873
- break;
874
- }
875
- }
876
856
  const declaration = ts.factory.createVariableStatement([
877
857
  ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
878
858
  ], ts.factory.createVariableDeclarationList([
@@ -909,8 +889,7 @@ var TsSchemaGenerator = class {
909
889
  createProviderObject(model) {
910
890
  const dsProvider = this.getDataSourceProvider(model);
911
891
  return ts.factory.createObjectLiteralExpression([
912
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type)),
913
- ts.factory.createPropertyAssignment("dialectConfigProvider", this.createDialectConfigProvider(dsProvider))
892
+ ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider.type))
914
893
  ], true);
915
894
  }
916
895
  createModelsObject(model) {
@@ -937,19 +916,26 @@ var TsSchemaGenerator = class {
937
916
  }
938
917
  createComputedFieldsObject(fields) {
939
918
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
940
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
919
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
941
920
  ]), ts.factory.createBlock([
942
921
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
943
922
  ts.factory.createStringLiteral("This is a stub for computed field")
944
923
  ]))
945
924
  ], true))), true);
946
925
  }
947
- mapTypeToTSSyntaxKeyword(type) {
948
- return (0, import_ts_pattern2.match)(type).with("String", () => ts.SyntaxKind.StringKeyword).with("Boolean", () => ts.SyntaxKind.BooleanKeyword).with("Int", () => ts.SyntaxKind.NumberKeyword).with("Float", () => ts.SyntaxKind.NumberKeyword).with("BigInt", () => ts.SyntaxKind.BigIntKeyword).with("Decimal", () => ts.SyntaxKind.NumberKeyword).otherwise(() => ts.SyntaxKind.UnknownKeyword);
926
+ mapFieldTypeToTSType(type) {
927
+ let result = (0, import_ts_pattern2.match)(type.type).with("String", () => "string").with("Boolean", () => "boolean").with("Int", () => "number").with("Float", () => "number").with("BigInt", () => "bigint").with("Decimal", () => "number").otherwise(() => "unknown");
928
+ if (type.array) {
929
+ result = `${result}[]`;
930
+ }
931
+ if (type.optional) {
932
+ result = `${result} | null`;
933
+ }
934
+ return result;
949
935
  }
950
936
  createDataModelFieldObject(field) {
951
937
  const objectFields = [
952
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
938
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
953
939
  ];
954
940
  if (isIdField(field)) {
955
941
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
@@ -969,9 +955,9 @@ var TsSchemaGenerator = class {
969
955
  if (field.attributes.length > 0) {
970
956
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
971
957
  }
972
- const defaultValue = this.getMappedDefault(field);
958
+ const defaultValue = this.getFieldMappedDefault(field);
973
959
  if (defaultValue !== void 0) {
974
- if (typeof defaultValue === "object") {
960
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
975
961
  if ("call" in defaultValue) {
976
962
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
977
963
  ts.factory.createStringLiteral(defaultValue.call),
@@ -990,7 +976,11 @@ var TsSchemaGenerator = class {
990
976
  throw new Error(`Unsupported default value type for field ${field.name}`);
991
977
  }
992
978
  } else {
993
- objectFields.push(ts.factory.createPropertyAssignment("default", typeof defaultValue === "string" ? ts.factory.createStringLiteral(defaultValue) : typeof defaultValue === "number" ? ts.factory.createNumericLiteral(defaultValue) : defaultValue === true ? ts.factory.createTrue() : ts.factory.createFalse()));
979
+ if (Array.isArray(defaultValue)) {
980
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
981
+ } else {
982
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
983
+ }
994
984
  }
995
985
  }
996
986
  if (hasAttribute(field, "@computed")) {
@@ -1007,12 +997,12 @@ var TsSchemaGenerator = class {
1007
997
  }
1008
998
  getDataSourceProvider(model) {
1009
999
  const dataSource = model.declarations.find(import_ast3.isDataSource);
1010
- (0, import_tiny_invariant.default)(dataSource, "No data source found in the model");
1000
+ (0, import_common_helpers.invariant)(dataSource, "No data source found in the model");
1011
1001
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
1012
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1002
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1013
1003
  const type = providerExpr.value;
1014
1004
  const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
1015
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1005
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1016
1006
  if ((0, import_ast3.isLiteralExpr)(urlExpr)) {
1017
1007
  return {
1018
1008
  type,
@@ -1020,8 +1010,8 @@ var TsSchemaGenerator = class {
1020
1010
  env: void 0
1021
1011
  };
1022
1012
  } else if ((0, import_ast3.isInvocationExpr)(urlExpr)) {
1023
- (0, import_tiny_invariant.default)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1024
- (0, import_tiny_invariant.default)(urlExpr.args.length === 1, "env function must have one argument");
1013
+ (0, import_common_helpers.invariant)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1014
+ (0, import_common_helpers.invariant)(urlExpr.args.length === 1, "env function must have one argument");
1025
1015
  return {
1026
1016
  type,
1027
1017
  env: urlExpr.args[0].value.value,
@@ -1031,34 +1021,39 @@ var TsSchemaGenerator = class {
1031
1021
  throw new Error("Unsupported URL type");
1032
1022
  }
1033
1023
  }
1034
- getMappedDefault(field) {
1024
+ getFieldMappedDefault(field) {
1035
1025
  const defaultAttr = getAttribute(field, "@default");
1036
1026
  if (!defaultAttr) {
1037
1027
  return void 0;
1038
1028
  }
1039
1029
  const defaultValue = defaultAttr.args[0]?.value;
1040
- (0, import_tiny_invariant.default)(defaultValue, "Expected a default value");
1041
- if ((0, import_ast3.isLiteralExpr)(defaultValue)) {
1042
- const lit = defaultValue.value;
1043
- return field.type.type === "Boolean" ? lit : [
1030
+ (0, import_common_helpers.invariant)(defaultValue, "Expected a default value");
1031
+ return this.getMappedValue(defaultValue, field.type);
1032
+ }
1033
+ getMappedValue(expr, fieldType) {
1034
+ if ((0, import_ast3.isLiteralExpr)(expr)) {
1035
+ const lit = expr.value;
1036
+ return fieldType.type === "Boolean" ? lit : [
1044
1037
  "Int",
1045
1038
  "Float",
1046
1039
  "Decimal",
1047
1040
  "BigInt"
1048
- ].includes(field.type.type) ? Number(lit) : lit;
1049
- } else if ((0, import_ast3.isReferenceExpr)(defaultValue) && (0, import_ast3.isEnumField)(defaultValue.target.ref)) {
1050
- return defaultValue.target.ref.name;
1051
- } else if ((0, import_ast3.isInvocationExpr)(defaultValue)) {
1041
+ ].includes(fieldType.type) ? Number(lit) : lit;
1042
+ } else if ((0, import_ast3.isArrayExpr)(expr)) {
1043
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1044
+ } else if ((0, import_ast3.isReferenceExpr)(expr) && (0, import_ast3.isEnumField)(expr.target.ref)) {
1045
+ return expr.target.ref.name;
1046
+ } else if ((0, import_ast3.isInvocationExpr)(expr)) {
1052
1047
  return {
1053
- call: defaultValue.function.$refText,
1054
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1048
+ call: expr.function.$refText,
1049
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1055
1050
  };
1056
- } else if (this.isAuthMemberAccess(defaultValue)) {
1051
+ } else if (this.isAuthMemberAccess(expr)) {
1057
1052
  return {
1058
- authMember: this.getMemberAccessChain(defaultValue)
1053
+ authMember: this.getMemberAccessChain(expr)
1059
1054
  };
1060
1055
  } else {
1061
- throw new Error(`Unsupported default value type for field ${field.name}`);
1056
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1062
1057
  }
1063
1058
  }
1064
1059
  getMemberAccessChain(expr) {
@@ -1157,7 +1152,7 @@ var TsSchemaGenerator = class {
1157
1152
  if (relation) {
1158
1153
  const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
1159
1154
  if (nameArg) {
1160
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1155
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1161
1156
  return nameArg.value.value;
1162
1157
  }
1163
1158
  }
@@ -1171,10 +1166,11 @@ var TsSchemaGenerator = class {
1171
1166
  for (const field of dm.fields) {
1172
1167
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1173
1168
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1174
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1169
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1175
1170
  ])));
1176
1171
  }
1177
1172
  }
1173
+ const seenKeys = /* @__PURE__ */ new Set();
1178
1174
  for (const attr of dm.attributes) {
1179
1175
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1180
1176
  const fieldNames = this.getReferenceNames(attr.args[0].value);
@@ -1184,13 +1180,18 @@ var TsSchemaGenerator = class {
1184
1180
  if (fieldNames.length === 1) {
1185
1181
  const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1186
1182
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1187
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1183
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1188
1184
  ])));
1189
1185
  } else {
1186
+ const key = fieldNames.join("_");
1187
+ if (seenKeys.has(key)) {
1188
+ continue;
1189
+ }
1190
+ seenKeys.add(key);
1190
1191
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1191
1192
  const fieldDef = dm.fields.find((f) => f.name === field);
1192
1193
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1193
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1194
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1194
1195
  ]));
1195
1196
  }))));
1196
1197
  }
@@ -1198,6 +1199,10 @@ var TsSchemaGenerator = class {
1198
1199
  }
1199
1200
  return ts.factory.createObjectLiteralExpression(properties, true);
1200
1201
  }
1202
+ generateFieldTypeLiteral(field) {
1203
+ (0, import_common_helpers.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1204
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1205
+ }
1201
1206
  createEnumObject(e) {
1202
1207
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1203
1208
  }
@@ -1218,44 +1223,6 @@ var TsSchemaGenerator = class {
1218
1223
  createLiteralNode(arg) {
1219
1224
  return arg === null ? ts.factory.createNull() : typeof arg === "string" ? ts.factory.createStringLiteral(arg) : typeof arg === "number" ? ts.factory.createNumericLiteral(arg) : arg === true ? ts.factory.createTrue() : arg === false ? ts.factory.createFalse() : void 0;
1220
1225
  }
1221
- createDialectConfigProvider(dsProvider) {
1222
- const type = dsProvider.type;
1223
- let urlExpr;
1224
- if (dsProvider.env !== void 0) {
1225
- urlExpr = ts.factory.createIdentifier(`process.env['${dsProvider.env}']`);
1226
- } else {
1227
- urlExpr = ts.factory.createStringLiteral(dsProvider.url);
1228
- if (type === "sqlite") {
1229
- let parsedUrl;
1230
- try {
1231
- parsedUrl = new URL(dsProvider.url);
1232
- } catch {
1233
- }
1234
- if (parsedUrl) {
1235
- if (parsedUrl.protocol !== "file:") {
1236
- throw new Error("Invalid SQLite URL: only file protocol is supported");
1237
- }
1238
- urlExpr = ts.factory.createStringLiteral(dsProvider.url.replace(/^file:/, ""));
1239
- }
1240
- }
1241
- }
1242
- return (0, import_ts_pattern2.match)(type).with("sqlite", () => {
1243
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1244
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1245
- urlExpr,
1246
- ts.factory.createIdentifier(`typeof __dirname !== 'undefined' ? __dirname : path.dirname(url.fileURLToPath(import.meta.url))`)
1247
- ]))
1248
- ], true));
1249
- }).with("postgresql", () => {
1250
- return ts.factory.createFunctionExpression(void 0, void 0, void 0, void 0, void 0, void 0, ts.factory.createBlock([
1251
- ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("toDialectConfig"), void 0, [
1252
- urlExpr
1253
- ]))
1254
- ], true));
1255
- }).otherwise(() => {
1256
- throw new Error(`Unsupported provider: ${type}`);
1257
- });
1258
- }
1259
1226
  createProceduresObject(procedures) {
1260
1227
  return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
1261
1228
  }
@@ -1290,6 +1257,8 @@ var TsSchemaGenerator = class {
1290
1257
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1291
1258
  //////////////////////////////////////////////////////////////////////////////////////////////
1292
1259
 
1260
+ /* eslint-disable */
1261
+
1293
1262
  `;
1294
1263
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1295
1264
  }
@@ -1384,6 +1353,132 @@ var TsSchemaGenerator = class {
1384
1353
  throw new Error(`Unsupported literal type: ${type}`);
1385
1354
  });
1386
1355
  }
1356
+ generateModels(model, outputDir) {
1357
+ const statements = [];
1358
+ statements.push(this.generateSchemaTypeImport(true, true));
1359
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports([
1360
+ ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`))
1361
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1362
+ const dataModels = model.declarations.filter(import_ast3.isDataModel);
1363
+ for (const dm of dataModels) {
1364
+ let modelType = ts.factory.createTypeAliasDeclaration([
1365
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1366
+ ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1367
+ ts.factory.createTypeReferenceNode("$Schema"),
1368
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1369
+ ]));
1370
+ if (dm.comments.length > 0) {
1371
+ modelType = this.generateDocs(modelType, dm);
1372
+ }
1373
+ statements.push(modelType);
1374
+ }
1375
+ const enums = model.declarations.filter(import_ast3.isEnum);
1376
+ for (const e of enums) {
1377
+ let enumDecl = ts.factory.createVariableStatement([
1378
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1379
+ ], ts.factory.createVariableDeclarationList([
1380
+ 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)))
1381
+ ], ts.NodeFlags.Const));
1382
+ if (e.comments.length > 0) {
1383
+ enumDecl = this.generateDocs(enumDecl, e);
1384
+ }
1385
+ statements.push(enumDecl);
1386
+ let typeAlias = ts.factory.createTypeAliasDeclaration([
1387
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1388
+ ], 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)))));
1389
+ if (e.comments.length > 0) {
1390
+ typeAlias = this.generateDocs(typeAlias, e);
1391
+ }
1392
+ statements.push(typeAlias);
1393
+ }
1394
+ this.generateBannerComments(statements);
1395
+ const outputFile = import_node_path.default.join(outputDir, "models.ts");
1396
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1397
+ const printer = ts.createPrinter();
1398
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1399
+ import_node_fs.default.writeFileSync(outputFile, result);
1400
+ }
1401
+ generateSchemaTypeImport(schemaObject, schemaType) {
1402
+ const importSpecifiers = [];
1403
+ if (schemaObject) {
1404
+ importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1405
+ }
1406
+ if (schemaType) {
1407
+ importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1408
+ }
1409
+ return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral("./schema"));
1410
+ }
1411
+ generateDocs(tsDecl, decl) {
1412
+ return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1413
+ * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1414
+ `, true);
1415
+ }
1416
+ generateInputTypes(model, outputDir) {
1417
+ const dataModels = model.declarations.filter(import_ast3.isDataModel);
1418
+ const statements = [];
1419
+ statements.push(this.generateSchemaTypeImport(false, true));
1420
+ const inputTypes = [
1421
+ "FindManyArgs",
1422
+ "FindUniqueArgs",
1423
+ "FindFirstArgs",
1424
+ "CreateArgs",
1425
+ "CreateManyArgs",
1426
+ "CreateManyAndReturnArgs",
1427
+ "UpdateArgs",
1428
+ "UpdateManyArgs",
1429
+ "UpdateManyAndReturnArgs",
1430
+ "UpsertArgs",
1431
+ "DeleteArgs",
1432
+ "DeleteManyArgs",
1433
+ "CountArgs",
1434
+ "AggregateArgs",
1435
+ "GroupByArgs",
1436
+ "WhereInput",
1437
+ "SelectInput",
1438
+ "IncludeInput",
1439
+ "OmitInput"
1440
+ ];
1441
+ const inputTypeNameFixes = {
1442
+ SelectInput: "Select",
1443
+ IncludeInput: "Include",
1444
+ OmitInput: "Omit"
1445
+ };
1446
+ 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")));
1447
+ statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1448
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedModelResult as $SimplifiedModelResult")),
1449
+ ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1450
+ ])), ts.factory.createStringLiteral("@zenstackhq/runtime")));
1451
+ for (const dm of dataModels) {
1452
+ for (const inputType of inputTypes) {
1453
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1454
+ statements.push(ts.factory.createTypeAliasDeclaration([
1455
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1456
+ ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1457
+ ts.factory.createTypeReferenceNode("$Schema"),
1458
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1459
+ ])));
1460
+ }
1461
+ statements.push(ts.factory.createTypeAliasDeclaration([
1462
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1463
+ ], `${dm.name}GetPayload`, [
1464
+ ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1465
+ ts.factory.createTypeReferenceNode("$Schema"),
1466
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1467
+ ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1468
+ ]))
1469
+ ], ts.factory.createTypeReferenceNode("$SimplifiedModelResult", [
1470
+ ts.factory.createTypeReferenceNode("$Schema"),
1471
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1472
+ ts.factory.createTypeReferenceNode("Args")
1473
+ ])));
1474
+ }
1475
+ this.generateBannerComments(statements);
1476
+ const outputFile = import_node_path.default.join(outputDir, "input.ts");
1477
+ const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1478
+ const printer = ts.createPrinter();
1479
+ const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1480
+ import_node_fs.default.writeFileSync(outputFile, result);
1481
+ }
1387
1482
  };
1388
1483
 
1389
1484
  // src/zmodel-code-generator.ts