@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.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[];
@@ -92,10 +100,11 @@ declare class TsSchemaGenerator {
92
100
  private createModelsObject;
93
101
  private createDataModelObject;
94
102
  private createComputedFieldsObject;
95
- private mapTypeToTSSyntaxKeyword;
103
+ private mapFieldTypeToTSType;
96
104
  private createDataModelFieldObject;
97
105
  private getDataSourceProvider;
98
- private getMappedDefault;
106
+ private getFieldMappedDefault;
107
+ private getMappedValue;
99
108
  private getMemberAccessChain;
100
109
  private isAuthMemberAccess;
101
110
  private isAuthInvocation;
@@ -106,6 +115,7 @@ declare class TsSchemaGenerator {
106
115
  private getRelationName;
107
116
  private getIdFields;
108
117
  private createUniqueFieldsObject;
118
+ private generateFieldTypeLiteral;
109
119
  private createEnumObject;
110
120
  private getLiteral;
111
121
  private createLiteralNode;
@@ -192,4 +202,4 @@ declare class ZModelCodeGenerator {
192
202
  private isCollectionPredicateOperator;
193
203
  }
194
204
 
195
- export { modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
205
+ 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[];
@@ -92,10 +100,11 @@ declare class TsSchemaGenerator {
92
100
  private createModelsObject;
93
101
  private createDataModelObject;
94
102
  private createComputedFieldsObject;
95
- private mapTypeToTSSyntaxKeyword;
103
+ private mapFieldTypeToTSType;
96
104
  private createDataModelFieldObject;
97
105
  private getDataSourceProvider;
98
- private getMappedDefault;
106
+ private getFieldMappedDefault;
107
+ private getMappedValue;
99
108
  private getMemberAccessChain;
100
109
  private isAuthMemberAccess;
101
110
  private isAuthInvocation;
@@ -106,6 +115,7 @@ declare class TsSchemaGenerator {
106
115
  private getRelationName;
107
116
  private getIdFields;
108
117
  private createUniqueFieldsObject;
118
+ private generateFieldTypeLiteral;
109
119
  private createEnumObject;
110
120
  private getLiteral;
111
121
  private createLiteralNode;
@@ -192,4 +202,4 @@ declare class ZModelCodeGenerator {
192
202
  private isCollectionPredicateOperator;
193
203
  }
194
204
 
195
- export { modelUtils as ModelUtils, PrismaSchemaGenerator, TsSchemaGenerator, ZModelCodeGenerator, type ZModelCodeOptions };
205
+ 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,11 +776,11 @@ 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 {
@@ -882,19 +881,26 @@ var TsSchemaGenerator = class {
882
881
  }
883
882
  createComputedFieldsObject(fields) {
884
883
  return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [], ts.factory.createTypeReferenceNode("OperandExpression", [
885
- ts.factory.createKeywordTypeNode(this.mapTypeToTSSyntaxKeyword(field.type.type))
884
+ ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type))
886
885
  ]), ts.factory.createBlock([
887
886
  ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
888
887
  ts.factory.createStringLiteral("This is a stub for computed field")
889
888
  ]))
890
889
  ], true))), true);
891
890
  }
892
- mapTypeToTSSyntaxKeyword(type) {
893
- 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);
891
+ mapFieldTypeToTSType(type) {
892
+ 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");
893
+ if (type.array) {
894
+ result = `${result}[]`;
895
+ }
896
+ if (type.optional) {
897
+ result = `${result} | null`;
898
+ }
899
+ return result;
894
900
  }
895
901
  createDataModelFieldObject(field) {
896
902
  const objectFields = [
897
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type ?? field.type.reference.$refText))
903
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
898
904
  ];
899
905
  if (isIdField(field)) {
900
906
  objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
@@ -914,9 +920,9 @@ var TsSchemaGenerator = class {
914
920
  if (field.attributes.length > 0) {
915
921
  objectFields.push(ts.factory.createPropertyAssignment("attributes", ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr)))));
916
922
  }
917
- const defaultValue = this.getMappedDefault(field);
923
+ const defaultValue = this.getFieldMappedDefault(field);
918
924
  if (defaultValue !== void 0) {
919
- if (typeof defaultValue === "object") {
925
+ if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
920
926
  if ("call" in defaultValue) {
921
927
  objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createCallExpression(ts.factory.createIdentifier("ExpressionUtils.call"), void 0, [
922
928
  ts.factory.createStringLiteral(defaultValue.call),
@@ -935,7 +941,11 @@ var TsSchemaGenerator = class {
935
941
  throw new Error(`Unsupported default value type for field ${field.name}`);
936
942
  }
937
943
  } else {
938
- 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()));
944
+ if (Array.isArray(defaultValue)) {
945
+ objectFields.push(ts.factory.createPropertyAssignment("default", ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)))));
946
+ } else {
947
+ objectFields.push(ts.factory.createPropertyAssignment("default", this.createLiteralNode(defaultValue)));
948
+ }
939
949
  }
