/**
 * @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
 */
declare const External_2: DecoratorWithoutArguments<InternalExternalTarget> & ((value: boolean) => InternalExternalTarget) & ClawjectDecorator<'External'>;
export { External_2 as 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 { }
