@zenstackhq/sdk 3.0.0-alpha.4 → 3.0.0-alpha.7

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,11 +809,11 @@ 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 {
@@ -915,19 +914,26 @@ var TsSchemaGenerator = class {
915
914
  }
916
915
  createComputedFieldsObject(fields) {
917
916
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
918
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
917
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
919
918
  ]), ts.factory.createBlock([
920
919
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
921
920
  ts.factory.createStringLiteral("This is a stub for computed field")
922
921
  ]))
923
922
  ], true))), true);
924
923
  }
925
- mapTypeToTSSyntaxKeyword(type) {
926
- 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);
924
+ mapFieldTypeToTSType(type) {
925
+ 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");
926
+ if (type.array) {
927
+ result = `${result}[]`;
928
+ }
929
+ if (type.optional) {
930
+ result = `${result} | null`;
931
+ }
932
+ return result;
927
933
  }
928
934
  createDataModelFieldObject(field) {
929
935
  const objectFields = [
930
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
936
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
931
937
  ];
932
938
  if (isIdField(field)) {
933
939
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
@@ -947,9 +953,9 @@ var TsSchemaGenerator = class {
947
953
  if (field.attributes.length > 0) {
948
954
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
949
955
  }
950
- const defaultValue = this.getMappedDefault(field);
956
+ const defaultValue = this.getFieldMappedDefault(field);
951
957
  if (defaultValue !== void 0) {
952
- if (typeof defaultValue === "object") {
958
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
953
959
  if ("call" in defaultValue) {
954
960
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
955
961
  ts.factory.createStringLiteral(defaultValue.call),
@@ -968,7 +974,11 @@ var TsSchemaGenerator = class {
968
974
  throw new Error(`Unsupported default value type for field ${field.name}`);
969
975
  }
970
976
  } else {
971
- 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()));
977
+ if (Array.isArray(defaultValue)) {
978
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
979
+ } else {
980
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
981
+ }
972
982
  }
973
983
  }
974
984
  if (hasAttribute(field, "@computed")) {
@@ -985,12 +995,12 @@ var TsSchemaGenerator = class {
985
995
  }
986
996
  getDataSourceProvider(model) {
987
997
  const dataSource = model.declarations.find(import_ast3.isDataSource);
988
- (0, import_tiny_invariant.default)(dataSource, "No data source found in the model");
998
+ (0, import_common_helpers.invariant)(dataSource, "No data source found in the model");
989
999
  const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
990
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
1000
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(providerExpr), "Provider must be a literal");
991
1001
  const type = providerExpr.value;
992
1002
  const urlExpr = dataSource.fields.find((f) => f.name === "url")?.value;
993
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
1003
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(urlExpr) || (0, import_ast3.isInvocationExpr)(urlExpr), "URL must be a literal or env function");
994
1004
  if ((0, import_ast3.isLiteralExpr)(urlExpr)) {
995
1005
  return {
996
1006
  type,
@@ -998,8 +1008,8 @@ var TsSchemaGenerator = class {
998
1008
  env: void 0
999
1009
  };
1000
1010
  } else if ((0, import_ast3.isInvocationExpr)(urlExpr)) {
1001
- (0, import_tiny_invariant.default)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1002
- (0, import_tiny_invariant.default)(urlExpr.args.length === 1, "env function must have one argument");
1011
+ (0, import_common_helpers.invariant)(urlExpr.function.$refText === "env", 'only "env" function is supported');
1012
+ (0, import_common_helpers.invariant)(urlExpr.args.length === 1, "env function must have one argument");
1003
1013
  return {
1004
1014
  type,
1005
1015
  env: urlExpr.args[0].value.value,
@@ -1009,34 +1019,39 @@ var TsSchemaGenerator = class {
1009
1019
  throw new Error("Unsupported URL type");
1010
1020
  }
1011
1021
  }
1012
- getMappedDefault(field) {
1022
+ getFieldMappedDefault(field) {
1013
1023
  const defaultAttr = getAttribute(field, "@default");
1014
1024
  if (!defaultAttr) {
1015
1025
  return void 0;
1016
1026
  }
1017
1027
  const defaultValue = defaultAttr.args[0]?.value;
1018
- (0, import_tiny_invariant.default)(defaultValue, "Expected a default value");
1019
- if ((0, import_ast3.isLiteralExpr)(defaultValue)) {
1020
- const lit = defaultValue.value;
1021
- return field.type.type === "Boolean" ? lit : [
1028
+ (0, import_common_helpers.invariant)(defaultValue, "Expected a default value");
1029
+ return this.getMappedValue(defaultValue, field.type);
1030
+ }
1031
+ getMappedValue(expr, fieldType) {
1032
+ if ((0, import_ast3.isLiteralExpr)(expr)) {
1033
+ const lit = expr.value;
1034
+ return fieldType.type === "Boolean" ? lit : [
1022
1035
  "Int",
1023
1036
  "Float",
1024
1037
  "Decimal",
1025
1038
  "BigInt"
1026
- ].includes(field.type.type) ? Number(lit) : lit;
1027
- } else if ((0, import_ast3.isReferenceExpr)(defaultValue) && (0, import_ast3.isEnumField)(defaultValue.target.ref)) {
1028
- return defaultValue.target.ref.name;
1029
- } else if ((0, import_ast3.isInvocationExpr)(defaultValue)) {
1039
+ ].includes(fieldType.type) ? Number(lit) : lit;
1040
+ } else if ((0, import_ast3.isArrayExpr)(expr)) {
1041
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1042
+ } else if ((0, import_ast3.isReferenceExpr)(expr) && (0, import_ast3.isEnumField)(expr.target.ref)) {
1043
+ return expr.target.ref.name;
1044
+ } else if ((0, import_ast3.isInvocationExpr)(expr)) {
1030
1045
  return {
1031
- call: defaultValue.function.$refText,
1032
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1046
+ call: expr.function.$refText,
1047
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1033
1048
  };
1034
- } else if (this.isAuthMemberAccess(defaultValue)) {
1049
+ } else if (this.isAuthMemberAccess(expr)) {
1035
1050
  return {
1036
- authMember: this.getMemberAccessChain(defaultValue)
1051
+ authMember: this.getMemberAccessChain(expr)
1037
1052
  };
1038
1053
  } else {
1039
- throw new Error(`Unsupported default value type for field ${field.name}`);
1054
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1040
1055
  }
1041
1056
  }
1042
1057
  getMemberAccessChain(expr) {
@@ -1135,7 +1150,7 @@ var TsSchemaGenerator = class {
1135
1150
  if (relation) {
1136
1151
  const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
1137
1152
  if (nameArg) {
1138
- (0, import_tiny_invariant.default)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1153
+ (0, import_common_helpers.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1139
1154
  return nameArg.value.value;
1140
1155
  }
1141
1156
  }
@@ -1149,10 +1164,11 @@ var TsSchemaGenerator = class {
1149
1164
  for (const field of dm.fields) {
1150
1165
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1151
1166
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1152
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1167
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1153
1168
  ])));
1154
1169
  }
1155
1170
  }
1171
+ const seenKeys = /* @__PURE__ */ new Set();
1156
1172
  for (const attr of dm.attributes) {
1157
1173
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1158
1174
  const fieldNames = this.getReferenceNames(attr.args[0].value);
@@ -1162,13 +1178,18 @@ var TsSchemaGenerator = class {
1162
1178
  if (fieldNames.length === 1) {
1163
1179
  const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1164
1180
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1165
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1181
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1166
1182
  ])));
1167
1183
  } else {
1184
+ const key = fieldNames.join("_");
1185
+ if (seenKeys.has(key)) {
1186
+ continue;
1187
+ }
1188
+ seenKeys.add(key);
1168
1189
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1169
1190
  const fieldDef = dm.fields.find((f) => f.name === field);
1170
1191
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1171
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1192
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1172
1193
  ]));
1173
1194
  }))));
1174
1195
  }
@@ -1176,6 +1197,10 @@ var TsSchemaGenerator = class {
1176
1197
  }
1177
1198
  return ts.factory.createObjectLiteralExpression(properties, true);
1178
1199
  }
1200
+ generateFieldTypeLiteral(field) {
1201
+ (0, import_common_helpers.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1202
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("unknown");
1203
+ }
1179
1204
  createEnumObject(e) {
1180
1205
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1181
1206
  }
@@ -1230,6 +1255,8 @@ var TsSchemaGenerator = class {
1230
1255
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1231
1256
  //////////////////////////////////////////////////////////////////////////////////////////////
1232
1257
 
1258
+ /* eslint-disable */
1259
+
1233
1260
  `;
1234
1261
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1235
1262
  }