UNPKG

@elsikora/cladi

Version:

Zero-dependency TypeScript DI toolkit with typed tokens and scoped lifecycles.

62 lines (59 loc) 2.41 kB
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