/** * The map of all source files to their content and compiled value */ let COMPILER_fileMap = { } /** * The compiled program */ let COMPILER_emitted_value = '' /** * Registers a file with the compiler * @param {*} fileName The file's name * @param {*} content The content of the file */ const COMPILER_registerFile = (fileName, content) => { let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName,false) loggerScripts.INFO('REGISTER FILE ' + normalizedFilePath) COMPILER_fileMap[normalizedFilePath] = { content: content, compiled: ts.createSourceFile( normalizedFilePath, content, ts.ScriptTarget.Latest ) } } /** * The callback invoked when the compiler host tries to read a file * @param {*} fileName The name of the file * @param {*} languageVersion The language version * @returns The file if it exists, null otherwise */ const COMPILER_getSourceFile = (fileName, languageVersion) => { if(!!COMPILER_fileMap[fileName]){ return COMPILER_fileMap[fileName].compiled } else { return null } } /** * Constructs the compiler host * https://www.typescriptlang.org/tsconfig/#compilerOptions */ const COMPILER_customCompilerHost = { getSourceFile: COMPILER_getSourceFile, writeFile: (fileName, data) => { let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) loggerScripts.INFO("EMIT FILE " + normalizedFilePath) let finalData = "let exports = { }\n" + data + "\n" + "return exports" // COMPILER_emitted_value = data COMPILER_fileMap[normalizedFilePath] = { content: data, //to be eval'd from top level moduleContent: finalData, //to be eval'd from require() } }, getDefaultLibFileName: () => "lib.d.ts", useCaseSensitiveFileNames: () => false, getCanonicalFileName: filename => filename, getCurrentDirectory: () => "", getNewLine: () => "\n", getDirectories: () => [], fileExists: () => true, readFile: () => "" } /** * Instructs Typescript to emit the final compiled value */ const COMPILER_run = () => { loggerScripts.INFO('COMPILE ALL REGISTERED FILES') const compilerOptions = { } const COMPILER_program = ts.createProgram( Object.keys(COMPILER_fileMap), compilerOptions, COMPILER_customCompilerHost ) COMPILER_program.emit() } /** * Loads a file * @param {*} fileName The name of the file to load (preferably already has .ts at the end) */ const COMPILER_runFile = (fileName) => { let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) if(!!COMPILER_fileMap[normalizedFilePath]){ loggerScripts.INFO('RUN FILE ' + normalizedFilePath) eval(COMPILER_fileMap[normalizedFilePath].content) } else { const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath loggerScripts.WARNING(message) throw new Error(message) } } /** * Loads a file * @param {*} fileName The name of the file to load (preferably already has .ts at the end) */ const COMPILER_printSource = (fileName) => { let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) if(!!COMPILER_fileMap[normalizedFilePath]){ loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath) } else { const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath loggerScripts.WARNING(message) loggerScripts.WARNING('file map content:') loggerScripts.WARNING(OBject.keys(COMPILER_fileMap) + "") throw new Error(message) } }