UNPKG

@typed/test

Version:
113 lines 4.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const crypto_1 = require("crypto"); const fs_1 = require("fs"); const path_1 = require("path"); const tempy_1 = require("tempy"); const typescript_1 = require("typescript"); const diagnosticToString_1 = require("./diagnosticToString"); // tslint:disable-next-line:no-var-requires const sourceMapSupport = require('source-map-support'); const DEFAULT_COMPILER_OPTIONS = { sourceMap: true, inlineSourceMap: false, inlineSources: true, declaration: false, noEmit: false, outDir: '$$ts-transpilation$$', }; function transpileNode(cwd, compilerOptions) { compilerOptions = Object.assign(Object.assign({}, compilerOptions), DEFAULT_COMPILER_OPTIONS); const cacheDirectory = tempy_1.directory(); const originalJsHandler = require.extensions['.js']; const memoryCache = { contents: Object.create(null), outputs: Object.create(null), }; const extensions = ['.ts', '.tsx']; const compile = (code, fileName) => { const result = typescript_1.transpileModule(code, { fileName, compilerOptions, reportDiagnostics: true, }); const diagnosticList = result.diagnostics; if (diagnosticList && diagnosticList.length) { throw new Error(diagnosticToString_1.diagnosticsToString(diagnosticList, cwd)); } return [result.outputText, result.sourceMapText]; }; sourceMapSupport.install({ environment: 'node', retrieveFile(path) { return memoryCache.outputs[path]; }, }); const register = { cwd, cacheDirectory, extensions, compile: readThrough(cacheDirectory, memoryCache, compile, path_1.extname), }; extensions.forEach(extension => { registerExtension(extension, register, originalJsHandler); }); } exports.transpileNode = transpileNode; function readThrough(cachedir, memoryCache, compile, getExtension) { // Make sure the cache directory exists before continuing. return (code, fileName) => { const cachePath = path_1.join(cachedir, getCacheName(code, fileName)); const extension = getExtension(fileName); const outputPath = `${cachePath}${extension}`; try { const contents = fs_1.readFileSync(outputPath, 'utf8'); if (isValidCacheContent(contents)) { memoryCache.outputs[fileName] = contents; return contents; } } catch (err) { /* Ignore. */ } const [value, sourceMap] = compile(code, fileName); const output = updateOutput(value, fileName, sourceMap, getExtension); memoryCache.outputs[fileName] = output; fs_1.writeFileSync(outputPath, output); return output; }; } function updateOutput(outputText, fileName, sourceMap, getExtension) { const base64Map = Buffer.from(updateSourceMap(sourceMap, fileName), 'utf8').toString('base64'); const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}`; const sourceMapLength = `${path_1.basename(fileName)}.map`.length + (getExtension(fileName).length - path_1.extname(fileName).length); return outputText.slice(0, -sourceMapLength) + sourceMapContent; } function updateSourceMap(sourceMapText, fileName) { const sourceMap = JSON.parse(sourceMapText); sourceMap.file = fileName; sourceMap.sources = [fileName]; delete sourceMap.sourceRoot; return JSON.stringify(sourceMap); } function isValidCacheContent(contents) { return /(?:9|0=|Q==)$/.test(contents.slice(-3)); } function getCacheName(sourceCode, fileName) { return crypto_1.createHash('sha256') .update(path_1.extname(fileName), 'utf8') .update('\x00', 'utf8') .update(sourceCode, 'utf8') .digest('hex'); } function registerExtension(ext, register, originalHandler) { const old = require.extensions[ext] || originalHandler; require.extensions[ext] = (m, filename) => { const _compile = m._compile; m._compile = function (code, fileName) { return _compile.call(this, register.compile(code, fileName), fileName); }; return old(m, filename); }; } //# sourceMappingURL=transpileNode.js.map