UNPKG

metarize

Version:

A lightweight, ESM-compatible TypeScript metadata library for creating and inspecting decorators with zero dependencies

163 lines (148 loc) 5.07 kB
import 'reflect-metadata'; /* eslint-disable @typescript-eslint/no-explicit-any */ /* * namespaced wrapper to handle reflect api */ export class NamespacedReflect { /** * @param namespace - Namespace to bind this reflect context */ constructor(private namespace?: string) {} private getMetadataKey(metadataKey: string): string { // prefix namespace, if provided, to the metadata key return this.namespace ? this.namespace + ':' + metadataKey : metadataKey; } /** * define metadata for a target class or it's property/method */ defineMetadata(metadataKey: string, metadataValue: any, target: Object, propertyKey?: string) { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey); } else { Reflect.defineMetadata(metadataKey, metadataValue, target); } } /** * lookup metadata from a target object and its prototype chain */ getMetadata(metadataKey: string, target: Object, propertyKey?: string): any { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { return Reflect.getMetadata(metadataKey, target, propertyKey); } return Reflect.getMetadata(metadataKey, target); } /** * get own metadata for a target object or it's property/method */ getOwnMetadata(metadataKey: string, target: Object, propertyKey?: string): any { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { return Reflect.getOwnMetadata(metadataKey, target, propertyKey); } return Reflect.getOwnMetadata(metadataKey, target); } /** * Check if the target has corresponding metadata * @param metadataKey - Key * @param target - Target * @param propertyKey - Optional property key */ hasMetadata(metadataKey: string, target: Object, propertyKey?: string): boolean { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { return Reflect.hasMetadata(metadataKey, target, propertyKey); } return Reflect.hasMetadata(metadataKey, target); } hasOwnMetadata(metadataKey: string, target: Object, propertyKey?: string): boolean { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { return Reflect.hasOwnMetadata(metadataKey, target, propertyKey); } return Reflect.hasOwnMetadata(metadataKey, target); } deleteMetadata(metadataKey: string, target: Object, propertyKey?: string): boolean { metadataKey = this.getMetadataKey(metadataKey); if (propertyKey) { return Reflect.deleteMetadata(metadataKey, target, propertyKey); } return Reflect.deleteMetadata(metadataKey, target); } getMetadataKeys(target: Object, propertyKey?: string): string[] { let keys: string[]; if (propertyKey) { keys = Reflect.getMetadataKeys(target, propertyKey); } else { keys = Reflect.getMetadataKeys(target); } const metaKeys = []; if (keys) { if (!this.namespace) return keys; // No normalization is needed const prefix = this.namespace + ':'; for (const key of keys) { if (key.indexOf(prefix) === 0) { // Only add keys with the namespace prefix metaKeys.push(key.slice(prefix.length)); } } } return metaKeys; } getOwnMetadataKeys(target: Object, propertyKey?: string): string[] { let keys: string[]; if (propertyKey) { keys = Reflect.getOwnMetadataKeys(target, propertyKey); } else { keys = Reflect.getOwnMetadataKeys(target); } const metaKeys = []; if (keys) { if (!this.namespace) return keys; // No normalization is needed const prefix = this.namespace + ':'; for (const key of keys) { if (key.indexOf(prefix) === 0) { // Only add keys with the namespace prefix metaKeys.push(key.slice(prefix.length)); } } } return metaKeys; } decorate( decorators: (PropertyDecorator | MethodDecorator)[], target: Object, targetKey?: string | symbol, descriptor?: PropertyDescriptor ): PropertyDescriptor | Function; decorate(decorators: ClassDecorator[], target: Object): PropertyDescriptor | Function; decorate( decorators: (PropertyDecorator | MethodDecorator)[] | ClassDecorator[], target: Object, targetKey?: string | symbol, descriptor?: PropertyDescriptor ): PropertyDescriptor | Function { if (targetKey) { return Reflect.decorate( <(PropertyDecorator | MethodDecorator)[]>decorators, target, targetKey, descriptor ); } else { return Reflect.decorate(<ClassDecorator[]>decorators, <Function>target); } } metadata( metadataKey: string, metadataValue: any ): { (target: Function): void; (target: Object, targetKey: string | symbol): void; } { metadataKey = this.getMetadataKey(metadataKey); return Reflect.metadata(metadataKey, metadataValue); } } export const Reflector = new NamespacedReflect('metarize');