import { argumentNotNull, each, isPrimitive, isPromise } from "../../safe"; import { DescriptorBuilder } from "./DescriptorBuilder"; import { RegistrationBuilder, FluentRegistrations, ContainerConfiguration } from "./interfaces"; import { Cancellation } from "../../Cancellation"; import { ServiceContainer } from "../interfaces"; export class FluentConfiguration { _builders: { [k in keyof S]?: RegistrationBuilder } = {}; provided(): FluentConfiguration> { return this; } register(name: K, builder: RegistrationBuilder): FluentConfiguration>; register(config: FluentRegistrations): FluentConfiguration>; register(nameOrConfig: K | FluentRegistrations, builder?: RegistrationBuilder): FluentConfiguration> { if (isPrimitive(nameOrConfig)) { argumentNotNull(builder, "builder"); this._builders[nameOrConfig] = builder; } else { each(nameOrConfig, (v, k) => this.register(k, v)); } return this; } configure(config: FluentRegistrations): ContainerConfiguration { return this.register(config); } apply(target: ServiceContainer, ct = Cancellation.none) { let pending = 1; const _t2 = target as unknown as ServiceContainer; return new Promise>((resolve, reject) => { function guard(v: void | Promise) { if (isPromise(v)) v.catch(reject); } function complete() { if (!--pending) resolve(_t2); } each(this._builders, (v, k) => { pending++; const d = new DescriptorBuilder(_t2, result => { _t2.register(k, result); complete(); }, reject ); try { guard(v(d, ct)); } catch (e) { reject(e); } }); complete(); }); } }