UNPKG

@fromjs/backend

Version:
110 lines (109 loc) 4.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const proxy_instrumenter_1 = require("@fromjs/proxy-instrumenter"); const core_1 = require("@fromjs/core"); process.on("message", function (message) { if (message.arguments[1]) { throw Error("todo......"); } const ret = proxy[message.method].call(proxy, message.arguments[0]); process.send({ type: "messageResponse", ret, messageId: message.messageId }); }); let proxy; const options = JSON.parse(process.argv[process.argv.length - 1]); const { accessToken, bePort, proxyPort, certDirectory, dontTrack, block, disableDefaultBlockList } = options; process.title = "FromJS - Proxy (" + proxyPort + ")"; let defaultBlockList = [ "inspectlet.com", "google-analytics.com", "newrelic.com", "intercom.com", "segment.com", "bugsnag", "mixpanel", "piwik" ]; proxy_instrumenter_1.startProxy({ babelPluginOptions: { accessToken, backendPort: bePort }, certDirectory: certDirectory, handleEvalScript: core_1.handleEvalScript, port: proxyPort, instrumenterFilePath: __dirname + "/instrumentCode.js", verbose: false, shouldBlock: ({ url }) => { if (block.some(dt => url.includes(dt))) { return true; } if (!disableDefaultBlockList && defaultBlockList.some(dt => url.includes(dt))) { console.log(url + " blocked because it's on the default block list. You can disable this by passing in --disableDefaultBlockList"); return true; } return false; }, shouldInstrument: ({ port, path, url }) => { if (dontTrack.some(dt => url.includes(dt))) { return false; } if (url.includes("product_registry_impl_module.js") && url.includes("chrome-devtools-frontend")) { // External file loaded by Chrome DevTools when opened return false; } return (port !== bePort || path.startsWith("/start") || path.startsWith("/fromJSInternal")); }, rewriteHtml: html => { const originalHtml = html; // Not accurate because there could be an attribute attribute value like ">", should work // most of the time const openingBodyTag = html.match(/<body.*?>/); const openingHeadTag = html.match(/<head.*?>/); let bodyStartIndex; if (openingBodyTag) { bodyStartIndex = html.search(openingBodyTag[0]) + openingBodyTag[0].length; } let insertionIndex = 0; if (openingHeadTag) { insertionIndex = html.search(openingHeadTag[0]) + openingHeadTag[0].length; } else if (openingBodyTag) { insertionIndex = bodyStartIndex; } if (openingBodyTag) { const hasScriptTagInBody = html.slice(bodyStartIndex).includes("<script"); if (!hasScriptTagInBody) { // insert script tag just so that HTML origin mapping is done const closingBodyTagIndex = html.search(/<\/body/); if (closingBodyTagIndex !== -1) { html = html.slice(0, closingBodyTagIndex) + `<script data-fromjs-remove-before-initial-html-mapping src="http://localhost:${bePort}/fromJSInternal/empty.js"></script>` + html.slice(closingBodyTagIndex); } } } // Note: we don't want to have any empty text between the text, since that won't be removed // alongside the data-fromjs-remove-before-initial-html-mapping tags! var insertedHtml = `<script data-fromjs-dont-instrument data-fromjs-remove-before-initial-html-mapping>window.__fromJSInitialPageHtml = decodeURI("${encodeURI(originalHtml)}")</script>` + `<script src="http://localhost:${bePort}/jsFiles/babel-standalone.js" data-fromjs-remove-before-initial-html-mapping></script>` + `<script src="http://localhost:${bePort}/jsFiles/compileInBrowser.js" data-fromjs-remove-before-initial-html-mapping></script>`; return (html.slice(0, insertionIndex) + insertedHtml + html.slice(insertionIndex)); }, onCompilationComplete: (response) => { process.send({ type: "storeLocs", locs: response.locs }); }, onRegisterEvalScript: response => { process.send({ type: "storeLocs", locs: response.locs }); } }).then(p => { proxy = p; process.send({ type: "isReady" }); });