import * as ts from 'typescript' ; import * as path from 'path' ; import NormalizedPath from '../types/NormalizedPath' ; import { SourceFileProvider } from './SourceFileProvider' ; export default class TypeScriptProgram implements SourceFileProvider { private compilerOptions : ts . CompilerOptions ; private compilerHost : ts . CompilerHost ; private program : ts . Program ; constructor ( configFile ) { const config = readConfigFile ( configFile ) ; const projectPath = path . dirname ( configFile ) ; const parsedConfig = ts . parseJsonConfigFileContent ( config , ts . sys , projectPath ) ; this . compilerOptions = parsedConfig . options ; this . compilerHost = ts . createCompilerHost ( this . compilerOptions ) ; this . program = ts . createProgram ( parsedConfig . fileNames , this . compilerOptions , this . compilerHost ) ; } getSourceFiles ( ) { return this . program . getSourceFiles ( ) . map ( file => file . fileName ) . filter ( fileName => ! fileName . endsWith ( '.d.ts' ) ) ; } getImportsForFile ( fileName ) { let fileInfo = ts . preProcessFile ( ts . sys . readFile ( fileName ) , true , true ) ; return fileInfo . importedFiles . map ( importedFile => importedFile . fileName ) ; } resolveImportFromFile ( containingFile , moduleName ) { const resolvedFile = ts . resolveModuleName ( moduleName , containingFile . replace ( /\\/g , '/' ) , this . compilerOptions , this . compilerHost , null ) ; return resolvedFile . resolvedModule && resolvedFile . resolvedModule . resolvedFileName ; } } function readConfigFile ( configFile ) { const { config , error } = ts . readConfigFile ( configFile , ts . sys . readFile ) ; if ( error ) { throw new Error ( 'Error reading project file: ' + error . messageText ) ; } return config ; }