Files
CHOMPStation2/tgui/packages/tgui-dev-server/link/retrace.js
CHOMPStation2 85ca379bb2 [MIRROR] [TGUI 5.0 Prep] JS to JSX (#7414)
Co-authored-by: Selis <sirlionfur@hotmail.de>
Co-authored-by: Selis <selis@xynolabs.com>
2023-12-13 23:23:03 +01:00

89 lines
2.4 KiB
JavaScript

/**
* @file
* @copyright 2020 Aleksej Komarov
* @license MIT
*/
import fs from 'fs';
import { basename } from 'path';
import { createLogger } from '../logging';
import { require } from '../require';
import { resolveGlob } from '../util';
const SourceMap = require('source-map');
const { parse: parseStackTrace } = require('stacktrace-parser');
const logger = createLogger('retrace');
const { SourceMapConsumer } = SourceMap;
const sourceMaps = [];
export const loadSourceMaps = async (bundleDir) => {
// Destroy and garbage collect consumers
while (sourceMaps.length !== 0) {
const { consumer } = sourceMaps.shift();
consumer.destroy();
}
// Load new sourcemaps
const paths = await resolveGlob(bundleDir, '*.map');
for (let path of paths) {
try {
const file = basename(path).replace('.map', '');
const consumer = await new SourceMapConsumer(
JSON.parse(fs.readFileSync(path, 'utf8'))
);
sourceMaps.push({ file, consumer });
} catch (err) {
logger.error(err);
}
}
logger.log(`loaded ${sourceMaps.length} source maps`);
};
export const retrace = (stack) => {
if (typeof stack !== 'string') {
logger.log('ERROR: Stack is not a string!', stack);
return stack;
}
const header = stack.split(/\n\s.*at/)[0];
const mappedStack = parseStackTrace(stack)
.map((frame) => {
if (!frame.file) {
return frame;
}
// Find the correct source map
const sourceMap = sourceMaps.find((sourceMap) => {
return frame.file.includes(sourceMap.file);
});
if (!sourceMap) {
return frame;
}
// Map the frame
const { consumer } = sourceMap;
const mappedFrame = consumer.originalPositionFor({
source: basename(frame.file),
line: frame.lineNumber,
column: frame.column,
});
return {
...frame,
file: mappedFrame.source,
lineNumber: mappedFrame.line,
column: mappedFrame.column,
};
})
.map((frame) => {
// Stringify the frame
const { file, methodName, lineNumber } = frame;
if (!file) {
return ` at ${methodName}`;
}
const compactPath = file
.replace(/^webpack:\/\/\/?/, './')
.replace(/.*node_modules\//, '');
return ` at ${methodName} (${compactPath}:${lineNumber})`;
})
.join('\n');
return header + '\n' + mappedStack;
};