@hemjs/gather
Version:
A lightweight library for collecting and merging configuration from multiple sources
96 lines (95 loc) • 2.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Gather = void 0;
const notions_1 = require("@hemjs/notions");
const uid_1 = require("uid");
const utils_1 = require("./utils");
/**
* Gather configuration generated by configuration providers.
*/
class Gather {
/**
* Create a new Gather instance.
* @param providers the configuration providers
*/
constructor(providers = []) {
this.config = this.loadFromProviders(providers);
}
/**
* Returns merged configurations object
* @returns merged configurations object
*/
getMerged() {
return this.config;
}
/**
* Iterate providers, merging config from each with the previous.
* @param providers an array of configuration providers
* @returns merged configurations object
*/
loadFromProviders(providers) {
const merged = {};
for (const provider of providers) {
const instance = this.resolveProvider(provider);
if (this.isModuleProvider(instance)) {
(0, utils_1.merge)(merged, instance.register());
}
else if ((0, notions_1.isPlainObject)(instance)) {
(0, utils_1.merge)(merged, instance);
}
}
return merged;
}
/**
* Resolve a provider.
* @param providers an array of configuration providers
* @returns merged configurations object
*/
resolveProvider(provider) {
if ((0, notions_1.isObject)(provider)) {
return provider;
}
if ((0, notions_1.isClass)(provider)) {
const typeProvider = provider;
return new typeProvider();
}
if (!(0, notions_1.isFunction)(provider)) {
throw new Error('Invalid config provider');
}
const metatype = this.mapToClass(provider);
return new metatype();
}
/**
* Check if the given provider has the register method.
* @param provider the provider to check
* @returns whether the given provider has the register method
*/
isModuleProvider(provider) {
return (0, notions_1.isFunction)(provider.register);
}
/**
* Map a function to a class.
* @param instance the function to map
* @returns the resulting class
*/
mapToClass(instance) {
return this.assignToken(class {
constructor() {
this.register = (...params) => {
return instance(...params);
};
}
});
}
/**
* Assign unique token to a metatype.
* @param metatype the metatype to assign token
* @param token the unique token
* @returns the resulting metatype
*/
assignToken(metatype, token = (0, uid_1.uid)(21)) {
Object.defineProperty(metatype, 'name', { value: token });
return metatype;
}
}
exports.Gather = Gather;