UNPKG

five-server

Version:

Development Server with Live Reload Capability. (Maintained Fork of Live Server)

130 lines 5.03 kB
"use strict"; /** * @author Yannick Deubel (https://github.com/yandeu) * @copyright Copyright (c) 2021 Yannick Deubel * @license {@link https://github.com/yandeu/five-server/blob/main/LICENSE LICENSE} */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.injectCode = exports.code = exports.Inject = void 0; const fs_1 = require("fs"); const path_1 = require("path"); const stream_1 = require("stream"); const zlib_1 = require("zlib"); const url_1 = __importDefault(require("url")); /** * unzip: Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header. * https://nodejs.org/api/zlib.html#zlib_class_zlib_unzip */ const unzip = (buffer) => { return new Promise((resolve, reject) => { (0, zlib_1.unzip)(buffer, (err, buffer) => { if (err) return reject(err); return resolve(buffer.toString()); }); }); }; class Inject extends stream_1.Writable { constructor(tags, code) { super(); this.tags = tags; this.code = code; this.size = 0; this.chunks = []; this.data = ''; this.injectTag = ''; } doInjection(data) { const injectCandidates = [new RegExp('</head>', 'i'), new RegExp('</html>', 'i'), new RegExp('</body>', 'i')]; let match; for (let i = 0; i < injectCandidates.length; ++i) { match = injectCandidates[i].exec(data); if (match) { this.injectTag = match[0]; break; } } if (this.injectTag && typeof this.injectTag === 'string') { data = data.replace(this.injectTag, this.code + this.injectTag); } // inject the code at the bottom of the file, // if there are at least some html tags else if (/<[a-z]\w+>/gm.test(data)) { this.injectTag = true; data = `${data}\n${this.code}`; } // convert cache to [src|href]="/.cache/.." const replacer = (match, p1, p2, _offset, _string) => match.replace(p1, '').replace(p2, `/.cache/${p2.replace(/^\//, '')}`); data = data.replace(/<[^>]*(cache.)[^>]*[src|href]="(\S+)"[^>]*>/gm, replacer); this.data = data; } _write(chunk, encoding, callback) { this.chunks.push(chunk); callback(); } async _final(callback) { const buffer = Buffer.concat(this.chunks); this.data = buffer.toString(); const raw = await unzip(buffer).catch(() => { }); if (raw) this.data = raw; this.doInjection(this.data); callback(); } } exports.Inject = Inject; const code = (filePath, baseURL, injectBodyOptions) => { const a = injectBodyOptions ? ' data-inject-body="true"' : ''; return `<!-- Code injected by Five-server --> <script async data-id="five-server" data-file="${filePath}"${a} type="application/javascript" src="${baseURL}fiveserver.js"></script> `; }; exports.code = code; /** Injects the five-server script into the html page and converts the cache attributes. */ const injectCode = (root, baseURL, PHP, injectBodyOptions) => { return async (req, res, next) => { const { pathname } = url_1.default.parse(req.url); if (pathname && (pathname === '/' || (0, path_1.extname)(pathname) === '.html' || (0, path_1.extname)(pathname) === '.htm' || (0, path_1.extname)(pathname) === '.php')) { let filePath = (0, path_1.resolve)((0, path_1.join)(root + pathname)); filePath = decodeURI(filePath); if (!(0, fs_1.existsSync)(filePath)) return next(); if (!(0, fs_1.statSync)(filePath).isFile()) return next(); const inject = new Inject(['</head>', '</html>', '</body>'], (0, exports.code)(filePath, baseURL, injectBodyOptions)); if ((0, path_1.extname)(pathname) === '.php') { const html = await PHP.parseFile(filePath, res); inject.doInjection(html); res.type('html'); res.setHeader('Content-Length', inject.data.length); return res.send(inject.data); } (0, fs_1.createReadStream)(filePath) .pipe(inject) .on('finish', () => { if (!inject.injectTag) return next(); else { res.type('html'); res.setHeader('Content-Length', inject.data.length); res.send(inject.data); } }) .on('error', () => { return next(); }); } else { return next(); } }; }; exports.injectCode = injectCode; //# sourceMappingURL=injectCode.js.map