@zenstackhq/language 3.0.0-beta.3 → 3.0.0-beta.30

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/utils.cjs CHANGED
@@ -40,6 +40,7 @@ __export(utils_exports, {
40
40
  getAllLoadedAndReachableDataModelsAndTypeDefs: () => getAllLoadedAndReachableDataModelsAndTypeDefs,
41
41
  getAllLoadedDataModelsAndTypeDefs: () => getAllLoadedDataModelsAndTypeDefs,
42
42
  getAttribute: () => getAttribute,
43
+ getAttributeArg: () => getAttributeArg,
43
44
  getAttributeArgLiteral: () => getAttributeArgLiteral,
44
45
  getAuthDecl: () => getAuthDecl,
45
46
  getContainingDataModel: () => getContainingDataModel,
@@ -52,20 +53,20 @@ __export(utils_exports, {
52
53
  getModelIdFields: () => getModelIdFields,
53
54
  getModelUniqueFields: () => getModelUniqueFields,
54
55
  getObjectLiteral: () => getObjectLiteral,
56
+ getPluginDocuments: () => getPluginDocuments,
55
57
  getRecursiveBases: () => getRecursiveBases,
56
58
  getStringLiteral: () => getStringLiteral,
57
59
  getUniqueFields: () => getUniqueFields,
58
60
  hasAttribute: () => hasAttribute,
59
61
  isAuthInvocation: () => isAuthInvocation,
60
62
  isAuthOrAuthMemberAccess: () => isAuthOrAuthMemberAccess,
63
+ isBeforeInvocation: () => isBeforeInvocation,
61
64
  isCheckInvocation: () => isCheckInvocation,
62
65
  isCollectionPredicate: () => isCollectionPredicate,
63
66
  isDataFieldReference: () => isDataFieldReference,
64
67
  isDelegateModel: () => isDelegateModel,
65
68
  isEnumFieldReference: () => isEnumFieldReference,
66
69
  isFromStdlib: () => isFromStdlib,
67
- isFutureExpr: () => isFutureExpr,
68
- isFutureInvocation: () => isFutureInvocation,
69
70
  isMemberContainer: () => isMemberContainer,
70
71
  isRelationshipField: () => isRelationshipField,
71
72
  mapBuiltinTypeToExpressionType: () => mapBuiltinTypeToExpressionType,
@@ -76,13 +77,15 @@ __export(utils_exports, {
76
77
  typeAssignable: () => typeAssignable
77
78
  });
78
79
  module.exports = __toCommonJS(utils_exports);
79
- var import_common_helpers = require("@zenstackhq/common-helpers");
80
80
  var import_langium = require("langium");
81
81
  var import_node_fs = __toESM(require("fs"), 1);
82
- var import_path = __toESM(require("path"), 1);
82
+ var import_node_module = require("module");
83
+ var import_node_path = __toESM(require("path"), 1);
84
+ var import_node_url = require("url");
83
85
 
84
86
  // src/constants.ts
85
87
  var STD_LIB_MODULE_NAME = "stdlib.zmodel";
88
+ var PLUGIN_MODULE_NAME = "plugin.zmodel";
86
89
 
87
90
  // src/generated/ast.ts
88
91
  var langium = __toESM(require("langium"), 1);
@@ -175,6 +178,10 @@ function isObjectExpr(item) {
175
178
  }
176
179
  __name(isObjectExpr, "isObjectExpr");
177
180
  var Plugin = "Plugin";
181
+ function isPlugin(item) {
182
+ return reflection.isInstance(item, Plugin);
183
+ }
184
+ __name(isPlugin, "isPlugin");
178
185
  var PluginField = "PluginField";
179
186
  var Procedure = "Procedure";
180
187
  var ProcedureParam = "ProcedureParam";
@@ -1039,6 +1046,7 @@ var ZModelAstReflection = class extends langium.AbstractAstReflection {
1039
1046
  var reflection = new ZModelAstReflection();
1040
1047
 
1041
1048
  // src/utils.ts
1049
+ var import_meta = {};
1042
1050
  function hasAttribute(decl, name) {
1043
1051
  return !!getAttribute(decl, name);
1044
1052
  }
@@ -1118,10 +1126,6 @@ function isRelationshipField(field) {
1118
1126
  return isDataModel(field.type.reference?.ref);
1119
1127
  }
1120
1128
  __name(isRelationshipField, "isRelationshipField");
1121
- function isFutureExpr(node) {
1122
- return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
1123
- }
1124
- __name(isFutureExpr, "isFutureExpr");
1125
1129
  function isDelegateModel(node) {
1126
1130
  return isDataModel(node) && hasAttribute(node, "@@delegate");
1127
1131
  }
@@ -1139,8 +1143,14 @@ function getRecursiveBases(decl, includeDelegate = true, seen = /* @__PURE__ */
1139
1143
  return result;
1140
1144
  }
1141
1145
  seen.add(decl);
1142
- decl.mixins.forEach((mixin) => {
1143
- const baseDecl = mixin.ref;
1146
+ const bases = [
1147
+ ...decl.mixins,
1148
+ ...isDataModel(decl) && decl.baseModel ? [
1149
+ decl.baseModel
1150
+ ] : []
1151
+ ];
1152
+ bases.forEach((base) => {
1153
+ const baseDecl = decl.$container.declarations.find((d) => (isTypeDef(d) || isDataModel(d)) && d.name === base.$refText);
1144
1154
  if (baseDecl) {
1145
1155
  if (!includeDelegate && isDelegateModel(baseDecl)) {
1146
1156
  return;
@@ -1263,6 +1273,10 @@ function getArray(expr) {
1263
1273
  return isArrayExpr(expr) || isConfigArrayExpr(expr) ? expr.items : void 0;
1264
1274
  }
1265
1275
  __name(getArray, "getArray");
1276
+ function getAttributeArg(attr, name) {
1277
+ return attr.args.find((arg) => arg.$resolvedParam?.name === name)?.value;
1278
+ }
1279
+ __name(getAttributeArg, "getAttributeArg");
1266
1280
  function getAttributeArgLiteral(attr, name) {
1267
1281
  for (const arg of attr.args) {
1268
1282
  if (arg.$resolvedParam?.name === name) {
@@ -1299,7 +1313,7 @@ function getFieldReference(expr) {
1299
1313
  }
1300
1314
  __name(getFieldReference, "getFieldReference");
1301
1315
  function isCheckInvocation(node) {
1302
- return isInvocationExpr(node) && node.function.ref?.name === "check" && isFromStdlib(node.function.ref);
1316
+ return isInvocationExpr(node) && node.function.ref?.name === "check";
1303
1317
  }
1304
1318
  __name(isCheckInvocation, "isCheckInvocation");
1305
1319
  function resolveTransitiveImports(documents, model) {
@@ -1349,9 +1363,9 @@ function resolveImportUri(imp) {
1349
1363
  return void 0;
1350
1364
  }
1351
1365
  const doc = import_langium.AstUtils.getDocument(imp);
1352
- const dir = import_path.default.dirname(doc.uri.fsPath);
1366
+ const dir = import_node_path.default.dirname(doc.uri.fsPath);
1353
1367
  const importPath = imp.path.endsWith(".zmodel") ? imp.path : `${imp.path}.zmodel`;
1354
- return import_langium.URI.file(import_path.default.resolve(dir, importPath));
1368
+ return import_langium.URI.file(import_node_path.default.resolve(dir, importPath));
1355
1369
  }
1356
1370
  __name(resolveImportUri, "resolveImportUri");
1357
1371
  function getDataModelAndTypeDefs(model, includeIgnored = false) {
@@ -1369,17 +1383,17 @@ function getAllDeclarationsIncludingImports(documents, model) {
1369
1383
  }
1370
1384
  __name(getAllDeclarationsIncludingImports, "getAllDeclarationsIncludingImports");
1371
1385
  function getAuthDecl(decls) {
1372
- let authModel = decls.find((m) => hasAttribute(m, "@@auth"));
1386
+ let authModel = decls.find((d) => hasAttribute(d, "@@auth"));
1373
1387
  if (!authModel) {
1374
- authModel = decls.find((m) => m.name === "User");
1388
+ authModel = decls.find((d) => d.name === "User");
1375
1389
  }
1376
1390
  return authModel;
1377
1391
  }
1378
1392
  __name(getAuthDecl, "getAuthDecl");
1379
- function isFutureInvocation(node) {
1380
- return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
1393
+ function isBeforeInvocation(node) {
1394
+ return isInvocationExpr(node) && node.function.ref?.name === "before";
1381
1395
  }
1382
- __name(isFutureInvocation, "isFutureInvocation");
1396
+ __name(isBeforeInvocation, "isBeforeInvocation");
1383
1397
  function isCollectionPredicate(node) {
1384
1398
  return isBinaryExpr(node) && [
1385
1399
  "?",
@@ -1434,12 +1448,14 @@ function getAllFields(decl, includeIgnored = false, seen = /* @__PURE__ */ new S
1434
1448
  seen.add(decl);
1435
1449
  const fields = [];
1436
1450
  for (const mixin of decl.mixins) {
1437
- (0, import_common_helpers.invariant)(mixin.ref, `Mixin ${mixin.$refText} is not resolved`);
1438
- fields.push(...getAllFields(mixin.ref, includeIgnored, seen));
1451
+ if (mixin.ref) {
1452
+ fields.push(...getAllFields(mixin.ref, includeIgnored, seen));
1453
+ }
1439
1454
  }
1440
1455
  if (isDataModel(decl) && decl.baseModel) {
1441
- (0, import_common_helpers.invariant)(decl.baseModel.ref, `Base model ${decl.baseModel.$refText} is not resolved`);
1442
- fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));
1456
+ if (decl.baseModel.ref) {
1457
+ fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));
1458
+ }
1443
1459
  }
1444
1460
  fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, "@ignore")));
1445
1461
  return fields;
@@ -1452,17 +1468,29 @@ function getAllAttributes(decl, seen = /* @__PURE__ */ new Set()) {
1452
1468
  seen.add(decl);
1453
1469
  const attributes = [];
1454
1470
  for (const mixin of decl.mixins) {
1455
- (0, import_common_helpers.invariant)(mixin.ref, `Mixin ${mixin.$refText} is not resolved`);
1456
- attributes.push(...getAllAttributes(mixin.ref, seen));
1471
+ if (mixin.ref) {
1472
+ attributes.push(...getAllAttributes(mixin.ref, seen));
1473
+ }
1457
1474
  }
1458
1475
  if (isDataModel(decl) && decl.baseModel) {
1459
- (0, import_common_helpers.invariant)(decl.baseModel.ref, `Base model ${decl.baseModel.$refText} is not resolved`);
1460
- attributes.push(...getAllAttributes(decl.baseModel.ref, seen));
1476
+ if (decl.baseModel.ref) {
1477
+ const attrs = getAllAttributes(decl.baseModel.ref, seen).filter((attr) => !isNonInheritableAttribute(attr));
1478
+ attributes.push(...attrs);
1479
+ }
1461
1480
  }
1462
1481
  attributes.push(...decl.attributes);
1463
1482
  return attributes;
1464
1483
  }
1465
1484
  __name(getAllAttributes, "getAllAttributes");
1485
+ function isNonInheritableAttribute(attr) {
1486
+ const attrName = attr.decl.ref?.name ?? attr.decl.$refText;
1487
+ return [
1488
+ "@@map",
1489
+ "@@unique",
1490
+ "@@index"
1491
+ ].includes(attrName);
1492
+ }
1493
+ __name(isNonInheritableAttribute, "isNonInheritableAttribute");
1466
1494
  function getDocument(node) {
1467
1495
  const rootNode = findRootNode(node);
1468
1496
  const result = rootNode.$document;
@@ -1472,6 +1500,71 @@ function getDocument(node) {
1472
1500
  return result;
1473
1501
  }
1474
1502
  __name(getDocument, "getDocument");
1503
+ function getPluginDocuments(model, schemaPath) {
1504
+ const result = [];
1505
+ for (const decl of model.declarations.filter(isPlugin)) {
1506
+ const providerField = decl.fields.find((f) => f.name === "provider");
1507
+ if (!providerField) {
1508
+ continue;
1509
+ }
1510
+ const provider = getLiteral(providerField.value);
1511
+ if (!provider) {
1512
+ continue;
1513
+ }
1514
+ let pluginModelFile;
1515
+ let providerPath = import_node_path.default.resolve(import_node_path.default.dirname(schemaPath), provider);
1516
+ if (import_node_fs.default.existsSync(providerPath)) {
1517
+ if (import_node_fs.default.statSync(providerPath).isDirectory()) {
1518
+ providerPath = import_node_path.default.join(providerPath, "index.js");
1519
+ }
1520
+ pluginModelFile = import_node_path.default.resolve(import_node_path.default.dirname(providerPath), PLUGIN_MODULE_NAME);
1521
+ if (!import_node_fs.default.existsSync(pluginModelFile)) {
1522
+ pluginModelFile = findUp([
1523
+ PLUGIN_MODULE_NAME
1524
+ ], import_node_path.default.dirname(providerPath));
1525
+ }
1526
+ }
1527
+ if (!pluginModelFile) {
1528
+ if (typeof import_meta.resolve === "function") {
1529
+ try {
1530
+ const resolvedUrl = import_meta.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);
1531
+ pluginModelFile = (0, import_node_url.fileURLToPath)(resolvedUrl);
1532
+ } catch {
1533
+ }
1534
+ }
1535
+ }
1536
+ if (!pluginModelFile) {
1537
+ try {
1538
+ const require2 = (0, import_node_module.createRequire)((0, import_node_url.pathToFileURL)(schemaPath));
1539
+ pluginModelFile = require2.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);
1540
+ } catch {
1541
+ }
1542
+ }
1543
+ if (pluginModelFile && import_node_fs.default.existsSync(pluginModelFile)) {
1544
+ result.push(pluginModelFile);
1545
+ }
1546
+ }
1547
+ return result;
1548
+ }
1549
+ __name(getPluginDocuments, "getPluginDocuments");
1550
+ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
1551
+ if (!names.some((name) => !!name)) {
1552
+ return void 0;
1553
+ }
1554
+ const target = names.find((name) => import_node_fs.default.existsSync(import_node_path.default.join(cwd, name)));
1555
+ if (multiple === false && target) {
1556
+ return import_node_path.default.join(cwd, target);
1557
+ }
1558
+ if (target) {
1559
+ result.push(import_node_path.default.join(cwd, target));
1560
+ }
1561
+ const up = import_node_path.default.resolve(cwd, "..");
1562
+ if (up === cwd) {
1563
+ return multiple && result.length > 0 ? result : void 0;
1564
+ }
1565
+ return findUp(names, up, multiple, result);
1566
+ }
1567
+ __name(findUp, "findUp");
1475
1568
  function findRootNode(node) {
1476
1569
  while (node.$container) {
1477
1570
  node = node.$container;
@@ -1490,6 +1583,7 @@ __name(findRootNode, "findRootNode");
1490
1583
  getAllLoadedAndReachableDataModelsAndTypeDefs,
1491
1584
  getAllLoadedDataModelsAndTypeDefs,
1492
1585
  getAttribute,
1586
+ getAttributeArg,
1493
1587
  getAttributeArgLiteral,
1494
1588
  getAuthDecl,
1495
1589
  getContainingDataModel,
@@ -1502,20 +1596,20 @@ __name(findRootNode, "findRootNode");
1502
1596
  getModelIdFields,
1503
1597
  getModelUniqueFields,
1504
1598
  getObjectLiteral,
1599
+ getPluginDocuments,
1505
1600
  getRecursiveBases,
1506
1601
  getStringLiteral,
1507
1602
  getUniqueFields,
1508
1603
  hasAttribute,
1509
1604
  isAuthInvocation,
1510
1605
  isAuthOrAuthMemberAccess,
1606
+ isBeforeInvocation,
1511
1607
  isCheckInvocation,
1512
1608
  isCollectionPredicate,
1513
1609
  isDataFieldReference,
1514
1610
  isDelegateModel,
1515
1611
  isEnumFieldReference,
1516
1612
  isFromStdlib,
1517
- isFutureExpr,
1518
- isFutureInvocation,
1519
1613
  isMemberContainer,
1520
1614
  isRelationshipField,
1521
1615
  mapBuiltinTypeToExpressionType,