UNPKG

@aedart/support

Version:

The Ion support package

669 lines (649 loc) 18.4 kB
/** * @aedart/support * * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>. */ import { Key } from '@aedart/contracts/support'; import { MetaEntry, MetaTargetContext, MetaCallback, Repository, Context, MetadataRecord, InitializerCallback, MetaException, TargetRepository, MetaAddress, MetaOwnerReference } from '@aedart/contracts/support/meta'; import { DecoratorResult, ClassDecoratorResult, ClassMethodDecoratorResult } from '@aedart/contracts'; /** * Meta Entry * * @see MetaEntry */ declare class Entry implements MetaEntry { /** * Key or path identifier * * @type {Key} */ key: Key; /** * Value to store * * @type {unknown} */ value: unknown; /** * Create a new Meta Entry instance * * @param {Key} key * @param {unknown} value */ constructor(key: Key, value: unknown); /** * Create a new Meta Entry instance * * @param {Key} key * @param {unknown} value * * @return {this|MetaEntry} * * @static */ static make(key: Key, value: unknown): MetaEntry; /** * Resolves given key and returns a new Meta Entry instance * * @param {MetaTargetContext} targetContext * @param {Key | MetaCallback} key * @param {any} [value] * * @return {this|MetaEntry} * * @static */ static resolve(targetContext: MetaTargetContext, key: Key | MetaCallback, value?: any): MetaEntry; /** * Resolves given key-value pair and returns a new Meta Entry instance, with prefixed key * * @param {MetaTargetContext} targetContext * @param {Key} prefixKey * @param {Key|MetaCallback} key * @param {unknown} [value] * * @return {this|MetaEntry} * * @static */ static resolveWithPrefix(targetContext: MetaTargetContext, prefixKey: Key, key: Key | MetaCallback, value?: any): MetaEntry; } /** * Meta Repository * * @see Repository */ declare class MetaRepository implements Repository { /** * The owner class * * @type {object} * * @protected * @readonly */ protected readonly _owner: object; /** * Create a new Meta Repository instance * * @param {object} owner */ constructor(owner: object); /** * Create a new Meta Repository instance * * @param {object} owner * * @return {this|Repository} */ static make(owner: object): Repository; /** * The owner class * * @type {object} */ get owner(): object; /** * Set value for given key * * **Caution**: _Method is intended to be invoked inside a decorator!_ * * @param {object} target Decorator target, e.g. class, field, method...etc * @param {Context} context * @param {Key | MetaCallback} key * @param {any} [value] Value to be stored. Ignored if `key` argument is a callback. * * @return {DecoratorResult} */ set(target: object, context: Context, key: Key | MetaCallback, value?: any): DecoratorResult; /** * Get value for given key * * @template T Return value type * @template D=undefined Type of default value * * @param {Key} key * @param {D} [defaultValue] * * @return {T | D} */ get<T, D = undefined>(key: Key, defaultValue?: D): T | D; /** * Determine if value exists for key * * @param {Key} key */ has(key: Key): boolean; /** * Get all metadata * * @return {MetadataRecord} */ all(): MetadataRecord; /** * Save metadata * * @param {MetaTargetContext} targetContext * @param {Key | MetaCallback} key * @param {any} [value] * * @return {void} * * @protected */ protected save(targetContext: MetaTargetContext, key: Key | MetaCallback, value?: any): void; /** * Defines the {@link METADATA} property in given owner * * @param {object} owner * * @return {void} * * @protected */ protected defineMetadataProperty(owner: object): void; /** * Invokes the given initialisation callbacks * * @param {MetaTargetContext} targetContext * @param {InitializerCallback[]} callbacks * * @return {void} * * @protected */ protected runInitCallbacks(targetContext: MetaTargetContext, callbacks: InitializerCallback[]): void; /** * Determine if metadata record can be used from decorator context * * @param {Context} context * * @return {boolean} * * @protected */ protected useMetadataFromContext(context: Context): boolean; /** * Resolve the metadata record that must be used when writing new metadata * * @param {object} owner * @param {Context} context * * @protected */ protected resolveMetadataRecord(owner: object, context: Context): MetadataRecord; /** * Resolve the "meta" entry's key and value * * @param {MetaTargetContext} targetContext * @param {Key | MetaCallback} key * @param {any} [value] * * @return {MetaEntry} * * @protected */ protected resolveEntry(targetContext: MetaTargetContext, key: Key | MetaCallback, value?: any): MetaEntry; /** * Resolve the meta target context * * **Caution**: _`thisArg` should only be set from an "addInitializer" callback * function, via decorator context._ * * @param {object} target Target the is being decorated * @param {object} thisArg The bound "this" value, from "addInitializer" callback function. * @param {Context} context * * @return {MetaTargetContext} * * @protected */ protected resolveMetaTargetContext(target: object, thisArg: object, context: Context): MetaTargetContext; } /** * Meta Target Context * * @see MetaTargetContext */ declare class TargetContext implements MetaTargetContext { /** * The class that owns the meta * * @type {object} */ owner: object; /** * "This" argument * * @type {any} */ thisArg: any; /** * The target class, field, method... that is being decorated * * @type {object} */ target: object; /** * Decorator context * * @type {Context} */ context: Context; /** * Create a new Meta Target Context instance * * @param {object} owner * @param {any} thisArg * @param {object} target * @param {Context} context */ constructor(owner: object, thisArg: any, /* eslint-disable-line @typescript-eslint/no-explicit-any */ target: object, context: Context); /** * Returns a new Meta Target Context instance * * @param {object} owner * @param {any} thisArg * @param {object} target * @param {Context} context * * @return {this|MetaTargetContext} * * @static */ static make(owner: object, thisArg: any, /* eslint-disable-line @typescript-eslint/no-explicit-any */ target: object, context: Context): MetaTargetContext; /** * Resolves target's owner and returns a new Meta Target Instance * * @param {object} target * @param {object} thisArg * @param {Context} context * * @return {this|MetaTargetContext} * * @static */ static resolveOwner(target: object, thisArg: object, context: Context): MetaTargetContext; } /** * Returns [Meta Repository]{@link Repository} for given owner * * @param {object} owner * * @return {Repository} */ declare function getMetaRepository(owner: object): Repository; /** * Determine if owner has metadata for given key * * @param {object} owner * @param {Key} key * * @return {boolean} */ declare function hasMeta(owner: object, key: Key): boolean; /** * Returns all registered metadata for given target, if available * * @see getMeta * * @param {object} owner Class that owns metadata * * @returns {Readonly<MetadataRecord>} */ declare function getAllMeta(owner: object): Readonly<MetadataRecord>; /** * Return metadata that matches key, for given target * * @see getAllMeta * * @template T * @template D=unknown Type of default value * * @param {object} owner Class that owns metadata * @param {Key} key Key or path identifier * @param {D} [defaultValue=undefined] Default value to return, in case key does not exist * * @returns {T | D | undefined} */ declare function getMeta<T, D = unknown>(owner: object, key: Key, defaultValue?: D): T | D | undefined; /** * Store value as metadata, for given key. * * **Note**: _Method is intended to be used as a decorator!_ * * @example * ```js * @meta('my-key', 'my-value) * class A {} * * getMeta(A, 'my-key'); // 'my-value' * ``` * * @see getMeta * @see getAllMeta * * @param {Key | MetaCallback} key Key or path identifier. If callback is given, * then its resulting [MetaEntry]{@link import('@aedart/contracts/support/meta').MetaEntry}'s `key` * and `value` are stored. * @param {unknown} [value] Value to store. Ignored if `key` argument is a callback. * * @returns {Decorator} */ declare function meta(key: Key | MetaCallback, value?: unknown): (target: object, context: Context) => any; /** * Meta Error * * @see MetaException */ declare class MetaError extends Error implements MetaException { /** * Create a new Meta Error instance * * @param {string} message * @param {ErrorOptions} [options] */ constructor(message: string, options?: ErrorOptions); } /** * Target Meta Repository * * @see TargetRepository */ declare class TargetMetaRepository implements TargetRepository { /** * Returns a new Target Meta Repository * * @return {this|TargetRepository} */ static make(): TargetRepository; /** * Set value for given key, and associates it directly with the target * * **Caution**: _Method is intended to be invoked inside a decorator!_ * * @param {object} target Class or class method target * @param {Context} context * @param {Key | MetaCallback} key * @param {any} [value] Value to be stored. Ignored if `key` argument is a callback. * * @return {ClassDecoratorResult | ClassMethodDecoratorResult} * * @throws {MetaError} */ set(target: object, context: Context, key: Key | MetaCallback, value?: any): ClassDecoratorResult | ClassMethodDecoratorResult; /** * Get value for given key * * @template T Return value type * @template D=undefined Type of default value * * @param {object} target Class or class method target * @param {Key} key * @param {D} [defaultValue] * * @return {T | D} */ get<T, D = undefined>(target: object, key: Key, defaultValue?: D): T | D; /** * Determine if value exists for key * * @param {object} target Class or class method target * @param {Key} key * * @return {boolean} */ has(target: object, key: Key): boolean; /** * Determine there is any metadata associated with target * * @param {object} target * * @return {boolean} */ hasAny(target: object): boolean; /** * Inherit "target" meta from a base class. * * **Note**: _Method is intended to be used as a decorator for static class methods, * in situations where you overwrite static methods and wish to inherit * "target" meta from the parent method._ * * @param {object} target * @param {Context} context * * @return {ClassMethodDecoratorResult} * * @throws {MetaError} */ inherit(target: object, context: Context): ClassMethodDecoratorResult; /** * Find the address where "target" meta is stored for the given target * * @param {object} target * * @return {MetaAddress|undefined} */ find(target: object): MetaAddress | undefined; /** * Returns a new meta callback for given key-value pair. * * **Note**: _Callback is responsible for associating key-value pair with class * or class method._ * * @param {Key | MetaCallback} key * @param {any} [value] * * @protected */ protected makeMetaCallback(key: Key | MetaCallback, value?: any): MetaCallback; /** * Save metadata address in internal registry, for given target * * @param {object} target The target metadata is to be associated with * @param {MetaAddress} address Location where actual metadata is to be found * * @return {void} * * @protected */ protected save(target: object, address: MetaAddress): void; /** * Returns a "prefix" key (path) where "target" metadata must be stored * * @param {Context} context * * @return {Key} * * @throws {MetaError} If {@link Context.kind} is not supported * * @protected */ protected makePrefixKey(context: Context): Key; /** * Returns a new Meta Target Context * * @param {object} owner * @param {any} thisArg * @param {object} target * @param {Context} context * * @return {MetaTargetContext} * * @protected */ protected makeMetaTargetContext(owner: object, thisArg: any, /* eslint-disable-line @typescript-eslint/no-explicit-any */ target: object, context: Context): MetaTargetContext; /*** * Returns a new metadata entry, with prefixed key * * @param {MetaTargetContext} targetContext * @param {Key} prefixKey * @param {Key|MetaCallback} key User provided key or callback * @param {unknown} [value] Value to store. Ignored if `key` argument is * a callback. * * @return {MetaEntry} * * @protected */ protected makeMetaEntry(targetContext: MetaTargetContext, prefixKey: Key, key: Key | MetaCallback, value?: unknown): MetaEntry; /** * Returns a new meta address * * @param {object|MetaOwnerReference} owner * @param {Key} key * * @return {MetaAddress} * * @protected */ protected makeMetaAddress(owner: object | MetaOwnerReference, key: Key): MetaAddress; /** * Returns a new Repository instance for given owner * * @param {object} owner * * @return {Repository} * * @protected */ protected makeRepository(owner: object): Repository; } /** * Returns a new Target Meta Repository * * @return {TargetRepository} */ declare function getTargetMetaRepository(): TargetRepository; /** * Determine there is any metadata associated with target * * @param {object} target * * @return {boolean} */ declare function hasAnyTargetMeta(target: object): boolean; /** * Return metadata that matches key, that belongs to the given target * * **Note**: _Unlike the {@link getMeta} method, this method does not require you * to know the owner object (e.g. the class) that holds metadata, provided * that metadata has been associated with given target, via {@link targetMeta}._ * * @see targetMeta * @see getMeta * * @template T * @template D=unknown Type of default value * * @param {object} target Class or method that owns metadata * @param {Key} key Key or path identifier * @param {D} [defaultValue=undefined] Default value to return, in case key does not exist * * @returns {T | D | undefined} */ declare function getTargetMeta<T, D = unknown>(target: object, key: Key, defaultValue?: D): T | D | undefined; /** * Determine if value exists for key, in given target * * @param {object} target * @param {Key} key * * @return {boolean} */ declare function hasTargetMeta(target: object, key: Key): boolean; /** * Inherit "target" meta from a base class. * * **Note**: _Method is intended to be used as a static method decorator!_ * * **Note**: _To be used in situations where you overwrite static methods and wish to inherit * "target" meta from the parent method._ * * @see targetMeta * * @example * ```ts * class A { * @targetMeta('bar', 'zaz') * static foo() {} * } * * class B extends A { * * @inheritTargetMeta() * static foo() { * // ...overwritten static method...// * } * } * * getTargetMeta(B.foo, 'bar'); // 'zaz' * ``` * * @returns {ClassMethodDecorator} * * @throws {MetaError} When decorated element's owner class has no parent, or when no "target" metadata available * on parent element. */ declare function inheritTargetMeta(): (target: object, context: Context) => any; /** * Stores value for given key, and associates it directly with the target * * **Note**: _Method is intended to be used as a class or method decorator!_ * * @example * ```js * class A { * @targetMeta('my-key', 'my-value') * foo() {} * } * * const a: A = new A(); * getTargetMeta(a.foo, 'my-key'); // 'my-value' * ``` * * @see getTargetMeta * * @param {Key | MetaCallback} key Key or path identifier. If callback is given, * then its resulting [MetaEntry]{@link import('@aedart/contracts/support/meta').MetaEntry}'s `key` * and `value` are stored. * @param {unknown} [value] Value to store. Ignored if `key` argument is * a callback. * @returns {ClassDecorator | ClassMethodDecorator} * * @throws {MetaError} When decorated element is not supported */ declare function targetMeta(key: Key | MetaCallback, value?: unknown): (target: object, context: Context) => any; /** * Element Kind Identifiers * * @type {Record<string, symbol>} */ declare const ELEMENT_KIND_IDENTIFIERS: Record<string, symbol>; /** * Static element identifier * * @type {symbol} */ declare const STATIC_IDENTIFIER: unique symbol; export { ELEMENT_KIND_IDENTIFIERS, Entry, MetaError, MetaRepository, STATIC_IDENTIFIER, TargetContext, TargetMetaRepository, getAllMeta, getMeta, getMetaRepository, getTargetMeta, getTargetMetaRepository, hasAnyTargetMeta, hasMeta, hasTargetMeta, inheritTargetMeta, meta, targetMeta };