mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix(renderer): Vendor ansicolor as typescript
Fixes #15635 Importing ansicolor from node_modules or vendored as is failed because there is no ES5 transpiler configured for ES6 libs. - remove ansicolor from package.json - add ansicolor to public/vendor/ansicolor and port to typescript - adapt all ansicolor imports - add `public/vendor` as a path to be considered by ts compiler
This commit is contained in:
parent
9383b04efd
commit
26236b4bc3
@ -169,7 +169,6 @@
|
||||
"angular-native-dragdrop": "1.2.2",
|
||||
"angular-route": "1.6.6",
|
||||
"angular-sanitize": "1.6.6",
|
||||
"ansicolor": "1.1.78",
|
||||
"baron": "^3.0.3",
|
||||
"brace": "^0.10.0",
|
||||
"classnames": "^2.2.6",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ansicolor from 'vendor/ansicolor/ansicolor';
|
||||
|
||||
interface Style {
|
||||
[key: string]: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import ansicolor from 'ansicolor';
|
||||
import ansicolor from 'vendor/ansicolor/ansicolor';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
|
471
public/vendor/ansicolor/ansicolor.ts
vendored
Normal file
471
public/vendor/ansicolor/ansicolor.ts
vendored
Normal file
@ -0,0 +1,471 @@
|
||||
// Vendored and converted to TS, source: https://github.com/xpl/ansicolor/blob/b82360563ed29de444dc7618b9236191e0a77096/ansicolor.js
|
||||
// License: Unlicense, author: https://github.com/xpl
|
||||
|
||||
const O = Object;
|
||||
|
||||
/* See https://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
const colorCodes = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'lightGray', '', 'default'],
|
||||
colorCodesLight = [
|
||||
'darkGray',
|
||||
'lightRed',
|
||||
'lightGreen',
|
||||
'lightYellow',
|
||||
'lightBlue',
|
||||
'lightMagenta',
|
||||
'lightCyan',
|
||||
'white',
|
||||
'',
|
||||
],
|
||||
styleCodes = ['', 'bright', 'dim', 'italic', 'underline', '', '', 'inverse'],
|
||||
asBright = {
|
||||
red: 'lightRed',
|
||||
green: 'lightGreen',
|
||||
yellow: 'lightYellow',
|
||||
blue: 'lightBlue',
|
||||
magenta: 'lightMagenta',
|
||||
cyan: 'lightCyan',
|
||||
black: 'darkGray',
|
||||
lightGray: 'white',
|
||||
},
|
||||
types = {
|
||||
0: 'style',
|
||||
2: 'unstyle',
|
||||
3: 'color',
|
||||
9: 'colorLight',
|
||||
4: 'bgColor',
|
||||
10: 'bgColorLight',
|
||||
},
|
||||
subtypes = {
|
||||
color: colorCodes,
|
||||
colorLight: colorCodesLight,
|
||||
bgColor: colorCodes,
|
||||
bgColorLight: colorCodesLight,
|
||||
style: styleCodes,
|
||||
unstyle: styleCodes,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
const clean = obj => {
|
||||
for (const k in obj) {
|
||||
if (!obj[k]) {
|
||||
delete obj[k];
|
||||
}
|
||||
}
|
||||
return O.keys(obj).length === 0 ? undefined : obj;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
class Color {
|
||||
background: string;
|
||||
name: string;
|
||||
brightness: number;
|
||||
|
||||
constructor(background?, name?, brightness?) {
|
||||
this.background = background;
|
||||
this.name = name;
|
||||
this.brightness = brightness;
|
||||
}
|
||||
|
||||
get inverse() {
|
||||
return new Color(!this.background, this.name || (this.background ? 'black' : 'white'), this.brightness);
|
||||
}
|
||||
|
||||
get clean() {
|
||||
return clean({
|
||||
name: this.name === 'default' ? '' : this.name,
|
||||
bright: this.brightness === Code.bright,
|
||||
dim: this.brightness === Code.dim,
|
||||
});
|
||||
}
|
||||
|
||||
defaultBrightness(value) {
|
||||
return new Color(this.background, this.name, this.brightness || value);
|
||||
}
|
||||
|
||||
css(inverted) {
|
||||
const color = inverted ? this.inverse : this;
|
||||
|
||||
const rgbName = (color.brightness === Code.bright && asBright[color.name]) || color.name;
|
||||
|
||||
const prop = color.background ? 'background:' : 'color:',
|
||||
rgb = Colors.rgb[rgbName],
|
||||
alpha = this.brightness === Code.dim ? 0.5 : 1;
|
||||
|
||||
return rgb
|
||||
? prop + 'rgba(' + [...rgb, alpha].join(',') + ');'
|
||||
: !color.background && alpha < 1 ? 'color:rgba(0,0,0,0.5);' : ''; // Chrome does not support 'opacity' property...
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
class Code {
|
||||
static reset = 0;
|
||||
static bright = 1;
|
||||
static dim = 2;
|
||||
static inverse = 7;
|
||||
static noBrightness = 22;
|
||||
static noItalic = 23;
|
||||
static noUnderline = 24;
|
||||
static noInverse = 27;
|
||||
static noColor = 39;
|
||||
static noBgColor = 49;
|
||||
|
||||
value: number;
|
||||
|
||||
constructor(n?) {
|
||||
if (n !== undefined) {
|
||||
this.value = Number(n);
|
||||
}
|
||||
}
|
||||
|
||||
get type() {
|
||||
return types[Math.floor(this.value / 10)];
|
||||
}
|
||||
|
||||
get subtype() {
|
||||
return subtypes[this.type][this.value % 10];
|
||||
}
|
||||
|
||||
get str() {
|
||||
return this.value ? '\u001b[' + this.value + 'm' : '';
|
||||
}
|
||||
|
||||
static str(x) {
|
||||
return new Code(x).str;
|
||||
}
|
||||
|
||||
get isBrightness() {
|
||||
return this.value === Code.noBrightness || this.value === Code.bright || this.value === Code.dim;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
const replaceAll = (str, a, b) => str.split(a).join(b);
|
||||
|
||||
/* ANSI brightness codes do not overlap, e.g. "{bright}{dim}foo" will be rendered bright (not dim).
|
||||
So we fix it by adding brightness canceling before each brightness code, so the former example gets
|
||||
converted to "{noBrightness}{bright}{noBrightness}{dim}foo" – this way it gets rendered as expected.
|
||||
*/
|
||||
|
||||
const denormalizeBrightness = s => s.replace(/(\u001b\[(1|2)m)/g, '\u001b[22m$1');
|
||||
const normalizeBrightness = s => s.replace(/\u001b\[22m(\u001b\[(1|2)m)/g, '$1');
|
||||
|
||||
const wrap = (x, openCode, closeCode) => {
|
||||
const open = Code.str(openCode),
|
||||
close = Code.str(closeCode);
|
||||
|
||||
return String(x)
|
||||
.split('\n')
|
||||
.map(line => denormalizeBrightness(open + replaceAll(normalizeBrightness(line), close, open) + close))
|
||||
.join('\n');
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
const camel = (a, b) => a + b.charAt(0).toUpperCase() + b.slice(1);
|
||||
|
||||
const stringWrappingMethods = (() =>
|
||||
[
|
||||
...colorCodes.map(
|
||||
(k, i) =>
|
||||
!k
|
||||
? []
|
||||
: [
|
||||
// color methods
|
||||
|
||||
[k, 30 + i, Code.noColor],
|
||||
[camel('bg', k), 40 + i, Code.noBgColor],
|
||||
]
|
||||
),
|
||||
|
||||
...colorCodesLight.map(
|
||||
(k, i) =>
|
||||
!k
|
||||
? []
|
||||
: [
|
||||
// light color methods
|
||||
|
||||
[k, 90 + i, Code.noColor],
|
||||
[camel('bg', k), 100 + i, Code.noBgColor],
|
||||
]
|
||||
),
|
||||
|
||||
/* THIS ONE IS FOR BACKWARDS COMPATIBILITY WITH PREVIOUS VERSIONS (had 'bright' instead of 'light' for backgrounds)
|
||||
*/
|
||||
...['', 'BrightRed', 'BrightGreen', 'BrightYellow', 'BrightBlue', 'BrightMagenta', 'BrightCyan'].map(
|
||||
(k, i) => (!k ? [] : [['bg' + k, 100 + i, Code.noBgColor]])
|
||||
),
|
||||
|
||||
...styleCodes.map(
|
||||
(k, i) =>
|
||||
!k
|
||||
? []
|
||||
: [
|
||||
// style methods
|
||||
|
||||
[k, i, k === 'bright' || k === 'dim' ? Code.noBrightness : 20 + i],
|
||||
]
|
||||
),
|
||||
].reduce((a, b) => a.concat(b)))();
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
const assignStringWrappingAPI = (target, wrapBefore = target) =>
|
||||
stringWrappingMethods.reduce(
|
||||
(memo, [k, open, close]) =>
|
||||
O.defineProperty(memo, k, {
|
||||
get: () => assignStringWrappingAPI(str => wrapBefore(wrap(str, open, close))),
|
||||
}),
|
||||
|
||||
target
|
||||
);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
const TEXT = 0,
|
||||
BRACKET = 1,
|
||||
CODE = 2;
|
||||
|
||||
function rawParse(s) {
|
||||
let state = TEXT,
|
||||
buffer = '',
|
||||
text = '',
|
||||
code = '',
|
||||
codes = [];
|
||||
const spans = [];
|
||||
|
||||
for (let i = 0, n = s.length; i < n; i++) {
|
||||
const c = s[i];
|
||||
|
||||
buffer += c;
|
||||
|
||||
switch (state) {
|
||||
case TEXT: {
|
||||
if (c === '\u001b') {
|
||||
state = BRACKET;
|
||||
buffer = c;
|
||||
} else {
|
||||
text += c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BRACKET:
|
||||
if (c === '[') {
|
||||
state = CODE;
|
||||
code = '';
|
||||
codes = [];
|
||||
} else {
|
||||
state = TEXT;
|
||||
text += buffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case CODE:
|
||||
if (c >= '0' && c <= '9') {
|
||||
code += c;
|
||||
} else if (c === ';') {
|
||||
codes.push(new Code(code));
|
||||
code = '';
|
||||
} else if (c === 'm' && code.length) {
|
||||
codes.push(new Code(code));
|
||||
for (const code of codes) {
|
||||
spans.push({ text, code });
|
||||
text = '';
|
||||
}
|
||||
state = TEXT;
|
||||
} else {
|
||||
state = TEXT;
|
||||
text += buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state !== TEXT) {
|
||||
text += buffer;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
spans.push({ text, code: new Code() });
|
||||
}
|
||||
|
||||
return spans;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* Represents an ANSI-escaped string.
|
||||
*/
|
||||
export default class Colors {
|
||||
spans: any[];
|
||||
static names = stringWrappingMethods.map(([k]) => k);
|
||||
static rgb = {
|
||||
black: [0, 0, 0],
|
||||
darkGray: [100, 100, 100],
|
||||
lightGray: [200, 200, 200],
|
||||
white: [255, 255, 255],
|
||||
|
||||
red: [204, 0, 0],
|
||||
lightRed: [255, 51, 0],
|
||||
|
||||
green: [0, 204, 0],
|
||||
lightGreen: [51, 204, 51],
|
||||
|
||||
yellow: [204, 102, 0],
|
||||
lightYellow: [255, 153, 51],
|
||||
|
||||
blue: [0, 0, 255],
|
||||
lightBlue: [26, 140, 255],
|
||||
|
||||
magenta: [204, 0, 204],
|
||||
lightMagenta: [255, 0, 255],
|
||||
|
||||
cyan: [0, 153, 255],
|
||||
lightCyan: [0, 204, 255],
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} s a string containing ANSI escape codes.
|
||||
*/
|
||||
constructor(s?) {
|
||||
this.spans = s ? rawParse(s) : [];
|
||||
}
|
||||
|
||||
get str() {
|
||||
return this.spans.reduce((str, p) => str + p.text + p.code.str, '');
|
||||
}
|
||||
|
||||
get parsed() {
|
||||
let color, bgColor, brightness, styles;
|
||||
|
||||
function reset() {
|
||||
(color = new Color()),
|
||||
(bgColor = new Color(true /* background */)),
|
||||
(brightness = undefined),
|
||||
(styles = new Set());
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
return O.assign(new Colors(), {
|
||||
spans: this.spans
|
||||
.map(span => {
|
||||
const c = span.code;
|
||||
|
||||
const inverted = styles.has('inverse'),
|
||||
underline = styles.has('underline') ? 'text-decoration: underline;' : '',
|
||||
italic = styles.has('italic') ? 'font-style: italic;' : '',
|
||||
bold = brightness === Code.bright ? 'font-weight: bold;' : '';
|
||||
|
||||
const foreColor = color.defaultBrightness(brightness);
|
||||
|
||||
const styledSpan = O.assign(
|
||||
{ css: bold + italic + underline + foreColor.css(inverted) + bgColor.css(inverted) },
|
||||
clean({ bold: !!bold, color: foreColor.clean, bgColor: bgColor.clean }),
|
||||
span
|
||||
);
|
||||
|
||||
for (const k of styles) {
|
||||
styledSpan[k] = true;
|
||||
}
|
||||
|
||||
if (c.isBrightness) {
|
||||
brightness = c.value;
|
||||
} else if (span.code.value !== undefined) {
|
||||
if (span.code.value === Code.reset) {
|
||||
reset();
|
||||
} else {
|
||||
switch (span.code.type) {
|
||||
case 'color':
|
||||
case 'colorLight':
|
||||
color = new Color(false, c.subtype);
|
||||
break;
|
||||
|
||||
case 'bgColor':
|
||||
case 'bgColorLight':
|
||||
bgColor = new Color(true, c.subtype);
|
||||
break;
|
||||
|
||||
case 'style':
|
||||
styles.add(c.subtype);
|
||||
break;
|
||||
case 'unstyle':
|
||||
styles.delete(c.subtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return styledSpan;
|
||||
})
|
||||
.filter(s => s.text.length > 0),
|
||||
});
|
||||
}
|
||||
|
||||
/* Outputs with Chrome DevTools-compatible format */
|
||||
|
||||
get asChromeConsoleLogArguments() {
|
||||
const spans = this.parsed.spans;
|
||||
|
||||
return [spans.map(s => '%c' + s.text).join(''), ...spans.map(s => s.css)];
|
||||
}
|
||||
|
||||
get browserConsoleArguments() /* LEGACY, DEPRECATED */ {
|
||||
return this.asChromeConsoleLogArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc installs String prototype extensions
|
||||
* @example
|
||||
* require ('ansicolor').nice
|
||||
* console.log ('foo'.bright.red)
|
||||
*/
|
||||
static get nice() {
|
||||
Colors.names.forEach(k => {
|
||||
if (!(k in String.prototype)) {
|
||||
O.defineProperty(String.prototype, k, {
|
||||
get: function() {
|
||||
return Colors[k](this);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc parses a string containing ANSI escape codes
|
||||
* @return {Colors} parsed representation.
|
||||
*/
|
||||
static parse(s) {
|
||||
return new Colors(s).parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc strips ANSI codes from a string
|
||||
* @param {string} s a string containing ANSI escape codes.
|
||||
* @return {string} clean string.
|
||||
*/
|
||||
static strip(s) {
|
||||
return s.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g, ''); // hope V8 caches the regexp
|
||||
}
|
||||
|
||||
/**
|
||||
* @example
|
||||
* const spans = [...ansi.parse ('\u001b[7m\u001b[7mfoo\u001b[7mbar\u001b[27m')]
|
||||
*/
|
||||
[Symbol.iterator]() {
|
||||
return this.spans[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
assignStringWrappingAPI(Colors, str => str);
|
@ -32,5 +32,5 @@
|
||||
"sass": ["sass"]
|
||||
}
|
||||
},
|
||||
"include": ["public/app/**/*.ts", "public/app/**/*.tsx", "public/test/**/*.ts"]
|
||||
"include": ["public/app/**/*.ts", "public/app/**/*.tsx", "public/test/**/*.ts", "public/vendor/**/*.ts"]
|
||||
}
|
||||
|
@ -2690,11 +2690,6 @@ ansi-styles@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
|
||||
integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=
|
||||
|
||||
ansicolor@1.1.78:
|
||||
version "1.1.78"
|
||||
resolved "https://registry.yarnpkg.com/ansicolor/-/ansicolor-1.1.78.tgz#4c1f1dbef81ff3e1292e6f95b4bfb8ba51212db9"
|
||||
integrity sha512-mdNo/iRwUyb4Z0L8AthEV4BZ3TlSWr6YakKtItA48ufGBzYYtTVp+gX6bkweKTfs7wGpUepOz+qHrTPqfBus2Q==
|
||||
|
||||
ansicolors@~0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
|
||||
|
Loading…
Reference in New Issue
Block a user