940
950
  }
941
951
  if (hasAttribute(field, "@computed")) {
@@ -976,34 +986,39 @@ var TsSchemaGenerator = class {
976
986
  throw new Error("Unsupported URL type");
977
987
  }
978
988
  }
979
- getMappedDefault(field) {
989
+ getFieldMappedDefault(field) {
980
990
  const defaultAttr = getAttribute(field, "@default");
981
991
  if (!defaultAttr) {
982
992
  return void 0;
983
993
  }
984
994
  const defaultValue = defaultAttr.args[0]?.value;
985
995
  invariant(defaultValue, "Expected a default value");
986
- if (isLiteralExpr3(defaultValue)) {
987
- const lit = defaultValue.value;
988
- return field.type.type === "Boolean" ? lit : [
996
+ return this.getMappedValue(defaultValue, field.type);
997
+ }
998
+ getMappedValue(expr, fieldType) {
999
+ if (isLiteralExpr3(expr)) {
1000
+ const lit = expr.value;
1001
+ return fieldType.type === "Boolean" ? lit : [
989
1002
  "Int",
990
1003
  "Float",
991
1004
  "Decimal",
992
1005
  "BigInt"
993
- ].includes(field.type.type) ? Number(lit) : lit;
994
- } else if (isReferenceExpr3(defaultValue) && isEnumField(defaultValue.target.ref)) {
995
- return defaultValue.target.ref.name;
996
- } else if (isInvocationExpr2(defaultValue)) {
1006
+ ].includes(fieldType.type) ? Number(lit) : lit;
1007
+ } else if (isArrayExpr3(expr)) {
1008
+ return expr.items.map((item) => this.getMappedValue(item, fieldType));
1009
+ } else if (isReferenceExpr3(expr) && isEnumField(expr.target.ref)) {
1010
+ return expr.target.ref.name;
1011
+ } else if (isInvocationExpr2(expr)) {
997
1012
  return {
998
- call: defaultValue.function.$refText,
999
- args: defaultValue.args.map((arg) => this.getLiteral(arg.value))
1013
+ call: expr.function.$refText,
1014
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
1000
1015
  };
1001
- } else if (this.isAuthMemberAccess(defaultValue)) {
1016
+ } else if (this.isAuthMemberAccess(expr)) {
1002
1017
  return {
1003
- authMember: this.getMemberAccessChain(defaultValue)
1018
+ authMember: this.getMemberAccessChain(expr)
1004
1019
  };
1005
1020
  } else {
1006
- throw new Error(`Unsupported default value type for field ${field.name}`);
1021
+ throw new Error(`Unsupported default value type for ${expr.$type}`);
1007
1022
  }
1008
1023
  }
1009
1024
  getMemberAccessChain(expr) {
@@ -1116,10 +1131,11 @@ var TsSchemaGenerator = class {
1116
1131
  for (const field of dm.fields) {
1117
1132
  if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1118
1133
  properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1119
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(field.type.type))
1134
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1120
1135
  ])));
1121
1136
  }
1122
1137
  }
1138
+ const seenKeys = /* @__PURE__ */ new Set();
1123
1139
  for (const attr of dm.attributes) {
1124
1140
  if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1125
1141
  const fieldNames = this.getReferenceNames(attr.args[0].value);
@@ -1129,13 +1145,18 @@ var TsSchemaGenerator = class {
1129
1145
  if (fieldNames.length === 1) {
1130
1146
  const fieldDef = dm.fields.find((f) => f.name === fieldNames[0]);
1131
1147
  properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1132
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1148
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1133
1149
  ])));
1134
1150
  } else {
1151
+ const key = fieldNames.join("_");
1152
+ if (seenKeys.has(key)) {
1153
+ continue;
1154
+ }
1155
+ seenKeys.add(key);
1135
1156
  properties.push(ts.factory.createPropertyAssignment(fieldNames.join("_"), ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1136
1157
  const fieldDef = dm.fields.find((f) => f.name === field);
1137
1158
  return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1138
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(fieldDef.type.type))
1159
+ ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1139
1160
  ]));
1140
1161
  }))));
1141
1162
  }
@@ -1143,6 +1164,10 @@ var TsSchemaGenerator = class {
1143
1164
  }
1144
1165
  return ts.factory.createObjectLiteralExpression(properties, true);
1145
1166
  }
1167
+ generateFieldTypeLiteral(field) {
1168
+ invariant(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1169
+ return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("unknown");
1170
+ }
1146
1171
  createEnumObject(e) {
1147
1172
  return ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createStringLiteral(field.name))), true);
1148
1173
  }
@@ -1197,6 +1222,8 @@ var TsSchemaGenerator = class {
1197
1222
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1198
1223
  //////////////////////////////////////////////////////////////////////////////////////////////
1199
1224
 
1225
+ /* eslint-disable */
1226
+
1200
1227
  `;
1201
1228
  ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1202
1229
  }