diff --git a/src/main/ts/di/ActivationError.ts b/src/main/ts/di/ActivationError.ts --- a/src/main/ts/di/ActivationError.ts +++ b/src/main/ts/di/ActivationError.ts @@ -9,7 +9,7 @@ export class ActivationError { message: string; - constructor(service: string, activationStack: ActivationContextInfo[], innerException) { + constructor(service: string, activationStack: ActivationContextInfo[], innerException: any) { this.message = "Failed to activate the service"; this.activationStack = activationStack; this.service = service; diff --git a/src/main/ts/di/AggregateDescriptor.ts b/src/main/ts/di/AggregateDescriptor.ts --- a/src/main/ts/di/AggregateDescriptor.ts +++ b/src/main/ts/di/AggregateDescriptor.ts @@ -2,10 +2,10 @@ import { Descriptor, isDescriptor } from import { ActivationContext } from "./ActivationContext"; import { isPrimitive } from "../safe"; -export class AggregateDescriptor implements Descriptor { - _value: object; +export class AggregateDescriptor implements Descriptor { + _value: T; - constructor(value: object) { + constructor(value: T) { this._value = value; } @@ -14,7 +14,7 @@ export class AggregateDescriptor impleme } // TODO: make async - _parse(value, context: ActivationContext, path: string) { + _parse(value: T, context: ActivationContext, path: string) { if (isPrimitive(value)) return value; diff --git a/src/main/ts/di/Configuration.ts b/src/main/ts/di/Configuration.ts --- a/src/main/ts/di/Configuration.ts +++ b/src/main/ts/di/Configuration.ts @@ -28,7 +28,7 @@ import { ICancellation } from "../interf const trace = TraceSource.get("@implab/core/di/Configuration"); -async function mapAll(data: object | any[], map?: (v, k) => any): Promise { +async function mapAll(data: any | any[], map?: (v: any, k: keyof any) => any): Promise { if (data instanceof Array) { return Promise.all(map ? data.map(map) : data); } else { @@ -57,9 +57,9 @@ export class Configuration { _path: Array<_key>; - _configName: string; + _configName: string | undefined; - _require: ModuleResolver; + _require: ModuleResolver | undefined; constructor(container: Container) { argumentNotNull(container, "container"); @@ -78,7 +78,7 @@ export class Configuration { this._configName = moduleName; - const r = await makeResolver(null, contextRequire); + const r = await makeResolver(undefined, contextRequire); const config = await r(moduleName, ct); @@ -114,9 +114,9 @@ export class Configuration { this._container.register(services); } - _makeError(inner) { + _makeError(inner: any) { const e = new ConfigError("Failed to load configuration", inner); - e.configName = this._configName; + e.configName = this._configName || ""; e.path = this._makePath(); return e; } @@ -144,11 +144,13 @@ export class Configuration { _loadModule(moduleName: string) { trace.debug("loadModule {0}", moduleName); + if (!this._require) + throw new Error("Module loader isn't specified"); return this._require(moduleName); } - async _visitRegistrations(data, name: _key) { + async _visitRegistrations(data: any, name: _key) { this._enter(name); if (data.constructor && @@ -168,8 +170,8 @@ export class Configuration { return services; } - _enter(name: _key) { - this._path.push(name); + _enter(name: keyof any) { + this._path.push(name.toString()); trace.debug(">{0}", name); } @@ -178,7 +180,7 @@ export class Configuration { trace.debug("<{0}", name); } - async _visit(data, name: string) { + async _visit(data: T, name: keyof T) { if (isPrimitive(data) || isDescriptor(data)) return data; @@ -233,7 +235,7 @@ export class Configuration { return v; } - _makeServiceParams(data: ServiceRegistration) { + _makeServiceParams(data: ServiceRegistration) { const opts: any = { owner: this._container }; @@ -289,17 +291,17 @@ export class Configuration { return opts; } - async _visitValueRegistration(data: ValueRegistration, name: _key) { + async _visitValueRegistration(data: ValueRegistration, name: _key) { this._enter(name); const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value); this._leave(); return d; } - async _visitDependencyRegistration(data: DependencyRegistration, name: _key) { + async _visitDependencyRegistration(data: DependencyRegistration, name: keyof S) { argumentNotEmptyString(data && data.$dependency, "data.$dependency"); this._enter(name); - const d = new ReferenceDescriptor({ + const d = new ReferenceDescriptor({ name: data.$dependency, lazy: data.lazy, optional: data.optional, @@ -310,7 +312,7 @@ export class Configuration { return d; } - async _visitTypeRegistration(data: TypeRegistration, name: _key) { + async _visitTypeRegistration(data: TypeRegistration, name: _key) { argumentNotNull(data.$type, "data.$type"); this._enter(name); @@ -331,7 +333,7 @@ export class Configuration { return d; } - async _visitFactoryRegistration(data: FactoryRegistration, name: _key) { + async _visitFactoryRegistration(data: FactoryRegistration, name: _key) { argumentOfType(data.$factory, Function, "data.$factory"); this._enter(name); diff --git a/src/main/ts/di/ReferenceDescriptor.ts b/src/main/ts/di/ReferenceDescriptor.ts --- a/src/main/ts/di/ReferenceDescriptor.ts +++ b/src/main/ts/di/ReferenceDescriptor.ts @@ -3,16 +3,16 @@ import { ActivationContext } from "./Act import { ServiceMap, Descriptor } from "./interfaces"; import { ActivationError } from "./ActivationError"; -export interface ReferenceDescriptorParams { - name: string; +export interface ReferenceDescriptorParams { + name: K; lazy?: boolean; optional?: boolean; - default?; + default?: S[K]; services?: ServiceMap; } -export class ReferenceDescriptor implements Descriptor { - _name: string; +export class ReferenceDescriptor implements Descriptor { + _name: K; _lazy = false; @@ -22,13 +22,14 @@ export class ReferenceDescriptor impleme _services: ServiceMap; - constructor(opts: ReferenceDescriptorParams) { + constructor(opts: ReferenceDescriptorParams) { argumentNotEmptyString(opts && opts.name, "opts.name"); this._name = opts.name; this._lazy = !!opts.lazy; this._optional = !!opts.optional; this._default = opts.default; - this._services = opts.services; + + this._services = opts.services || {}; } activate(context: ActivationContext, name: string) { @@ -54,7 +55,7 @@ export class ReferenceDescriptor impleme return this._optional ? ct.resolve(this._name, this._default) : ct .resolve(this._name); } catch (error) { - throw new ActivationError(this._name, ct.getStack(), error); + throw new ActivationError(this._name.toString(), ct.getStack(), error); } }; } else { @@ -88,7 +89,7 @@ export class ReferenceDescriptor impleme parts.push("} "); } - parts.push(this._name); + parts.push(this._name.toString()); if (!isNull(this._default)) { parts.push(" = "); diff --git a/src/main/ts/di/ValueDescriptor.ts b/src/main/ts/di/ValueDescriptor.ts --- a/src/main/ts/di/ValueDescriptor.ts +++ b/src/main/ts/di/ValueDescriptor.ts @@ -1,9 +1,9 @@ import { Descriptor } from "./interfaces"; -export class ValueDescriptor implements Descriptor { - _value; +export class ValueDescriptor implements Descriptor { + _value: T; - constructor(value) { + constructor(value: T) { this._value = value; } diff --git a/src/main/ts/di/interfaces.ts b/src/main/ts/di/interfaces.ts --- a/src/main/ts/di/interfaces.ts +++ b/src/main/ts/di/interfaces.ts @@ -1,18 +1,18 @@ -import { isNull, isPrimitive } from "../safe"; +import { isPrimitive } from "../safe"; import { ActivationContext } from "./ActivationContext"; import { Constructor, Factory } from "../interfaces"; -export interface Descriptor { - activate(context: ActivationContext, name?: string); +export interface Descriptor { + activate(context: ActivationContext, name?: string): T; } -export function isDescriptor(x): x is Descriptor { +export function isDescriptor(x: any): x is Descriptor { return (!isPrimitive(x)) && (x.activate instanceof Function); } -export interface ServiceMap { - [s: string]: Descriptor; +export type ServiceMap = { + [k in keyof S]: Descriptor; } export enum ActivationType { @@ -23,53 +23,53 @@ export enum ActivationType { Call } -export interface RegistrationWithServices { - services?: object; +export interface RegistrationWithServices { + services?: ServiceMap; } -export interface ServiceRegistration extends RegistrationWithServices { +export interface ServiceRegistration extends RegistrationWithServices { activation?: "singleton" | "container" | "hierarchy" | "context" | "call"; - params?; + params?: P; inject?: object | object[]; - cleanup?: (instance) => void | string; + cleanup?: ((instance: T) => void) | string; } -export interface TypeRegistration extends ServiceRegistration { - $type: string | Constructor; +export interface TypeRegistration extends ServiceRegistration { + $type: string | Constructor; } -export interface FactoryRegistration extends ServiceRegistration { - $factory: string | Factory; +export interface FactoryRegistration extends ServiceRegistration { + $factory: string | Factory; } -export interface ValueRegistration { - $value; +export interface ValueRegistration { + $value: T; parse?: boolean; } -export interface DependencyRegistration extends RegistrationWithServices { - $dependency: string; +export interface DependencyRegistration extends RegistrationWithServices { + $dependency: K; lazy?: boolean; optional?: boolean; - default?; + default?: S[K]; } -export function isTypeRegistration(x): x is TypeRegistration { +export function isTypeRegistration(x: any): x is TypeRegistration { return (!isPrimitive(x)) && ("$type" in x); } -export function isFactoryRegistration(x): x is FactoryRegistration { +export function isFactoryRegistration(x: any): x is FactoryRegistration { return (!isPrimitive(x)) && ("$factory" in x); } -export function isValueRegistration(x): x is ValueRegistration { +export function isValueRegistration(x: any): x is ValueRegistration { return (!isPrimitive(x)) && ("$value" in x); } -export function isDependencyRegistration(x): x is DependencyRegistration { +export function isDependencyRegistration(x: any): x is DependencyRegistration { return (!isPrimitive(x)) && ("$dependency" in x); }