UNPKG

ts-transformer-preval-macro

Version:
112 lines (110 loc) 4.54 kB
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const shell = __importStar(require("child_process")); const crypto_1 = __importDefault(require("crypto")); const findCacheDir = require("find-cache-dir"); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const deleteDir = __importStar(require("rimraf")); const ts = __importStar(require("typescript")); let OPTIONS = { cacheActivated: false, debug: false, mode: 'development' }; function preevaluationTransformer() { return (context) => { let tagName = 'preval'; const visit = (node) => { if (ts.isImportDeclaration(node) && node.moduleSpecifier.getText().indexOf('prevalTransformer') > -1) { if (node.importClause !== undefined) { tagName = node.importClause.getText().slice(1, -1); } return undefined; } if (ts.isTaggedTemplateExpression(node) && node.tag.getText() === tagName) { let code = node.template.getText().slice(1, -1); const dir = path.dirname(node.getSourceFile().fileName); const hash = crypto_1.default .createHash('sha1') .update(code) .digest('hex'); // const evalFileDir = dir.split('/')[dir.split('/').length - 1]; const evalFilename = '_eval.' + hash; const evalPath = path.join(dir, evalFilename + '.ts'); const evalDir = `${dir}/_temp_${hash}`; const cacheDir = findCacheDir({ create: true, name: `ts-transformer-preval-macro/${OPTIONS.mode}` }); if (cacheDir === null) { throw new Error('not able to create a cache dir'); } const evalResult = path.join(cacheDir, `/${hash}.json`); code = `${code} run().then((result) => { console.log(JSON.stringify(result)); });`; if (fs.existsSync(evalResult) && OPTIONS.cacheActivated) { const cachedRawResult = fs.readFileSync(evalResult); return transformResult(cachedRawResult); } fs.writeFileSync(evalPath, code); try { shell.execSync(`tsc ${evalPath} --outDir ${evalDir}`); } catch (e) { // TODO parse tsc errors and decide if something gone really wrong if (!OPTIONS.debug) { fs.unlinkSync(evalPath); deleteDir.sync(evalDir); throw e; } } let rawResult = 'null'; try { rawResult = shell .execSync(`node ${evalDir}/${evalFilename}.js`) .toString(); } catch (e) { if (!OPTIONS.debug) { fs.unlinkSync(evalPath); deleteDir.sync(evalDir); throw e; } } if (!OPTIONS.debug) { fs.unlinkSync(evalPath); deleteDir.sync(evalDir); } fs.writeFileSync(evalResult, rawResult); return transformResult(rawResult); } return ts.visitEachChild(node, (child) => visit(child), context); }; return (node) => { return ts.visitNode(node, visit); }; }; } function transformResult(rawResult) { const result = JSON.stringify(JSON.parse(rawResult)); return ts.createCall(ts.createPropertyAccess(ts.createIdentifier('JSON'), ts.createIdentifier('parse')), undefined, [ts.createStringLiteral(result)]); } exports.default = (options) => { OPTIONS = Object.assign({}, OPTIONS, options); return preevaluationTransformer; };