Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chalk from 'chalk';
- import path from 'path';
- import errorCallSites from 'error-callsites';
- import {SourceMapConsumer} from 'source-map';
- import {retrieveSourceMap} from 'source-map-support/source-map-support';
- const sourceMapCache = {};
- const fileContentsCache = {};
- export function supportRelativeURL(file, url) {
- if (!file) return url;
- const dir = path.dirname(file);
- const match = /^\w+:\/\/[^\/]*/.exec(dir);
- const protocol = match ? match[0] : '';
- return protocol + path.resolve(dir.slice(protocol.length), url);
- }
- export const getPosition = (frame) => ({
- source: frame.getFileName(),
- line: frame.getLineNumber(),
- column: frame.getColumnNumber(),
- });
- export const getSourceMapConsumer = (frame) => {
- const {source} = getPosition(frame);
- let consumer = sourceMapCache[source];
- if (consumer === undefined) {
- const urlAndMap = retrieveSourceMap(source);
- if (urlAndMap) {
- consumer = sourceMapCache[source] = new SourceMapConsumer(urlAndMap.map);
- if (consumer.sourcesContent) {
- consumer.sources.forEach(function(source, i) {
- const contents = consumer.sourcesContent[i];
- if (contents) {
- const url = supportRelativeURL(urlAndMap.url, source);
- fileContentsCache[url] = contents;
- }
- });
- }
- } else {
- consumer = sourceMapCache[source] = null;
- }
- }
- return consumer;
- };
- export const getOriginalPosition = (frame) => {
- const position = getPosition(frame);
- const consumer = getSourceMapConsumer(frame);
- if (!consumer) {
- return null;
- }
- return consumer.originalPositionFor(position);
- };
- export const getSourceContent = (frame) => {
- const originalPosition = getOriginalPosition(frame);
- const consumer = getSourceMapConsumer(frame);
- if (!originalPosition || !consumer) {
- return null;
- }
- return consumer.sourceContentFor(originalPosition.source);
- };
- export const getFrameContext = (frame, {leading = 2, trailing = 2} = {}) => {
- const sourceContent = getSourceContent(frame);
- const originalPosition = getOriginalPosition(frame);
- if (!sourceContent || !originalPosition) {
- return null;
- }
- const lines = sourceContent.split(/(?:\r\n|\r|\n)/);
- const offset = Math.max(1, originalPosition.line - leading);
- const end = Math.min(lines.length, originalPosition.line + trailing);
- return {
- ...originalPosition,
- offset,
- lines: lines.slice(offset - 1, end),
- };
- };
- export const formatContext = (context, {color = false} = {}) => {
- const id = (str) => str;
- const red = color ? chalk.red : id;
- const gray = color ? chalk.gray : id;
- const bold = color ? chalk.bold : id;
- const pad = (len, str = '') =>
- `${(new Array(len - `${str}`.length)).join(' ')}${str}`;
- const digits = (context.offset + context.lines.length - 1).toString().length;
- const lines = context.lines.map((line, index) => {
- const current = context.line === context.offset + index;
- const lineNumber = pad(digits, index + context.offset);
- return `${
- current ? bold('> ') : ' '
- }${
- gray(lineNumber)
- } | ${
- (current ? red : gray)(line)
- }${
- current
- ? `\n ${pad(digits) } | ${pad(context.column) }${bold('^')}`
- : ''
- }`;
- });
- return `@ ${context.source}\n\n${lines.join('\n')}`;
- };
- export const formatError = (error, options = {}) => {
- const {frames = 5} = options;
- const contexts = [];
- errorCallSites(error).slice(0, frames).forEach((frame) => {
- const context = getFrameContext(frame, options);
- if (context) {
- contexts.push(formatContext(context, options));
- }
- });
- return contexts.join('\n\n');
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement