Advertisement
Guest User

Untitled

a guest
Sep 26th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.59 KB | None | 0 0
  1. import chalk from 'chalk';
  2. import path from 'path';
  3. import errorCallSites from 'error-callsites';
  4. import {SourceMapConsumer} from 'source-map';
  5. import {retrieveSourceMap} from 'source-map-support/source-map-support';
  6.  
  7. const sourceMapCache = {};
  8. const fileContentsCache = {};
  9.  
  10. export function supportRelativeURL(file, url) {
  11. if (!file) return url;
  12. const dir = path.dirname(file);
  13. const match = /^\w+:\/\/[^\/]*/.exec(dir);
  14. const protocol = match ? match[0] : '';
  15. return protocol + path.resolve(dir.slice(protocol.length), url);
  16. }
  17.  
  18. export const getPosition = (frame) => ({
  19. source: frame.getFileName(),
  20. line: frame.getLineNumber(),
  21. column: frame.getColumnNumber(),
  22. });
  23.  
  24. export const getSourceMapConsumer = (frame) => {
  25. const {source} = getPosition(frame);
  26.  
  27. let consumer = sourceMapCache[source];
  28.  
  29. if (consumer === undefined) {
  30. const urlAndMap = retrieveSourceMap(source);
  31. if (urlAndMap) {
  32. consumer = sourceMapCache[source] = new SourceMapConsumer(urlAndMap.map);
  33.  
  34. if (consumer.sourcesContent) {
  35. consumer.sources.forEach(function(source, i) {
  36. const contents = consumer.sourcesContent[i];
  37. if (contents) {
  38. const url = supportRelativeURL(urlAndMap.url, source);
  39. fileContentsCache[url] = contents;
  40. }
  41. });
  42. }
  43. } else {
  44. consumer = sourceMapCache[source] = null;
  45. }
  46. }
  47.  
  48. return consumer;
  49. };
  50.  
  51. export const getOriginalPosition = (frame) => {
  52. const position = getPosition(frame);
  53. const consumer = getSourceMapConsumer(frame);
  54.  
  55. if (!consumer) {
  56. return null;
  57. }
  58.  
  59. return consumer.originalPositionFor(position);
  60. };
  61.  
  62. export const getSourceContent = (frame) => {
  63. const originalPosition = getOriginalPosition(frame);
  64. const consumer = getSourceMapConsumer(frame);
  65.  
  66. if (!originalPosition || !consumer) {
  67. return null;
  68. }
  69.  
  70. return consumer.sourceContentFor(originalPosition.source);
  71. };
  72.  
  73. export const getFrameContext = (frame, {leading = 2, trailing = 2} = {}) => {
  74. const sourceContent = getSourceContent(frame);
  75. const originalPosition = getOriginalPosition(frame);
  76.  
  77. if (!sourceContent || !originalPosition) {
  78. return null;
  79. }
  80.  
  81. const lines = sourceContent.split(/(?:\r\n|\r|\n)/);
  82.  
  83. const offset = Math.max(1, originalPosition.line - leading);
  84. const end = Math.min(lines.length, originalPosition.line + trailing);
  85.  
  86. return {
  87. ...originalPosition,
  88. offset,
  89. lines: lines.slice(offset - 1, end),
  90. };
  91. };
  92.  
  93. export const formatContext = (context, {color = false} = {}) => {
  94. const id = (str) => str;
  95. const red = color ? chalk.red : id;
  96. const gray = color ? chalk.gray : id;
  97. const bold = color ? chalk.bold : id;
  98.  
  99. const pad = (len, str = '') =>
  100. `${(new Array(len - `${str}`.length)).join(' ')}${str}`;
  101.  
  102. const digits = (context.offset + context.lines.length - 1).toString().length;
  103.  
  104. const lines = context.lines.map((line, index) => {
  105. const current = context.line === context.offset + index;
  106. const lineNumber = pad(digits, index + context.offset);
  107.  
  108. return `${
  109. current ? bold('> ') : ' '
  110. }${
  111. gray(lineNumber)
  112. } | ${
  113. (current ? red : gray)(line)
  114. }${
  115. current
  116. ? `\n ${pad(digits) } | ${pad(context.column) }${bold('^')}`
  117. : ''
  118. }`;
  119. });
  120.  
  121. return `@ ${context.source}\n\n${lines.join('\n')}`;
  122. };
  123.  
  124. export const formatError = (error, options = {}) => {
  125. const {frames = 5} = options;
  126. const contexts = [];
  127.  
  128. errorCallSites(error).slice(0, frames).forEach((frame) => {
  129. const context = getFrameContext(frame, options);
  130. if (context) {
  131. contexts.push(formatContext(context, options));
  132. }
  133. });
  134.  
  135. return contexts.join('\n\n');
  136. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement