Code coverage report for core/src/env.ts

Statements: 83.33% (25 / 30)      Branches: 60.61% (20 / 33)      Functions: 100% (8 / 8)      Lines: 82.76% (24 / 29)      Ignored: none     

All files » core/src/ » env.ts
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                                        1 63         9 9   9       9     9       9         60     60   60 62         60         18         3 2 2           3 3 1   3             1 1 1      
import {Supplier} from './util';
 
 
export type KeyFallback = {
  name: string;
  global?: string;
};
export type Key = string | KeyFallback;
 
 
export interface Props {
  getConfig(prefix: string, or?: Props | Supplier<Props | undefined>): Props;
 
  getProp(key: Key, or?: string | Supplier<string | undefined>): string | undefined;
}
 
 
let instance: Env;
 
 
export class Env implements Props {
  constructor(private readonly props: Record<string, string>, private readonly parent?: Props) {
  }
 
 
  getProp(key: Key, or?: string | Supplier<string | undefined>): string | undefined {
    const _key: Key = typeof key === 'string' ? { name: key } : key;
    let result: string | undefined = this.props[_key.name] || this.parent?.getProp(_key);
 
    Iif (!result && _key.global) {
      result = this.props[_key.global] || this.parent?.getProp(_key.global);
    }
 
    Iif (!result && typeof or === 'function') {
      result = or();
    }
    else Iif (typeof or === 'string') {
      result = or;
    }
 
    return result;
  }
 
 
  getConfig(fqn: string | { fqn: string }): Props {
    fqn = (
      typeof fqn === 'string' ? fqn : fqn.fqn
    );
    const props: Record<string, string> = {};
 
    for (const [k, v] of Object.entries(this.props)) {
      Iif (k.startsWith(fqn)) {
        const name = k.replace(fqn, '').replace(/^_/, '');
        props[name] = v;
      }
    }
    return new Env(props);
  }
 
 
  static root(): Env | undefined {
    return instance;
  }
 
 
  static load(suppliers: Supplier<Record<string, string>>[], root = false): Env {
    const props: Record<string, string> = suppliers.reduce((last, loader) => {
      const more = loader();
      return {
        ...last,
        ...more,
      }
    }, {} as Record<string, string>);
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    const result = new Env(props);
    if (!instance || root) {
      instance = result;
    }
    return result;
  }
 
 
}
 
 
export function loadEnvWithObj(object: Record<string, string>): Supplier<Record<string, string>> {
  return function loadObj(): Record<string, string> {
    return object;
  };
}