@clawject/di
Version:
<p align="center"> <a href="https://clawject.com/" target="_blank"><img src="https://clawject.com/img/logo.svg" align="center" alt="Clawject Logo" width="120" height="120" /></a> </p>
620 lines (570 loc) • 24.2 kB
TypeScript
/**
* @internalApi It's a part of API used by clawject internally,
* do not rely on it in your code because it **may and will be changed** without notice.
*
* @public
*/
export declare interface ___TypeReferenceTable___ {
Array: ReadonlyArray<any> | Array<any> | readonly any[] | any[];
Set: ReadonlySet<any> | Set<any>;
Map: ReadonlyMap<any, any> | Map<any, any>;
MapStringToAny: ReadonlyMap<string, any> | Map<string, any>;
Promise: Promise<any> | PromiseLike<any>;
ImportedConfiguration: ImportedConfiguration<any, any>;
BeanConstructorFactory: BeanConstructorFactory<any, any>;
ClawjectDecorator: ClawjectDecorator<any>;
}
/**
* Indicates that a method/property produces/contains a bean or a bean constructor
* to be managed by the Clawject container.
*
* @docs https://clawject.com/docs/fundamentals/bean
*
* @public
*/
export declare const Bean: {
<C extends ClassConstructor<any>>(classConstructor: C): BeanConstructorFactory<InstanceType<C>, C>;
<C extends ClassConstructor<any>>(classConstructor: Promise<C> | PromiseLike<C>): Promise<BeanConstructorFactory<InstanceType<C>, C>>;
<T, C extends ClassConstructor<T>>(classConstructor: C): BeanConstructorFactory<T, C>;
<T, C extends ClassConstructor<T>>(classConstructor: Promise<C> | PromiseLike<C>): Promise<BeanConstructorFactory<T, C>>;
} & DecoratorWithoutArguments<BeanTarget> & ClawjectDecorator<'Bean'>;
/** @public */
export declare interface BeanConstructorFactory<T, C extends ClassConstructor<T>> {
constructor: C;
factory: (...args: ConstructorParameters<C>) => T;
}
/**
* @internalApi Changes to it will not be considered a breaking change in terms of semantic versioning.
*
* @public
* */
export declare interface BeanMetadata {
readonly parentConfigurationClassConstructor: ClassConstructor<any>;
readonly parentConfigurationInstance: object;
readonly name: string;
readonly classPropertyName: string;
readonly scope: string | number;
readonly resolvedConstructor: ClassConstructor<any> | null;
}
/**
* @internalApi Changes to it will not be considered a breaking change in terms of semantic versioning.
*
* @public
* */
export declare interface BeanProcessor {
processFactory?(factoryMetadata: BeanProcessorFactoryMetadata): BeanProcessorFactoryMetadata['factory'];
onBeansInitialized?(): void;
}
/**
* @internalApi Changes to it will not be considered a breaking change in terms of semantic versioning.
*
* @public
* */
export declare interface BeanProcessorFactoryMetadata {
readonly beanMetadata: BeanMetadata;
readonly factory: (...injectedBeans: unknown[]) => ObjectFactoryResult | Promise<ObjectFactoryResult>;
}
/** @public */
export declare type BeanTarget = PropertyDecorator & MethodDecorator & ModernClassFieldDecorator & ModernClassGetterDecorator & ModernClassMethodDecorator;
/**
* @internalApi Just a utility type.
*
* @public
*/
export declare type ClassConstructor<T, A extends any[] = any[]> = {
new (...args: A): T;
};
/**
* Indicates that a target class is a {@link Configuration @Configuration} class and an entry point for the Clawject application.
*
* @docs https://clawject.com/docs/fundamentals/configurations
*
* @public
*/
export declare const ClawjectApplication: DecoratorWithoutArguments<ClawjectApplicationTarget> & ClawjectDecorator<'ClawjectApplication'>;
/**
* It is an object that stores and manages configurations and beans of the application.
*
* @docs https://clawject.com/docs/fundamentals/clawject-application-context
*
* @public
*/
export declare interface ClawjectApplicationContext<T extends ClassConstructor<any>> {
/**
* Returns the exposed bean instance by the given name.
* */
getExposedBean<K extends keyof GetBeansResult<T>>(beanName: K & string): Promise<GetBeansResult<T>[K]>;
/**
* Returns all exposed beans.
* */
getExposedBeans(): Promise<GetBeansResult<T>>;
/**
* Closes the application context and destroys all beans.
* Functions annotated with `@PreDestroy` will be called for all beans.
* */
destroy(): Promise<void>;
}
/** @public */
export declare type ClawjectApplicationTarget = ClassDecorator & ModernClassDecorator;
/**
* Type-indicator for a clawject decorators.
*
* @public
* */
export declare interface ClawjectDecorator<Name extends string> {
}
/**
* Use ClawjectFactory to create an application context instance.
*
* @public
* */
export declare const ClawjectFactory: ClawjectFactoryStatic;
/**
* It's a factory class that creates a {@link ClawjectApplicationContext} instance.
*
* @docs https://clawject.com/docs/fundamentals/clawject-factory
*
* @public
* */
declare class ClawjectFactoryStatic {
private beanProcessors;
private scopes;
private readonly scopeRegister;
private constructor();
static readonly instance: ClawjectFactoryStatic;
/**
* Creates a {@link ClawjectApplicationContext} instance.
*
* @param clawjectApplication - The class that is annotated with {@link ClawjectApplication @ClawjectApplication}.
* */
createApplicationContext<C extends ClassConstructor<any, []>>(clawjectApplication: C): Promise<ClawjectApplicationContext<C>>;
/**
* Creates a {@link ClawjectApplicationContext} instance.
*
* @param clawjectApplication - The class that is annotated with {@link ClawjectApplication @ClawjectApplication}.
* @param constructorParameters - The constructor parameters of the `clawjectApplication` class.
* */
createApplicationContext<C extends ClassConstructor<any>>(clawjectApplication: C, constructorParameters: InstantiationConstructorParameters<ConstructorParameters<C>>): Promise<ClawjectApplicationContext<C>>;
/**
* Creates new instance of {@link ClawjectFactoryStatic} with assigned {@link BeanProcessor}.
* */
withBeanProcessor(beanProcessor: BeanProcessor): ClawjectFactoryStatic;
/**
* Creates new instance of {@link ClawjectFactoryStatic} with assigned {@link Scope}.
* */
withScope(scopeName: string | number, scope: Scope): ClawjectFactoryStatic;
/**
* Creates new instance of {@link ClawjectFactoryStatic} with assigned scope alias.
* */
withScopeAlias(from: ScopeValue, to: string | number): ClawjectFactoryStatic;
}
/**
* Indicates that a target class is a Configuration class, and can contains bean definitions, configuration imports.
*
* @docs https://clawject.com/docs/fundamentals/configurations
*
* @public
*/
export declare const Configuration: DecoratorWithoutArguments<ConfigurationTarget> & ClawjectDecorator<'Configuration'>;
/** @public */
export declare type ConfigurationTarget = ClassDecorator & ModernClassDecorator;
/**
* @internalApi Type declaration for a decorator without arguments.
*
* @public
*/
export declare type DecoratorWithoutArguments<T> = T & ((this: void) => T);
/**
* When applied to {@link Bean} - all object members will be registered as a beans.
*
* @docs https://clawject.com/docs/fundamentals/embedded
*
* @public
*/
export declare const Embedded: DecoratorWithoutArguments<BeanTarget> & ClawjectDecorator<'Embedded'>;
/**
* *ExposeBeans* function allows you to expose beans from the application context,
* so that they can be accessed from the outside of the {@link ClawjectApplication @ClawjectApplication} class.
*
* This function will have an effect only on the root of your application context class
* (the one annotated with {@link ClawjectApplication @ClawjectApplication}).
* Clawject will validate the beans that are being exposed
* and will report an error if the bean is not found in the application context.
*
* @docs https://clawject.com/docs/fundamentals/expose-beans
*
* @public
* */
export declare const ExposeBeans: <T extends object>() => (exposedBeans: ExposedBeans<T>) => ExposedBeans<T>;
/**
* Object that is produced by {@link ExposeBeans} function.
*
* @public
* */
export declare interface ExposedBeans<T extends object> {
readonly beans: T;
readonly ___clawject_internal_token___: never;
}
/**
* It Indicates that the bean or configuration import is only visible within the class in which it is applied.
* When applied on class level,
* all beans and configuration imports defined in the class are only visible within the class.
*
* @docs https://clawject.com/docs/fundamentals/internal-external#internal
*
* @public
*/
export declare const External: DecoratorWithoutArguments<InternalExternalTarget> & ((value: boolean) => InternalExternalTarget) & ClawjectDecorator<'External'>;
/**
* @internalApi Just a utility type.
*
* @public
*/
export declare type FieldValues<T extends object> = T[keyof T];
/**
* @internalApi Object that is produced by {@link ClawjectApplicationContext#getExposedBeans} function.
*
* @public
*/
export declare type GetBeansResult<T extends ClassConstructor<any>> = MergedObjects<ReturnType<FieldValues<PickFieldsWithType<InstanceType<T>, (arg: ExposedBeans<any>) => ExposedBeans<any>>>>['beans'] | {}>;
/**
* *Import* function allows you
* to import a {@link Configuration @Configuration} class into the target {@link Configuration @Configuration} class
* to use beans that is provided by imported configuration.
*
* @public
* */
export declare const Import: {
<C extends ClassConstructor<any, []>>(configurationClass: C): ImportedConfiguration<C>;
<C extends ClassConstructor<any>>(configurationClass: C, constructorParameters: InstantiationConstructorParameters<ConstructorParameters<C>>): ImportedConfiguration<C>;
<C extends ClassConstructor<any, []>>(configurationClass: Promise<C>): Promise<ImportedConfiguration<C>>;
<C extends ClassConstructor<any>>(configurationClass: Promise<C>, constructorParameters: InstantiationConstructorParameters<ConstructorParameters<C>>): Promise<ImportedConfiguration<C>>;
};
/**
* @internalApi Object that is produced by {@link Import} function.
*
* @public
*/
export declare interface ImportedConfiguration<C extends ClassConstructor<any>, A extends any[] = ConstructorParameters<C>> {
readonly constructor: C;
readonly constructorParameters: A | (() => A | Promise<A>);
readonly ___clawject_internal_token___: never;
}
/**
* Just a utility type.
*
* @public
*/
export declare type InstantiationConstructorParameters<A extends any[]> = A | (() => A | Promise<A>);
/**
* It Indicates that the bean or configuration import is visible outside the class in which they are defined.
* When applied on class level, all beans and configuration imports defined in the class become visible outside the class.
*
* @docs https://clawject.com/docs/fundamentals/internal-external#external
*
* @public
*/
export declare const Internal: DecoratorWithoutArguments<InternalExternalTarget> & ((value: boolean) => InternalExternalTarget) & ClawjectDecorator<'Internal'>;
/** @public */
export declare type InternalExternalTarget = ClassDecorator & PropertyDecorator & MethodDecorator & ModernClassDecorator & ModernClassFieldDecorator & ModernClassGetterDecorator & ModernClassMethodDecorator;
/**
* Indicates whether a bean is to be lazily initialized.
*
* @docs https://clawject.com/docs/fundamentals/lazy
*
* @public
*/
export declare const Lazy: DecoratorWithoutArguments<LazyTarget> & ((value: boolean) => LazyTarget) & ClawjectDecorator<'Lazy'>;
/** @public */
export declare type LazyTarget = ClassDecorator & PropertyDecorator & MethodDecorator & ModernClassDecorator & ModernClassFieldDecorator & ModernClassGetterDecorator & ModernClassMethodDecorator;
/** @public */
export declare type LifecycleFunctionTarget = PropertyDecorator & MethodDecorator & ModernClassFieldDecorator & ModernClassMethodDecorator;
/**
* @internalApi Just a utility type.
* @public
*/
export declare type MergedObjects<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
/**
* @internalApi Type declaration for a modern class decorator.
*
* @public
*/
export declare type ModernClassDecorator = (target: any, context: ClassDecoratorContext) => void;
/**
* @internalApi Type declaration for a modern class field.
*
* @public
*/
export declare type ModernClassFieldDecorator = (target: any, context: ClassFieldDecoratorContext) => void;
/**
* @internalApi Type declaration for a modern class getter decorator.
*
* @public
*/
export declare type ModernClassGetterDecorator = (target: any, context: ClassGetterDecoratorContext) => void;
/**
* @internalApi Type declaration for a modern class method decorator.
*
* @public
*/
export declare type ModernClassMethodDecorator = (target: any, context: ClassMethodDecoratorContext) => void;
/**
* Defines a factory which can return an Object instance when invoked.
*
* @see Scope
*
* @public
*/
export declare interface ObjectFactory {
getObject(): ObjectFactoryResult | Promise<ObjectFactoryResult>;
}
/** @public */
export declare type ObjectFactoryResult = string | number | boolean | bigint | symbol | object;
/**
* @public
*/
export declare type PickFieldsWithType<T, U> = {
[K in keyof T as T[K] extends U ? K : never]: T[K];
};
/**
* Indicates that an annotated method or property with arrow function should be called
* after configuration or the bean has been constructed.
*
* @docs https://clawject.com/docs/fundamentals/lifecycle#postconstruct
*
* @public */
export declare const PostConstruct: DecoratorWithoutArguments<LifecycleFunctionTarget> & ClawjectDecorator<'PostConstruct'>;
/**
* Indicates that an annotated method or property with arrow function should be called
* before the application context will be closed or the bean will be destroyed.
*
* @docs https://clawject.com/docs/fundamentals/lifecycle#predestroy
*
* @public */
export declare const PreDestroy: DecoratorWithoutArguments<LifecycleFunctionTarget> & ClawjectDecorator<'PreDestroy'>;
/**
* Indicates that a specific bean is a primary candidate for injection.
*
* @docs https://clawject.com/docs/fundamentals/primary
*
* @public */
export declare const Primary: DecoratorWithoutArguments<BeanTarget> & ClawjectDecorator<'Primary'>;
/**
* Allows us to specify a name for a bean.
*
* @docs https://clawject.com/docs/fundamentals/qualifier
*
* @public
*/
export declare const Qualifier: ((value: string) => BeanTarget) & ClawjectDecorator<'Qualifier'>;
/**
* Namespace for runtime errors.
*
* Each error class is a subclass of `Error` and has a unique name.
*
* @docs https://clawject.com/docs/errors#runtime
*
* @public
*/
export declare namespace RuntimeErrors {
/** @public */
export class ExposedBeanNotFoundError extends Error {
name: "ExposedBeanNotFoundError";
}
/** @public */
export class CorruptedMetadataError extends Error {
name: "CorruptedMetadataError";
}
/** @public */
export class IllegalUsageError extends Error {
name: "IllegalUsageError";
}
/** @public */
export class DuplicateScopeError extends Error {
name: "DuplicateScopeError";
}
/** @public */
export class IllegalArgumentError extends Error {
name: "IllegalArgumentError";
}
/** @public */
export class IllegalStateError extends Error {
name: "IllegalStateError";
}
/** @public */
export class NoClassMetadataFoundError extends Error {
name: "NoClassMetadataFoundError";
}
/** @public */
export class CouldNotBeProxiedError extends Error {
name: "CouldNotBeProxiedError";
}
/** @public */
export class ScopeIsNotRegisteredError extends Error {
name: "ScopeIsNotRegisteredError";
}
/** @public */
export class UsageWithoutConfiguredDIError extends Error {
name: "UsageWithoutConfiguredDIError";
}
}
/**
* The interface that represents a scope.
* You should implement it if you want to create your own custom scope.
*
* @docs https://clawject.com/docs/guides/creating-scope
*
* @public
*/
export declare interface Scope {
/**
* This method that is called if application context contains beans with this scope.
* It is called before any bean with this scope is created.
* If you have more than one application context, this method will be called for each of them.
*
* It receives callback that should be called when scope is started, e.g., when request is started.
* Callback should be called only once at the beginning of the scope.
* Callback should be awaited if scope can store asynchronous beans.
*
* Callback is singleton in the `context of a single application context`.
*/
registerScopeBeginCallback(callback: () => Promise<void>): void;
/**
* This method is called before the application context is destroyed.
*
* It should remove this callback from the list of callbacks.
*
* Callback is singleton in the `context of a single application context`.
*/
removeScopeBeginCallback(callback: () => Promise<void>): void;
/**
* Return the object with the given name from the underlying scope,
* and {@link ObjectFactory.getObject creating it}
* if not found in the underlying storage mechanism.
*
* If ObjectFactory is a Promise, it should return a promise with the object,
* after promise is resolved -
* should store the object in the underlying storage mechanism and return for the next calls.
*
* @param name - the name of the object to retrieve, always unique, auto-generated by the container
* @param objectFactory - the {@link ObjectFactory} instance to use to create the scoped
*
* @returns Promise<ObjectFactoryResult> | ObjectFactoryResult - the desired object (never: `null` or `undefined`)
*/
get(name: string, objectFactory: ObjectFactory): Promise<ObjectFactoryResult> | ObjectFactoryResult;
/**
* Remove the object with the given `name` from the underlying scope.
* <p>Returns `null` if no object was found, otherwise
* returns the removed {@link ObjectFactoryResult object}.
* <p>Note that an implementation should also remove a registered destruction
* callback for the specified object, if any.
* It does, however, <i>not</i>
* need to <i>execute</i> a registered destruction callback in this case,
* since the caller will destroy the object (if appropriate).
*
* <b>Note: This is an optional operation.</b>
*
* @param name - the name of the object to remove, always unique, auto-generated by the container
* @returns Removed - {@link ObjectFactoryResult object}, or `null` if no object was present
* @see #registerDestructionCallback
*/
remove(name: string): ObjectFactoryResult | null;
/**
* Register a callback to be executed on destruction of the specified
* object in the scope (or at destruction of the entire scope, if the
* scope does not destroy individual objects but rather only terminates
* in its entirety).
*
* <b>Note:</b> This is an optional operation.
* This method will only
* be called for scoped beans with actual destruction configuration
* (methods that are decorated with \@PreDestroy).
* Implementations should do their best to execute a given callback
* at the appropriate time.
* If such a callback is not supported by the
* underlying runtime environment at all, the callback <i>must be
* ignored and a corresponding warning should be logged</i>.
*
* <b>Note:</b> that 'destruction' refers to automatic destruction of
* the object as part of the scope's own lifecycle, not to the individual
* scoped object having been explicitly removed by the application.
* If a scoped object gets removed via this facade's {@link Scope#remove remove}
* method, any registered destruction callback should be removed as well,
* assuming that the removed object will be reused or manually destroyed.
*
* <b>Note:</b> This method could be called more than once,
* so it should just re-write old callback with new one by given name.
*
* @param name - the name of the object to execute the destruction callback for,
* name is always unique, auto-generated by the container
* @param callback - the destruction callback to be executed.
* @see PreDestroy
*/
registerDestructionCallback(name: string, callback: () => void): void;
/**
* Indicates whether a proxy should be injected or the raw object.
*
* In default scopes (singleton, transient) `false` value is returned from this method,
* but if you want to implement your own scope (for example - http-request scope),
* most likely you will need to return `true` from this method.
*
* Be careful with primitive values because they are not supported by JavaScript Proxies (at least for now),
* and if bean with scope that returns `true` from this method will be created -
* error will be thrown {@link RuntimeErrors.CouldNotBeProxiedError}.
*
* @returns boolean `true` if a proxy should be injected, `false` otherwise.
*/
useProxy?(): boolean;
}
/**
* Specifies the scope of Bean or Beans when applied on {@link Configuration @Configuration} level.
*
* @docs https://clawject.com/docs/fundamentals/scope
*
* @public
*/
export declare const Scope: ClawjectDecorator<'Scope'> & ((scope: ScopeValue) => ScopeTarget);
/**
* `ScopeRegister` serves as the main entry point for working with globally defined scopes.
* It allows you to register custom scopes, deregister them and check if they are registered for all instances of the application.
*
* @public
* */
export declare class ScopeRegister {
/**
* Registers a custom scope for all instances of the application.
*
* @param scopeName - The name of the scope that should be registered.
* @param scope - The custom scope object.
*
* @throws RuntimeErrors.DuplicateScopeError If the scope with the same name was already registered.
*
* @docs https://clawject.com/docs/fundamentals/scope-register#registerscope
*/
static registerScope(scopeName: string | number, scope: Scope): void;
/**
* Registers an alias name for the scope.
*
* @param from - The name of the scope that should be aliased.
* @param to - The name of the scope that should be used as an alias.
*
* @throws RuntimeErrors.ScopeIsNotRegisteredError If the scope with the name `from` is not registered.
* @throws RuntimeErrors.DuplicateScopeError If the scope with the name `to` was already registered.
*
* @docs TODO
*/
static registerScopeAlias(from: ScopeValue, to: string | number): void;
/**
* Check whether the scope with the given name is registered for all instances of the application.
*
* @returns `true` if scope by given name exists, or `false` if the scope does not exist.
*
* @docs https://clawject.com/docs/fundamentals/scope-register#hasscope
* */
static hasScope(scopeName: string | number): boolean;
}
/** @public */
export declare type ScopeTarget = ClassDecorator & PropertyDecorator & MethodDecorator & ModernClassDecorator & ModernClassFieldDecorator & ModernClassGetterDecorator & ModernClassMethodDecorator;
/** @public */
export declare type ScopeValue = 'singleton' | 'transient' | string | number;
export { }