@via-profit/ability 2.0.0-rc.3 → 2.0.0-rc.4

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.
@@ -236,25 +236,24 @@ class AbilityParser {
236
236
  policies.forEach(policy => {
237
237
  policy.ruleSet.forEach(ruleSet => {
238
238
  ruleSet.rules.forEach(rule => {
239
- const [leftFieldPath, condition, rightFiledPath] = rule.matches;
240
239
  let value = 'any';
241
240
  switch (true) {
242
- case condition.isEqual(AbilityCondition_1.default.NOT_EQUAL):
243
- case condition.isEqual(AbilityCondition_1.default.EQUAL):
244
- value = typeof rightFiledPath;
241
+ case rule.condition.isEqual(AbilityCondition_1.default.NOT_EQUAL):
242
+ case rule.condition.isEqual(AbilityCondition_1.default.EQUAL):
243
+ value = typeof rule.staticValueOrPathName;
245
244
  break;
246
- case condition.isEqual(AbilityCondition_1.default.IN):
247
- case condition.isEqual(AbilityCondition_1.default.NOT_IN):
248
- value = `${typeof rightFiledPath}[]`;
245
+ case rule.condition.isEqual(AbilityCondition_1.default.IN):
246
+ case rule.condition.isEqual(AbilityCondition_1.default.NOT_IN):
247
+ value = `${typeof rule.staticValueOrPathName}[]`;
249
248
  break;
250
- case condition.isEqual(AbilityCondition_1.default.MORE_OR_EQUAL):
251
- case condition.isEqual(AbilityCondition_1.default.MORE_THAN):
252
- case condition.isEqual(AbilityCondition_1.default.LESS_OR_EQUAL):
253
- case condition.isEqual(AbilityCondition_1.default.LESS_THAN):
249
+ case rule.condition.isEqual(AbilityCondition_1.default.MORE_OR_EQUAL):
250
+ case rule.condition.isEqual(AbilityCondition_1.default.MORE_THAN):
251
+ case rule.condition.isEqual(AbilityCondition_1.default.LESS_OR_EQUAL):
252
+ case rule.condition.isEqual(AbilityCondition_1.default.LESS_THAN):
254
253
  value = 'number';
255
254
  break;
256
255
  }
257
- AbilityParser.setValueDotValue(record, leftFieldPath, value);
256
+ AbilityParser.setValueDotValue(record, rule.subjectPathName, value);
258
257
  });
259
258
  });
260
259
  });
@@ -280,7 +279,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
280
279
  };
281
280
  Object.defineProperty(exports, "__esModule", ({ value: true }));
282
281
  exports.AbilityPolicy = void 0;
283
- const AbilityRule_1 = __importDefault(__webpack_require__(/*! ./AbilityRule */ "./src/AbilityRule.ts"));
284
282
  const AbilityRuleSet_1 = __importDefault(__webpack_require__(/*! ./AbilityRuleSet */ "./src/AbilityRuleSet.ts"));
285
283
  const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */ "./src/AbilityMatch.ts"));
286
284
  const AbilityCompare_1 = __importDefault(__webpack_require__(/*! ./AbilityCompare */ "./src/AbilityCompare.ts"));
