UNPKG

@aedart/contracts

Version:

The Ion contracts package. Contains types, interfaces and unique identifiers

451 lines (440 loc) 12.8 kB
/** * @aedart/contracts * * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>. */ import { Constructor, Callback, ClassMethodReference, ConstructorLike } from '@aedart/contracts'; import { CallbackWrapper } from '@aedart/contracts/support'; import { Throwable } from '@aedart/contracts/support/exceptions'; /** * Contextual Binding Builder * * Adaptation of Laravel's Contextual Binding Builder. * * @see https://github.com/laravel/framework/blob/master/src/Illuminate/Contracts/Container/ContextualBindingBuilder.php */ interface ContextualBindingBuilder { /** * Define the target identifier in this context. * * @param {Identifier} identifier * * @return {this} */ needs(identifier: Identifier): this; /** * Define the implementation to be resolved in this context. * * @param {FactoryCallback | Constructor} implementation * * @return {void} * * @throws {TypeError} */ give(implementation: FactoryCallback | Constructor): void; } /** * Service Container * * Adaptation of Psr's `ContainerInterface`, and Laravel's service `Container`. * * @see https://www.php-fig.org/psr/psr-11/#31-psrcontainercontainerinterface * @see https://github.com/laravel/framework/blob/master/src/Illuminate/Contracts/Container/Container.php */ interface Container { /** * Register a binding * * @param {Identifier} identifier * @param {FactoryCallback | Constructor} [concrete] * @param {boolean} [shared=false] * * @returns {this} * * @throws {TypeError} */ bind(identifier: Identifier, concrete?: FactoryCallback | Constructor, shared?: boolean): this; /** * Register a binding, if none already exists for given identifier * * @param {Identifier} identifier * @param {FactoryCallback | Constructor} [concrete] * @param {boolean} [shared=false] * * @returns {this} * * @throws {TypeError} */ bindIf(identifier: Identifier, concrete?: FactoryCallback | Constructor, shared?: boolean): this; /** * Register a shared binding * * @param {Identifier} identifier * @param {FactoryCallback | Constructor} [concrete] * * @returns {this} * * @throws {TypeError} */ singleton(identifier: Identifier, concrete?: FactoryCallback | Constructor): this; /** * Register a shared binding, if none already exists for given identifier * * @param {Identifier} identifier * @param {FactoryCallback | Constructor} [concrete] * * @returns {this} * * @throws {TypeError} */ singletonIf(identifier: Identifier, concrete?: FactoryCallback | Constructor): this; /** * Register existing object instance as a shared binding * * @template T = object * * @param {Identifier} identifier * @param {T} instance * * @returns {T} * * @throws {TypeError} */ instance<T = object>(identifier: Identifier, instance: T): T; /** * Add a contextual binding in this container * * @param {Constructor} concrete * @param {Identifier} identifier * @param {FactoryCallback | Constructor} implementation * * @return {this} * * @throws {TypeError} */ addContextualBinding(concrete: Constructor, identifier: Identifier, implementation: FactoryCallback | Constructor): this; /** * Define a contextual binding * * @param {...Constructor[]} concrete * * @return {ContextualBindingBuilder} * * @throws {TypeError} */ when(...concrete: Constructor[]): ContextualBindingBuilder; /** * Resolves binding value that matches identifier and returns it * * @template T = any * * @param {Identifier} identifier * * @returns {T} * * @throws {NotFoundException} * @throws {ContainerException} */ get<T = any>(identifier: Identifier): T; /** * Determine if an entry is registered for given identifier. * * @param {Identifier} identifier * * @returns {boolean} */ has(identifier: Identifier): boolean; /** * Alias for {@link has} * * @param {Identifier} identifier * * @returns {boolean} */ bound(identifier: Identifier): boolean; /** * Alias identifier as a different identifier * * @param {Identifier} identifier * @param {Alias} alias * * @returns {this} * * @throws {TypeError} */ alias(identifier: Identifier, alias: Alias): this; /** * Determine if identifier is an alias * * @param {Identifier} identifier * * @return {boolean} */ isAlias(identifier: Identifier): boolean; /** * Determine if identifier is registered as a "shared" binding * * @param {Identifier} identifier * * @returns {boolean} */ isShared(identifier: Identifier): boolean; /** * Resolves binding value that matches identifier and returns it * * @template T = any * * @param {Identifier} identifier * @param {any[]} [args] Eventual arguments to pass on to {@link FactoryCallback} or {@link Constructor} * * @returns {T} * * @throws {NotFoundException} * @throws {ContainerException} */ make<T = any>(identifier: Identifier, args?: any[]): T; /** * Resolves values if a binding exists for identifier, or returns a default value * * @template T = any * @template D = undefined * * @param {Identifier} identifier * @param {any[]} [args] Eventual arguments to pass on to {@link FactoryCallback} or {@link Constructor} * @param {D} [defaultValue] * * @returns {T} * * @throws {ContainerException} */ makeOrDefault<T = any, /* eslint-disable-line @typescript-eslint/no-explicit-any */ D = undefined>(identifier: Identifier, args?: any[], defaultValue?: D): T | D; /** * Instantiate a new instance of given concrete * * @template T = object * * @param {Constructor<T> | Binding<T>} concrete * @param {any[]} [args] Eventual arguments to pass on the concrete instance's constructor. * * @returns {T} * * @throws {ContainerException} */ build<T = object>(concrete: Constructor<T> | Binding<T>, args?: any[]): T; /** * Call given method and inject dependencies if needed * * @param {Callback | CallbackWrapper | ClassMethodReference} method * @param {any[]} [args] * * @return {any} * * @throws {ContainerException} */ call(method: Callback | CallbackWrapper | ClassMethodReference, args?: any[]): any; /** * Extend the registered binding * * @param {Identifier} identifier * @param {ExtendCallback} callback * * @return {this} * * @throws {TypeError} * @throws {ContainerException} */ extend(identifier: Identifier, callback: ExtendCallback): this; /** * Register a callback to be invoked whenever identifier is "rebound" * * @param {Identifier} identifier * @param {ReboundCallback} callback * * @return {any | void} * * @throws {ContainerException} */ rebinding(identifier: Identifier, callback: ReboundCallback): any | void; /** * Forget binding and resolved instance for given identifier * * @param {Identifier} identifier * * @returns {boolean} */ forget(identifier: Identifier): boolean; /** * Forget resolved instance for given identifier * * @param {Identifier} identifier * * @return {boolean} */ forgetInstance(identifier: Identifier): boolean; /** * Flush container of all bindings and resolved instances * * @returns {void} */ flush(): void; /** * Determine if identifier has been resolved * * @param {Identifier} identifier * * @return {boolean} */ isResolved(identifier: Identifier): boolean; /** * Register a callback to be invoked before a binding is resolved * * @param {Identifier} identifier * @param {BeforeResolvedCallback} callback * * @return {this} */ before(identifier: Identifier, callback: BeforeResolvedCallback): this; /** * Register a callback to be invoked after a binding has been resolved * * @param {Identifier} identifier * @param {AfterResolvedCallback} callback * * @return {this} */ after(identifier: Identifier, callback: AfterResolvedCallback): this; } /** * Binding Identifier * * A unique identifier used for associating "concrete" items or values in * a service container. */ type Identifier = string | symbol | number | NonNullable<object> | ConstructorLike | Callback; /** * Binding Alias * * @see Identifier */ type Alias = Identifier; /** * Factory Callback * * The callback is responsible for resolving a value, when a binding * is resolved in a service container. */ type FactoryCallback<Value = any> = (container: Container, ...args: any[]) => Value; /** * Extend Callback * * Callback can be used to "extend", decorate or modify a resolved value * from the service container. */ type ExtendCallback<Value = any, /* eslint-disable-line @typescript-eslint/no-explicit-any */ ExtendedValue extends Value = any> = (resolved: Value, container: Container) => ExtendedValue; /** * Rebound Callback * * Callback to be invoked when a binding is "rebound". */ type ReboundCallback<Value = any> = (resolved: Value, container: Container) => void; /** * Before Resolved Callback * * Callback to be invoked before a binding is resolved. */ type BeforeResolvedCallback = (identifier: Identifier, args: any[], /* eslint-disable-line @typescript-eslint/no-explicit-any */ container: Container) => void; /** * After Resolved Callback * * Callback to be invoked after a binding has been resolved. */ type AfterResolvedCallback<Value = any> = (identifier: Identifier, resolved: Value, container: Container) => void; /** * Binding Entry * * @template T = any */ interface Binding<T = any> { /** * This binding's identifier * * @type {Identifier} * * @readonly */ readonly identifier: Identifier; /** * The bound value to be resolved by a service container * * @template T = any * * @type {FactoryCallback<T> | Constructor<T>} * * @readonly */ readonly value: FactoryCallback<T> | Constructor<T>; /** * Shared state of resolved value * * @type {boolean} If `true`, then service container must register resolved * value as a singleton. * * @readonly */ readonly shared: boolean; /** * Determine if bound value is a {@link FactoryCallback} * * @returns {boolean} */ isFactoryCallback(): boolean; /** * Determine if bound value is a {@link Constructor} * * @returns {boolean} */ isConstructor(): boolean; } /** * Container Exception * * General exception to be thrown when something went wrong inside * a service container. Inspired by Psr's `ContainerExceptionInterface`. * * @see https://www.php-fig.org/psr/psr-11/#32-psrcontainercontainerexceptioninterface */ interface ContainerException extends Throwable { } /** * Circular Dependency Exception * * To be thrown in situations when a binding has a circular dependency. */ interface CircularDependencyException extends ContainerException { } /** * Not Found Exception * * To be thrown when no entry was found for a given binding identifier. * Inspired by Psr's `NotFoundExceptionInterface`. * * @see https://www.php-fig.org/psr/psr-11/#33-psrcontainernotfoundexceptioninterface */ interface NotFoundException extends ContainerException { } /** * Container identifier * * @type {Symbol} */ declare const CONTAINER: unique symbol; /** * Dependencies identifier * * Symbol is intended to be used as an identifier for when associating binding identifiers * or "concrete" dependencies with an element, e.g. a class, class method, function,...etc. * * @type {symbol} */ declare const DEPENDENCIES: unique symbol; export { type AfterResolvedCallback, type Alias, type BeforeResolvedCallback, type Binding, CONTAINER, type CircularDependencyException, type Container, type ContainerException, type ContextualBindingBuilder, DEPENDENCIES, type ExtendCallback, type FactoryCallback, type Identifier, type NotFoundException, type ReboundCallback };