forked from validatem/core
Refactor colors, heuristically detect the source of a validation failure
parent
9a31868883
commit
2d26d92d17
@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
|
||||
const supportsColor = require("supports-color");
|
||||
|
||||
// NOTE: We do some manual ANSI escape code stuff here for now, because using `chalk` would significantly inflate the bundle size of the core.
|
||||
// TODO: Find a better solution for this.
|
||||
let openHighlight, openDim, openHighlightBold, openDimBold, closeColor;
|
||||
|
||||
if (supportsColor.stderr) {
|
||||
openHighlight = `\u001b[32m`; // green
|
||||
openDim = `\u001b[90m`; // gray
|
||||
openHighlightBold = `\u001b[32;1m`; // green bold
|
||||
openDimBold = `\u001b[90;1m`; // gray bold
|
||||
// closeColor = `\u001b[39m`; // Does not reset bold!
|
||||
closeColor = `\u001b[0m`;
|
||||
} else {
|
||||
openHighlight = "";
|
||||
openDim = "";
|
||||
openHighlightBold = ""; // cyan bold
|
||||
openDimBold = ""; // gray bold
|
||||
closeColor = "";
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
dim: (string) => openDim + string + closeColor,
|
||||
highlight: (string) => openHighlight + string + closeColor,
|
||||
dimBold: (string) => openDimBold + string + closeColor,
|
||||
highlightBold: (string) => openHighlightBold + string + closeColor,
|
||||
};
|
||||
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
|
||||
// FIXME: Move this into its own package!
|
||||
|
||||
const execall = require("execall");
|
||||
const defaultValue = require("default-value");
|
||||
|
||||
// I'm so, so sorry...
|
||||
let lineRegex = /\s+at\s+(?:(?:([^\[$\n]+)\[as ([^\]]+)\] |([^\($\n]+))\(([^\)\n]+)\)|([^\n]+))(?:\n|$)/gm;
|
||||
let positionRegex = /(.+):(\d+):(\d+)/;
|
||||
|
||||
function maybeTrim(value) {
|
||||
if (value != null) {
|
||||
return value.trim();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function parseLocation(locationString) {
|
||||
let match = positionRegex.exec(locationString);
|
||||
|
||||
if (match != null) {
|
||||
return {
|
||||
path: match[1],
|
||||
line: parseInt(match[2]),
|
||||
column: parseInt(match[3])
|
||||
};
|
||||
} else {
|
||||
throw new Error(`Could not parse location from string: ${locationString}`);
|
||||
}
|
||||
}
|
||||
|
||||
function extractFrames(stack) {
|
||||
// TODO: Maybe make this code even more cautious, and match each stacktrace line individually, aborting as soon as any one line cannot be parsed?
|
||||
let matches = execall(lineRegex, stack);
|
||||
|
||||
return matches.map((match) => {
|
||||
let groups = match.subMatches;
|
||||
|
||||
return {
|
||||
functionName: maybeTrim(defaultValue(groups[0], groups[2])),
|
||||
alias: groups[1],
|
||||
location: parseLocation(defaultValue(groups[3], groups[4]))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function parseStackTrace(error) {
|
||||
let stack = error.stack;
|
||||
let lines = stack.split("\n");
|
||||
|
||||
let firstStackLine = lines
|
||||
.map((line) => line.trim())
|
||||
.findIndex((line) => line.startsWith("at ") && positionRegex.test(line));
|
||||
|
||||
if (firstStackLine !== -1) {
|
||||
let cleanStack = lines
|
||||
.slice(firstStackLine)
|
||||
.join("\n");
|
||||
|
||||
return extractFrames(cleanStack);
|
||||
} else {
|
||||
throw new Error(`Could not find a stacktrace frame`);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue