@via-profit/ability 2.0.0-rc.2 → 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, { AbilityRuleConfig } from './AbilityRule';
2
1
  import AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';
3
2
  import AbilityMatch from './AbilityMatch';
4
3
  import AbilityCompare from './AbilityCompare';
@@ -7,9 +6,9 @@ export type AbilityPolicyConfig = {
7
6
  readonly action: string;
8
7
  readonly effect: number;
9
8
  readonly compareMethod: number;
10
- readonly ruleSet: (AbilityRuleConfig | AbilityRuleSetConfig)[];
11
- readonly id?: string;
12
- readonly name?: string;
9
+ readonly ruleSet: AbilityRuleSetConfig[];
10
+ readonly id: string;
11
+ readonly name: string;
13
12
  };
14
13
  export declare class AbilityPolicy<Resources extends object = object> {
15
14
  matchState: AbilityMatch;
@@ -31,31 +30,26 @@ export declare class AbilityPolicy<Resources extends object = object> {
31
30
  /**
32
31
  * Policy name
33
32
  */
34
- name: string | symbol;
33
+ name: string;
35
34
  /**
36
35
  * Policy ID
37
36
  */
38
- id: string | symbol;
37
+ id: string;
39
38
  /**
40
39
  * Soon
41
40
  */
42
41
  action: string;
43
42
  constructor(params: {
43
+ id: string;
44
+ name: string;
44
45
  action: string;
45
46
  effect: AbilityPolicyEffect;
46
- name?: string | symbol;
47
- id?: string | symbol;
48
47
  });
49
48
  /**
50
49
  * Add rule set to the policy
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,28 +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
- readonly name?: string | symbol;
6
- readonly matches: [string, string, string | number | boolean];
4
+ readonly id: string;
5
+ readonly name: string;
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;
7
15
  };
8
16
  export declare class AbilityRule<Resources extends object = object> {
9
- matches: AbilityRuleMatches;
10
- name: string | symbol;
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;
26
+ name: string;
27
+ id: string;
11
28
  state: AbilityMatch;
12
- constructor(params: {
13
- matches: AbilityRuleMatches;
14
- name?: string | symbol;
15
- });
29
+ constructor(params: AbilityRuleConfig);
16
30
  /**
17
31
  * Check if the rule is matched
18
32
  * @param resource - The resource to check
19
33
  */
20
34
  check(resource: Resources | null): AbilityMatch;
21
35
  /**
22
- * Extract values from the resource
23
- * @param resource - The resource to extract values from
36
+ * Extract values from the resourceData
37
+ * @param resourceData - The resourceData to extract values from
24
38
  */
25
- extractValues(resource: Resources | null): [
39
+ extractValues(resourceData: Resources | null): [
26
40
  string | number | boolean | (string | number)[] | null | undefined,
27
41
  string | number | boolean | (string | number)[] | null | undefined
28
42
  ];
@@ -2,7 +2,7 @@ import AbilityRule, { AbilityRuleConfig } from './AbilityRule';
2
2
  import AbilityCompare from './AbilityCompare';
3
3
  import AbilityMatch from './AbilityMatch';
4
4
  export type AbilityRuleSetConfig = {
5
- readonly id?: string | symbol;
5
+ readonly id: string;
6
6
  readonly name: string;
7
7
  readonly compareMethod: number;
8
8
  readonly rules: AbilityRuleConfig[];
@@ -23,15 +23,12 @@ export declare class AbilityRuleSet<Resources extends object = object> {
23
23
  /**
24
24
  * Group name
25
25
  */
26
- name: string | symbol;
26
+ name: string;
27
27
  /**
28
28
  * Group ID
29
29
  */
30
- id: string | symbol;
31
- constructor(params?: {
32
- name?: string | symbol;
33
- id?: string | symbol;
34
- });
30
+ id: string;
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
  });
@@ -259,7 +258,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
259
258
  };
260
259
  Object.defineProperty(exports, "__esModule", ({ value: true }));
261
260
  exports.AbilityPolicy = void 0;
262
- const AbilityRule_1 = __importDefault(__webpack_require__(476));
263
261
  const AbilityRuleSet_1 = __importDefault(__webpack_require__(402));
264
262
  const AbilityMatch_1 = __importDefault(__webpack_require__(909));
265
263
  const AbilityCompare_1 = __importDefault(__webpack_require__(923));
@@ -296,8 +294,8 @@ class AbilityPolicy {
296
294
  action;
297
295
  constructor(params) {
298
296
  const { name, id, action, effect } = params;
299
- this.name = name || Symbol('name');
300
- this.id = id || Symbol('id');
297
+ this.name = name;
298
+ this.id = id;
301
299
  this.action = action;
302
300
  this.effect = effect;
303
301
  }
@@ -309,16 +307,6 @@ class AbilityPolicy {
309
307
  this.ruleSet.push(ruleSet);
310
308
  return this;
311
309
  }
312
- /**
313
- * Add rule to the policy
314
- * @param rule - The rule to add
315
- */
316
- addRule(rule) {
317
- this.addRuleSet(new AbilityRuleSet_1.default({
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
@@ -352,7 +340,7 @@ class AbilityPolicy {
352
340
  */
353
341
  static parse(configOrJson) {
354
342
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
355
- ['id', 'string', false],
343
+ ['id', 'string', true],
356
344
  ['name', 'string', true],
357
345
  ['action', 'string', true],
358
346
  ['effect', 'number', true],
@@ -368,15 +356,8 @@ class AbilityPolicy {
368
356
  effect: new AbilityPolicyEffect_1.default(effect),
369
357
  });
370
358
  policy.compareMethod = new AbilityCompare_1.default(compareMethod);
371
- ruleSet.forEach(ruleOrRuleSet => {
372
- // is ruleset
373
- if ('rules' in ruleOrRuleSet) {
374
- policy.addRuleSet(AbilityRuleSet_1.default.parse(ruleOrRuleSet));
375
- }
376
- // is simple rule
377
- if (!('rules' in ruleOrRuleSet)) {
378
- policy.addRule(AbilityRule_1.default.parse(ruleOrRuleSet));
379
- }
359
+ ruleSet.forEach(ruleSetConfig => {
360
+ policy.addRuleSet(AbilityRuleSet_1.default.parse(ruleSetConfig));
380
361
  });
381
362
  return policy;
382
363
  }
@@ -522,41 +503,52 @@ const AbilityMatch_1 = __importDefault(__webpack_require__(909));
522
503
  const AbilityCondition_1 = __importDefault(__webpack_require__(261));
523
504
  const AbilityParser_1 = __importDefault(__webpack_require__(189));
524
505
  class AbilityRule {
525
- 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;
526
515
  name;
516
+ id;
527
517
  state = AbilityMatch_1.default.PENDING;
528
518
  constructor(params) {
529
- const { name, matches } = params;
530
- this.name = name || Symbol('name');
531
- this.matches = matches;
519
+ const { id, name, subject, resource, condition } = params;
520
+ this.id = id;
521
+ this.name = name;
522
+ this.subject = subject;
523
+ this.resource = resource;
524
+ this.condition = new AbilityCondition_1.default(condition);
532
525
  }
533
526
  /**
534
527
  * Check if the rule is matched
535
528
  * @param resource - The resource to check
536
529
  */
537
530
  check(resource) {
538
- const [_subjectPathName, condition, _staticValueOrPathName] = this.matches;
539
531
  let is = false;
540
532
  const [valueS, valueO] = this.extractValues(resource);
541
- if (AbilityCondition_1.default.LESS_THAN.isEqual(condition)) {
533
+ if (AbilityCondition_1.default.LESS_THAN.isEqual(this.condition)) {
542
534
  is = Number(valueS) < Number(valueO);
543
535
  }
544
- if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(condition)) {
536
+ if (AbilityCondition_1.default.LESS_OR_EQUAL.isEqual(this.condition)) {
545
537
  is = Number(valueS) <= Number(valueO);
546
538
  }
547
- if (AbilityCondition_1.default.MORE_THAN.isEqual(condition)) {
539
+ if (AbilityCondition_1.default.MORE_THAN.isEqual(this.condition)) {
548
540
  is = Number(valueS) > Number(valueO);
549
541
  }
550
- if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(condition)) {
542
+ if (AbilityCondition_1.default.MORE_OR_EQUAL.isEqual(this.condition)) {
551
543
  is = Number(valueS) >= Number(valueO);
552
544
  }
553
- if (AbilityCondition_1.default.EQUAL.isEqual(condition)) {
545
+ if (AbilityCondition_1.default.EQUAL.isEqual(this.condition)) {
554
546
  is = valueS === valueO;
555
547
  }
556
- if (AbilityCondition_1.default.NOT_EQUAL.isEqual(condition)) {
548
+ if (AbilityCondition_1.default.NOT_EQUAL.isEqual(this.condition)) {
557
549
  is = valueS !== valueO;
558
550
  }
559
- if (AbilityCondition_1.default.IN.isEqual(condition)) {
551
+ if (AbilityCondition_1.default.IN.isEqual(this.condition)) {
560
552
  // [<some>] and [<some>]
561
553
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
562
554
  is = valueS.some(v => valueO.find(v1 => v1 === v));
@@ -570,7 +562,7 @@ class AbilityRule {
570
562
  is = valueS.includes(valueO);
571
563
  }
572
564
  }
573
- if (AbilityCondition_1.default.NOT_IN.isEqual(condition)) {
565
+ if (AbilityCondition_1.default.NOT_IN.isEqual(this.condition)) {
574
566
  // [<some>] and [<some>]
575
567
  if (Array.isArray(valueS) && Array.isArray(valueO)) {
576
568
  is = !valueS.some(v => valueO.find(v1 => v1 === v));
@@ -588,27 +580,26 @@ class AbilityRule {
588
580
  return this.state;
589
581
  }
590
582
  /**
591
- * Extract values from the resource
592
- * @param resource - The resource to extract values from
583
+ * Extract values from the resourceData
584
+ * @param resourceData - The resourceData to extract values from
593
585
  */
594
- extractValues(resource) {
595
- const [subjectPathName, _condition, staticValueOrPathName] = this.matches;
586
+ extractValues(resourceData) {
596
587
  let leftSideValue;
597
588
  let rightSideValue;
598
- if (resource === null || typeof resource === 'undefined') {
589
+ if (resourceData === null || typeof resourceData === 'undefined') {
599
590
  return [NaN, NaN];
600
591
  }
601
592
  const isPath = (str) => {
602
593
  return typeof str === 'string' && str.match(/\./g) !== null;
603
594
  };
604
- if (isPath(subjectPathName)) {
605
- leftSideValue = this.getDotNotationValue(resource, subjectPathName);
595
+ if (isPath(this.subject)) {
596
+ leftSideValue = this.getDotNotationValue(resourceData, this.subject);
606
597
  }
607
- if (isPath(staticValueOrPathName)) {
608
- rightSideValue = this.getDotNotationValue(resource, staticValueOrPathName);
598
+ if (isPath(this.resource)) {
599
+ rightSideValue = this.getDotNotationValue(resourceData, this.resource);
609
600
  }
610
601
  else {
611
- rightSideValue = staticValueOrPathName;
602
+ rightSideValue = this.resource;
612
603
  }
613
604
  return [leftSideValue, rightSideValue];
614
605
  }
@@ -642,25 +633,29 @@ class AbilityRule {
642
633
  }
643
634
  static parse(configOrJson) {
644
635
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
645
- ['id', 'string', false],
636
+ ['id', 'string', true],
646
637
  ['name', 'string', true],
647
- ['matches', 'array', true],
638
+ ['subject', 'string', true],
648
639
  ]);
649
- const { name, matches } = config;
650
- const [leftField, condition, rightField] = matches;
640
+ const { id, name, subject, resource, condition } = config;
651
641
  return new AbilityRule({
642
+ id,
652
643
  name,
653
- matches: [leftField, new AbilityCondition_1.default(condition), rightField],
644
+ subject,
645
+ resource,
646
+ condition,
654
647
  });
655
648
  }
656
649
  /**
657
650
  * Export the rule to config object
658
651
  */
659
652
  export() {
660
- const [leftField, condition, rightField] = this.matches;
661
653
  return {
654
+ id: this.id,
662
655
  name: this.name,
663
- matches: [leftField, condition.code, rightField],
656
+ subject: this.subject,
657
+ resource: this.resource,
658
+ condition: this.condition.code,
664
659
  };
665
660
  }
666
661
  }
@@ -705,9 +700,10 @@ class AbilityRuleSet {
705
700
  */
706
701
  id;
707
702
  constructor(params) {
708
- const { name, id } = params || {};
709
- this.name = name || Symbol('name');
710
- this.id = id || Symbol('id');
703
+ const { name, id, compareMethod } = params;
704
+ this.name = name;
705
+ this.id = id;
706
+ this.compareMethod = new AbilityCompare_1.default(compareMethod);
711
707
  }
712
708
  addRule(rule, compareMethod) {
713
709
  this.rules.push(rule);
@@ -743,17 +739,17 @@ class AbilityRuleSet {
743
739
  */
744
740
  static parse(configOrJson) {
745
741
  const config = AbilityParser_1.default.prepareAndValidateConfig(configOrJson, [
746
- ['id', 'string', false],
742
+ ['id', 'string', true],
747
743
  ['name', 'string', true],
748
744
  ['compareMethod', 'number', true],
749
745
  ['rules', 'array', true],
750
746
  ]);
751
747
  const { id, name, rules, compareMethod } = config;
752
748
  const ruleSet = new AbilityRuleSet({
749
+ compareMethod,
753
750
  name,
754
751
  id,
755
752
  });
756
- ruleSet.compareMethod = new AbilityCompare_1.default(compareMethod);
757
753
  // Adding rules if exists
758
754
  if (rules && rules.length > 0) {
759
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.2",
4
+ "version": "2.0.0-rc.4",
5
5
  "description": "Via-Profit Ability service",
6
6
  "keywords": [
7
7
  "ability",