UNPKG

@vulcan-sql/core

Version:
97 lines 5.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExtensionLoader = void 0; const tslib_1 = require("tslib"); const utils_1 = require("../utils"); const decorators_1 = require("../../models/extensions/decorators"); require("reflect-metadata"); const types_1 = require("../../containers/types"); const utils_2 = require("../utils"); const lodash_1 = require("lodash"); class ExtensionLoader { constructor(config) { this.extensionRegistry = new Map(); this.bound = false; this.config = config; } /** Load external extensions (should be called by core package) */ loadExternalExtensionModules() { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { if (this.bound) throw new utils_1.InternalError(`We must load all extensions before call bindExtension function`); const extensionModules = // {moduleA: 'nameA', moduleB: ['nameB', 'nameC']} (0, lodash_1.chain)(((_a = this.config) === null || _a === void 0 ? void 0 : _a.extensions) || {}) // [['moduleA', 'nameA'], ['moduleB',['nameB', 'nameC']]] .toPairs() // [{alias: 'moduleA', path: 'nameA'}, {alias: 'moduleB', path: 'nameB'}, {alias: 'moduleB', path: 'nameC'}] .flatMap(([alias, path]) => (typeof path === 'string' ? [path] : path).map((p) => ({ alias, path: p, }))) .value(); for (const module of extensionModules) { const moduleEntry = (yield (0, utils_1.defaultImport)(module.path))[0]; const extensions = (0, utils_2.flattenElements)(moduleEntry); extensions.forEach((extension) => this.loadExtension(module.alias, extension)); } }); } loadInternalExtensionModule(moduleEntry) { if (this.bound) throw new utils_1.InternalError(`We must load all extensions before call bindExtension function`); const extensions = (0, utils_2.flattenElements)(moduleEntry); for (const extension of extensions) { const name = Reflect.getMetadata(decorators_1.EXTENSION_NAME_METADATA_KEY, extension); if (name === undefined) throw new utils_1.InternalError(`Internal extension must have @VulcanInternalExtension decorator`); this.loadExtension(name, extension); } } bindExtensions(bind) { for (const type of this.extensionRegistry.keys()) { this.extensionRegistry.get(type).forEach(({ name, extension }) => { const extensionBinding = bind(type).to(extension).inSingletonScope(); const { extensionId } = this.getExtensionMetadata(extension); if (extensionId) extensionBinding.when((request) => { // If request contains named tag, i.e. @named or getNamed(), we check the extensionId, otherwise we fulfill the request. // It makes both @named tag and @multiInject work at same time. const namedTag = request.target.getNamedTag(); if (namedTag) return namedTag.value === extensionId; return true; }); bind(types_1.TYPES.ExtensionConfig) // Note they we can't bind undefined to container or it throw error while unbinding. // https://github.com/inversify/InversifyJS/issues/1462#issuecomment-1202099036 .toConstantValue(name.length > 0 ? this.config[name] || {} : {}) .whenInjectedInto(extension); bind(types_1.TYPES.ExtensionName) .toConstantValue(name || '') .whenInjectedInto(extension); }); } this.bound = true; } getExtensionMetadata(extension) { const extensionId = Reflect.getMetadata(decorators_1.EXTENSION_IDENTIFIER_METADATA_KEY, extension); const enforcedId = Reflect.getMetadata(decorators_1.EXTENSION_ENFORCED_ID_METADATA_KEY, extension); if (enforcedId && !extensionId) throw new utils_1.InternalError(`Extension ${extension.name} needed an extension id but was not found, please use the decorator @VulcanExtensionId to set the id.`); return { extensionId, }; } loadExtension(name, extension) { const extensionType = Reflect.getMetadata(decorators_1.EXTENSION_TYPE_METADATA_KEY, extension); if (!extensionType) throw new utils_1.InternalError(`Extension must have @VulcanExtension decorator, have you use extend the correct super class?`); if (!this.extensionRegistry.has(extensionType)) this.extensionRegistry.set(extensionType, []); this.extensionRegistry.get(extensionType).push({ name, extension }); } } exports.ExtensionLoader = ExtensionLoader; //# sourceMappingURL=extensionLoader.js.map