import {createLogger} from "@gongt/ts-stl-library/debug/create-logger"; import {LOG_LEVEL} from "@gongt/ts-stl-library/debug/levels"; import {transformFile as transformFileType, TransformOptions} from "babel-core"; import {Handler} from "express-serve-static-core" import {ensureDir, ensureDirSync, readFile, writeFile} from "fs-extra"; import {tmpdir} from "os"; import {dirname, resolve} from "path"; import {fileExists} from "../../file-operation/file-exists"; import {STL_SERVER_PACKAGE_ROOT} from "../../STL_SERVER_PACKAGE_ROOT"; import {createServeStatic} from "../inject/serve-static"; let transformFile: typeof transformFileType; const debug = createLogger(LOG_LEVEL.DEBUG, 'jspm-plug:ie'); const tempDir = resolve(tmpdir(), 'compile-ie'); ensureDirSync(tempDir); const isJs = /\.js$/; export function InternetExplorerProviders(clientPath: string, clientSource: string): Handler[] { if (!transformFile) { transformFile = require('babel-core').transformFile; } const tempMiddleware = createServeStatic(tempDir, { fallthrough: true, }); const clientProvider = [ tempMiddleware, (req, res, next) => { req.url = req.url.replace(/^\/_IE_/, ''); if (isJs.test(req.url)) { compileFile(clientPath, req.url.replace(/^\//g, '')).then(() => { tempMiddleware(req, res, next); }, (e) => { next(e); }); } else { next(); } }, ]; if (clientSource) { clientProvider.push( createServeStatic(clientPath, { fallthrough: true, }), createServeStatic(clientSource), ); } else { clientProvider.push( createServeStatic(clientPath), ); } return clientProvider; } async function compileFile(root: string, file: string) { const source = resolve(root, file); const target = resolve(tempDir, file); debug('transpile: %s -> %s', source, target); await ensureDir(dirname(target)); const source_map = source + '.map'; let sourceMap: object; if (await fileExists(source_map)) { sourceMap = JSON.parse(await readFile(source_map, {encoding: 'utf8'})); } const {code, map} = await new Promise((resolve, reject) => { const opt: TransformOptions = { ast: false, code: true, sourceMaps: true, comments: true, babelrc: true, "extends": STL_SERVER_PACKAGE_ROOT + '/.babelrc', inputSourceMap: sourceMap, minified: false, only: source, }; transformFile(source, opt, (err, data) => { err? reject(err) : resolve(data); }); }); await writeFile(target, code, {encoding: 'utf8'}); await writeFile(target + '.map', JSON.stringify(map), {encoding: 'utf8'}); }