UNPKG

@techdocs/cli

Version:

Utility CLI for managing TechDocs sites in Backstage.

96 lines (90 loc) 3.96 kB
'use strict'; var httpProxy = require('http-proxy'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var httpProxy__default = /*#__PURE__*/_interopDefaultCompat(httpProxy); const LIVE_RELOAD_ELEMENT = "live-reload"; const LIVE_RELOAD_ATTR_EPOCH = "live-reload-epoch"; const LIVE_RELOAD_ATTR_REQUEST_ID = "live-reload-request-id"; const CLI_LIVERELOAD_PATH = "/.livereload"; const MKDOCS_LIVERELOAD_PATH = "/livereload"; const CONTENT_TYPE_HTML = "text/html"; const HEADER_CONTENT_LENGTH = "content-length"; const BODY_START_RE = /<body\b[^>]*>/; const MKDOCS_LIVERELOAD_CALL_RE = /livereload\(\s*(\d+)\s*,\s*(\d+)\s*\)\s*;?/; function injectLivereloadParameters(html) { const livereloadMatch = html.match(MKDOCS_LIVERELOAD_CALL_RE); if (!livereloadMatch) { return html; } const [, epoch, requestId] = livereloadMatch; const liveReloadTag = `<${LIVE_RELOAD_ELEMENT} ${LIVE_RELOAD_ATTR_EPOCH}="${epoch}" ${LIVE_RELOAD_ATTR_REQUEST_ID}="${requestId}"></${LIVE_RELOAD_ELEMENT}>`; const bodyStart = html.match(BODY_START_RE); const bodyStartIndex = bodyStart?.index ?? 0; const bodyStartLength = bodyStart?.[0]?.length ?? 0; if (bodyStartIndex === 0 || bodyStartLength === 0) { return html; } const bodyEndIndex = bodyStartIndex + bodyStartLength; return html.slice(0, bodyEndIndex) + liveReloadTag + html.slice(bodyEndIndex); } function setCorsHeaders(response) { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS"); } function proxyHtmlWithLivereloadInjection(options) { const { request, response, mkdocsTargetAddress, proxyEndpoint, onError } = options; const htmlProxy = httpProxy__default.default.createProxyServer({ target: mkdocsTargetAddress, selfHandleResponse: true }); htmlProxy.on("error", onError); htmlProxy.on("proxyRes", (proxyRes, _req, res) => { const contentType = proxyRes.headers["content-type"]; const contentEncoding = proxyRes.headers["content-encoding"]; const isHtml = contentType && typeof contentType === "string" && contentType.startsWith(CONTENT_TYPE_HTML); if (isHtml && !contentEncoding) { const chunks = []; proxyRes.on("data", (chunk) => { chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); }); proxyRes.on("end", () => { const body = Buffer.concat(chunks).toString("utf8"); const modifiedHtml = injectLivereloadParameters(body); res.statusCode = proxyRes.statusCode ?? 200; Object.keys(proxyRes.headers).forEach((key) => { if (key.toLowerCase() !== HEADER_CONTENT_LENGTH) { res.setHeader(key, proxyRes.headers[key]); } }); setCorsHeaders(res); res.end(modifiedHtml); }); } else { res.statusCode = proxyRes.statusCode ?? 200; Object.keys(proxyRes.headers).forEach((key) => { res.setHeader(key, proxyRes.headers[key]); }); setCorsHeaders(res); proxyRes.pipe(res); } }); const forwardPath = request.url?.replace(new RegExp(`^${proxyEndpoint}`, "i"), "") || ""; request.url = forwardPath; htmlProxy.web(request, response); } function proxyMkdocsLivereload(options) { const { request, response, mkdocsTargetAddress, onError } = options; const proxy = httpProxy__default.default.createProxyServer({ target: mkdocsTargetAddress }); proxy.on("error", onError); setCorsHeaders(response); response.setHeader("Access-Control-Allow-Headers", "Content-Type"); request.url = request.url?.replace( CLI_LIVERELOAD_PATH, MKDOCS_LIVERELOAD_PATH ); proxy.web(request, response); } exports.injectLivereloadParameters = injectLivereloadParameters; exports.proxyHtmlWithLivereloadInjection = proxyHtmlWithLivereloadInjection; exports.proxyMkdocsLivereload = proxyMkdocsLivereload; //# sourceMappingURL=livereload.cjs.js.map