yasui
Version:
Lightweight Express-based framework for REST and web APIs
103 lines • 9.56 kB
JavaScript
import kleur from 'kleur';
import { Scopes } from './enums/index.js';
import { ReflectMetadata, getMetadata, defineMetadata } from './utils/reflect.js';
const InheritedScopes = [
Scopes.DEEP_LOCAL,
];
export class Injector {
logger;
decoratorValidator;
debug;
registry;
buildStack;
constructor(logger, decoratorValidator, debug = false) {
this.logger = logger;
this.decoratorValidator = decoratorValidator;
this.debug = debug;
this.registry = new Map();
this.buildStack = new Set();
}
get(name) {
return this.registry.get(name);
}
register(token, instance) {
this.registry.set(token, instance);
if (this.debug) {
const name = (typeof token === 'symbol' && token.description)
? kleur.yellow(token.description)
: token.toString();
this.logger.debug(`register ${name}`);
}
}
build(Provided, scope = Scopes.SHARED) {
const className = Provided.name;
const token = this.getToken(className, scope);
const runningInstance = this.get(token);
if (runningInstance) {
return runningInstance;
}
this.buildStack.add(className);
try {
const dependencies = this.buildDependencies(Provided, scope);
const instance = new Provided(...dependencies);
this.markMethodsDependencies(Provided, instance, scope);
this.register(token, instance);
}
finally {
this.buildStack.delete(className);
}
return this.get(token);
}
buildDependencies(Provided, scope) {
const deps = getMetadata(ReflectMetadata.DESIGN_PARAM_TYPES, Provided) || [];
const preInjectedDeps = getMetadata(ReflectMetadata.PRE_INJECTED_DEPS, Provided) || {};
const depScopes = getMetadata(ReflectMetadata.DEP_SCOPES, Provided) || {};
return deps.map((Dep, idx) => {
if (preInjectedDeps[idx]) {
this.decoratorValidator?.validateInjectionTokenRegistration(Provided.name, preInjectedDeps[idx]);
return this.get(preInjectedDeps[idx]);
}
this.decoratorValidator?.validateInjectable(Dep, scope, this.buildStack);
const depScope = InheritedScopes.includes(scope)
? scope
: (depScopes[idx] || Scopes.SHARED);
return this.build(Dep, depScope);
});
}
markMethodsDependencies(Provided, instance, scope) {
const methodsInjections = getMetadata(ReflectMetadata.METHOD_INJECTED_DEPS, Provided.prototype) || {};
for (const methodName in methodsInjections) {
const methodDeps = this.resolveMethodDependencies(Provided, methodName, methodsInjections[methodName], scope);
defineMetadata(ReflectMetadata.RESOLVED_METHOD_DEPS, methodDeps, instance, methodName);
}
}
resolveMethodDependencies(Provided, methodName, injections, scope) {
const depScopes = getMetadata(ReflectMetadata.DEP_SCOPES, Provided.prototype, methodName) || {};
const methodDeps = {};
for (const paramIndex in injections) {
const Dep = injections[paramIndex];
if (typeof Dep === 'string') {
this.decoratorValidator?.validateInjectionTokenRegistration(Provided.name, Dep);
methodDeps[paramIndex] = this.get(Dep);
continue;
}
this.decoratorValidator?.validateInjectable(Dep, scope, this.buildStack);
const depScope = InheritedScopes.includes(scope)
? scope
: (depScopes[paramIndex] || Scopes.SHARED);
methodDeps[paramIndex] = this.build(Dep, depScope);
}
return methodDeps;
}
getToken(name, scope) {
switch (scope) {
case Scopes.LOCAL:
case Scopes.DEEP_LOCAL:
return Symbol(name);
case Scopes.SHARED:
default:
return name;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5qZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUcxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUlsRixNQUFNLGVBQWUsR0FBYTtJQUNoQyxNQUFNLENBQUMsVUFBVTtDQUNsQixDQUFDO0FBRUYsTUFBTSxPQUFPLFFBQVE7SUFNQTtJQUNBO0lBQ0E7SUFOWCxRQUFRLENBQTRCO0lBQ3BDLFVBQVUsQ0FBYztJQUVoQyxZQUNtQixNQUFxQixFQUNyQixrQkFBNkMsRUFDN0MsUUFBUSxLQUFLO1FBRmIsV0FBTSxHQUFOLE1BQU0sQ0FBZTtRQUNyQix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQTJCO1FBQzdDLFVBQUssR0FBTCxLQUFLLENBQVE7UUFFOUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztRQUNyRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDdEMsQ0FBQztJQUdNLEdBQUcsQ0FBcUIsSUFBcUI7UUFDbEQsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQU0sQ0FBQztJQUN0QyxDQUFDO0lBRU0sUUFBUSxDQUNiLEtBQXNCLEVBQ3RCLFFBQVc7UUFFWCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFbkMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksR0FBVyxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDO2dCQUNuRSxDQUFDLENBQUMs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