UNPKG

ts-bakery

Version:

Baked dependency injection for Typescript.

140 lines 5.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); const TsImportType_1 = require("../Types/TsImportType"); const TsTypeReference_1 = require("../Types/TsTypeReference"); class ScriptIndex { constructor(bakeryConverter) { this.bakeryConverter = bakeryConverter; this.allFiles = []; this.pathMap = new Map(); } initialize(directory) { const filePaths = this.indexFiles(directory); for (const filePath of filePaths) { const parsedFile = this.bakeryConverter.convertPath(filePath); this.allFiles.push(parsedFile); this.pathMap.set(filePath, parsedFile); } } getFile(path) { if (!this.pathMap.has(path)) { throw new Error('Unable to resolve path ' + path); } return this.pathMap.get(path); } resolveParameterDefinition(parameter) { const filePath = parameter.getFilePath(); const file = this.getFile(filePath); if (file == null) { console.log(filePath); throw new Error('NOT FOUND'); } if (parameter.type instanceof TsTypeReference_1.TsClassTypeReference) { return this.resolveClassTypeReference(parameter.type, file); } else if (parameter.type instanceof TsTypeReference_1.TsQualifiedTypeReference) { return this.resolveQualifiedTypeReference(parameter.type, file); } throw new Error('Unable to build dependency graph. Parameter not injectable in file ' + filePath); } getInheritingClasses(classDefinition) { const inheritingClassDefinitions = []; for (const tsFile of this.allFiles) { for (const tsClass of tsFile.classes) { if (this.inheritsFrom(tsClass, classDefinition)) { inheritingClassDefinitions.push(tsClass); } } } return inheritingClassDefinitions; } inheritsFrom(child, parent) { //TODO: MAKE MORE ROBUST! check file imports of each classes for (const clause of child.heritageClauses) { if (clause == parent.name) { return true; } } return false; } resolveTypeReference(typeReference, typeOrigin) { if (typeReference instanceof TsTypeReference_1.TsClassTypeReference) { return this.resolveClassTypeReference(typeReference, typeOrigin); } else if (typeReference instanceof TsTypeReference_1.TsQualifiedTypeReference) { return this.resolveQualifiedTypeReference(typeReference, typeOrigin); } } resolveClassTypeReference(typeReference, typeOrigin) { return this.resolveTypeReferenceByString(typeReference.name, typeOrigin); } resolveQualifiedTypeReference(typeReference, typeOrigin) { const imports = typeOrigin.imports; for (const importDef of imports) { if (importDef.importType == TsImportType_1.default.Namespace && importDef.names.includes(typeReference.left)) { const modulePath = path.resolve(path.dirname(typeOrigin.path), importDef.modulePath + '.ts'); const moduleFile = this.getFile(modulePath); return this.resolveTypeReferenceByString(typeReference.right, moduleFile); } } return null; } resolveTypeReferenceByString(typeReferenceName, file) { const allClassDefintions = []; allClassDefintions.push(...file.classes); allClassDefintions.push(...file.interfaces); // Check classes / interfaces in file for (const classDefinition of allClassDefintions) { if (classDefinition.name == typeReferenceName || (typeReferenceName == 'default' && classDefinition.isDefault)) { return classDefinition; } } // Check imports for (const importDefinition of file.imports) { for (const importName of importDefinition.names) { if (importName == typeReferenceName) { const filePath = importDefinition.getFilePath(); const fileDirectory = path.dirname(filePath); const importedFilePath = path.resolve(fileDirectory, importDefinition.modulePath + '.ts'); const importedFile = this.getFile(importedFilePath); return this.resolveTypeReferenceByString(typeReferenceName, importedFile); } } } // Check classes / interfaces again but simply check default for (const classDefinition of allClassDefintions) { if (classDefinition.isDefault) { return classDefinition; } } //TODO: Check classes that are simply exported but also imported (like index.ts) throw new Error('Unable to resolve type reference ' + typeReferenceName + ' from file ' + file.getFilePath()); } indexFiles(directory) { const files = []; const directoryContents = fs.readdirSync(directory); for (let contentEntry of directoryContents) { if (contentEntry.startsWith('.')) { continue; } const fullPath = path.join(directory, contentEntry); const entryInfo = fs.statSync(fullPath); if (entryInfo.isFile() && contentEntry.endsWith('.ts')) { files.push(fullPath); } else if (entryInfo.isDirectory()) { if (contentEntry == 'node_modules') { continue; } const directoryFiles = this.indexFiles(fullPath); directoryFiles.forEach(file => files.push(file)); } } return files; } } exports.default = ScriptIndex; //# sourceMappingURL=ScriptIndex.js.map