UNPKG

@agape/metadata

Version:
172 lines 6.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetadataDescriptor = void 0; require("reflect-metadata"); /** * A descriptor that holds metadata information for classes, properties, methods, and parameters. * * The `MetadataDescriptor` class is used to store and retrieve metadata associated with various * elements in your codebase. It supports storing information like names, labelPlural, descriptions, * and other metadata that can be used for serialization, validation, documentation generation, * and other metadata-driven operations. * * @example * ### Creating a Descriptor * * ```ts * // create a get descriptor for a class * const descriptor = MetaDataDescriptor.for(MyClass); * * // create or get a descriptor for a property or method * const descriptor = MetaDataDescriptor.for(MyClass, 'myProperty'); * * // create or get adescriptor for a method parameter * const descriptor = MetaDataDescriptor.for(MyClass, 'myMethod', 0); * ``` * @example * ### Retrieving and Existing Descriptor * * ```ts * // get descriptor for a class * const descriptor = MetaDataDescriptor.get(MyClass); * * // get descriptor for a property or method * const descriptor = MetaDataDescriptor.get(MyClass, 'myProperty'); * * // get descriptor for a method parameter * const descriptor = MetaDataDescriptor.get(MyClass, 'myMethod', 0); * ``` * * @example * ### Example * * ```ts * class User { * @Label('Email address') * @Description('The user\'s email address') * @Sensitive() * email: string; * * @Label('Full name') * fullName: string; * } * * // Get metadata for the class * const classDescriptor = MetadataDescriptor.for(User); * console.log(classDescriptor.name); // 'User' * * // Get metadata for the email property * const emailDescriptor = MetadataDescriptor.for(User, 'email'); * console.log(emailDescriptor.label); // 'Email Address' * console.log(emailDescriptor.sensitive); // true * ``` */ class MetadataDescriptor { /** * Creates a new MetadataDescriptor instance. * * @param name - Optional name for the decorated element. If not provided, * the name can be set later or will be automatically determined * when using the `for()` method. */ constructor(name) { this.name = name; } /** * Gets or creates a MetadataDescriptor for the specified target. * * This method retrieves an existing metadata descriptor or creates a new one * if none exists. The name property is automatically set based on the context: * - For classes: uses the class name * - For properties: uses the property name * - For parameters: no name is set (undefined) * * @param target - The target class constructor or object to get metadata for. * @param property - Optional property name when getting metadata for a property or method. * @param index - Optional parameter index when getting metadata for a method parameter. * @returns The MetadataDescriptor for the specified target. If no descriptor exists, * a new one is created and returned. * * @example * ```ts * class Product { * name: string; * price: number; * * calculateTotal(tax: number): number { * return this.price * (1 + tax); * } * } * * // Get descriptor for the class * const classDescriptor = MetadataDescriptor.for(Product); * console.log(classDescriptor.name); // 'Product' * * // Get descriptor for a property * const nameDescriptor = MetadataDescriptor.for(Product, 'name'); * console.log(nameDescriptor.name); // 'name' * * // Get descriptor for a method parameter * const paramDescriptor = MetadataDescriptor.for(Product, 'calculateTotal', 0); * console.log(paramDescriptor.name); // undefined * ``` */ static for(target, property, index) { const prototype = typeof target === 'function' ? target.prototype : target; const token = index !== undefined ? `${property}:${index}` : property || ''; let descriptor = Reflect.getMetadata('agape:metadata', prototype, token); if (descriptor) return descriptor; let name; if (index !== undefined) { name = undefined; } else if (property) { name = property; } else if (typeof target === 'function') { name = target.name; } descriptor = new MetadataDescriptor(name); Reflect.defineMetadata('agape:metadata', descriptor, prototype, token); return descriptor; } /** * Retrieves an existing MetadataDescriptor for the specified target. * * This method only retrieves existing metadata descriptors and does not * create new ones. If no descriptor exists, it returns undefined. * * @param target - The target class constructor or object to get metadata for. * @param property - Optional property name when getting metadata for a property or method. * @param index - Optional parameter index when getting metadata for a method parameter. * @returns The existing MetadataDescriptor if found, otherwise undefined. * * @example * ```ts * class Product { * @Label('Product Name') * name: string; * } * * // Get existing descriptor for the class * const classDescriptor = MetadataDescriptor.get(Product); * console.log(classDescriptor?.name); // 'Product' (if descriptor exists) * * // Get existing descriptor for a property * const nameDescriptor = MetadataDescriptor.get(Product, 'name'); * console.log(nameDescriptor?.label); // 'Product Name' (if descriptor exists) * * // Try to get non-existent descriptor * const nonExistent = MetadataDescriptor.get(Product, 'nonExistent'); * console.log(nonExistent); // undefined * ``` */ static get(target, property, index) { const prototype = typeof target === 'function' ? target.prototype : target; const token = index !== undefined ? `${property}:${index}` : property || ''; return Reflect.getMetadata('agape:metadata', prototype, token); } } exports.MetadataDescriptor = MetadataDescriptor; //# sourceMappingURL=metadata.descriptor.js.map