/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ "use strict"; // RUNS UNTRANSFORMED IN NODE >= v4 // NO FANCY FEATURES, E.G. DESTRUCTURING, PLEASE! const SourceMapConsumer = require("source-map").SourceMapConsumer; const concat = require("concat-stream"); const net = require("net"); process.once("message", socket => { net .createServer( { allowHalfOpen: true }, connection => { connection.setEncoding("utf8"); connection.pipe( concat( data => symbolicate(connection, data).catch(console.error) // log the error as a last resort ) ); } ) .listen(socket, () => process.send(null)); }); function symbolicate(connection, data) { return Promise.resolve(data) .then(JSON.parse) .then(symbolicateStack) .then(JSON.stringify) .catch(makeErrorMessage) .then(message => connection.end(message)); } function symbolicateStack(data) { const consumers = new Map(data.maps.map(mapToConsumer)); return { result: data.stack.map(frame => mapFrame(frame, consumers)) }; } function mapFrame(frame, consumers) { const sourceUrl = frame.file; const consumer = consumers.get(sourceUrl); if (consumer == null) { return frame; } const original = consumer.originalPositionFor({ line: frame.lineNumber, column: frame.column }); if (!original) { return frame; } return Object.assign({}, frame, { file: original.source, lineNumber: original.line, column: original.column }); } function makeErrorMessage(error) { return JSON.stringify({ error: String((error && error.message) || error) }); } function mapToConsumer(tuple) { tuple[1] = new SourceMapConsumer(tuple[1]); return tuple; } // for testing exports.symbolicate = symbolicate;