/** * This Source Code is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) Infonomic Company Limited * * Typed dependency injection registry. Ported from the Modulus project * (https://github.com/infonomic/modulus) with permission. * * Provides compile-time validation of dependency graphs via TypeScript * conditional types. Services declare their dependencies via constructor * or factory signatures; the registry validates that all requirements * are satisfied before composition. */ type Token = string | symbol; type Normalize = T extends object ? { [P in keyof T]: T[P]; } : never; type Extend = Normalize & { [K in TName]: TValue; }>; type IsNever = [T] extends [never] ? true : false; type IsMergeable = { [K in keyof T1 & keyof T2]: IsNever extends true ? false : true; } extends Record ? true : false; type ValidateDeps = TName extends keyof TRequires ? { error: 'Name conflict with prior requirement'; name: TName; requirements: TRequires; } : TName extends keyof TProvides ? { error: 'Duplicate provider name'; name: TName; } : Pick extends Pick ? IsMergeable, Extract>>, Pick>>> extends true ? true : { error: 'Dependency type conflicts with required type'; deps: TDeps; requirements: TRequires; } : { error: 'Dependency type conflicts with provided type'; deps: TDeps; provides: TProvides; }; export declare class Registry = {}, TProvides extends Record = {}> { private readonly providers; addClass any, TValidation extends ValidateDeps[0]> = ValidateDeps[0]>>(name: Name, value: TValidation extends true ? TClass : TValidation): Registry[0], keyof TProvides>>, Extend>>; addFactory any, TValidation extends ValidateDeps[0]> = ValidateDeps[0]>>(name: Name, value: TValidation extends true ? TFactory : TValidation): Registry[0], keyof TProvides>>, Extend>>; addValue = ValidateDeps>(name: Name, value: TValidation extends true ? TValue : TValidation): Registry>; addNested, TValidation extends ValidateDeps ? TNestedRequired : never> = ValidateDeps ? TNestedRequired : never>>(name: Name, nested: TValidation extends true ? TNested : TValidation): TNested extends Registry ? Registry>, Extend> : never; compose(requirements: TRequires): Normalize; } export declare class AsyncRegistry = {}, TProvides extends Record = {}> { private readonly providers; addClass any, TValidation extends ValidateDeps[0]> = ValidateDeps[0]>>(name: Name, value: TValidation extends true ? TClass : TValidation): AsyncRegistry[0], keyof TProvides>>, Extend>>; addAsyncClass; }, TValidation extends ValidateDeps[0]> = ValidateDeps[0]>>(name: Name, value: TValidation extends true ? TClass : TValidation): AsyncRegistry[0], keyof TProvides>>, Extend>>>; addFactory any, TValidation extends ValidateDeps[0]> = ValidateDeps[0]>>(name: Name, value: TValidation extends true ? TFactory : TValidation): AsyncRegistry[0], keyof TProvides>>, Extend>>>; addValue = ValidateDeps>(name: Name, value: TValidation extends true ? TValue : TValidation): AsyncRegistry>>; addNested, TValidation extends ValidateDeps ? TNestedRequired : never> = ValidateDeps ? TNestedRequired : never>>(name: Name, nested: TValidation extends true ? TNested : TValidation): TNested extends Registry ? AsyncRegistry>, Extend> : never; addNestedAsync, TValidation extends ValidateDeps ? TNestedRequired : never> = ValidateDeps ? TNestedRequired : never>>(name: Name, nested: TValidation extends true ? TNested : TValidation): TNested extends AsyncRegistry ? AsyncRegistry>, Extend> : never; compose(requirements: TRequires): Promise>; } export type RegisteredServices | AsyncRegistry> = TRegistry extends Registry ? TProvided : TRegistry extends AsyncRegistry ? Normalize : never; export {};