@aedart/support
Version:
The Ion support package
669 lines (649 loc) • 18.4 kB
TypeScript
/**
* @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 };