All files / common/utils/src _meta.util.ts

0% Statements 0/35
0% Branches 0/20
0% Functions 0/7
0% Lines 0/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125                                                                                                                                                                                                                                                         
import { assert } from './assert.util';
import { isUndefined } from './utils';
 
declare let Reflect: {
  getOwnMetadata(
    key: string | symbol,
    target: object,
    propertyKey?: string | symbol,
  ): any;
  defineMetadata(
    key: string | symbol,
    value: any,
    target: object,
    propertyKey?: string | symbol,
  ): void;
 
  getOwnMetadataKeys(target: any, propertyKey?: string | symbol): string[];
};
 
// rough Reflect polyfill
Iif (!Reflect.getOwnMetadata || !Reflect.defineMetadata) {
  const _meta = new Map<
    any,
    Map<string | symbol | undefined, Map<string, any>>
  >();
 
  Reflect.getOwnMetadata = function (
    key: string,
    target: object,
    propertyKey?: string,
  ): any {
    return _meta.get(target)?.get(propertyKey)?.get(key);
  };
  Reflect.defineMetadata = function (
    key: string,
    value: any,
    target: object,
    propertyKey?: string,
  ): void {
    const tBucket = _meta.get(target) ?? new Map();
    const pkBucket = tBucket.get(propertyKey) ?? new Map();
 
    _meta.set(target, tBucket);
    tBucket.set(key, pkBucket);
    pkBucket.set(key, value);
  };
 
  Reflect.getOwnMetadataKeys = function (
    target: object,
    propertyKey?: string | symbol,
  ): string[] {
    const pkBucket = _meta.get(target)?.get(propertyKey ?? '') ?? new Map();
 
    return [...pkBucket.keys()];
  };
}
 
export function getMetadataKeys(
  target: object,
  propertyKey?: string | symbol,
): string[] {
  return Reflect.getOwnMetadataKeys(target, propertyKey);
}
 
export function defineMetadata(
  key: string,
  value: any,
  target: object,
  propertyKey?: string | symbol,
): void;
 
export function defineMetadata(
  key: string,
  value: any,
  target: object,
  propertyKey?: string | symbol,
) {
  return Reflect.defineMetadata(key, value, target, propertyKey);
}
 
export function getMetadata<T>(
  key: string | symbol,
  target: object,
  valueGenerator?: () => T,
  save?: boolean,
): T;
 
export function getMetadata<T>(
  key: string | symbol,
  target: object,
  propertyKey: string | symbol,
  valueGenerator?: () => T,
  save?: boolean,
): T;
export function getMetadata<T>(
  key: string | symbol,
  target: object,
  propertyKey?: string | symbol | (() => T),
  valueGenerator?: (() => T) | boolean,
  save = true,
): T {
  let _propertyKey = propertyKey as string | symbol | undefined;
  let _valueGenerator = valueGenerator as () => T | void;
  Iif (typeof valueGenerator === 'boolean') {
    save = valueGenerator;
  }
  Iif (typeof propertyKey === 'function') {
    _valueGenerator = propertyKey;
    _propertyKey = undefined;
  }
  _valueGenerator = _valueGenerator ?? (() => {});
 
  assert(!!target);
  let value = Reflect.getOwnMetadata(key, target, _propertyKey);
 
  Iif (isUndefined(value)) {
    value = _valueGenerator?.();
    Iif (save && value !== undefined) {
      Reflect.defineMetadata(key, value, target, _propertyKey);
    }
  }
 
  return value;
}