All files scope.ts

0% Statements 0/34
0% Branches 0/15
0% Functions 0/11
0% Lines 0/26
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                                                                                                                           
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 || !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 || !scopeStr.length) 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, []);
  }
}