node-dependency-injection
Version:
The NodeDependencyInjection component allows you to standardize and centralize the way objects are constructed in your application.
1 lines • 19.7 kB
JavaScript
;var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator"));var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _path=_interopRequireDefault(require("path"));var _fs=_interopRequireDefault(require("fs"));var _json=_interopRequireDefault(require("json5"));var _typescriptEstree=require("@typescript-eslint/typescript-estree");var _Definition=_interopRequireDefault(require("./Definition"));var _Reference=_interopRequireDefault(require("./Reference"));var _AutowireIdentifier=_interopRequireDefault(require("./AutowireIdentifier"));var _ContainerDefaultDirMustBeSet=_interopRequireDefault(require("./Exception/ContainerDefaultDirMustBeSet"));var _PassConfig=_interopRequireDefault(require("./PassConfig"));var _AutowireOverridePass=_interopRequireDefault(require("./CompilerPass/AutowireOverridePass"));function _createForOfIteratorHelper(r,e){var t="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(!t){if(Array.isArray(r)||(t=_unsupportedIterableToArray(r))||e&&r&&"number"==typeof r.length){t&&(r=t);var _n=0,F=function F(){};return{s:F,n:function n(){return _n>=r.length?{done:!0}:{done:!1,value:r[_n++]};},e:function e(r){throw r;},f:F};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var o,a=!0,u=!1;return{s:function s(){t=t.call(r);},n:function n(){var r=t.next();return a=r.done,r;},e:function e(r){u=!0,o=r;},f:function f(){try{a||null==t["return"]||t["return"]();}finally{if(u)throw o;}}};}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0;}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n;}var Autowire=exports["default"]=function(){function Autowire(container){var tsConfigFullPath=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;(0,_classCallCheck2["default"])(this,Autowire);this._ensureContainerIsValidForAutowire(container);this._rootDirectory=container.defaultDir;this._container=container;this._excludedFolders=[];this._serviceFile=null;try{this._tsConfigFullPath=tsConfigFullPath||_path["default"].join(process.cwd(),'tsconfig.json');this._tsConfigPaths=_json["default"].parse(_fs["default"].readFileSync(this._tsConfigFullPath,'utf-8')).compilerOptions.paths;}catch(e){this._container.loggerHelper.debug("Autowire: tsconfig.json not found or has no compilerOptions.paths at ".concat(this._tsConfigFullPath));this._tsConfigPaths=null;}this._container.autowire=this;}return(0,_createClass2["default"])(Autowire,[{key:"_ensureContainerIsValidForAutowire",value:function _ensureContainerIsValidForAutowire(container){if(container.defaultDir===null){throw new _ContainerDefaultDirMustBeSet["default"]();}}},{key:"container",get:function get(){return this._container;}},{key:"_walk",value:_regenerator["default"].mark(function _walk(dir){var files,_iterator,_step,file;return _regenerator["default"].wrap(function _walk$(_context){while(1)switch(_context.prev=_context.next){case 0:files=_fs["default"].readdirSync(dir,{withFileTypes:true});_iterator=_createForOfIteratorHelper(files);_context.prev=2;_iterator.s();case 4:if((_step=_iterator.n()).done){_context.next=12;break;}file=_step.value;if(!file.isDirectory()){_context.next=9;break;}return _context.delegateYield(this._walk(_path["default"].join(dir,file.name)),"t0",8);case 8:return _context.abrupt("continue",10);case 9:return _context.delegateYield(this._walkFilePath(dir,file.name),"t1",10);case 10:_context.next=4;break;case 12:_context.next=17;break;case 14:_context.prev=14;_context.t2=_context["catch"](2);_iterator.e(_context.t2);case 17:_context.prev=17;_iterator.f();return _context.finish(17);case 20:case"end":return _context.stop();}},_walk,this,[[2,14,17,20]]);})},{key:"_walkFilePath",value:_regenerator["default"].mark(function _walkFilePath(dir,fileName){var filePath;return _regenerator["default"].wrap(function _walkFilePath$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:_context2.prev=0;filePath=_path["default"].join(dir,fileName);this._ensureFileIsNotExcluded(filePath);_context2.next=5;return filePath;case 5:_context2.next=10;break;case 7:_context2.prev=7;_context2.t0=_context2["catch"](0);this._container.loggerHelper.debug("Autowire: skipping excluded file ".concat(_path["default"].join(dir,fileName)));case 10:case"end":return _context2.stop();}},_walkFilePath,this,[[0,7]]);})},{key:"_ensureFileIsNotExcluded",value:function _ensureFileIsNotExcluded(filePath){if(this._excludedFolders.some(function(excludedFolder){return filePath.includes(excludedFolder);})){throw new Error('Excluded Folder!');}}},{key:"addExclude",value:function addExclude(relativePath){var fullPathToExclude=_path["default"].join(this._rootDirectory,relativePath);this._excludedFolders.push(fullPathToExclude);}},{key:"_getServiceIdFromPath",value:(function(){var _getServiceIdFromPath2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee(path,type){var extension,readableId,_args3=arguments;return _regenerator["default"].wrap(function _callee$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:extension=_args3.length>2&&_args3[2]!==undefined?_args3[2]:'.ts';readableId=path.replace(/\//g,'__').replace(extension,'').replace('@','__').concat("__".concat(type));return _context3.abrupt("return",_AutowireIdentifier["default"].encode(readableId));case 3:case"end":return _context3.stop();}},_callee);}));function _getServiceIdFromPath(_x,_x2){return _getServiceIdFromPath2.apply(this,arguments);}return _getServiceIdFromPath;}())},{key:"process",value:(function(){var _process=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee2(){var promises,_iterator2,_step2,filePath;return _regenerator["default"].wrap(function _callee2$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:this._container.loggerHelper.info("Autowiring services from: ".concat(this._rootDirectory));promises=[];_iterator2=_createForOfIteratorHelper(this._walk(this._rootDirectory));try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){filePath=_step2.value;promises.push(this._executeFilePath(filePath));}}catch(err){_iterator2.e(err);}finally{_iterator2.f();}_context4.next=6;return Promise.all(promises);case 6:this._container.loggerHelper.info('Autowire scan completed');this._container.addCompilerPass(new _AutowireOverridePass["default"](),_PassConfig["default"].TYPE_BEFORE_OPTIMIZATION);case 8:case"end":return _context4.stop();}},_callee2,this);}));function process(){return _process.apply(this,arguments);}return process;}())},{key:"_executeFilePath",value:(function(){var _executeFilePath2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee3(filePath){var parsedFile,_yield$this$_getClass,classDeclaration,body,Class,importMap,definition,serviceId;return _regenerator["default"].wrap(function _callee3$(_context5){while(1)switch(_context5.prev=_context5.next){case 0:parsedFile=_path["default"].parse(filePath);if(!(parsedFile.ext!=='.ts')){_context5.next=4;break;}this._container.loggerHelper.debug("Autowire: skipping non-TypeScript file: ".concat(filePath));return _context5.abrupt("return");case 4:_context5.next=6;return this._getClassDeclaration(filePath);case 6:_yield$this$_getClass=_context5.sent;classDeclaration=_yield$this$_getClass.classDeclaration;body=_yield$this$_getClass.body;if(classDeclaration){_context5.next=12;break;}this._container.loggerHelper.debug("Autowire: no default export class found in: ".concat(filePath));return _context5.abrupt("return");case 12:Class=require(filePath)["default"];if(Class){_context5.next=16;break;}this._container.loggerHelper.warn("Autowire: file has export default declaration but no runtime default export: ".concat(filePath));return _context5.abrupt("return");case 16:importMap=this._buildImportMap(body);_context5.next=19;return this._getDefinition(classDeclaration,importMap,parsedFile,Class);case 19:definition=_context5.sent;if(definition){_context5.next=22;break;}return _context5.abrupt("return");case 22:_context5.next=24;return this._getServiceIdFromPath(filePath,Class.name);case 24:serviceId=_context5.sent;this._container.loggerHelper.debug("Autowire registering service: ".concat(Class.name," (").concat(serviceId,")"));this.container.setDefinition(serviceId,definition);_context5.next=29;return this._interfaceImplementations(classDeclaration,importMap,parsedFile,serviceId);case 29:case"end":return _context5.stop();}},_callee3,this);}));function _executeFilePath(_x3){return _executeFilePath2.apply(this,arguments);}return _executeFilePath;}())},{key:"_getClassDeclaration",value:(function(){var _getClassDeclaration2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee4(filePath){var sourceCode,body,classDeclaration;return _regenerator["default"].wrap(function _callee4$(_context6){while(1)switch(_context6.prev=_context6.next){case 0:sourceCode=_fs["default"].readFileSync(filePath,'utf8');body=(0,_typescriptEstree.parse)(sourceCode).body;classDeclaration=body.find(function(declaration){return declaration.type==='ExportDefaultDeclaration';});return _context6.abrupt("return",{classDeclaration:classDeclaration,body:body});case 4:case"end":return _context6.stop();}},_callee4);}));function _getClassDeclaration(_x4){return _getClassDeclaration2.apply(this,arguments);}return _getClassDeclaration;}())},{key:"_buildImportMap",value:function _buildImportMap(body){var importMap=new Map();var _iterator3=_createForOfIteratorHelper(body),_step3;try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){var declaration=_step3.value;if(declaration.specifiers){var _iterator4=_createForOfIteratorHelper(declaration.specifiers),_step4;try{for(_iterator4.s();!(_step4=_iterator4.n()).done;){var specifier=_step4.value;importMap.set(specifier.local.name,declaration.source.value);}}catch(err){_iterator4.e(err);}finally{_iterator4.f();}}}}catch(err){_iterator3.e(err);}finally{_iterator3.f();}return importMap;}},{key:"_getDefinition",value:(function(){var _getDefinition2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee5(classDeclaration,importMap,parsedFile,ServiceClass){var definition,constructorParams,_iterator5,_step5,_parameterDeclaration,_identifier$typeAnnot,parameterDeclaration,identifier,typeNameForArgument,paramName,argumentId;return _regenerator["default"].wrap(function _callee5$(_context7){while(1)switch(_context7.prev=_context7.next){case 0:_context7.prev=0;definition=new _Definition["default"](ServiceClass);_context7.next=4;return this._getConstructorParamsByDefinition(definition,classDeclaration,importMap,parsedFile);case 4:constructorParams=_context7.sent;_iterator5=_createForOfIteratorHelper(constructorParams);_context7.prev=6;_iterator5.s();case 8:if((_step5=_iterator5.n()).done){_context7.next=25;break;}parameterDeclaration=_step5.value;identifier=(_parameterDeclaration=parameterDeclaration.parameter)!==null&&_parameterDeclaration!==void 0?_parameterDeclaration:parameterDeclaration;typeNameForArgument=(_identifier$typeAnnot=identifier.typeAnnotation)===null||_identifier$typeAnnot===void 0||(_identifier$typeAnnot=_identifier$typeAnnot.typeAnnotation)===null||_identifier$typeAnnot===void 0||(_identifier$typeAnnot=_identifier$typeAnnot.typeName)===null||_identifier$typeAnnot===void 0?void 0:_identifier$typeAnnot.name;if(typeNameForArgument){_context7.next=16;break;}paramName=identifier.name;if(paramName&&this._container.binds.has(paramName)){definition.addArgument(this._container.binds.get(paramName),definition["abstract"]);}else{this._container.loggerHelper.debug("Autowire: skipping constructor parameter without type annotation in ".concat(ServiceClass.name));}return _context7.abrupt("continue",23);case 16:_context7.next=18;return this._getIdentifierFromImports(typeNameForArgument,importMap,parsedFile);case 18:argumentId=_context7.sent;if(argumentId){_context7.next=22;break;}this._container.loggerHelper.warn("Autowire: could not resolve dependency \"".concat(typeNameForArgument,"\" for service ").concat(ServiceClass.name,". ")+'Ensure the import exists and points to a valid file.');return _context7.abrupt("continue",23);case 22:definition.addArgument(new _Reference["default"](argumentId),definition["abstract"]);case 23:_context7.next=8;break;case 25:_context7.next=30;break;case 27:_context7.prev=27;_context7.t0=_context7["catch"](6);_iterator5.e(_context7.t0);case 30:_context7.prev=30;_iterator5.f();return _context7.finish(30);case 33:return _context7.abrupt("return",definition);case 36:_context7.prev=36;_context7.t1=_context7["catch"](0);this._container.loggerHelper.warn("Autowire: failed to create definition for ".concat(ServiceClass.name,": ").concat(_context7.t1.message));case 39:case"end":return _context7.stop();}},_callee5,this,[[0,36],[6,27,30,33]]);}));function _getDefinition(_x5,_x6,_x7,_x8){return _getDefinition2.apply(this,arguments);}return _getDefinition;}())},{key:"_getConstructorParamsByDefinition",value:(function(){var _getConstructorParamsByDefinition2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee6(definition,classDeclaration,importMap,parsedFile){var constructorDeclaration;return _regenerator["default"].wrap(function _callee6$(_context8){while(1)switch(_context8.prev=_context8.next){case 0:constructorDeclaration=classDeclaration.declaration.body.body.find(function(method){return method.key.name==='constructor';});if(classDeclaration.declaration["abstract"]){definition["abstract"]=true;}_context8.next=4;return this._parentDefinition(classDeclaration,importMap,parsedFile,definition);case 4:return _context8.abrupt("return",constructorDeclaration?constructorDeclaration.value.params:[]);case 5:case"end":return _context8.stop();}},_callee6,this);}));function _getConstructorParamsByDefinition(_x9,_x0,_x1,_x10){return _getConstructorParamsByDefinition2.apply(this,arguments);}return _getConstructorParamsByDefinition;}())},{key:"_parentDefinition",value:(function(){var _parentDefinition2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee7(classDeclaration,importMap,parsedFile,definition){var typeParent,parentId;return _regenerator["default"].wrap(function _callee7$(_context9){while(1)switch(_context9.prev=_context9.next){case 0:if(!classDeclaration.declaration.superClass){_context9.next=6;break;}typeParent=classDeclaration.declaration.superClass.name;_context9.next=4;return this._getIdentifierFromImports(typeParent,importMap,parsedFile);case 4:parentId=_context9.sent;if(parentId){definition.parent=parentId;}case 6:case"end":return _context9.stop();}},_callee7,this);}));function _parentDefinition(_x11,_x12,_x13,_x14){return _parentDefinition2.apply(this,arguments);}return _parentDefinition;}())},{key:"_interfaceImplementations",value:(function(){var _interfaceImplementations2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee8(classDeclaration,importMap,parsedFile,serviceId){var _classDeclaration$dec;var implementations,_iterator6,_step6,implement,interfaceType,aliasId;return _regenerator["default"].wrap(function _callee8$(_context0){while(1)switch(_context0.prev=_context0.next){case 0:implementations=(_classDeclaration$dec=classDeclaration.declaration["implements"])!==null&&_classDeclaration$dec!==void 0?_classDeclaration$dec:[];_iterator6=_createForOfIteratorHelper(implementations);_context0.prev=2;_iterator6.s();case 4:if((_step6=_iterator6.n()).done){_context0.next=16;break;}implement=_step6.value;interfaceType=implement.expression.name;_context0.next=9;return this._getIdentifierFromImports(interfaceType,importMap,parsedFile);case 9:aliasId=_context0.sent;if(!(!aliasId||this.container.hasAlias(aliasId))){_context0.next=12;break;}return _context0.abrupt("continue",14);case 12:this._container.loggerHelper.debug("Autowire aliasing interface: ".concat(interfaceType," -> ").concat(serviceId));this.container.setAlias(aliasId,serviceId);case 14:_context0.next=4;break;case 16:_context0.next=21;break;case 18:_context0.prev=18;_context0.t0=_context0["catch"](2);_iterator6.e(_context0.t0);case 21:_context0.prev=21;_iterator6.f();return _context0.finish(21);case 24:case"end":return _context0.stop();}},_callee8,this,[[2,18,21,24]]);}));function _interfaceImplementations(_x15,_x16,_x17,_x18){return _interfaceImplementations2.apply(this,arguments);}return _interfaceImplementations;}())},{key:"_getIdentifierFromImports",value:(function(){var _getIdentifierFromImports2=(0,_asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee9(type,importMap,parsedFile){var _this$_tsConfigPaths,rootDir,relativeImportForImplement,configPaths,hasAlias,aliasResolved,pathConfig,tsConfigPath,tsRelativePath,parsedTsConfigPath,absolutePathImportForImplement;return _regenerator["default"].wrap(function _callee9$(_context1){while(1)switch(_context1.prev=_context1.next){case 0:_context1.prev=0;rootDir=parsedFile.dir;relativeImportForImplement=importMap.get(type);if(!(relativeImportForImplement===undefined)){_context1.next=5;break;}return _context1.abrupt("return",undefined);case 5:configPaths=(_this$_tsConfigPaths=this._tsConfigPaths)!==null&&_this$_tsConfigPaths!==void 0?_this$_tsConfigPaths:[];hasAlias=relativeImportForImplement.startsWith('@');aliasResolved=false;_context1.t0=_regenerator["default"].keys(configPaths);case 9:if((_context1.t1=_context1.t0()).done){_context1.next=21;break;}pathConfig=_context1.t1.value;tsConfigPath=pathConfig.replace(/\*/g,'');tsRelativePath=this._tsConfigPaths[pathConfig][0].replace(/\*/g,'');if(relativeImportForImplement.includes(tsConfigPath)){_context1.next=15;break;}return _context1.abrupt("continue",9);case 15:relativeImportForImplement=relativeImportForImplement.replace(tsConfigPath,tsRelativePath);parsedTsConfigPath=_path["default"].parse(this._tsConfigFullPath);rootDir=parsedTsConfigPath.dir;aliasResolved=true;_context1.next=9;break;case 21:if(!(hasAlias&&!aliasResolved)){_context1.next=24;break;}this._container.loggerHelper.debug("Autowire: could not resolve tsconfig path alias for \"".concat(type,"\" (import: \"").concat(importMap.get(type),"\")"));return _context1.abrupt("return",undefined);case 24:absolutePathImportForImplement=_path["default"].join(rootDir,relativeImportForImplement);return _context1.abrupt("return",this._getServiceIdFromPath(absolutePathImportForImplement,type));case 28:_context1.prev=28;_context1.t2=_context1["catch"](0);this._container.loggerHelper.warn("Autowire: failed to resolve import identifier \"".concat(type,"\": ").concat(_context1.t2.message));case 31:case"end":return _context1.stop();}},_callee9,this,[[0,28]]);}));function _getIdentifierFromImports(_x19,_x20,_x21){return _getIdentifierFromImports2.apply(this,arguments);}return _getIdentifierFromImports;}())},{key:"serviceFile",get:function get(){return this._serviceFile;},set:function set(serviceFile){this._serviceFile=serviceFile;}}]);}();