All files builder.js

90.48% Statements 19/21
73.33% Branches 11/15
100% Functions 6/6
90.48% Lines 19/21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58      206x         40x 40x 40x 40x   40x       1x   1x               41x       103x       103x       103x   103x 50x     103x   103x       33x 33x   33x      
import { Ability } from './ability';
 
function isStringOrNonEmptyArray(value) {
  return typeof value === 'string' || Array.isArray(value) && value.length > 0;
}
 
export class AbilityBuilder {
  static define(params, dsl) {
    const options = typeof params === 'function' ? {} : params;
    const define = params === options ? dsl : params;
    const builder = new this();
    define(builder.can.bind(builder), builder.cannot.bind(builder));
 
    return new Ability(builder.rules, options);
  }
 
  static extract() {
    const builder = new this();
 
    return {
      can: builder.can.bind(builder),
      cannot: builder.cannot.bind(builder),
      rules: builder.rules
    };
  }
 
  constructor() {
    this.rules = [];
  }
 
  can(actions, subject, conditions) {
    Iif (!isStringOrNonEmptyArray(actions)) {
      throw new TypeError('AbilityBuilder#can expects the first parameter to be an action or array of actions');
    }
 
    Iif (!isStringOrNonEmptyArray(subject)) {
      throw new TypeError('AbilityBuilder#can expects the second argument to be a subject name or array of subject names');
    }
 
    const rule = { actions, subject };
 
    if (typeof conditions === 'object' && conditions) {
      rule.conditions = conditions;
    }
 
    this.rules.push(rule);
 
    return rule;
  }
 
  cannot(...args) {
    const rule = this.can(...args);
    rule.inverted = true;
 
    return rule;
  }
}