import { Container } from "../Container"; import { argumentNotNull, each, isPrimitive, isPromise } from "../../safe"; import { DescriptorBuilder } from "./DescriptorBuilder"; import { RegistrationBuilder, FluentRegistrations } from "./interfaces"; import { Cancellation } from "../../Cancellation"; export class FluentConfiguration { _builders: { [k in keyof S]?: RegistrationBuilder } = {}; 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; } apply(target: Container, ct = Cancellation.none) { let pending = 1; const _t2 = target as unknown as Container; 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(); }); } }