All files / src scope.ts

100% Statements 41/41
100% Branches 12/12
100% Functions 12/12
100% Lines 29/29
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 59 60 61 62    2x       4x 3x         3x 10x               7x 7x     46x 6x 22x   22x 12x 12x     10x 10x   10x   6x   6x         4x 4x   14x 8x 3x 6x 6x   3x 6x   3x   2x  
import { IAuthScope, StringStringMap } from './interfaces';
 
export default class AuthScope implements IAuthScope {
  private SCOPE: StringStringMap;
  private REVERSE_SCOPE: StringStringMap;
 
  constructor(scope: StringStringMap = {}) {
    this.SCOPE = {
      read: 'r',
      write: 'w',
      ...scope
    };
    this.REVERSE_SCOPE = Object.entries(this.SCOPE).reduce(
      (obj, [k, v]) => ({ ...obj, [v]: k }),
      {}
    );
  }
  /**
   * Returns a scope in the format 'a:r:w' using a set of rules like
   * ['admin:read', 'admin:write']
   */
  public create(scope: string[]): string {
    if (!scope.length) return '';
 
    let lastName: string;
    const shortPerm = (perm: string) => this.SCOPE[perm] || perm;
    const shortRole = (newScope: string[], r: string) => {
      const role = r.split(':').map(shortPerm);
 
      if (lastName === role[0]) {
        newScope[newScope.length - 1] += `:${role.slice(1).join(':')}`;
        return newScope;
      }
 
      lastName = role[0];
      newScope.push(role.join(':'));
 
      return newScope;
    };
    const scopeStr = scope.reduce(shortRole, []).join('|');
 
    return scopeStr;
  }
  /**
   * Returns a scope string as an array of rules
   */
  public parse(scopeStr: string): string[] {
    if (!scopeStr) return [];
 
    const longPerm = (perm: string) => this.REVERSE_SCOPE[perm] || perm;
    const joinPerm = (name: string) => (perm: string) => name + ':' + perm;
    const splitRole = (role: string) => {
      const [name, ...perms] = role.split(':').map(longPerm);
      return perms.map(joinPerm(name));
    };
    const pushRoles = (roles: string[], role: string) =>
      roles.concat(splitRole(role));
 
    return scopeStr.split('|').reduce(pushRoles, []);
  }
}