@aedart/contracts
Version:
The Ion contracts package. Contains types, interfaces and unique identifiers
451 lines (440 loc) • 12.8 kB
TypeScript
/**
* @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 };