@@ -317,8 +315,8 @@ class AbilityPolicy {
317
315
  action;
318
316
  constructor(params) {
319
317
  const { name, id, action, effect } = params;
320
- this.name = name || Symbol('name');
321
- this.id = id || Symbol('id');
318
+ this.name = name;
319
+ this.id = id;
322
320
  this.action = action;
323
321
  this.effect = effect;
324
322
  }
@@ -330,16 +328,6 @@ class AbilityPolicy {
330
328
  this.ruleSet.push(ruleSet);
331
329
  return this;
332
330
  }
333
- /**
334
- * Add rule to the policy
335
- * @param rule - The rule to add
336
- */
337
- addRule(rule) {
338
- this.addRuleSet(new AbilityRuleSet_1.default({
339
- name: rule.name,
340
- }).addRule(rule, AbilityCompare_1.default.AND));
341
- return this;
342
- }
343
331
  /**
344
332
  * Check if the policy is matched
345
333
  * @param resource - The resource to check
@@ -373,7 +361,7 @@ class AbilityPolicy {
373
361
  */
374
362
  static parse(configOrJson) {
375
363
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
376
- ['id', 'string', false],
364
+ ['id', 'string', true],
377
365
  ['name', 'string', true],
378
366
  ['action', 'string', true],
379
367
  ['effect', 'number', true],
@@ -389,15 +377,8 @@ class AbilityPolicy {
389
377
  effect: new AbilityPolicyEffect_1.default(effect),
390
378
  });
391
379
  policy.compareMethod = new AbilityCompare_1.default(compareMethod);
392
- ruleSet.forEach(ruleOrRuleSet => {
393
- // is ruleset
394
- if ('rules' in ruleOrRuleSet) {
395
- policy.addRuleSet(AbilityRuleSet_1.default.parse(ruleOrRuleSet));
396
- }
397
- // is simple rule
398
- if (!('rules' in ruleOrRuleSet)) {
399
- policy.addRule(AbilityRule_1.default.parse(ruleOrRuleSet));
400
- }
380
+ ruleSet.forEach(ruleSetConfig => {
381
+ policy.addRuleSet(AbilityRuleSet_1.default.parse(ruleSetConfig));
401
382
  });
402
383
  return policy;
403
384
  }
@@ -479,7 +460,7 @@ class AbilityResolver {
479
460
  const resolver = this.resolve(action, resource);
480
461
  if (resolver) {
481
462
  if (resolver.isDeny()) {
482
- throw new AbilityError_1.PermissionError(['Permission denied', resolver.getPolicy()?.name?.toString()].join('. '));
463
+ throw new AbilityError_1.PermissionError(resolver.getPolicy()?.name?.toString() || 'Unknown permission error');
483
464
  }
484
465
  }
485
466
  }
@@ -552,41 +533,52 @@ const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */
552
533
  const AbilityCondition_1 = __importDefault(__webpack_require__(/*! ./AbilityCondition */ "./src/AbilityCondition.ts"));
553
534
  const AbilityParser_1 = __importDefault(__webpack_require__(/*! ./AbilityParser */ "./src/AbilityParser.ts"));
554
535
  class AbilityRule {
555
- matches;
536
+ /**
537
+ * Subject key path like a 'user.name'
538
+ */
539
+ subjectPathName;
540
+ /**
541
+ * Resource key path like a 'user.name' or value
542
+ */
543
+ staticValueOrPathName;
544
+ condition;
556
545
  name;
546
+ id;
557
547
  state = AbilityMatch_1.default.PENDING;
558
548
  constructor(params) {
559
- const { name, matches } = params;
560
- this.name = name || Symbol('name');
561
- this.matches = matches;
549
+ const { id, name, subjectPathName, staticValueOrPathName, condition } = params;
550
+ this.id = id;
551
+ this.name = name;
552
+ this.subjectPathName = subjectPathName;
553
+ this.staticValueOrPathName = staticValueOrPathName;
554
+ this.condition = new AbilityCondition_1.default(condition);
562
555
  }
563
556
  /**
564
557
  * Check if the rule is matched
565
558
  * @param resource - The resource to check
566
559
  */
567
560
  check(resource) {
568
- const [_subjectPathName, condition, _staticValueOrPathName] = this.matches;
569
561
  let is = false;
570
562
  const [valueS, valueO] = this.extractValues(resource);
571
- if (AbilityCondition_1.default.LESS_THAN.isEqual(condition)) {
563
+ if (AbilityCondition_1.default.LESS_THAN.isEqual(this.condition)) {
572
564
  is = Number(valueS) < Number(valueO);
573
565
  }
574
- if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(condition)) {
566
+ if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(this.condition)) {
575
567
  is = Number(valueS) <= Number(valueO);
576
568
  }
577
- if (AbilityCondition_1.default.MORE_THAN.isEqual(condition)) {
569
+ if (AbilityCondition_1.default.MORE_THAN.isEqual(this.condition)) {
578
570
  is = Number(valueS) > Number(valueO);
579
571
  }
580
- if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(condition)) {
572
+ if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(this.condition)) {
581
573
  is = Number(valueS) >= Number(valueO);
582
574
  }
583
- if (AbilityCondition_1.default.EQUAL.isEqual(condition)) {
575
+ if (AbilityCondition_1.default.EQUAL.isEqual(this.condition)) {
584
576
  is = valueS === valueO;
585
577
  }
586
- if (AbilityCondition_1.default.NOT_EQUAL.isEqual(condition)) {
578
+ if (AbilityCondition_1.default.NOT_EQUAL.isEqual(this.condition)) {
587
579
  is = valueS !== valueO;
588
580
  }
589
- if (AbilityCondition_1.default.IN.isEqual(condition)) {
581
+ if (AbilityCondition_1.default.IN.isEqual(this.condition)) {
590
582
  // [<some>] and [<some>]
591
583
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
592
584
  is = valueS.some(v => valueO.find(v1 => v1 === v));
@@ -600,7 +592,7 @@ class AbilityRule {
600
592
  is = valueS.includes(valueO);
601
593
  }
602
594
  }
603
- if (AbilityCondition_1.default.NOT_IN.isEqual(condition)) {
595
+ if (AbilityCondition_1.default.NOT_IN.isEqual(this.condition)) {
604
596
  // [<some>] and [<some>]
605
597
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
606
598
  is = !valueS.some(v => valueO.find(v1 => v1 === v));
@@ -622,7 +614,6 @@ class AbilityRule {
622
614
  * @param resource - The resource to extract values from
623
615
  */
624
616
  extractValues(resource) {
625
- const [subjectPathName, _condition, staticValueOrPathName] = this.matches;
626
617
  let leftSideValue;
627
618
  let rightSideValue;
628
619
  if (resource === null || typeof resource === 'undefined') {
@@ -631,14 +622,14 @@ class AbilityRule {
631
622
  const isPath = (str) => {
632
623
  return typeof str === 'string' && str.match(/\./g) !== null;
633
624
  };
634
- if (isPath(subjectPathName)) {
635
- leftSideValue = this.getDotNotationValue(resource, subjectPathName);
625
+ if (isPath(this.subjectPathName)) {
626
+ leftSideValue = this.getDotNotationValue(resource, this.subjectPathName);
636
627
  }
637
- if (isPath(staticValueOrPathName)) {
638
- rightSideValue = this.getDotNotationValue(resource, staticValueOrPathName);
628
+ if (isPath(this.staticValueOrPathName)) {
629
+ rightSideValue = this.getDotNotationValue(resource, this.staticValueOrPathName);
639
630
  }
640
631
  else {
641
- rightSideValue = staticValueOrPathName;
632
+ rightSideValue = this.staticValueOrPathName;
642
633
  }
643
634
  return [leftSideValue, rightSideValue];
644
635
  }
@@ -672,25 +663,29 @@ class AbilityRule {
672
663
  }
673
664
  static parse(configOrJson) {
674
665
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
675
- ['id', 'string', false],
666
+ ['id', 'string', true],
676
667
  ['name', 'string', true],
677
- ['matches', 'array', true],
668
+ ['subjectPathName', 'string', true],
678
669
  ]);
679
- const { name, matches } = config;
680
- const [leftField, condition, rightField] = matches;
670
+ const { id, name, subjectPathName, staticValueOrPathName, condition } = config;
681
671
  return new AbilityRule({
672
+ id,
682
673
  name,
683
- matches: [leftField, new AbilityCondition_1.default(condition), rightField],
674
+ subjectPathName,
675
+ staticValueOrPathName,
676
+ condition,
684
677
  });
685
678
  }
686
679
  /**
687
680
  * Export the rule to config object
688
681
  */
689
682
  export() {
690
- const [leftField, condition, rightField] = this.matches;
691
683
  return {
684
+ id: this.id,
692
685
  name: this.name,
693
- matches: [leftField, condition.code, rightField],
686
+ subjectPathName: this.subjectPathName,
687
+ staticValueOrPathName: this.staticValueOrPathName,
688
+ condition: this.condition.code,
694
689
  };
695
690
  }
696
691
  }
@@ -738,9 +733,10 @@ class AbilityRuleSet {
738
733
  */
739
734
  id;
740
735
  constructor(params) {
741
- const { name, id } = params || {};
742
- this.name = name || Symbol('name');
743
- this.id = id || Symbol('id');
736
+ const { name, id, compareMethod } = params;
737
+ this.name = name;
738
+ this.id = id;
739
+ this.compareMethod = new AbilityCompare_1.default(compareMethod);
744
740
  }
745
741
  addRule(rule, compareMethod) {
746
742
  this.rules.push(rule);
@@ -776,17 +772,17 @@ class AbilityRuleSet {
776
772
  */
777
773
  static parse(configOrJson) {
778
774
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
779
- ['id', 'string', false],
775
+ ['id', 'string', true],
780
776
  ['name', 'string', true],
781
777
  ['compareMethod', 'number', true],
782
778
  ['rules', 'array', true],
783
779
  ]);
784
780
  const { id, name, rules, compareMethod } = config;
785
781
  const ruleSet = new AbilityRuleSet({
782
+ compareMethod,
786
783
  name,
787
784
  id,
788
785
  });
789
- ruleSet.compareMethod = new AbilityCompare_1.default(compareMethod);
790
786
  // Adding rules if exists
791
787
  if (rules && rules.length > 0) {
792
788
  const abilityRules = rules.map(ruleConfig => AbilityRule_1.default.parse(ruleConfig));
@@ -867,7 +863,7 @@ module.exports = require("node:http");
867
863
  \***************************/
868
864
  /***/ ((module) => {
869
865
 
870
- module.exports = /*#__PURE__*/JSON.parse('[{"name":"Просмотр чужого логина разрешен только владельцу аккаунта и администраторам","action":"account.read","effect":0,"compareMethod":0,"ruleSet":[{"name":"Не владелец аккаунта и не администратор","compareMethod":1,"rules":[{"name":"Владелец аккаунта","matches":["account.id","<>","resource.id"]},{"name":"Администратор","matches":["account.roles","not in","administrator"]}]}]},{"name":"Unauthorized. Access token expected","action":"access.auth","effect":0,"compareMethod":1,"ruleSet":[{"name":"Токен - AccessToken","matches":["token.type","=","access"]},{"name":"Токен не пустой","matches":["token.id","<>","ACCESS_TOKEN_EMPTY_ID"]}]},{"id":"1121","name":"Менеджеры не могут редактировать заказы, созданные более 3-х дней назад, а так же завершенные и отменённые заявки","action":"order.update","effect":0,"compareMethod":1,"ruleSet":[{"name":"Менеджеры","compareMethod":0,"rules":[{"name":"Отдел - Менеджеры","matches":["user.department","=","managers"]},{"name":"Роль - Менеджер","matches":["user.roles","in","manager"]}]},{"name":"Заказы более 3-х дней, а так же завершённые и отменённые заказы","compareMethod":0,"rules":[{"name":"заказ создан более 3-х дней назад","matches":["order.createdDaysAgo",">",3]},{"name":"заказ завершён","matches":["order.status","=","COMPLETED"]},{"name":"заказ отменён","matches":["order.status","=","CANCELLED"]}]}]},{"name":"Менеджеры не могут создавать заказы","action":"order.create","effect":0,"compareMethod":0,"ruleSet":[{"name":"Менеджеры","compareMethod":0,"rules":[{"name":"Отдел - Менеджеры","matches":["user.department","=","managers"]},{"name":"Роль - Менеджер","matches":["user.roles","in","manager"]}]}]},{"name":"Уборщицы не могут видеть стоимость заказа","action":"order.read","effect":0,"compareMethod":0,"ruleSet":[{"name":"все из отдела уборщиц","matches":["user.department","in","cleaner"]}]}]');
866
+ module.exports = /*#__PURE__*/JSON.parse('[{"id":"d7c491d2-b937-4f75-b26a-e989fb12f051","name":"Просмотр чужого логина разрешен только владельцу аккаунта и администраторам","action":"account.read","effect":0,"compareMethod":0,"ruleSet":[{"id":"3f3e2b42-55ae-4bf9-8438-5dfa7fd4b93e","name":"Не владелец аккаунта и не администратор","compareMethod":1,"rules":[{"id":"46d9aa89-e507-455d-9e8c-7544f75bbb8b","name":"Владелец аккаунта","subjectPathName":"account.id","staticValueOrPathName":"resource.id","condition":"<>"},{"id":"8ab0075a-1670-4d44-b643-16d55ec96831","name":"Администратор","subjectPathName":"account.roles","staticValueOrPathName":"administrator","condition":"not in"}]}]}]');
871
867
 
872
868
  /***/ })
873
869
 
@@ -1 +1 @@
1
- {"version":3,"file":"playground.js","mappings":"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","sources":["webpack://@via-profit/ability/./src/AbilityCode.ts","webpack://@via-profit/ability/./src/AbilityCompare.ts","webpack://@via-profit/ability/./src/AbilityCondition.ts","webpack://@via-profit/ability/./src/AbilityError.ts","webpack://@via-profit/ability/./src/AbilityMatch.ts","webpack://@via-profit/ability/./src/AbilityParser.ts","webpack://@via-profit/ability/./src/AbilityPolicy.ts","webpack://@via-profit/ability/./src/AbilityPolicyEffect.ts","webpack://@via-profit/ability/./src/AbilityResolver.ts","webpack://@via-profit/ability/./src/AbilityRule.ts","webpack://@via-profit/ability/./src/AbilityRuleSet.ts","webpack://@via-profit/ability/./src/playground.ts","webpack://@via-profit/ability/external node-commonjs \"node:http\"","webpack://@via-profit/ability/webpack/bootstrap","webpack://@via-profit/ability/webpack/before-startup","webpack://@via-profit/ability/webpack/startup","webpack://@via-profit/ability/webpack/after-startup"],"sourcesContent":["export class AbilityCode<T extends string | number | undefined = number> {\n public code: T;\n\n constructor(code: T) {\n this.code = code;\n }\n\n public isEqual(compareWith: AbilityCode<T> | null): boolean {\n return compareWith !== null && this.code === compareWith.code;\n }\n\n public isNotEqual(compareWith: AbilityCode<T> | null): boolean {\n return !this.isEqual(compareWith);\n }\n}\n\nexport default AbilityCode;","import AbilityCode from './AbilityCode';\n\nexport class AbilityCompare extends AbilityCode {\n public static OR = new AbilityCompare(0);\n public static AND = new AbilityCompare(1);\n}\n\nexport default AbilityCompare;\n","import AbilityCode from './AbilityCode';\n\nexport class AbilityCondition extends AbilityCode<string> {\n public static EQUAL = new AbilityCondition('=');\n public static NOT_EQUAL = new AbilityCondition('<>');\n public static MORE_THAN = new AbilityCondition('>');\n public static LESS_THAN = new AbilityCondition('<');\n public static LESS_OR_EQUAL = new AbilityCondition('<=');\n public static MORE_OR_EQUAL = new AbilityCondition('>=');\n public static IN = new AbilityCondition('in');\n public static NOT_IN = new AbilityCondition('not in');\n}\n\nexport default AbilityCondition;\n","export class AbilityError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class AbilityParserError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class PermissionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n","import AbilityCode from './AbilityCode';\n\nexport class AbilityMatch extends AbilityCode{\n public static PENDING = new AbilityMatch(2);\n public static MATCH = new AbilityMatch(1);\n public static MISMATCH = new AbilityMatch(0);\n}\n\nexport default AbilityMatch;","import { AbilityParserError } from './AbilityError';\nimport AbilityPolicy from './AbilityPolicy';\nimport AbilityCondition from './AbilityCondition';\n\ntype FieldValidateConfig = [string, 'string' | 'number' | 'array', boolean][];\n\n\nexport class AbilityParser {\n\n /**\n * Validates the configuration object based on the provided field validation configurations.\n * @param config - The configuration object to validate.\n * @param fields - An array of field validation configurations.\n * @throws {AbilityParserError} If a required field is missing or if a field has an incorrect type.\n */\n public static validateConfig(config: Record<string, any>, fields: FieldValidateConfig): void | never {\n fields.forEach(([field, type, isRequired]) => {\n const value = config[field as keyof typeof config];\n if (isRequired) {\n if (typeof value === 'undefined') {\n throw new AbilityParserError(`Missing required field [${field}]`);\n }\n }\n\n switch (type) {\n case 'array':\n if (typeof value !== 'object' || !Array.isArray(value)) {\n throw new AbilityParserError(`Field [${field}] must be an type of [${type}], bit got [${typeof value}]`);\n }\n break;\n\n default:\n if (typeof value !== type && typeof value !== 'undefined') {\n throw new AbilityParserError(`Field [${field}] must be a type of [${type}], bit got [${typeof value}]`);\n }\n break;\n }\n\n\n });\n }\n\n /**\n * Prepares and validates the configuration object or JSON string.\n * @param configOrJson - The configuration object or JSON string to validate.\n * @param fields - An array of field validation configurations.\n * @returns The validated configuration object.\n */\n public static prepareAndValidateConfig<T>(configOrJson: string | unknown, fields: FieldValidateConfig): T {\n const config = typeof configOrJson === 'string'\n ? (JSON.parse(configOrJson))\n : configOrJson;\n\n AbilityParser.validateConfig(config, fields);\n\n return config;\n }\n\n /*\n *\n * readonly ['order.update']: {\n * readonly user: {\n * readonly roles: readonly string[];\n * readonly department: string;\n * };\n * readonly order: {\n * readonly estimatedArrivalAt: number;\n * readonly status: string;\n * }\n * }\n *\n * */\n\n /**\n * Sets a value in a nested object structure based on a dot/bracket notation path.\n * @param object - The target object to modify.\n * @param path - The path to the property in dot/bracket notation.\n * @param value - The value to set at the specified path.\n */\n public static setValueDotValue(\n object: Record<string, any>,\n path: string,\n value: string | number | boolean\n ): void {\n const way = path.replace(/\\[/g, '.').replace(/\\]/g, '').split('.');\n const last = way.pop();\n\n if (!last) {\n throw new AbilityParserError(`Invalid path provided on a [${path}]`);\n }\n\n way.reduce((o, k, i, kk) => {\n if (!o[k]) {\n o[k] = isFinite(Number(kk[i + 1])) ? [] : {};\n }\n return o[k];\n }, object)[last] = value;\n }\n\n /**\n * Generates TypeScript type definitions based on the provided policies.\n * @param policies - An array of AbilityPolicy instances.\n * @param outPath - The output path for the generated type definitions.\n * @returns A record containing the generated type definitions.\n */\n public static generateTypeDefs(policies: readonly AbilityPolicy[], outPath: string) {\n const record: Record<string, any> = {};\n\n policies.forEach(policy => {\n policy.ruleSet.forEach(ruleSet => {\n ruleSet.rules.forEach(rule => {\n const [leftFieldPath, condition, rightFiledPath] = rule.matches;\n let value: string = 'any';\n\n switch (true) {\n case condition.isEqual(AbilityCondition.NOT_EQUAL):\n case condition.isEqual(AbilityCondition.EQUAL):\n value = typeof rightFiledPath;\n break;\n\n case condition.isEqual(AbilityCondition.IN):\n case condition.isEqual(AbilityCondition.NOT_IN):\n value = `${typeof rightFiledPath}[]`;\n break;\n\n case condition.isEqual(AbilityCondition.MORE_OR_EQUAL):\n case condition.isEqual(AbilityCondition.MORE_THAN):\n case condition.isEqual(AbilityCondition.LESS_OR_EQUAL):\n case condition.isEqual(AbilityCondition.LESS_THAN):\n value = 'number';\n break;\n }\n AbilityParser.setValueDotValue(record, leftFieldPath, value);\n });\n });\n });\n\n console.log(JSON.stringify(record));\n\n return record;\n }\n\n}\n\nexport default AbilityParser;","import AbilityRule, { AbilityRuleConfig } from './AbilityRule';\nimport AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';\nimport AbilityMatch from './AbilityMatch';\nimport AbilityCompare from './AbilityCompare';\nimport AbilityPolicyEffect from './AbilityPolicyEffect';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityPolicyConfig = {\n readonly action: string;\n readonly effect: number;\n readonly compareMethod: number;\n readonly ruleSet: (AbilityRuleConfig | AbilityRuleSetConfig)[];\n readonly id?: string;\n readonly name?: string;\n};\n\nexport class AbilityPolicy<Resources extends object = object> {\n public matchState: AbilityMatch = AbilityMatch.PENDING;\n /**\n * List of rules\n */\n public ruleSet: AbilityRuleSet[] = [];\n\n /**\n * Policy effect\n */\n public effect: AbilityPolicyEffect;\n\n /**\n * Rules compare method.\\\n * For the «and» method the rule will be permitted if all\\\n * rules will be returns «permit» status and for the «or» - if\\\n * one of the rules returns as «permit»\n */\n public compareMethod: AbilityCompare = AbilityCompare.AND;\n\n /**\n * Policy name\n */\n public name: string | symbol;\n\n /**\n * Policy ID\n */\n public id: string | symbol;\n\n /**\n * Soon\n */\n public action: string;\n\n public constructor(params: {\n action: string;\n effect: AbilityPolicyEffect;\n name?: string | symbol;\n id?: string | symbol;\n }) {\n const { name, id, action, effect } = params;\n this.name = name || Symbol('name');\n this.id = id || Symbol('id');\n this.action = action;\n this.effect = effect;\n }\n\n\n /**\n * Add rule set to the policy\n * @param ruleSet - The rule set to add\n */\n public addRuleSet(ruleSet: AbilityRuleSet): this {\n this.ruleSet.push(ruleSet);\n\n return this;\n }\n\n /**\n * Add rule to the policy\n * @param rule - The rule to add\n */\n public addRule(rule: AbilityRule<Resources>): this {\n this.addRuleSet(\n new AbilityRuleSet({\n name: rule.name,\n }).addRule(rule, AbilityCompare.AND),\n );\n\n return this;\n }\n\n\n /**\n * Check if the policy is matched\n * @param resource - The resource to check\n */\n public check(resource: Resources): AbilityMatch {\n this.matchState = AbilityMatch.MISMATCH;\n\n /**\n * If policy contain a rules\n */\n if (this.ruleSet.length) {\n const ruleCheckStates: AbilityMatch[] = [];\n this.ruleSet.forEach(rule => {\n const ruleCheckState = rule.check(resource);\n ruleCheckStates.push(ruleCheckState);\n });\n\n if (AbilityCompare.AND.isEqual(this.compareMethod)) {\n if (ruleCheckStates.every(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.matchState = AbilityMatch.MATCH;\n }\n }\n\n if (AbilityCompare.OR.isEqual(this.compareMethod)) {\n if (ruleCheckStates.some(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.matchState = AbilityMatch.MATCH;\n }\n }\n }\n\n return this.matchState;\n }\n\n\n\n\n /**\n * Parse the config JSON format to Policy class instance\n */\n public static parse<Resources extends object = object>(\n configOrJson: AbilityPolicyConfig | string,\n ): AbilityPolicy<Resources> {\n\n\n const config = AbilityParser.prepareAndValidateConfig<AbilityPolicyConfig>(configOrJson, [\n ['id', 'string', false],\n ['name', 'string', true],\n ['action', 'string', true],\n ['effect', 'number', true],\n ['compareMethod', 'number', true],\n ['ruleSet', 'array', true],\n ]);\n\n const { id, name, ruleSet, compareMethod, action, effect } = config;\n\n // Create the empty policy\n const policy = new AbilityPolicy<Resources>({\n name,\n id,\n action,\n effect: new AbilityPolicyEffect(effect),\n });\n\n policy.compareMethod = new AbilityCompare(compareMethod);\n\n ruleSet.forEach(ruleOrRuleSet => {\n // is ruleset\n if ('rules' in ruleOrRuleSet) {\n policy.addRuleSet(AbilityRuleSet.parse(ruleOrRuleSet));\n }\n\n // is simple rule\n if (!('rules' in ruleOrRuleSet)) {\n policy.addRule(AbilityRule.parse(ruleOrRuleSet));\n }\n });\n\n return policy;\n }\n\n public export(): AbilityPolicyConfig {\n return {\n id: this.id.toString(),\n name: this.name.toString(),\n compareMethod: this.compareMethod.code,\n ruleSet: this.ruleSet.map(rule => rule.export()),\n action: this.action,\n effect: this.effect.code,\n };\n }\n}\n\nexport default AbilityPolicy;\n","import AbilityCode from './AbilityCode';\n\nexport class AbilityPolicyEffect extends AbilityCode{\n public static DENY = new AbilityPolicyEffect(0);\n public static PERMIT = new AbilityPolicyEffect(1);\n}\n\nexport default AbilityPolicyEffect;","import AbilityPolicy from './AbilityPolicy';\nimport AbilityPolicyEffect from './AbilityPolicyEffect';\nimport AbilityMatch from './AbilityMatch';\nimport { PermissionError } from './AbilityError';\n\nexport class AbilityResolver<Resources extends object = object> {\n policies: readonly AbilityPolicy<Resources>[];\n\n public constructor(policies: readonly AbilityPolicy<Resources>[]) {\n this.policies = policies;\n }\n\n /**\n * Resolve policy for the resource and action\n *\n @param action - Action\n * @param resource - Resource\n */\n public resolve<Action extends keyof Resources>(\n action: Action,\n resource: Resources[Action],\n ): this {\n const filteredPolicies: AbilityPolicy[] = this.policies.filter(policy => {\n return AbilityResolver.isInActionContain(policy.action, String(action));\n });\n\n filteredPolicies.map(policy => policy.check(resource as object));\n\n this.policies = filteredPolicies;\n\n return this;\n }\n\n public enforce<Action extends keyof Resources>(\n action: Action,\n resource: Resources[Action],\n ): void | never {\n const resolver = this.resolve(action, resource);\n if (resolver) {\n if (resolver.isDeny()) {\n throw new PermissionError(\n ['Permission denied', resolver.getPolicy()?.name?.toString()].join('. '),\n );\n }\n }\n }\n\n /**\n * Get the last effect of the policy\n *\n * @returns {AbilityPolicyEffect | null}\n */\n public getEffect(): AbilityPolicyEffect | null {\n const effects = this.policies.reduce<AbilityPolicyEffect[]>((collect, policy, _index) => {\n if (policy.matchState.isEqual(AbilityMatch.MATCH)) {\n return collect.concat(policy.effect);\n }\n return collect;\n }, []);\n\n if (effects.length) {\n return effects[effects.length - 1];\n }\n\n return null;\n }\n\n public isPermit() {\n const effect = this.getEffect();\n\n return effect !== null && effect.isEqual(AbilityPolicyEffect.PERMIT);\n }\n\n public isDeny() {\n const effect = this.getEffect();\n\n return effect !== null && effect.isEqual(AbilityPolicyEffect.DENY);\n }\n\n public getPolicy(): AbilityPolicy<Resources> | null {\n const lastPolicy = this.policies.length ? this.policies[this.policies.length - 1] : null;\n\n return lastPolicy && lastPolicy.matchState.isEqual(AbilityMatch.MATCH) ? lastPolicy : null;\n }\n\n /**\n * Check if the action is contained in another action\n * @param actionA - The first action to check\n * @param actionB - The second action to check\n */\n public static isInActionContain(actionA: string, actionB: string) {\n const actionAArray = String(actionA).split('.');\n const actionBArray = String(actionB).split('.');\n\n const a = actionAArray.length >= actionBArray.length ? actionAArray : actionBArray;\n const b = actionBArray.length >= actionAArray.length ? actionBArray : actionAArray;\n\n return a\n .reduce<boolean[]>((acc, chunk, index) => {\n const iterationRes = chunk === b[index] || b[index] === '*' || chunk === '*';\n\n return acc.concat(iterationRes);\n }, [])\n .every(Boolean);\n }\n}\n\nexport default AbilityResolver;\n","import AbilityMatch from './AbilityMatch';\nimport AbilityCondition from './AbilityCondition';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityRuleMatches = [string, AbilityCondition, string | number | boolean];\n\nexport type AbilityRuleConfig = {\n readonly name?: string | symbol;\n readonly matches: [string, string, string | number | boolean];\n};\n\nexport class AbilityRule<Resources extends object = object> {\n public matches: AbilityRuleMatches;\n public name: string | symbol;\n public state: AbilityMatch = AbilityMatch.PENDING;\n\n public constructor(params: { matches: AbilityRuleMatches; name?: string | symbol }) {\n const { name, matches } = params;\n this.name = name || Symbol('name');\n this.matches = matches;\n }\n\n /**\n * Check if the rule is matched\n * @param resource - The resource to check\n */\n public check(resource: Resources | null): AbilityMatch {\n const [_subjectPathName, condition, _staticValueOrPathName] = this.matches;\n\n let is: boolean = false;\n\n const [valueS, valueO] = this.extractValues(resource);\n\n if (AbilityCondition.LESS_THAN.isEqual(condition)) {\n is = Number(valueS) < Number(valueO);\n }\n\n if (AbilityCondition.LESS_OR_EQUAL.isEqual(condition)) {\n is = Number(valueS) <= Number(valueO);\n }\n\n if (AbilityCondition.MORE_THAN.isEqual(condition)) {\n is = Number(valueS) > Number(valueO);\n }\n\n if (AbilityCondition.MORE_OR_EQUAL.isEqual(condition)) {\n is = Number(valueS) >= Number(valueO);\n }\n\n if (AbilityCondition.EQUAL.isEqual(condition)) {\n is = valueS === valueO;\n }\n\n if (AbilityCondition.NOT_EQUAL.isEqual(condition)) {\n is = valueS !== valueO;\n }\n\n if (AbilityCondition.IN.isEqual(condition)) {\n // [<some>] and [<some>]\n if (Array.isArray(valueS) && Array.isArray(valueO)) {\n is = valueS.some(v => valueO.find(v1 => v1 === v));\n }\n // <some> and [<some>]\n if ((typeof valueS === 'string' || typeof valueS === 'number') && Array.isArray(valueO)) {\n is = valueO.includes(valueS);\n }\n // [<some>] and <some>\n if ((typeof valueO === 'string' || typeof valueO === 'number') && Array.isArray(valueS)) {\n is = valueS.includes(valueO);\n }\n }\n\n if (AbilityCondition.NOT_IN.isEqual(condition)) {\n // [<some>] and [<some>]\n if (Array.isArray(valueS) && Array.isArray(valueO)) {\n is = !valueS.some(v => valueO.find(v1 => v1 === v));\n }\n // <some> and [<some>]\n if ((typeof valueS === 'string' || typeof valueS === 'number') && Array.isArray(valueO)) {\n is = !valueO.includes(valueS);\n }\n // [<some>] and <some>\n if ((typeof valueO === 'string' || typeof valueO === 'number') && Array.isArray(valueS)) {\n is = !valueS.includes(valueO);\n }\n }\n\n this.state = is ? AbilityMatch.MATCH : AbilityMatch.MISMATCH;\n\n return this.state;\n }\n\n /**\n * Extract values from the resource\n * @param resource - The resource to extract values from\n */\n public extractValues(\n resource: Resources | null,\n ): [\n string | number | boolean | (string | number)[] | null | undefined,\n string | number | boolean | (string | number)[] | null | undefined,\n ] {\n const [subjectPathName, _condition, staticValueOrPathName] = this.matches;\n let leftSideValue;\n let rightSideValue;\n\n if (resource === null || typeof resource === 'undefined') {\n return [NaN, NaN];\n }\n\n const isPath = (str: unknown): str is string => {\n return typeof str === 'string' && str.match(/\\./g) !== null;\n };\n\n if (isPath(subjectPathName)) {\n leftSideValue = this.getDotNotationValue<number | boolean | string | (string | number)[]>(\n resource,\n subjectPathName,\n );\n }\n if (isPath(staticValueOrPathName)) {\n rightSideValue = this.getDotNotationValue<number | boolean | string | (string | number)[]>(\n resource,\n staticValueOrPathName,\n );\n } else {\n rightSideValue = staticValueOrPathName as number | boolean | string | (string | number)[];\n }\n\n return [leftSideValue, rightSideValue];\n }\n\n /**\n * Get the value of the object by dot notation\n * @param resource - The object to get the value from\n * @param desc - The dot notation string\n */\n public getDotNotationValue<T = unknown>(resource: unknown, desc: string): T | undefined {\n const arr = desc.split('.');\n\n while (arr.length && resource) {\n const comp = arr.shift() || '';\n const match = new RegExp('(.+)\\\\[([0-9]*)\\\\]').exec(comp);\n\n if (match !== null && match.length == 3) {\n const arrayData = {\n arrName: match[1],\n arrIndex: match[2],\n };\n\n if (resource[arrayData.arrName as keyof typeof resource] !== undefined) {\n resource = resource[arrayData.arrName as keyof typeof resource][arrayData.arrIndex];\n } else {\n resource = undefined;\n }\n } else {\n resource = resource[comp as keyof typeof resource];\n }\n }\n\n return resource as T;\n }\n\n public static parse<Resources extends object>(\n configOrJson: AbilityRuleConfig | string,\n ): AbilityRule<Resources> {\n const config = AbilityParser.prepareAndValidateConfig<AbilityRuleConfig>(configOrJson, [\n ['id', 'string', false],\n ['name', 'string', true],\n ['matches', 'array', true],\n ]);\n\n const { name, matches } = config;\n const [leftField, condition, rightField] = matches;\n\n return new AbilityRule<Resources>({\n name,\n matches: [leftField, new AbilityCondition(condition), rightField],\n });\n }\n\n /**\n * Export the rule to config object\n */\n public export(): AbilityRuleConfig {\n const [leftField, condition, rightField] = this.matches;\n\n return {\n name: this.name,\n matches: [leftField, condition.code, rightField],\n };\n }\n}\n\nexport default AbilityRule;\n","import AbilityRule, { AbilityRuleConfig } from './AbilityRule';\nimport AbilityCompare from './AbilityCompare';\nimport AbilityMatch from './AbilityMatch';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityRuleSetConfig = {\n readonly id?: string | symbol;\n readonly name: string;\n readonly compareMethod: number;\n readonly rules: AbilityRuleConfig[];\n};\n\nexport class AbilityRuleSet<Resources extends object = object> {\n public state: AbilityMatch = AbilityMatch.PENDING;\n /**\n * List of rules\n */\n public rules: AbilityRule[] = [];\n\n /**\n * Rules compare method.\\\n * For the «and» method the rule will be permitted if all\\\n * rules will be returns «permit» status and for the «or» - if\\\n * one of the rules returns as «permit»\n */\n public compareMethod: AbilityCompare = AbilityCompare.AND;\n\n /**\n * Group name\n */\n public name: string | symbol;\n\n /**\n * Group ID\n */\n public id: string | symbol;\n\n public constructor(params?: { name?: string | symbol; id?: string | symbol }) {\n const { name, id } = params || {};\n\n this.name = name || Symbol('name');\n this.id = id || Symbol('id');\n }\n\n public addRule(rule: AbilityRule, compareMethod: AbilityCompare): this {\n this.rules.push(rule);\n this.compareMethod = compareMethod;\n\n return this;\n }\n\n public addRules(rules: AbilityRule[], compareMethod: AbilityCompare): this {\n rules.forEach(rule => this.addRule(rule, compareMethod));\n\n return this;\n }\n\n public check(resources: Resources | null): AbilityMatch {\n this.state = AbilityMatch.MISMATCH;\n\n if (!this.rules.length) {\n return this.state;\n }\n\n const ruleCheckStates = this.rules.reduce<AbilityMatch[]>((collect, rule) => {\n return collect.concat(rule.check(resources));\n }, []);\n\n if (AbilityCompare.AND.isEqual(this.compareMethod)) {\n if (ruleCheckStates.every(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.state = AbilityMatch.MATCH;\n }\n }\n\n if (AbilityCompare.OR.isEqual(this.compareMethod)) {\n if (ruleCheckStates.some(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.state = AbilityMatch.MATCH;\n }\n }\n\n return this.state;\n }\n\n\n /**\n * Parse the config JSON format to Group class instance\n */\n public static parse<Resource extends object = object>(\n configOrJson: AbilityRuleSetConfig | string,\n ): AbilityRuleSet<Resource> {\n\n const config = AbilityParser.prepareAndValidateConfig<AbilityRuleSetConfig>(configOrJson, [\n ['id', 'string', false],\n ['name', 'string', true],\n ['compareMethod', 'number', true],\n ['rules', 'array', true],\n ]);\n\n const { id, name, rules, compareMethod } = config;\n\n const ruleSet = new AbilityRuleSet<Resource>({\n name,\n id,\n });\n\n ruleSet.compareMethod = new AbilityCompare(compareMethod);\n\n // Adding rules if exists\n if (rules && rules.length > 0) {\n const abilityRules = rules.map(ruleConfig => AbilityRule.parse(ruleConfig));\n\n ruleSet.addRules(abilityRules, ruleSet.compareMethod);\n }\n\n return ruleSet;\n }\n\n public export(): AbilityRuleSetConfig {\n return {\n id: this.id.toString(),\n name: this.name.toString(),\n compareMethod: this.compareMethod.code,\n rules: this.rules.map(rule => rule.export()),\n };\n }\n}\n\nexport default AbilityRuleSet;\n","import http from 'node:http';\nimport AbilityPolicy, { AbilityPolicyConfig } from './AbilityPolicy';\nimport AbilityResolver from '~/AbilityResolver';\n\nimport policies from './policies.json';\n\nconst server = http.createServer();\n\nserver.on('request', (_req, res) => {\n new AbilityResolver<Resources>(\n policies.map(p => {\n return AbilityPolicy.parse(p as AbilityPolicyConfig);\n }),\n ).enforce('account.read', {\n account: {\n id: '1',\n roles: ['managers'],\n },\n resource: {\n id: '1',\n },\n });\n\n res.statusCode = 200;\n res.setHeader('content-type', 'application/json');\n\n res.write(\n JSON.stringify({\n status: 'Done',\n }),\n );\n res.end();\n});\n\nserver.listen(8080, 'localhost', () => {\n console.debug('server started at http://localhost:8080');\n});\n\nexport type Resources = {\n readonly ['account.read']: {\n readonly account: {\n readonly id: string;\n readonly roles: readonly string[];\n };\n readonly resource: {\n readonly id: string;\n };\n };\n readonly ['access.auth']: {\n readonly token: {\n readonly type: string;\n readonly id: string;\n };\n };\n readonly ['order.update']: {\n readonly account: {\n readonly roles: readonly string[];\n readonly department: string;\n };\n readonly order: {\n readonly status: string;\n };\n };\n};\n","module.exports = require(\"node:http\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/playground.ts\");\n",""],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"playground.js","mappings":"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","sources":["webpack://@via-profit/ability/./src/AbilityCode.ts","webpack://@via-profit/ability/./src/AbilityCompare.ts","webpack://@via-profit/ability/./src/AbilityCondition.ts","webpack://@via-profit/ability/./src/AbilityError.ts","webpack://@via-profit/ability/./src/AbilityMatch.ts","webpack://@via-profit/ability/./src/AbilityParser.ts","webpack://@via-profit/ability/./src/AbilityPolicy.ts","webpack://@via-profit/ability/./src/AbilityPolicyEffect.ts","webpack://@via-profit/ability/./src/AbilityResolver.ts","webpack://@via-profit/ability/./src/AbilityRule.ts","webpack://@via-profit/ability/./src/AbilityRuleSet.ts","webpack://@via-profit/ability/./src/playground.ts","webpack://@via-profit/ability/external node-commonjs \"node:http\"","webpack://@via-profit/ability/webpack/bootstrap","webpack://@via-profit/ability/webpack/before-startup","webpack://@via-profit/ability/webpack/startup","webpack://@via-profit/ability/webpack/after-startup"],"sourcesContent":["export class AbilityCode<T extends string | number | undefined = number> {\n public code: T;\n\n constructor(code: T) {\n this.code = code;\n }\n\n public isEqual(compareWith: AbilityCode<T> | null): boolean {\n return compareWith !== null && this.code === compareWith.code;\n }\n\n public isNotEqual(compareWith: AbilityCode<T> | null): boolean {\n return !this.isEqual(compareWith);\n }\n}\n\nexport default AbilityCode;","import AbilityCode from './AbilityCode';\n\nexport class AbilityCompare extends AbilityCode {\n public static OR = new AbilityCompare(0);\n public static AND = new AbilityCompare(1);\n}\n\nexport default AbilityCompare;\n","import AbilityCode from './AbilityCode';\n\nexport type AbilityConditionVariantType = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'in' | 'not in';\n\nexport class AbilityCondition extends AbilityCode<AbilityConditionVariantType> {\n public static EQUAL = new AbilityCondition('=');\n public static NOT_EQUAL = new AbilityCondition('<>');\n public static MORE_THAN = new AbilityCondition('>');\n public static LESS_THAN = new AbilityCondition('<');\n public static LESS_OR_EQUAL = new AbilityCondition('<=');\n public static MORE_OR_EQUAL = new AbilityCondition('>=');\n public static IN = new AbilityCondition('in');\n public static NOT_IN = new AbilityCondition('not in');\n}\n\nexport default AbilityCondition;\n","export class AbilityError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class AbilityParserError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class PermissionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n","import AbilityCode from './AbilityCode';\n\nexport class AbilityMatch extends AbilityCode{\n public static PENDING = new AbilityMatch(2);\n public static MATCH = new AbilityMatch(1);\n public static MISMATCH = new AbilityMatch(0);\n}\n\nexport default AbilityMatch;","import { AbilityParserError } from './AbilityError';\nimport AbilityPolicy from './AbilityPolicy';\nimport AbilityCondition from './AbilityCondition';\n\ntype FieldValidateConfig = [string, 'string' | 'number' | 'array', boolean][];\n\n\nexport class AbilityParser {\n\n /**\n * Validates the configuration object based on the provided field validation configurations.\n * @param config - The configuration object to validate.\n * @param fields - An array of field validation configurations.\n * @throws {AbilityParserError} If a required field is missing or if a field has an incorrect type.\n */\n public static validateConfig(config: Record<string, any>, fields: FieldValidateConfig): void | never {\n fields.forEach(([field, type, isRequired]) => {\n const value = config[field as keyof typeof config];\n if (isRequired) {\n if (typeof value === 'undefined') {\n throw new AbilityParserError(`Missing required field [${field}]`);\n }\n }\n\n switch (type) {\n case 'array':\n if (typeof value !== 'object' || !Array.isArray(value)) {\n throw new AbilityParserError(`Field [${field}] must be an type of [${type}], bit got [${typeof value}]`);\n }\n break;\n\n default:\n if (typeof value !== type && typeof value !== 'undefined') {\n throw new AbilityParserError(`Field [${field}] must be a type of [${type}], bit got [${typeof value}]`);\n }\n break;\n }\n\n\n });\n }\n\n /**\n * Prepares and validates the configuration object or JSON string.\n * @param configOrJson - The configuration object or JSON string to validate.\n * @param fields - An array of field validation configurations.\n * @returns The validated configuration object.\n */\n public static prepareAndValidateConfig<T>(configOrJson: string | unknown, fields: FieldValidateConfig): T {\n const config = typeof configOrJson === 'string'\n ? (JSON.parse(configOrJson))\n : configOrJson;\n\n AbilityParser.validateConfig(config, fields);\n\n return config;\n }\n\n /*\n *\n * readonly ['order.update']: {\n * readonly user: {\n * readonly roles: readonly string[];\n * readonly department: string;\n * };\n * readonly order: {\n * readonly estimatedArrivalAt: number;\n * readonly status: string;\n * }\n * }\n *\n * */\n\n /**\n * Sets a value in a nested object structure based on a dot/bracket notation path.\n * @param object - The target object to modify.\n * @param path - The path to the property in dot/bracket notation.\n * @param value - The value to set at the specified path.\n */\n public static setValueDotValue(\n object: Record<string, any>,\n path: string,\n value: string | number | boolean\n ): void {\n const way = path.replace(/\\[/g, '.').replace(/\\]/g, '').split('.');\n const last = way.pop();\n\n if (!last) {\n throw new AbilityParserError(`Invalid path provided on a [${path}]`);\n }\n\n way.reduce((o, k, i, kk) => {\n if (!o[k]) {\n o[k] = isFinite(Number(kk[i + 1])) ? [] : {};\n }\n return o[k];\n }, object)[last] = value;\n }\n\n /**\n * Generates TypeScript type definitions based on the provided policies.\n * @param policies - An array of AbilityPolicy instances.\n * @param outPath - The output path for the generated type definitions.\n * @returns A record containing the generated type definitions.\n */\n public static generateTypeDefs(policies: readonly AbilityPolicy[], outPath: string) {\n const record: Record<string, any> = {};\n\n policies.forEach(policy => {\n policy.ruleSet.forEach(ruleSet => {\n ruleSet.rules.forEach(rule => {\n let value: string = 'any';\n\n switch (true) {\n case rule.condition.isEqual(AbilityCondition.NOT_EQUAL):\n case rule.condition.isEqual(AbilityCondition.EQUAL):\n value = typeof rule.staticValueOrPathName;\n break;\n\n case rule.condition.isEqual(AbilityCondition.IN):\n case rule.condition.isEqual(AbilityCondition.NOT_IN):\n value = `${typeof rule.staticValueOrPathName}[]`;\n break;\n\n case rule.condition.isEqual(AbilityCondition.MORE_OR_EQUAL):\n case rule.condition.isEqual(AbilityCondition.MORE_THAN):\n case rule.condition.isEqual(AbilityCondition.LESS_OR_EQUAL):\n case rule.condition.isEqual(AbilityCondition.LESS_THAN):\n value = 'number';\n break;\n }\n AbilityParser.setValueDotValue(record, rule.subjectPathName, value);\n });\n });\n });\n\n console.log(JSON.stringify(record));\n\n return record;\n }\n\n}\n\nexport default AbilityParser;","import AbilityRule from './AbilityRule';\nimport AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';\nimport AbilityMatch from './AbilityMatch';\nimport AbilityCompare from './AbilityCompare';\nimport AbilityPolicyEffect from './AbilityPolicyEffect';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityPolicyConfig = {\n readonly action: string;\n readonly effect: number;\n readonly compareMethod: number;\n readonly ruleSet: AbilityRuleSetConfig[];\n readonly id: string;\n readonly name: string;\n};\n\nexport class AbilityPolicy<Resources extends object = object> {\n public matchState: AbilityMatch = AbilityMatch.PENDING;\n /**\n * List of rules\n */\n public ruleSet: AbilityRuleSet[] = [];\n\n /**\n * Policy effect\n */\n public effect: AbilityPolicyEffect;\n\n /**\n * Rules compare method.\\\n * For the «and» method the rule will be permitted if all\\\n * rules will be returns «permit» status and for the «or» - if\\\n * one of the rules returns as «permit»\n */\n public compareMethod: AbilityCompare = AbilityCompare.AND;\n\n /**\n * Policy name\n */\n public name: string;\n\n /**\n * Policy ID\n */\n public id: string;\n\n /**\n * Soon\n */\n public action: string;\n\n public constructor(params: {\n id: string;\n name: string;\n action: string;\n effect: AbilityPolicyEffect;\n }) {\n const { name, id, action, effect } = params;\n this.name = name;\n this.id = id;\n this.action = action;\n this.effect = effect;\n }\n\n\n /**\n * Add rule set to the policy\n * @param ruleSet - The rule set to add\n */\n public addRuleSet(ruleSet: AbilityRuleSet): this {\n this.ruleSet.push(ruleSet);\n\n return this;\n }\n\n\n /**\n * Check if the policy is matched\n * @param resource - The resource to check\n */\n public check(resource: Resources): AbilityMatch {\n this.matchState = AbilityMatch.MISMATCH;\n\n /**\n * If policy contain a rules\n */\n if (this.ruleSet.length) {\n const ruleCheckStates: AbilityMatch[] = [];\n this.ruleSet.forEach(rule => {\n const ruleCheckState = rule.check(resource);\n ruleCheckStates.push(ruleCheckState);\n });\n\n if (AbilityCompare.AND.isEqual(this.compareMethod)) {\n if (ruleCheckStates.every(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.matchState = AbilityMatch.MATCH;\n }\n }\n\n if (AbilityCompare.OR.isEqual(this.compareMethod)) {\n if (ruleCheckStates.some(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.matchState = AbilityMatch.MATCH;\n }\n }\n }\n\n return this.matchState;\n }\n\n\n\n\n /**\n * Parse the config JSON format to Policy class instance\n */\n public static parse<Resources extends object = object>(\n configOrJson: AbilityPolicyConfig | string,\n ): AbilityPolicy<Resources> {\n\n\n const config = AbilityParser.prepareAndValidateConfig<AbilityPolicyConfig>(configOrJson, [\n ['id', 'string', true],\n ['name', 'string', true],\n ['action', 'string', true],\n ['effect', 'number', true],\n ['compareMethod', 'number', true],\n ['ruleSet', 'array', true],\n ]);\n\n const { id, name, ruleSet, compareMethod, action, effect } = config;\n\n // Create the empty policy\n const policy = new AbilityPolicy<Resources>({\n name,\n id,\n action,\n effect: new AbilityPolicyEffect(effect),\n });\n\n policy.compareMethod = new AbilityCompare(compareMethod);\n\n ruleSet.forEach(ruleSetConfig => {\n policy.addRuleSet(AbilityRuleSet.parse(ruleSetConfig));\n });\n\n return policy;\n }\n\n public export(): AbilityPolicyConfig {\n return {\n id: this.id.toString(),\n name: this.name.toString(),\n compareMethod: this.compareMethod.code,\n ruleSet: this.ruleSet.map(rule => rule.export()),\n action: this.action,\n effect: this.effect.code,\n };\n }\n}\n\nexport default AbilityPolicy;\n","import AbilityCode from './AbilityCode';\n\nexport class AbilityPolicyEffect extends AbilityCode{\n public static DENY = new AbilityPolicyEffect(0);\n public static PERMIT = new AbilityPolicyEffect(1);\n}\n\nexport default AbilityPolicyEffect;","import AbilityPolicy from './AbilityPolicy';\nimport AbilityPolicyEffect from './AbilityPolicyEffect';\nimport AbilityMatch from './AbilityMatch';\nimport { PermissionError } from './AbilityError';\n\nexport class AbilityResolver<Resources extends object = object> {\n policies: readonly AbilityPolicy<Resources>[];\n\n public constructor(policies: readonly AbilityPolicy<Resources>[]) {\n this.policies = policies;\n }\n\n /**\n * Resolve policy for the resource and action\n *\n @param action - Action\n * @param resource - Resource\n */\n public resolve<Action extends keyof Resources>(\n action: Action,\n resource: Resources[Action],\n ): this {\n const filteredPolicies: AbilityPolicy[] = this.policies.filter(policy => {\n return AbilityResolver.isInActionContain(policy.action, String(action));\n });\n\n filteredPolicies.map(policy => policy.check(resource as object));\n\n this.policies = filteredPolicies;\n\n return this;\n }\n\n public enforce<Action extends keyof Resources>(\n action: Action,\n resource: Resources[Action],\n ): void | never {\n const resolver = this.resolve(action, resource);\n if (resolver) {\n if (resolver.isDeny()) {\n throw new PermissionError(resolver.getPolicy()?.name?.toString() || 'Unknown permission error');\n }\n }\n }\n\n /**\n * Get the last effect of the policy\n *\n * @returns {AbilityPolicyEffect | null}\n */\n public getEffect(): AbilityPolicyEffect | null {\n const effects = this.policies.reduce<AbilityPolicyEffect[]>((collect, policy, _index) => {\n if (policy.matchState.isEqual(AbilityMatch.MATCH)) {\n return collect.concat(policy.effect);\n }\n return collect;\n }, []);\n\n if (effects.length) {\n return effects[effects.length - 1];\n }\n\n return null;\n }\n\n public isPermit() {\n const effect = this.getEffect();\n\n return effect !== null && effect.isEqual(AbilityPolicyEffect.PERMIT);\n }\n\n public isDeny() {\n const effect = this.getEffect();\n\n return effect !== null && effect.isEqual(AbilityPolicyEffect.DENY);\n }\n\n public getPolicy(): AbilityPolicy<Resources> | null {\n const lastPolicy = this.policies.length ? this.policies[this.policies.length - 1] : null;\n\n return lastPolicy && lastPolicy.matchState.isEqual(AbilityMatch.MATCH) ? lastPolicy : null;\n }\n\n /**\n * Check if the action is contained in another action\n * @param actionA - The first action to check\n * @param actionB - The second action to check\n */\n public static isInActionContain(actionA: string, actionB: string) {\n const actionAArray = String(actionA).split('.');\n const actionBArray = String(actionB).split('.');\n\n const a = actionAArray.length >= actionBArray.length ? actionAArray : actionBArray;\n const b = actionBArray.length >= actionAArray.length ? actionBArray : actionAArray;\n\n return a\n .reduce<boolean[]>((acc, chunk, index) => {\n const iterationRes = chunk === b[index] || b[index] === '*' || chunk === '*';\n\n return acc.concat(iterationRes);\n }, [])\n .every(Boolean);\n }\n}\n\nexport default AbilityResolver;\n","import AbilityMatch from './AbilityMatch';\nimport AbilityCondition, { AbilityConditionVariantType } from './AbilityCondition';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityRuleConfig = {\n readonly id: string;\n readonly name: string;\n\n /**\n * Subject key path like a 'user.name'\n */\n readonly subjectPathName: string;\n /**\n * Resource key path like a 'user.name' or value\n */\n readonly staticValueOrPathName: string | number | boolean | (string | number)[];\n\n readonly condition: AbilityConditionVariantType;\n};\n\nexport class AbilityRule<Resources extends object = object> {\n /**\n * Subject key path like a 'user.name'\n */\n public subjectPathName: string;\n /**\n * Resource key path like a 'user.name' or value\n */\n public staticValueOrPathName: string | number | boolean | (string | number)[];\n\n public condition: AbilityCondition;\n public name: string;\n public id: string;\n public state: AbilityMatch = AbilityMatch.PENDING;\n\n public constructor(params: AbilityRuleConfig) {\n const { id, name, subjectPathName, staticValueOrPathName, condition } = params;\n this.id = id;\n this.name = name;\n this.subjectPathName = subjectPathName;\n this.staticValueOrPathName = staticValueOrPathName;\n this.condition = new AbilityCondition(condition);\n }\n\n /**\n * Check if the rule is matched\n * @param resource - The resource to check\n */\n public check(resource: Resources | null): AbilityMatch {\n let is: boolean = false;\n\n const [valueS, valueO] = this.extractValues(resource);\n\n if (AbilityCondition.LESS_THAN.isEqual(this.condition)) {\n is = Number(valueS) < Number(valueO);\n }\n\n if (AbilityCondition.LESS_OR_EQUAL.isEqual(this.condition)) {\n is = Number(valueS) <= Number(valueO);\n }\n\n if (AbilityCondition.MORE_THAN.isEqual(this.condition)) {\n is = Number(valueS) > Number(valueO);\n }\n\n if (AbilityCondition.MORE_OR_EQUAL.isEqual(this.condition)) {\n is = Number(valueS) >= Number(valueO);\n }\n\n if (AbilityCondition.EQUAL.isEqual(this.condition)) {\n is = valueS === valueO;\n }\n\n if (AbilityCondition.NOT_EQUAL.isEqual(this.condition)) {\n is = valueS !== valueO;\n }\n\n if (AbilityCondition.IN.isEqual(this.condition)) {\n // [<some>] and [<some>]\n if (Array.isArray(valueS) && Array.isArray(valueO)) {\n is = valueS.some(v => valueO.find(v1 => v1 === v));\n }\n // <some> and [<some>]\n if ((typeof valueS === 'string' || typeof valueS === 'number') && Array.isArray(valueO)) {\n is = valueO.includes(valueS);\n }\n // [<some>] and <some>\n if ((typeof valueO === 'string' || typeof valueO === 'number') && Array.isArray(valueS)) {\n is = valueS.includes(valueO);\n }\n }\n\n if (AbilityCondition.NOT_IN.isEqual(this.condition)) {\n // [<some>] and [<some>]\n if (Array.isArray(valueS) && Array.isArray(valueO)) {\n is = !valueS.some(v => valueO.find(v1 => v1 === v));\n }\n // <some> and [<some>]\n if ((typeof valueS === 'string' || typeof valueS === 'number') && Array.isArray(valueO)) {\n is = !valueO.includes(valueS);\n }\n // [<some>] and <some>\n if ((typeof valueO === 'string' || typeof valueO === 'number') && Array.isArray(valueS)) {\n is = !valueS.includes(valueO);\n }\n }\n\n this.state = is ? AbilityMatch.MATCH : AbilityMatch.MISMATCH;\n\n return this.state;\n }\n\n /**\n * Extract values from the resource\n * @param resource - The resource to extract values from\n */\n public extractValues(\n resource: Resources | null,\n ): [\n string | number | boolean | (string | number)[] | null | undefined,\n string | number | boolean | (string | number)[] | null | undefined,\n ] {\n let leftSideValue;\n let rightSideValue;\n\n if (resource === null || typeof resource === 'undefined') {\n return [NaN, NaN];\n }\n\n const isPath = (str: unknown): str is string => {\n return typeof str === 'string' && str.match(/\\./g) !== null;\n };\n\n if (isPath(this.subjectPathName)) {\n leftSideValue = this.getDotNotationValue<number | boolean | string | (string | number)[]>(\n resource,\n this.subjectPathName,\n );\n }\n if (isPath(this.staticValueOrPathName)) {\n rightSideValue = this.getDotNotationValue<number | boolean | string | (string | number)[]>(\n resource,\n this.staticValueOrPathName,\n );\n } else {\n rightSideValue = this.staticValueOrPathName as\n | number\n | boolean\n | string\n | (string | number)[];\n }\n\n return [leftSideValue, rightSideValue];\n }\n\n /**\n * Get the value of the object by dot notation\n * @param resource - The object to get the value from\n * @param desc - The dot notation string\n */\n public getDotNotationValue<T = unknown>(resource: unknown, desc: string): T | undefined {\n const arr = desc.split('.');\n\n while (arr.length && resource) {\n const comp = arr.shift() || '';\n const match = new RegExp('(.+)\\\\[([0-9]*)\\\\]').exec(comp);\n\n if (match !== null && match.length == 3) {\n const arrayData = {\n arrName: match[1],\n arrIndex: match[2],\n };\n\n if (resource[arrayData.arrName as keyof typeof resource] !== undefined) {\n resource = resource[arrayData.arrName as keyof typeof resource][arrayData.arrIndex];\n } else {\n resource = undefined;\n }\n } else {\n resource = resource[comp as keyof typeof resource];\n }\n }\n\n return resource as T;\n }\n\n public static parse<Resources extends object>(\n configOrJson: AbilityRuleConfig | string,\n ): AbilityRule<Resources> {\n const config = AbilityParser.prepareAndValidateConfig<AbilityRuleConfig>(configOrJson, [\n ['id', 'string', true],\n ['name', 'string', true],\n ['subjectPathName', 'string', true],\n ]);\n\n const { id, name, subjectPathName, staticValueOrPathName, condition } = config;\n\n return new AbilityRule<Resources>({\n id,\n name,\n subjectPathName,\n staticValueOrPathName,\n condition,\n });\n }\n\n /**\n * Export the rule to config object\n */\n public export(): AbilityRuleConfig {\n return {\n id: this.id,\n name: this.name,\n subjectPathName: this.subjectPathName,\n staticValueOrPathName: this.staticValueOrPathName,\n condition: this.condition.code,\n };\n }\n}\n\nexport default AbilityRule;\n","import AbilityRule, { AbilityRuleConfig } from './AbilityRule';\nimport AbilityCompare from './AbilityCompare';\nimport AbilityMatch from './AbilityMatch';\nimport AbilityParser from './AbilityParser';\n\nexport type AbilityRuleSetConfig = {\n readonly id: string;\n readonly name: string;\n readonly compareMethod: number;\n readonly rules: AbilityRuleConfig[];\n};\n\nexport class AbilityRuleSet<Resources extends object = object> {\n public state: AbilityMatch = AbilityMatch.PENDING;\n /**\n * List of rules\n */\n public rules: AbilityRule[] = [];\n\n /**\n * Rules compare method.\\\n * For the «and» method the rule will be permitted if all\\\n * rules will be returns «permit» status and for the «or» - if\\\n * one of the rules returns as «permit»\n */\n public compareMethod: AbilityCompare = AbilityCompare.AND;\n\n /**\n * Group name\n */\n public name: string;\n\n /**\n * Group ID\n */\n public id: string;\n\n public constructor(params: Pick<AbilityRuleSetConfig, 'id' | 'name' | 'compareMethod'>) {\n const { name, id, compareMethod } = params;\n\n this.name = name;\n this.id = id;\n this.compareMethod = new AbilityCompare(compareMethod);\n }\n\n public addRule(rule: AbilityRule, compareMethod: AbilityCompare): this {\n this.rules.push(rule);\n this.compareMethod = compareMethod;\n\n return this;\n }\n\n public addRules(rules: AbilityRule[], compareMethod: AbilityCompare): this {\n rules.forEach(rule => this.addRule(rule, compareMethod));\n\n return this;\n }\n\n public check(resources: Resources | null): AbilityMatch {\n this.state = AbilityMatch.MISMATCH;\n\n if (!this.rules.length) {\n return this.state;\n }\n\n const ruleCheckStates = this.rules.reduce<AbilityMatch[]>((collect, rule) => {\n return collect.concat(rule.check(resources));\n }, []);\n\n if (AbilityCompare.AND.isEqual(this.compareMethod)) {\n if (ruleCheckStates.every(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.state = AbilityMatch.MATCH;\n }\n }\n\n if (AbilityCompare.OR.isEqual(this.compareMethod)) {\n if (ruleCheckStates.some(ruleState => AbilityMatch.MATCH.isEqual(ruleState))) {\n this.state = AbilityMatch.MATCH;\n }\n }\n\n return this.state;\n }\n\n /**\n * Parse the config JSON format to Group class instance\n */\n public static parse<Resource extends object = object>(\n configOrJson: AbilityRuleSetConfig | string,\n ): AbilityRuleSet<Resource> {\n const config = AbilityParser.prepareAndValidateConfig<AbilityRuleSetConfig>(configOrJson, [\n ['id', 'string', true],\n ['name', 'string', true],\n ['compareMethod', 'number', true],\n ['rules', 'array', true],\n ]);\n\n const { id, name, rules, compareMethod } = config;\n\n const ruleSet = new AbilityRuleSet<Resource>({\n compareMethod,\n name,\n id,\n });\n\n // Adding rules if exists\n if (rules && rules.length > 0) {\n const abilityRules = rules.map(ruleConfig => AbilityRule.parse(ruleConfig));\n\n ruleSet.addRules(abilityRules, ruleSet.compareMethod);\n }\n\n return ruleSet;\n }\n\n public export(): AbilityRuleSetConfig {\n return {\n id: this.id.toString(),\n name: this.name.toString(),\n compareMethod: this.compareMethod.code,\n rules: this.rules.map(rule => rule.export()),\n };\n }\n}\n\nexport default AbilityRuleSet;\n","import http from 'node:http';\nimport AbilityPolicy, { AbilityPolicyConfig } from './AbilityPolicy';\nimport AbilityResolver from '~/AbilityResolver';\n\nimport policies from './policies.json';\n\nconst server = http.createServer();\n\nserver.on('request', (_req, res) => {\n new AbilityResolver<Resources>(\n policies.map(p => {\n return AbilityPolicy.parse(p as AbilityPolicyConfig);\n }),\n ).enforce('account.read', {\n account: {\n id: '1',\n roles: ['managers'],\n },\n resource: {\n id: '1',\n },\n });\n\n res.statusCode = 200;\n res.setHeader('content-type', 'application/json');\n\n res.write(\n JSON.stringify({\n status: 'Done',\n }),\n );\n res.end();\n});\n\nserver.listen(8080, 'localhost', () => {\n console.debug('server started at http://localhost:8080');\n});\n\nexport type Resources = {\n readonly ['account.read']: {\n readonly account: {\n readonly id: string;\n readonly roles: readonly string[];\n } | null;\n readonly resource: {\n readonly id: string;\n };\n };\n readonly ['access.auth']: {\n readonly token: {\n readonly type: string;\n readonly id: string;\n } | null;\n };\n readonly ['order.update']: {\n readonly account: {\n readonly roles: readonly string[];\n readonly department: string;\n } | null;\n readonly order: {\n readonly status: string;\n } | null;\n };\n};\n","module.exports = require(\"node:http\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/playground.ts\");\n",""],"names":[],"sourceRoot":""}
@@ -1,5 +1,6 @@
1
1
  import AbilityCode from './AbilityCode';
2
- export declare class AbilityCondition extends AbilityCode<string> {
2
+ export type AbilityConditionVariantType = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'in' | 'not in';
3
+ export declare class AbilityCondition extends AbilityCode<AbilityConditionVariantType> {
3
4
  static EQUAL: AbilityCondition;
4
5
  static NOT_EQUAL: AbilityCondition;
5
6
  static MORE_THAN: AbilityCondition;
@@ -1,4 +1,3 @@
1
- import AbilityRule from './AbilityRule';
2
1
  import AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';
3
2
  import AbilityMatch from './AbilityMatch';
4
3
  import AbilityCompare from './AbilityCompare';
@@ -51,11 +50,6 @@ export declare class AbilityPolicy<Resources extends object = object> {
51
50
  * @param ruleSet - The rule set to add
52
51
  */
53
52
  addRuleSet(ruleSet: AbilityRuleSet): this;
54
- /**
55
- * Add rule to the policy
56
- * @param rule - The rule to add
57
- */
58
- addRule(rule: AbilityRule<Resources>): this;
59
53
  /**
60
54
  * Check if the policy is matched
61
55
  * @param resource - The resource to check
@@ -1,31 +1,42 @@
1
1
  import AbilityMatch from './AbilityMatch';
2
- import AbilityCondition from './AbilityCondition';
3
- export type AbilityRuleMatches = [string, AbilityCondition, string | number | boolean];
2
+ import AbilityCondition, { AbilityConditionVariantType } from './AbilityCondition';
4
3
  export type AbilityRuleConfig = {
5
4
  readonly id: string;
6
5
  readonly name: string;
7
- readonly matches: [string, string, string | number | boolean];
6
+ /**
7
+ * Subject key path like a 'user.name'
8
+ */
9
+ readonly subject: string;
10
+ /**
11
+ * Resource key path like a 'user.name' or value
12
+ */
13
+ readonly resource: string | number | boolean | (string | number)[];
14
+ readonly condition: AbilityConditionVariantType;
8
15
  };
9
16
  export declare class AbilityRule<Resources extends object = object> {
10
- matches: AbilityRuleMatches;
17
+ /**
18
+ * Subject key path like a 'user.name'
19
+ */
20
+ subject: string;
21
+ /**
22
+ * Resource key path like a 'user.name' or value
23
+ */
24
+ resource: string | number | boolean | (string | number)[];
25
+ condition: AbilityCondition;
11
26
  name: string;
12
27
  id: string;
13
28
  state: AbilityMatch;
14
- constructor(params: {
15
- readonly id: string;
16
- readonly name: string;
17
- readonly matches: AbilityRuleMatches;
18
- });
29
+ constructor(params: AbilityRuleConfig);
19
30
  /**
20
31
  * Check if the rule is matched
21
32
  * @param resource - The resource to check
22
33
  */
23
34
  check(resource: Resources | null): AbilityMatch;
24
35
  /**
25
- * Extract values from the resource
26
- * @param resource - The resource to extract values from
36
+ * Extract values from the resourceData
37
+ * @param resourceData - The resourceData to extract values from
27
38
  */
28
- extractValues(resource: Resources | null): [
39
+ extractValues(resourceData: Resources | null): [
29
40
  string | number | boolean | (string | number)[] | null | undefined,
30
41
  string | number | boolean | (string | number)[] | null | undefined
31
42
  ];
@@ -28,10 +28,7 @@ export declare class AbilityRuleSet<Resources extends object = object> {
28
28
  * Group ID
29
29
  */
30
30
  id: string;
31
- constructor(params: {
32
- name: string;
33
- id: string;
34
- });
31
+ constructor(params: Pick<AbilityRuleSetConfig, 'id' | 'name' | 'compareMethod'>);
35
32
  addRule(rule: AbilityRule, compareMethod: AbilityCompare): this;
36
33
  addRules(rules: AbilityRule[], compareMethod: AbilityCompare): this;
37
34
  check(resources: Resources | null): AbilityMatch;
package/dist/index.js CHANGED
@@ -218,25 +218,24 @@ class AbilityParser {
218
218
  policies.forEach(policy => {
219
219
  policy.ruleSet.forEach(ruleSet => {
220
220
  ruleSet.rules.forEach(rule => {
221
- const [leftFieldPath, condition, rightFiledPath] = rule.matches;
222
221
  let value = 'any';
223
222
  switch (true) {
224
- case condition.isEqual(AbilityCondition_1.default.NOT_EQUAL):
225
- case condition.isEqual(AbilityCondition_1.default.EQUAL):
226
- value = typeof rightFiledPath;
223
+ case rule.condition.isEqual(AbilityCondition_1.default.NOT_EQUAL):
224
+ case rule.condition.isEqual(AbilityCondition_1.default.EQUAL):
225
+ value = typeof rule.resource;
227
226
  break;
228
- case condition.isEqual(AbilityCondition_1.default.IN):
229
- case condition.isEqual(AbilityCondition_1.default.NOT_IN):
230
- value = `${typeof rightFiledPath}[]`;
227
+ case rule.condition.isEqual(AbilityCondition_1.default.IN):
228
+ case rule.condition.isEqual(AbilityCondition_1.default.NOT_IN):
229
+ value = `${typeof rule.resource}[]`;
231
230
  break;
232
- case condition.isEqual(AbilityCondition_1.default.MORE_OR_EQUAL):
233
- case condition.isEqual(AbilityCondition_1.default.MORE_THAN):
234
- case condition.isEqual(AbilityCondition_1.default.LESS_OR_EQUAL):
235
- case condition.isEqual(AbilityCondition_1.default.LESS_THAN):
231
+ case rule.condition.isEqual(AbilityCondition_1.default.MORE_OR_EQUAL):
232
+ case rule.condition.isEqual(AbilityCondition_1.default.MORE_THAN):
233
+ case rule.condition.isEqual(AbilityCondition_1.default.LESS_OR_EQUAL):
234
+ case rule.condition.isEqual(AbilityCondition_1.default.LESS_THAN):
236
235
  value = 'number';
237
236
  break;
238
237
  }
239
- AbilityParser.setValueDotValue(record, leftFieldPath, value);
238
+ AbilityParser.setValueDotValue(record, rule.subject, value);
240
239
  });
241
240
  });
242
241
  });
@@ -308,17 +307,6 @@ class AbilityPolicy {
308
307
  this.ruleSet.push(ruleSet);
309
308
  return this;
310
309
  }
311
- /**
312
- * Add rule to the policy
313
- * @param rule - The rule to add
314
- */
315
- addRule(rule) {
316
- this.addRuleSet(new AbilityRuleSet_1.default({
317
- id: rule.id,
318
- name: rule.name,
319
- }).addRule(rule, AbilityCompare_1.default.AND));
320
- return this;
321
- }
322
310
  /**
323
311
  * Check if the policy is matched
324
312
  * @param resource - The resource to check
@@ -515,43 +503,52 @@ const AbilityMatch_1 = __importDefault(__webpack_require__(909));
515
503
  const AbilityCondition_1 = __importDefault(__webpack_require__(261));
516
504
  const AbilityParser_1 = __importDefault(__webpack_require__(189));
517
505
  class AbilityRule {
518
- matches;
506
+ /**
507
+ * Subject key path like a 'user.name'
508
+ */
509
+ subject;
510
+ /**
511
+ * Resource key path like a 'user.name' or value
512
+ */
513
+ resource;
514
+ condition;
519
515
  name;
520
516
  id;
521
517
  state = AbilityMatch_1.default.PENDING;
522
518
  constructor(params) {
523
- const { id, name, matches } = params;
519
+ const { id, name, subject, resource, condition } = params;
524
520
  this.id = id;
525
521
  this.name = name;
526
- this.matches = matches;
522
+ this.subject = subject;
523
+ this.resource = resource;
524
+ this.condition = new AbilityCondition_1.default(condition);
527
525
  }
528
526
  /**
529
527
  * Check if the rule is matched
530
528
  * @param resource - The resource to check
531
529
  */
532
530
  check(resource) {
533
- const [_subjectPathName, condition, _staticValueOrPathName] = this.matches;
534
531
  let is = false;
535
532
  const [valueS, valueO] = this.extractValues(resource);
536
- if (AbilityCondition_1.default.LESS_THAN.isEqual(condition)) {
533
+ if (AbilityCondition_1.default.LESS_THAN.isEqual(this.condition)) {
537
534
  is = Number(valueS) < Number(valueO);
538
535
  }
539
- if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(condition)) {
536
+ if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(this.condition)) {
540
537
  is = Number(valueS) <= Number(valueO);
541
538
  }
542
- if (AbilityCondition_1.default.MORE_THAN.isEqual(condition)) {
539
+ if (AbilityCondition_1.default.MORE_THAN.isEqual(this.condition)) {
543
540
  is = Number(valueS) > Number(valueO);
544
541
  }
545
- if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(condition)) {
542
+ if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(this.condition)) {
546
543
  is = Number(valueS) >= Number(valueO);
547
544
  }
548
- if (AbilityCondition_1.default.EQUAL.isEqual(condition)) {
545
+ if (AbilityCondition_1.default.EQUAL.isEqual(this.condition)) {
549
546
  is = valueS === valueO;
550
547
  }
551
- if (AbilityCondition_1.default.NOT_EQUAL.isEqual(condition)) {
548
+ if (AbilityCondition_1.default.NOT_EQUAL.isEqual(this.condition)) {
552
549
  is = valueS !== valueO;
553
550
  }
554
- if (AbilityCondition_1.default.IN.isEqual(condition)) {
551
+ if (AbilityCondition_1.default.IN.isEqual(this.condition)) {
555
552
  // [<some>] and [<some>]
556
553
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
557
554
  is = valueS.some(v => valueO.find(v1 => v1 === v));
@@ -565,7 +562,7 @@ class AbilityRule {
565
562
  is = valueS.includes(valueO);
566
563
  }
567
564
  }
568
- if (AbilityCondition_1.default.NOT_IN.isEqual(condition)) {
565
+ if (AbilityCondition_1.default.NOT_IN.isEqual(this.condition)) {
569
566
  // [<some>] and [<some>]
570
567
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
571
568
  is = !valueS.some(v => valueO.find(v1 => v1 === v));
@@ -583,27 +580,26 @@ class AbilityRule {
583
580
  return this.state;
584
581
  }
585
582
  /**
586
- * Extract values from the resource
587
- * @param resource - The resource to extract values from
583
+ * Extract values from the resourceData
584
+ * @param resourceData - The resourceData to extract values from
588
585
  */
589
- extractValues(resource) {
590
- const [subjectPathName, _condition, staticValueOrPathName] = this.matches;
586
+ extractValues(resourceData) {
591
587
  let leftSideValue;
592
588
  let rightSideValue;
593
- if (resource === null || typeof resource === 'undefined') {
589
+ if (resourceData === null || typeof resourceData === 'undefined') {
594
590
  return [NaN, NaN];
595
591
  }
596
592
  const isPath = (str) => {
597
593
  return typeof str === 'string' && str.match(/\./g) !== null;
598
594
  };
599
- if (isPath(subjectPathName)) {
600
- leftSideValue = this.getDotNotationValue(resource, subjectPathName);
595
+ if (isPath(this.subject)) {
596
+ leftSideValue = this.getDotNotationValue(resourceData, this.subject);
601
597
  }
602
- if (isPath(staticValueOrPathName)) {
603
- rightSideValue = this.getDotNotationValue(resource, staticValueOrPathName);
598
+ if (isPath(this.resource)) {
599
+ rightSideValue = this.getDotNotationValue(resourceData, this.resource);
604
600
  }
605
601
  else {
606
- rightSideValue = staticValueOrPathName;
602
+ rightSideValue = this.resource;
607
603
  }
608
604
  return [leftSideValue, rightSideValue];
609
605
  }
@@ -639,25 +635,27 @@ class AbilityRule {
639
635
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
640
636
  ['id', 'string', true],
641
637
  ['name', 'string', true],
642
- ['matches', 'array', true],
638
+ ['subject', 'string', true],
643
639
  ]);
644
- const { id, name, matches } = config;
645
- const [leftField, condition, rightField] = matches;
640
+ const { id, name, subject, resource, condition } = config;
646
641
  return new AbilityRule({
647
642
  id,
648
643
  name,
649
- matches: [leftField, new AbilityCondition_1.default(condition), rightField],
644
+ subject,
645
+ resource,
646
+ condition,
650
647
  });
651
648
  }
652
649
  /**
653
650
  * Export the rule to config object
654
651
  */
655
652
  export() {
656
- const [leftField, condition, rightField] = this.matches;
657
653
  return {
658
654
  id: this.id,
659
655
  name: this.name,
660
- matches: [leftField, condition.code, rightField],
656
+ subject: this.subject,
657
+ resource: this.resource,
658
+ condition: this.condition.code,
661
659
  };
662
660
  }
663
661
  }
@@ -702,9 +700,10 @@ class AbilityRuleSet {
702
700
  */
703
701
  id;
704
702
  constructor(params) {
705
- const { name, id } = params;
703
+ const { name, id, compareMethod } = params;
706
704
  this.name = name;
707
705
  this.id = id;
706
+ this.compareMethod = new AbilityCompare_1.default(compareMethod);
708
707
  }
709
708
  addRule(rule, compareMethod) {
710
709
  this.rules.push(rule);
@@ -747,10 +746,10 @@ class AbilityRuleSet {
747
746
  ]);
748
747
  const { id, name, rules, compareMethod } = config;
749
748
  const ruleSet = new AbilityRuleSet({
749
+ compareMethod,
750
750
  name,
751
751
  id,
752
752
  });
753
- ruleSet.compareMethod = new AbilityCompare_1.default(compareMethod);
754
753
  // Adding rules if exists
755
754
  if (rules && rules.length > 0) {
756
755
  const abilityRules = rules.map(ruleConfig => AbilityRule_1.default.parse(ruleConfig));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@via-profit/ability",
3
3
  "support": "https://via-profit.ru",
4
- "version": "2.0.0-rc.3",
4
+ "version": "2.0.0-rc.4",
5
5
  "description": "Via-Profit Ability service",
6
6
  "keywords": [
7
7
  "ability",