ts-snippet
Version:
A TypeScript snippet testing library for any test framework
67 lines (66 loc) • 3.03 kB
JavaScript
import * as ts from "typescript";
export class Compiler {
constructor(compilerOptions = {}, rootDirectory = process.cwd()) {
function normalize(path) {
return path.replace(/\\/g, "/");
}
const { errors, options } = ts.convertCompilerOptionsFromJson(Object.assign({ moduleResolution: "node", skipLibCheck: true, target: "es2017" }, compilerOptions), normalize(rootDirectory));
const [error] = errors;
if (error) {
throw new Error(this.formatDiagnostic(error));
}
this._compilerOptions = options;
this._files = {};
const languageServiceHost = {
directoryExists: ts.sys.directoryExists,
fileExists: ts.sys.fileExists,
getCompilationSettings: () => this._compilerOptions,
getCurrentDirectory: () => normalize(rootDirectory),
getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options),
getScriptFileNames: () => Object.keys(this._files),
getScriptSnapshot: (fileName) => {
if (this._files[fileName]) {
return ts.ScriptSnapshot.fromString(this._files[fileName].content);
}
else if (ts.sys.fileExists(fileName)) {
return ts.ScriptSnapshot.fromString(ts.sys.readFile(fileName).toString());
}
return undefined;
},
getScriptVersion: (fileName) => {
return (this._files[fileName] && this._files[fileName].version.toString());
},
readDirectory: ts.sys.readDirectory,
readFile: ts.sys.readFile,
};
this._languageService = ts.createLanguageService(languageServiceHost, ts.createDocumentRegistry());
}
compile(files) {
Object.keys(files).forEach((fileName) => {
if (!this._files[fileName]) {
this._files[fileName] = { content: "", version: 0 };
}
this._files[fileName].content = files[fileName];
this._files[fileName].version++;
});
const program = this._languageService.getProgram();
if (!program) {
throw new Error("No program.");
}
return program;
}
formatDiagnostic(diagnostic) {
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
if (diagnostic.file) {
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
return `Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`;
}
return `Error: ${message}`;
}
getDiagnostics(fileName) {
return this._languageService
.getCompilerOptionsDiagnostics()
.concat(this._languageService.getSyntacticDiagnostics(fileName))
.concat(this._languageService.getSemanticDiagnostics(fileName));
}
}