import { isUndefined } from '@cabloy/utils'; import 'reflect-metadata'; export type MetadataKey = symbol | string; export class AppMetadata { defineMetadata(metadataKey: MetadataKey, metadataValue: V, target: object, prop?: MetadataKey) { if (isUndefined(prop)) { Reflect.defineMetadata(metadataKey, metadataValue, target); } else { Reflect.defineMetadata(metadataKey, metadataValue, target, prop); } } getOwnMetadata(metadataKey: MetadataKey, target: object, prop?: MetadataKey): V | undefined { if (isUndefined(prop)) return Reflect.getOwnMetadata(metadataKey, target); return Reflect.getOwnMetadata(metadataKey, target, prop); } getMetadata(metadataKey: MetadataKey, target: object, prop?: MetadataKey): V | undefined { if (isUndefined(prop)) return Reflect.getMetadata(metadataKey, target); return Reflect.getMetadata(metadataKey, target, prop); } getOwnMetadataArray(inherit: boolean, metadataKey: MetadataKey, target: object, prop?: MetadataKey): Array { let own: Array | undefined = this.getOwnMetadata(metadataKey, target, prop); if (!own) { if (!inherit) { own = []; } else { const parent: Array | undefined = this.getMetadata(metadataKey, target, prop); if (parent) { own = parent.slice(); } else { own = []; } } this.defineMetadata(metadataKey, own, target, prop); } return own; } getOwnMetadataMap(inherit: boolean, metadataKey: MetadataKey, target: object, prop?: MetadataKey): Record { let own: Record | undefined = this.getOwnMetadata(metadataKey, target, prop); if (!own) { if (!inherit) { own = {} as Record; } else { const parent: Record | undefined = this.getMetadata(metadataKey, target, prop); if (parent) { own = Object.assign({}, parent); } else { own = {} as Record; } } this.defineMetadata(metadataKey, own, target, prop); } return own; } getDesignType(target: object, prop?: MetadataKey) { return this.getMetadata('design:type', target as any, prop); } getDesignParamtypes(target: object, prop?: MetadataKey) { return this.getMetadata('design:paramtypes', target, prop); } getDesignReturntype(target: object, prop?: MetadataKey) { return this.getMetadata('design:returntype', target, prop); } } export const appMetadata = new AppMetadata();