UNPKG

metarize

Version:

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

175 lines 7.45 kB
import debugModule from './debug.js'; import { DecoratorFactory } from './decorator-factory.js'; import { NamespacedReflect, Reflector } from './reflect.js'; const debug = debugModule('metarize:metadata:inspector'); /** * TypeScript reflector without a namespace. The TypeScript compiler can be * configured to add design time metadata. * * See https://www.typescriptlang.org/docs/handbook/decorators.html */ const TSReflector = new NamespacedReflect(); /** * Inspector for metadata applied by decorators */ export class MetadataInspector { /** * Expose Reflector, which is a wrapper of `Reflect` and it uses `metarize` * as the namespace prefix for all metadata keys */ static Reflector = Reflector; /** * Expose the reflector for TypeScript design-time metadata */ static DesignTimeReflector = TSReflector; /** * Get the metadata associated with the given key for a given class * @param key - Metadata key * @param target - Class that contains the metadata * @param options - Options for inspection */ static getClassMetadata(key, target, options) { return options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); } /** * Define metadata for the given target * @param key - Metadata key * @param value - Metadata value * @param target - Target for the metadata * @param member - Optional property or method name */ static defineMetadata(key, value, target, member) { Reflector.defineMetadata(key.toString(), value, target, member); } /** * Get the metadata associated with the given key for all methods of the * target class or prototype * @param key - Metadata key * @param target - Class for static methods or prototype for instance methods * @param options - Options for inspection */ static getAllMethodMetadata(key, target, options) { return options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); } /** * Get the metadata associated with the given key for a given method of the * target class or prototype * @param key - Metadata key * @param target - Class for static methods or prototype for instance methods * @param methodName - Method name. If not present, default to '' to use * the constructor * @param options - Options for inspection */ static getMethodMetadata(key, target, methodName, options) { methodName = methodName ?? ''; const meta = options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); return meta?.[methodName]; } /** * Get the metadata associated with the given key for all properties of the * target class or prototype * @param key - Metadata key * @param target - Class for static methods or prototype for instance methods * @param options - Options for inspection */ static getAllPropertyMetadata(key, target, options) { return options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); } /** * Get the metadata associated with the given key for a given property of the * target class or prototype * @param key - Metadata key * @param target - Class for static properties or prototype for instance * properties * @param propertyName - Property name * @param options - Options for inspection */ static getPropertyMetadata(key, target, propertyName, options) { const meta = options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); return meta?.[propertyName]; } /** * Get the metadata associated with the given key for all parameters of a * given method * @param key - Metadata key * @param target - Class for static methods or prototype for instance methods * @param methodName - Method name. If not present, default to '' to use * the constructor * @param options - Options for inspection */ static getAllParameterMetadata(key, target, methodName, options) { methodName = methodName ?? ''; const meta = options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); return meta?.[methodName]; } /** * Get the metadata associated with the given key for a parameter of a given * method by index * @param key - Metadata key * @param target - Class for static methods or prototype for instance methods * @param methodName - Method name. If not present, default to '' to use * the constructor * @param index - Index of the parameter, starting with 0 * @param options - Options for inspection */ static getParameterMetadata(key, target, methodName, index, options) { methodName = methodName || ''; const meta = options?.ownMetadataOnly ? Reflector.getOwnMetadata(key.toString(), target) : Reflector.getMetadata(key.toString(), target); const params = meta?.[methodName]; return params?.[index]; } /** * Get TypeScript design time type for a property * @param target - Class or prototype * @param propertyName - Property name * @returns Design time metadata. The return value is `undefined` when: * - The property has type `undefined`, `null` * - The TypeScript project has not enabled the compiler option `emitDecoratorMetadata`. * - The code is written in vanilla JavaScript. */ static getDesignTypeForProperty(target, propertyName) { return TSReflector.getMetadata('design:type', target, propertyName); } /** * Get TypeScript design time type for a method. * @param target - Class or prototype * @param methodName - Method name * @returns Design time metadata. The return value is `undefined` * in projects that do not enable `emitDecoratorMetadata` * in TypeScript compiler options or are written in vanilla JavaScript. */ static getDesignTypeForMethod(target, methodName) { const type = TSReflector.getMetadata('design:type', target, methodName); const parameterTypes = TSReflector.getMetadata('design:paramtypes', target, methodName); const returnType = TSReflector.getMetadata('design:returntype', target, methodName); if (type === undefined && parameterTypes === undefined && returnType === undefined) { /* istanbul ignore next */ if (debug.enabled) { const targetName = DecoratorFactory.getTargetName(target, methodName); debug('No design-time type metadata found while inspecting %s. ' + 'Did you forget to enable TypeScript compiler option `emitDecoratorMetadata`?', targetName); } return undefined; } return { type, parameterTypes, returnType, }; } } //# sourceMappingURL=inspector.js.map