@elsikora/cladi
Version:
Zero-dependency TypeScript DI toolkit with typed tokens and scoped lifecycles.
62 lines (59 loc) • 2.41 kB
JavaScript
import { BaseError } from '../../../infrastructure/class/base/error.class.js';
import { composeModules } from './compose-modules.utility.js';
import { createModuleFromDecorator } from './create/module-from-decorator.utility.js';
/**
* Composes module graph from mixed decorated module classes and plain module definitions.
* @param {IDIContainer} container Target container.
* @param {Array<Constructor<unknown> | IDIModule>} modules Decorated module classes or plain module definitions.
*/
function composeDecoratedModules(container, modules) {
const resolvedModules = modules.map((moduleEntry) => resolveModuleDefinition(moduleEntry));
composeModules(container, resolvedModules);
}
/**
* Checks whether input is constructable class constructor.
* @param {unknown} candidate Candidate value.
* @returns {boolean} True when value is a constructable class.
*/
function isConstructable(candidate) {
if (typeof candidate !== "function") {
return false;
}
const candidateAsConstructor = candidate;
const prototype = candidateAsConstructor.prototype;
return !!prototype && prototype.constructor === candidate;
}
/**
* Checks whether input is module definition shape.
* @param {unknown} candidate Candidate value.
* @returns {boolean} True when candidate is module definition-like.
*/
function isModuleDefinition(candidate) {
if (typeof candidate !== "object" || candidate === null) {
return false;
}
const moduleCandidate = candidate;
return Array.isArray(moduleCandidate.exports) && Array.isArray(moduleCandidate.imports) && Array.isArray(moduleCandidate.providers);
}
/**
* Resolves a module entry to plain module definition.
* @param {Constructor<unknown> | IDIModule} moduleEntry Module entry.
* @returns {IDIModule} Plain module definition.
*/
function resolveModuleDefinition(moduleEntry) {
if (isModuleDefinition(moduleEntry)) {
return moduleEntry;
}
if (isConstructable(moduleEntry)) {
return createModuleFromDecorator(moduleEntry);
}
throw new BaseError("Module entry must be a decorated module class or module definition", {
code: "MODULE_ENTRY_INVALID",
context: {
entryType: typeof moduleEntry,
},
source: "composeDecoratedModules",
});
}
export { composeDecoratedModules };
//# sourceMappingURL=compose-decorated-modules.utility.js.map