##// END OF EJS Templates
working on fluent configuration
working on fluent configuration

File last commit:

r1:a51ea59f0423 default
r1:a51ea59f0423 default
Show More
FluentConfiguration.ts
67 lines | 2.4 KiB | video/mp2t | TypeScriptLexer
/ src / main / ts / FluentConfiguration.ts
import { DescriptorBuilder } from "./DescriptorBuilder";
import { ConfigurableKeys, ContainerServices, ConfigurableServices, RegistrationBuildersMap, RequiredKeys } from "./interfaces";
import { ServiceContainer } from "./interfaces";
import { argumentNotNull, each, isKey } from "./traits";
export class FluentConfiguration<S extends object, Y extends ConfigurableKeys<S> = ConfigurableKeys<S>> {
_builders: Partial<RegistrationBuildersMap<S>> = {};
declare<D extends Partial<Pick<S, keyof D & keyof S>>>(): FluentConfiguration<S & D, Y | ConfigurableKeys<D>> {
return this as FluentConfiguration<S & D, Y | ConfigurableKeys<D>>;
}
provided<P extends Pick<S, keyof P & keyof S>>(): FluentConfiguration<S & P, Exclude<Y, keyof P>> {
return this as FluentConfiguration<S & P, Exclude<Y, keyof P>>;
}
register<K extends Y>(name: K, builder: RegistrationBuildersMap<S>[K]): FluentConfiguration<S, Exclude<Y, K>>;
register<K extends Y>(config: RegistrationBuildersMap<S, K>): FluentConfiguration<S, Exclude<Y, K>>;
register<K extends Y>(nameOrConfig: K | RegistrationBuildersMap<S, K>, builder?: RegistrationBuildersMap<S>[K]) {
if (isKey(nameOrConfig)) {
argumentNotNull(builder, "builder");
this._builders[nameOrConfig] = builder;
} else {
each(nameOrConfig, (v, k) => this.register(k, v));
}
return this as FluentConfiguration<S, Exclude<Y, K>>;
}
done(missing: RequiredKeys<S, Y> extends never ? void : RequiredKeys<S, Y>) {
if (missing !== undefined)
throw new Error("The configuration isn't complete");
return this;
}
apply<A extends Partial<S>>(target: ServiceContainer<A>) {
let pending = 1;
const _t2 = target as ServiceContainer<S>;
const reject = (ex: unknown) => { throw ex; };
const complete = () => !--pending;
each(this._builders, (v, k) => {
pending++;
const d = new DescriptorBuilder<ContainerServices<S>, NonNullable<ConfigurableServices<S>[typeof k]>>(_t2,
result => {
_t2.register(k, result);
complete();
},
reject
);
v(d);
});
if (!complete())
throw new Error("The configuration didn't complete.");
return _t2 as ServiceContainer<A & S>;
}
}