UNPKG

awilix-manager

Version:

Wrapper over awilix to support more complex use-cases, such as async init and eager injection

157 lines (156 loc) 6.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AwilixManager = void 0; exports.asMockClass = asMockClass; exports.asMockValue = asMockValue; exports.asMockFunction = asMockFunction; exports.asyncInit = asyncInit; exports.eagerInject = eagerInject; exports.getWithTags = getWithTags; exports.getByPredicate = getByPredicate; exports.asyncDispose = asyncDispose; const awilix_1 = require("awilix"); function asMockClass(Type, opts) { return (0, awilix_1.asClass)(Type, opts); } function asMockValue(value) { return (0, awilix_1.asValue)(value); } function asMockFunction(fn, opts) { return (0, awilix_1.asFunction)(fn, opts); } class AwilixManager { config; constructor(config) { this.config = config; if (config.strictBooleanEnforced) { for (const entry of Object.entries(config.diContainer.registrations)) { const [dependencyName, config] = entry; if ('enabled' in config && config.enabled !== true && config.enabled !== false) { throw new Error(`Invalid config for ${dependencyName}. "enabled" field can only be set to true or false, or omitted`); } } } } async executeInit() { if (this.config.eagerInject) { eagerInject(this.config.diContainer); } if (this.config.asyncInit) { await asyncInit(this.config.diContainer); } } async executeDispose() { await asyncDispose(this.config.diContainer); } getWithTags(tags) { return getWithTags(this.config.diContainer, tags); } getByPredicate(predicate) { return getByPredicate(this.config.diContainer, predicate); } } exports.AwilixManager = AwilixManager; async function asyncInit(diContainer) { const dependenciesWithAsyncInit = Object.entries(diContainer.registrations) .filter((entry) => { return entry[1].asyncInit && entry[1].enabled !== false; }) .sort((entry1, entry2) => { const [key1, resolver1] = entry1; const [key2, resolver2] = entry2; const asyncInitPriority1 = resolver1.asyncInitPriority ?? 1; const asyncInitPriority2 = resolver2.asyncInitPriority ?? 1; if (asyncInitPriority1 !== asyncInitPriority2) { return asyncInitPriority1 - asyncInitPriority2; } return key1.localeCompare(key2); }); for (const [key, description] of dependenciesWithAsyncInit) { const resolvedValue = diContainer.resolve(key); // use default asyncInit method if (description.asyncInit === true) { if (!('asyncInit' in resolvedValue)) { throw new Error(`Method asyncInit does not exist on dependency ${key}`); } await resolvedValue.asyncInit(diContainer.cradle); continue; } // use function asyncInit if (typeof description.asyncInit === 'function') { await description.asyncInit(resolvedValue, diContainer); continue; } // @ts-expect-error if (!(description.asyncInit in resolvedValue)) { throw new Error(`Method ${description.asyncInit} for asyncInit does not exist on dependency ${key}`); } // @ts-expect-error await resolvedValue[description.asyncInit](diContainer.cradle); } } function eagerInject(diContainer) { const dependenciesWithEagerInject = Object.entries(diContainer.registrations).filter(([_key, description]) => { return description.eagerInject && description.enabled !== false; }); for (const [key, description] of dependenciesWithEagerInject) { const resolvedComponent = diContainer.resolve(key); if (typeof description.eagerInject === 'string') { resolvedComponent[description.eagerInject](); } } } function getWithTags(diContainer, tags) { const dependenciesWithTags = Object.entries(diContainer.registrations).filter(([_key, description]) => { return (description.enabled !== false && tags.every((v) => description.tags && description.tags.includes(v))); }); const resolvedComponents = {}; for (const [key] of dependenciesWithTags) { resolvedComponents[key] = diContainer.resolve(key); } return resolvedComponents; } function getByPredicate(diContainer, predicate) { const enabledDependencies = Object.entries(diContainer.registrations).filter(([_key, description]) => { return description.enabled !== false; }); const resolvedComponents = {}; for (const [key] of enabledDependencies) { const resolvedElement = diContainer.resolve(key); if (predicate(resolvedElement)) { resolvedComponents[key] = resolvedElement; } } return resolvedComponents; } async function asyncDispose(diContainer) { const dependenciesWithAsyncDispose = Object.entries(diContainer.registrations) .filter(([_key, description]) => { return description.asyncDispose && description.enabled !== false; }) .sort((entry1, entry2) => { const [key1, resolver1] = entry1; const [key2, resolver2] = entry2; const asyncDisposePriority1 = resolver1.asyncDisposePriority ?? 1; const asyncDisposePriority2 = resolver2.asyncDisposePriority ?? 1; if (asyncDisposePriority1 !== asyncDisposePriority2) { return asyncDisposePriority1 - asyncDisposePriority2; } return key1.localeCompare(key2); }); for (const [key, description] of dependenciesWithAsyncDispose) { const resolvedValue = diContainer.resolve(key); const asyncDispose = description.asyncDispose; if (typeof asyncDispose === 'function') { await asyncDispose(resolvedValue); continue; } if (asyncDispose === true) { await resolvedValue.asyncDispose(); continue; } // @ts-ignore await resolvedValue[asyncDispose](); } }