Running everything through prettier
This commit is contained in:
parent
b647b8fae6
commit
94d9731cdd
@ -21,7 +21,7 @@ Logging.error("Just an simple message as error")
|
||||
Logging.errorMessage("Nearly the same as error")
|
||||
```
|
||||
|
||||
All Logging types except the simple error take as many arguments as you want. These will be joined with spaces and serialized with the node util.inspect function.
|
||||
All Logging types except the simple error take as many arguments as you want. These will be joined with spaces and serialized with the node util.inspect function.
|
||||
|
||||
# Setup
|
||||
|
||||
@ -81,7 +81,7 @@ The `ObservableInterface` comes from `@hibas123/utils`. It provides a very simpl
|
||||
|
||||
More Details on Observable [git](https://git.stamm.me/OpenServer/Utils) or [npm](https://www.npmjs.com/package/@hibas123/utils)
|
||||
|
||||
# License
|
||||
# License
|
||||
MIT
|
||||
|
||||
Copyright (c) 2018 Fabian Stamm
|
||||
@ -90,4 +90,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,166 +1,154 @@
|
||||
import { ObservableInterface } from "@hibas123/utils";
|
||||
import { Colors } from "./index";
|
||||
import {
|
||||
<<<<<<< HEAD
|
||||
Adapter,
|
||||
Message,
|
||||
FormattedLine,
|
||||
TerminalFormats,
|
||||
FormatTypes
|
||||
=======
|
||||
Adapter,
|
||||
Message,
|
||||
FormattedLine,
|
||||
TerminalFormats,
|
||||
FormatTypes,
|
||||
>>>>>>> facb7e7b403e1dfaa8790426259e6effb0618efb
|
||||
} from "./types";
|
||||
|
||||
const browser = typeof window !== "undefined";
|
||||
|
||||
export class ConsoleAdapter implements Adapter {
|
||||
init(observable: ObservableInterface<Message>) {
|
||||
observable.subscribe(this.onMessage.bind(this));
|
||||
}
|
||||
init(observable: ObservableInterface<Message>) {
|
||||
observable.subscribe(this.onMessage.bind(this));
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
flush() {}
|
||||
=======
|
||||
flush() {}
|
||||
>>>>>>> facb7e7b403e1dfaa8790426259e6effb0618efb
|
||||
|
||||
// TODO: Check if required!
|
||||
// private escape(text: string): string {
|
||||
// return text
|
||||
// .replace(/%s/g, "%%s")
|
||||
// .replace(/%c/g, "%%c")
|
||||
// }
|
||||
// TODO: Check if required!
|
||||
// private escape(text: string): string {
|
||||
// return text
|
||||
// .replace(/%s/g, "%%s")
|
||||
// .replace(/%c/g, "%%c")
|
||||
// }
|
||||
|
||||
private formatLine(line: FormattedLine): [string, string[] | undefined] {
|
||||
let text = "";
|
||||
let style_formats: string[] = [];
|
||||
private formatLine(line: FormattedLine): [string, string[] | undefined] {
|
||||
let text = "";
|
||||
let style_formats: string[] = [];
|
||||
|
||||
if (!browser) {
|
||||
for (let part of line) {
|
||||
let formats = "";
|
||||
for (let format of part.formats) {
|
||||
switch (format.type) {
|
||||
case FormatTypes.BOLD:
|
||||
formats += TerminalFormats.Bold;
|
||||
break;
|
||||
case FormatTypes.UNDERSCORE:
|
||||
formats += TerminalFormats.Underscore;
|
||||
break;
|
||||
case FormatTypes.BLINK:
|
||||
formats += TerminalFormats.Blink;
|
||||
break;
|
||||
case FormatTypes.COLOR:
|
||||
switch (format.color) {
|
||||
case Colors.RED:
|
||||
formats += TerminalFormats.FgRed;
|
||||
break;
|
||||
case Colors.GREEN:
|
||||
formats += TerminalFormats.FgGreen;
|
||||
break;
|
||||
case Colors.YELLOW:
|
||||
formats += TerminalFormats.FgYellow;
|
||||
break;
|
||||
case Colors.BLUE:
|
||||
formats += TerminalFormats.FgBlue;
|
||||
break;
|
||||
case Colors.MAGENTA:
|
||||
formats += TerminalFormats.FgMagenta;
|
||||
break;
|
||||
case Colors.CYAN:
|
||||
formats += TerminalFormats.FgCyan;
|
||||
break;
|
||||
case Colors.WHITE:
|
||||
formats += TerminalFormats.FgWhite;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
text += formats + part.text + TerminalFormats.Reset;
|
||||
if (!browser) {
|
||||
for (let part of line) {
|
||||
let formats = "";
|
||||
for (let format of part.formats) {
|
||||
switch (format.type) {
|
||||
case FormatTypes.BOLD:
|
||||
formats += TerminalFormats.Bold;
|
||||
break;
|
||||
case FormatTypes.UNDERSCORE:
|
||||
formats += TerminalFormats.Underscore;
|
||||
break;
|
||||
case FormatTypes.BLINK:
|
||||
formats += TerminalFormats.Blink;
|
||||
break;
|
||||
case FormatTypes.COLOR:
|
||||
switch (format.color) {
|
||||
case Colors.RED:
|
||||
formats += TerminalFormats.FgRed;
|
||||
break;
|
||||
case Colors.GREEN:
|
||||
formats += TerminalFormats.FgGreen;
|
||||
break;
|
||||
case Colors.YELLOW:
|
||||
formats += TerminalFormats.FgYellow;
|
||||
break;
|
||||
case Colors.BLUE:
|
||||
formats += TerminalFormats.FgBlue;
|
||||
break;
|
||||
case Colors.MAGENTA:
|
||||
formats += TerminalFormats.FgMagenta;
|
||||
break;
|
||||
case Colors.CYAN:
|
||||
formats += TerminalFormats.FgCyan;
|
||||
break;
|
||||
case Colors.WHITE:
|
||||
formats += TerminalFormats.FgWhite;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
text += formats + part.text + TerminalFormats.Reset;
|
||||
}
|
||||
} else {
|
||||
for (let part of line) {
|
||||
let styles: string[] = [];
|
||||
let resetStyles: string[] = [];
|
||||
for (let format of part.formats) {
|
||||
switch (format.type) {
|
||||
case FormatTypes.BOLD:
|
||||
styles.push("font-weight: bold;");
|
||||
resetStyles.push("font-weight: unset");
|
||||
break;
|
||||
case FormatTypes.UNDERSCORE:
|
||||
styles.push("text-decoration: underline");
|
||||
resetStyles.push("text-decoration: unset");
|
||||
break;
|
||||
case FormatTypes.BLINK:
|
||||
styles.push("text-decoration: blink");
|
||||
resetStyles.push("text-decoration: unset");
|
||||
break;
|
||||
case FormatTypes.COLOR:
|
||||
let color = "";
|
||||
switch (format.color) {
|
||||
case Colors.RED:
|
||||
color = "red";
|
||||
break;
|
||||
case Colors.GREEN:
|
||||
color = "green";
|
||||
break;
|
||||
case Colors.YELLOW:
|
||||
color = "gold";
|
||||
break;
|
||||
case Colors.BLUE:
|
||||
color = "blue";
|
||||
break;
|
||||
case Colors.MAGENTA:
|
||||
color = "magenta";
|
||||
break;
|
||||
case Colors.CYAN:
|
||||
color = "cyan";
|
||||
break;
|
||||
case Colors.WHITE:
|
||||
color = "white";
|
||||
break;
|
||||
}
|
||||
styles.push("color: " + color);
|
||||
resetStyles.push("color: unset");
|
||||
break;
|
||||
}
|
||||
}
|
||||
text += "%c" + part.text.replace(/%c/g, "%%c") + "%c";
|
||||
style_formats.push(styles.join(";"), resetStyles.join(";"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let part of line) {
|
||||
let styles: string[] = [];
|
||||
let resetStyles: string[] = [];
|
||||
for (let format of part.formats) {
|
||||
switch (format.type) {
|
||||
case FormatTypes.BOLD:
|
||||
styles.push("font-weight: bold;");
|
||||
resetStyles.push("font-weight: unset");
|
||||
break;
|
||||
case FormatTypes.UNDERSCORE:
|
||||
styles.push("text-decoration: underline");
|
||||
resetStyles.push("text-decoration: unset");
|
||||
break;
|
||||
case FormatTypes.BLINK:
|
||||
styles.push("text-decoration: blink");
|
||||
resetStyles.push("text-decoration: unset");
|
||||
break;
|
||||
case FormatTypes.COLOR:
|
||||
let color = "";
|
||||
switch (format.color) {
|
||||
case Colors.RED:
|
||||
color = "red";
|
||||
break;
|
||||
case Colors.GREEN:
|
||||
color = "green";
|
||||
break;
|
||||
case Colors.YELLOW:
|
||||
color = "gold";
|
||||
break;
|
||||
case Colors.BLUE:
|
||||
color = "blue";
|
||||
break;
|
||||
case Colors.MAGENTA:
|
||||
color = "magenta";
|
||||
break;
|
||||
case Colors.CYAN:
|
||||
color = "cyan";
|
||||
break;
|
||||
case Colors.WHITE:
|
||||
color = "white";
|
||||
break;
|
||||
}
|
||||
styles.push("color: " + color);
|
||||
resetStyles.push("color: unset");
|
||||
break;
|
||||
}
|
||||
}
|
||||
text += "%c" + part.text.replace(/%c/g, "%%c") + "%c";
|
||||
style_formats.push(styles.join(";"), resetStyles.join(";"));
|
||||
|
||||
return [text, style_formats];
|
||||
}
|
||||
|
||||
onMessage(message: Message) {
|
||||
let lines = message.text.formatted;
|
||||
|
||||
let prefix = "";
|
||||
if (message.name) prefix = `[${message.name}]=>`;
|
||||
|
||||
if (browser) {
|
||||
let formats: string[] = [];
|
||||
let text = lines
|
||||
.map((line) => {
|
||||
let [t, fmts] = this.formatLine(line);
|
||||
formats.push(...fmts);
|
||||
return prefix + t;
|
||||
})
|
||||
.join("\n");
|
||||
// console.log(formats);
|
||||
console.log(text, ...formats);
|
||||
} else {
|
||||
lines.forEach((line) => {
|
||||
let [text] = this.formatLine(line);
|
||||
console.log(prefix + text);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return [text, style_formats];
|
||||
}
|
||||
|
||||
onMessage(message: Message) {
|
||||
let lines = message.text.formatted;
|
||||
|
||||
let prefix = "";
|
||||
if (message.name) prefix = `[${message.name}]=>`;
|
||||
|
||||
if (browser) {
|
||||
let formats: string[] = [];
|
||||
let text = lines
|
||||
.map(line => {
|
||||
let [t, fmts] = this.formatLine(line);
|
||||
formats.push(...fmts);
|
||||
return prefix + t;
|
||||
})
|
||||
.join("\n");
|
||||
// console.log(formats);
|
||||
console.log(text, ...formats);
|
||||
} else {
|
||||
lines.forEach(line => {
|
||||
let [text] = this.formatLine(line);
|
||||
console.log(prefix + text);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
src/index.ts
29
src/index.ts
@ -1,18 +1,23 @@
|
||||
import { LoggingBase } from "./base";
|
||||
export { ConsoleAdapter } from "./consolewriter";
|
||||
export { LoggingBase, LoggingBaseOptions, removeColors, withColor } from "./base";
|
||||
export {
|
||||
Adapter,
|
||||
LoggingTypes,
|
||||
Message,
|
||||
FormatConfig,
|
||||
FormattedLine,
|
||||
DefaultFormatConfig as DefaultColorMap,
|
||||
FormattedText,
|
||||
Colors,
|
||||
Format,
|
||||
FormatTypes,
|
||||
TerminalFormats
|
||||
LoggingBase,
|
||||
LoggingBaseOptions,
|
||||
removeColors,
|
||||
withColor,
|
||||
} from "./base";
|
||||
export {
|
||||
Adapter,
|
||||
LoggingTypes,
|
||||
Message,
|
||||
FormatConfig,
|
||||
FormattedLine,
|
||||
DefaultFormatConfig as DefaultColorMap,
|
||||
FormattedText,
|
||||
Colors,
|
||||
Format,
|
||||
FormatTypes,
|
||||
TerminalFormats,
|
||||
} from "./types";
|
||||
|
||||
export { ObservableInterface } from "@hibas123/utils";
|
||||
|
636
src/inspect.ts
636
src/inspect.ts
@ -1,12 +1,11 @@
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
interface InspectOptions {
|
||||
depth: number;
|
||||
colors: boolean;
|
||||
showHidden: boolean;
|
||||
depth: number;
|
||||
colors: boolean;
|
||||
showHidden: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,397 +18,440 @@ interface InspectOptions {
|
||||
*/
|
||||
/* legacy: obj, showHidden, depth, colors*/
|
||||
export default function inspect(obj: any, opts: Partial<InspectOptions>) {
|
||||
// default options
|
||||
let ctx = {
|
||||
seen: [],
|
||||
stylize: stylizeNoColor,
|
||||
depth: undefined,
|
||||
colors: undefined,
|
||||
showHidden: undefined,
|
||||
customInspect: undefined
|
||||
};
|
||||
// legacy...
|
||||
if (arguments.length >= 3) ctx.depth = arguments[2];
|
||||
if (arguments.length >= 4) ctx.colors = arguments[3];
|
||||
if (isBoolean(opts)) {
|
||||
// legacy...
|
||||
ctx.showHidden = opts;
|
||||
} else if (opts) {
|
||||
// got an "options" object
|
||||
_extend(ctx, opts);
|
||||
}
|
||||
// set default options
|
||||
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
||||
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
||||
if (isUndefined(ctx.colors)) ctx.colors = false;
|
||||
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
||||
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
||||
return formatValue(ctx, obj, ctx.depth);
|
||||
// default options
|
||||
let ctx = {
|
||||
seen: [],
|
||||
stylize: stylizeNoColor,
|
||||
depth: undefined,
|
||||
colors: undefined,
|
||||
showHidden: undefined,
|
||||
customInspect: undefined,
|
||||
};
|
||||
// legacy...
|
||||
if (arguments.length >= 3) ctx.depth = arguments[2];
|
||||
if (arguments.length >= 4) ctx.colors = arguments[3];
|
||||
if (isBoolean(opts)) {
|
||||
// legacy...
|
||||
ctx.showHidden = opts;
|
||||
} else if (opts) {
|
||||
// got an "options" object
|
||||
_extend(ctx, opts);
|
||||
}
|
||||
// set default options
|
||||
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
||||
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
||||
if (isUndefined(ctx.colors)) ctx.colors = false;
|
||||
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
||||
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
||||
return formatValue(ctx, obj, ctx.depth);
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||||
inspect.colors = {
|
||||
'bold': [1, 22],
|
||||
'italic': [3, 23],
|
||||
'underline': [4, 24],
|
||||
'inverse': [7, 27],
|
||||
'white': [37, 39],
|
||||
'grey': [90, 39],
|
||||
'black': [30, 39],
|
||||
'blue': [34, 39],
|
||||
'cyan': [36, 39],
|
||||
'green': [32, 39],
|
||||
'magenta': [35, 39],
|
||||
'red': [31, 39],
|
||||
'yellow': [33, 39]
|
||||
bold: [1, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
inverse: [7, 27],
|
||||
white: [37, 39],
|
||||
grey: [90, 39],
|
||||
black: [30, 39],
|
||||
blue: [34, 39],
|
||||
cyan: [36, 39],
|
||||
green: [32, 39],
|
||||
magenta: [35, 39],
|
||||
red: [31, 39],
|
||||
yellow: [33, 39],
|
||||
};
|
||||
|
||||
// Don't use 'blue' not visible on cmd.exe
|
||||
inspect.styles = {
|
||||
'special': 'cyan',
|
||||
'number': 'yellow',
|
||||
'boolean': 'yellow',
|
||||
'undefined': 'grey',
|
||||
'null': 'bold',
|
||||
'string': 'green',
|
||||
'date': 'magenta',
|
||||
// "name": intentionally not styling
|
||||
'regexp': 'red'
|
||||
special: "cyan",
|
||||
number: "yellow",
|
||||
boolean: "yellow",
|
||||
undefined: "grey",
|
||||
null: "bold",
|
||||
string: "green",
|
||||
date: "magenta",
|
||||
// "name": intentionally not styling
|
||||
regexp: "red",
|
||||
};
|
||||
|
||||
function stylizeNoColor(str, styleType) {
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
|
||||
function isBoolean(arg) {
|
||||
return typeof arg === 'boolean';
|
||||
return typeof arg === "boolean";
|
||||
}
|
||||
|
||||
function isUndefined(arg) {
|
||||
return arg === void 0;
|
||||
return arg === void 0;
|
||||
}
|
||||
|
||||
function stylizeWithColor(str, styleType) {
|
||||
var style = inspect.styles[styleType];
|
||||
var style = inspect.styles[styleType];
|
||||
|
||||
if (style) {
|
||||
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
|
||||
'\u001b[' + inspect.colors[style][1] + 'm';
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
if (style) {
|
||||
return (
|
||||
"\u001b[" +
|
||||
inspect.colors[style][0] +
|
||||
"m" +
|
||||
str +
|
||||
"\u001b[" +
|
||||
inspect.colors[style][1] +
|
||||
"m"
|
||||
);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
function isFunction(arg) {
|
||||
return typeof arg === 'function';
|
||||
return typeof arg === "function";
|
||||
}
|
||||
|
||||
function isString(arg) {
|
||||
return typeof arg === 'string';
|
||||
return typeof arg === "string";
|
||||
}
|
||||
|
||||
function isNumber(arg) {
|
||||
return typeof arg === 'number';
|
||||
return typeof arg === "number";
|
||||
}
|
||||
|
||||
function isNull(arg) {
|
||||
return arg === null;
|
||||
return arg === null;
|
||||
}
|
||||
|
||||
function hasOwn(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
function isRegExp(re) {
|
||||
return isObject(re) && objectToString(re) === '[object RegExp]';
|
||||
return isObject(re) && objectToString(re) === "[object RegExp]";
|
||||
}
|
||||
|
||||
function isObject(arg) {
|
||||
return typeof arg === 'object' && arg !== null;
|
||||
return typeof arg === "object" && arg !== null;
|
||||
}
|
||||
|
||||
function isError(e) {
|
||||
return isObject(e) &&
|
||||
(objectToString(e) === '[object Error]' || e instanceof Error);
|
||||
return (
|
||||
isObject(e) &&
|
||||
(objectToString(e) === "[object Error]" || e instanceof Error)
|
||||
);
|
||||
}
|
||||
|
||||
function isDate(d) {
|
||||
return isObject(d) && objectToString(d) === '[object Date]';
|
||||
return isObject(d) && objectToString(d) === "[object Date]";
|
||||
}
|
||||
|
||||
function objectToString(o) {
|
||||
return Object.prototype.toString.call(o);
|
||||
return Object.prototype.toString.call(o);
|
||||
}
|
||||
|
||||
function arrayToHash(array) {
|
||||
var hash = {};
|
||||
var hash = {};
|
||||
|
||||
array.forEach(function (val, idx) {
|
||||
hash[val] = true;
|
||||
});
|
||||
array.forEach(function (val, idx) {
|
||||
hash[val] = true;
|
||||
});
|
||||
|
||||
return hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
||||
var output = [];
|
||||
for (var i = 0, l = value.length; i < l; ++i) {
|
||||
if (hasOwn(value, String(i))) {
|
||||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||||
String(i), true));
|
||||
} else {
|
||||
output.push('');
|
||||
}
|
||||
}
|
||||
keys.forEach(function (key) {
|
||||
if (!key.match(/^\d+$/)) {
|
||||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||||
key, true));
|
||||
}
|
||||
});
|
||||
return output;
|
||||
var output = [];
|
||||
for (var i = 0, l = value.length; i < l; ++i) {
|
||||
if (hasOwn(value, String(i))) {
|
||||
output.push(
|
||||
formatProperty(
|
||||
ctx,
|
||||
value,
|
||||
recurseTimes,
|
||||
visibleKeys,
|
||||
String(i),
|
||||
true
|
||||
)
|
||||
);
|
||||
} else {
|
||||
output.push("");
|
||||
}
|
||||
}
|
||||
keys.forEach(function (key) {
|
||||
if (!key.match(/^\d+$/)) {
|
||||
output.push(
|
||||
formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)
|
||||
);
|
||||
}
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
function formatError(value) {
|
||||
return '[' + Error.prototype.toString.call(value) + ']';
|
||||
return "[" + Error.prototype.toString.call(value) + "]";
|
||||
}
|
||||
|
||||
function formatValue(ctx, value, recurseTimes) {
|
||||
// Provide a hook for user-specified inspect functions.
|
||||
// Check that value is an object with an inspect function on it
|
||||
if (ctx.customInspect &&
|
||||
value &&
|
||||
isFunction(value.inspect) &&
|
||||
// Filter out the util module, it's inspect function is special
|
||||
value.inspect !== inspect &&
|
||||
// Also filter out any prototype objects using the circular check.
|
||||
!(value.constructor && value.constructor.prototype === value)) {
|
||||
var ret = value.inspect(recurseTimes, ctx);
|
||||
if (!isString(ret)) {
|
||||
ret = formatValue(ctx, ret, recurseTimes);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// Provide a hook for user-specified inspect functions.
|
||||
// Check that value is an object with an inspect function on it
|
||||
if (
|
||||
ctx.customInspect &&
|
||||
value &&
|
||||
isFunction(value.inspect) &&
|
||||
// Filter out the util module, it's inspect function is special
|
||||
value.inspect !== inspect &&
|
||||
// Also filter out any prototype objects using the circular check.
|
||||
!(value.constructor && value.constructor.prototype === value)
|
||||
) {
|
||||
var ret = value.inspect(recurseTimes, ctx);
|
||||
if (!isString(ret)) {
|
||||
ret = formatValue(ctx, ret, recurseTimes);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Primitive types cannot have properties
|
||||
var primitive = formatPrimitive(ctx, value);
|
||||
if (primitive) {
|
||||
return primitive;
|
||||
}
|
||||
// Primitive types cannot have properties
|
||||
var primitive = formatPrimitive(ctx, value);
|
||||
if (primitive) {
|
||||
return primitive;
|
||||
}
|
||||
|
||||
// Look up the keys of the object.
|
||||
var keys = Object.keys(value);
|
||||
var visibleKeys = arrayToHash(keys);
|
||||
// Look up the keys of the object.
|
||||
var keys = Object.keys(value);
|
||||
var visibleKeys = arrayToHash(keys);
|
||||
|
||||
try {
|
||||
if (ctx.showHidden && Object.getOwnPropertyNames) {
|
||||
keys = Object.getOwnPropertyNames(value);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
if (ctx.showHidden && Object.getOwnPropertyNames) {
|
||||
keys = Object.getOwnPropertyNames(value);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// IE doesn't make error fields non-enumerable
|
||||
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
||||
if (isError(value)
|
||||
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
|
||||
return formatError(value);
|
||||
}
|
||||
// IE doesn't make error fields non-enumerable
|
||||
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
||||
if (
|
||||
isError(value) &&
|
||||
(keys.indexOf("message") >= 0 || keys.indexOf("description") >= 0)
|
||||
) {
|
||||
return formatError(value);
|
||||
}
|
||||
|
||||
// Some type of object without properties can be shortcutted.
|
||||
if (keys.length === 0) {
|
||||
if (isFunction(value)) {
|
||||
var name = value.name ? ': ' + value.name : '';
|
||||
return ctx.stylize('[Function' + name + ']', 'special');
|
||||
}
|
||||
if (isRegExp(value)) {
|
||||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||||
}
|
||||
if (isDate(value)) {
|
||||
return ctx.stylize(Date.prototype.toString.call(value), 'date');
|
||||
}
|
||||
if (isError(value)) {
|
||||
return formatError(value);
|
||||
}
|
||||
}
|
||||
// Some type of object without properties can be shortcutted.
|
||||
if (keys.length === 0) {
|
||||
if (isFunction(value)) {
|
||||
var name = value.name ? ": " + value.name : "";
|
||||
return ctx.stylize("[Function" + name + "]", "special");
|
||||
}
|
||||
if (isRegExp(value)) {
|
||||
return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
||||
}
|
||||
if (isDate(value)) {
|
||||
return ctx.stylize(Date.prototype.toString.call(value), "date");
|
||||
}
|
||||
if (isError(value)) {
|
||||
return formatError(value);
|
||||
}
|
||||
}
|
||||
|
||||
var base = '', array = false, braces = ['{', '}'];
|
||||
var base = "",
|
||||
array = false,
|
||||
braces = ["{", "}"];
|
||||
|
||||
// Make Array say that they are Array
|
||||
if (Array.isArray(value)) {
|
||||
array = true;
|
||||
braces = ['[', ']'];
|
||||
}
|
||||
// Make Array say that they are Array
|
||||
if (Array.isArray(value)) {
|
||||
array = true;
|
||||
braces = ["[", "]"];
|
||||
}
|
||||
|
||||
// Make functions say that they are functions
|
||||
if (isFunction(value)) {
|
||||
var n = value.name ? ': ' + value.name : '';
|
||||
base = ' [Function' + n + ']';
|
||||
}
|
||||
// Make functions say that they are functions
|
||||
if (isFunction(value)) {
|
||||
var n = value.name ? ": " + value.name : "";
|
||||
base = " [Function" + n + "]";
|
||||
}
|
||||
|
||||
// Make RegExps say that they are RegExps
|
||||
if (isRegExp(value)) {
|
||||
base = ' ' + RegExp.prototype.toString.call(value);
|
||||
}
|
||||
// Make RegExps say that they are RegExps
|
||||
if (isRegExp(value)) {
|
||||
base = " " + RegExp.prototype.toString.call(value);
|
||||
}
|
||||
|
||||
// Make dates with properties first say the date
|
||||
if (isDate(value)) {
|
||||
base = ' ' + Date.prototype.toUTCString.call(value);
|
||||
}
|
||||
// Make dates with properties first say the date
|
||||
if (isDate(value)) {
|
||||
base = " " + Date.prototype.toUTCString.call(value);
|
||||
}
|
||||
|
||||
// Make error with message first say the error
|
||||
if (isError(value)) {
|
||||
base = ' ' + formatError(value);
|
||||
}
|
||||
// Make error with message first say the error
|
||||
if (isError(value)) {
|
||||
base = " " + formatError(value);
|
||||
}
|
||||
|
||||
if (keys.length === 0 && (!array || value.length == 0)) {
|
||||
return braces[0] + base + braces[1];
|
||||
}
|
||||
if (keys.length === 0 && (!array || value.length == 0)) {
|
||||
return braces[0] + base + braces[1];
|
||||
}
|
||||
|
||||
if (recurseTimes < 0) {
|
||||
if (isRegExp(value)) {
|
||||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||||
} else {
|
||||
return ctx.stylize('[Object]', 'special');
|
||||
}
|
||||
}
|
||||
if (recurseTimes < 0) {
|
||||
if (isRegExp(value)) {
|
||||
return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
||||
} else {
|
||||
return ctx.stylize("[Object]", "special");
|
||||
}
|
||||
}
|
||||
|
||||
ctx.seen.push(value);
|
||||
ctx.seen.push(value);
|
||||
|
||||
var output;
|
||||
if (array) {
|
||||
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
||||
} else {
|
||||
output = keys.map(function (key) {
|
||||
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
||||
});
|
||||
}
|
||||
var output;
|
||||
if (array) {
|
||||
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
||||
} else {
|
||||
output = keys.map(function (key) {
|
||||
return formatProperty(
|
||||
ctx,
|
||||
value,
|
||||
recurseTimes,
|
||||
visibleKeys,
|
||||
key,
|
||||
array
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
ctx.seen.pop();
|
||||
ctx.seen.pop();
|
||||
|
||||
return reduceToSingleString(output, base, braces);
|
||||
return reduceToSingleString(output, base, braces);
|
||||
}
|
||||
|
||||
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
||||
var name, str, desc;
|
||||
desc = { value: void 0 };
|
||||
try {
|
||||
// ie6 › navigator.toString
|
||||
// throws Error: Object doesn't support this property or method
|
||||
desc.value = value[key];
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
// ie10 › Object.getOwnPropertyDescriptor(window.location, 'hash')
|
||||
// throws TypeError: Object doesn't support this action
|
||||
if (Object.getOwnPropertyDescriptor) {
|
||||
desc = Object.getOwnPropertyDescriptor(value, key) || desc;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
if (desc.get) {
|
||||
if (desc.set) {
|
||||
str = ctx.stylize('[Getter/Setter]', 'special');
|
||||
} else {
|
||||
str = ctx.stylize('[Getter]', 'special');
|
||||
}
|
||||
} else {
|
||||
if (desc.set) {
|
||||
str = ctx.stylize('[Setter]', 'special');
|
||||
}
|
||||
}
|
||||
if (!hasOwn(visibleKeys, key)) {
|
||||
name = '[' + key + ']';
|
||||
}
|
||||
if (!str) {
|
||||
if (ctx.seen.indexOf(desc.value) < 0) {
|
||||
if (isNull(recurseTimes)) {
|
||||
str = formatValue(ctx, desc.value, null);
|
||||
var name, str, desc;
|
||||
desc = { value: void 0 };
|
||||
try {
|
||||
// ie6 › navigator.toString
|
||||
// throws Error: Object doesn't support this property or method
|
||||
desc.value = value[key];
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
// ie10 › Object.getOwnPropertyDescriptor(window.location, 'hash')
|
||||
// throws TypeError: Object doesn't support this action
|
||||
if (Object.getOwnPropertyDescriptor) {
|
||||
desc = Object.getOwnPropertyDescriptor(value, key) || desc;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
if (desc.get) {
|
||||
if (desc.set) {
|
||||
str = ctx.stylize("[Getter/Setter]", "special");
|
||||
} else {
|
||||
str = ctx.stylize("[Getter]", "special");
|
||||
}
|
||||
} else {
|
||||
if (desc.set) {
|
||||
str = ctx.stylize("[Setter]", "special");
|
||||
}
|
||||
}
|
||||
if (!hasOwn(visibleKeys, key)) {
|
||||
name = "[" + key + "]";
|
||||
}
|
||||
if (!str) {
|
||||
if (ctx.seen.indexOf(desc.value) < 0) {
|
||||
if (isNull(recurseTimes)) {
|
||||
str = formatValue(ctx, desc.value, null);
|
||||
} else {
|
||||
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
||||
}
|
||||
if (str.indexOf("\n") > -1) {
|
||||
if (array) {
|
||||
str = str
|
||||
.split("\n")
|
||||
.map(function (line) {
|
||||
return " " + line;
|
||||
})
|
||||
.join("\n")
|
||||
.substr(2);
|
||||
} else {
|
||||
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
||||
str =
|
||||
"\n" +
|
||||
str
|
||||
.split("\n")
|
||||
.map(function (line) {
|
||||
return " " + line;
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
if (str.indexOf('\n') > -1) {
|
||||
if (array) {
|
||||
str = str.split('\n').map(function (line) {
|
||||
return ' ' + line;
|
||||
}).join('\n').substr(2);
|
||||
} else {
|
||||
str = '\n' + str.split('\n').map(function (line) {
|
||||
return ' ' + line;
|
||||
}).join('\n');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
str = ctx.stylize('[Circular]', 'special');
|
||||
}
|
||||
}
|
||||
if (isUndefined(name)) {
|
||||
if (array && key.match(/^\d+$/)) {
|
||||
return str;
|
||||
}
|
||||
name = JSON.stringify('' + key);
|
||||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||||
name = name.substr(1, name.length - 2);
|
||||
name = ctx.stylize(name, 'name');
|
||||
} else {
|
||||
name = name.replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(^"|"$)/g, "'");
|
||||
name = ctx.stylize(name, 'string');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
str = ctx.stylize("[Circular]", "special");
|
||||
}
|
||||
}
|
||||
if (isUndefined(name)) {
|
||||
if (array && key.match(/^\d+$/)) {
|
||||
return str;
|
||||
}
|
||||
name = JSON.stringify("" + key);
|
||||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||||
name = name.substr(1, name.length - 2);
|
||||
name = ctx.stylize(name, "name");
|
||||
} else {
|
||||
name = name
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(^"|"$)/g, "'");
|
||||
name = ctx.stylize(name, "string");
|
||||
}
|
||||
}
|
||||
|
||||
return name + ': ' + str;
|
||||
return name + ": " + str;
|
||||
}
|
||||
|
||||
function formatPrimitive(ctx, value) {
|
||||
if (isUndefined(value))
|
||||
return ctx.stylize('undefined', 'undefined');
|
||||
if (isString(value)) {
|
||||
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
||||
if (isUndefined(value)) return ctx.stylize("undefined", "undefined");
|
||||
if (isString(value)) {
|
||||
var simple =
|
||||
"'" +
|
||||
JSON.stringify(value)
|
||||
.replace(/^"|"$/g, "")
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"') + '\'';
|
||||
return ctx.stylize(simple, 'string');
|
||||
}
|
||||
if (isNumber(value))
|
||||
return ctx.stylize('' + value, 'number');
|
||||
if (isBoolean(value))
|
||||
return ctx.stylize('' + value, 'boolean');
|
||||
// For some reason typeof null is "object", so special case here.
|
||||
if (isNull(value))
|
||||
return ctx.stylize('null', 'null');
|
||||
.replace(/\\"/g, '"') +
|
||||
"'";
|
||||
return ctx.stylize(simple, "string");
|
||||
}
|
||||
if (isNumber(value)) return ctx.stylize("" + value, "number");
|
||||
if (isBoolean(value)) return ctx.stylize("" + value, "boolean");
|
||||
// For some reason typeof null is "object", so special case here.
|
||||
if (isNull(value)) return ctx.stylize("null", "null");
|
||||
}
|
||||
|
||||
function reduceToSingleString(output, base, braces) {
|
||||
var numLinesEst = 0;
|
||||
var length = output.reduce(function (prev, cur) {
|
||||
numLinesEst++;
|
||||
if (cur.indexOf('\n') >= 0) numLinesEst++;
|
||||
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
|
||||
}, 0);
|
||||
var numLinesEst = 0;
|
||||
var length = output.reduce(function (prev, cur) {
|
||||
numLinesEst++;
|
||||
if (cur.indexOf("\n") >= 0) numLinesEst++;
|
||||
return prev + cur.replace(/\u001b\[\d\d?m/g, "").length + 1;
|
||||
}, 0);
|
||||
|
||||
if (length > 60) {
|
||||
return braces[0] +
|
||||
(base === '' ? '' : base + '\n ') +
|
||||
' ' +
|
||||
output.join(',\n ') +
|
||||
' ' +
|
||||
braces[1];
|
||||
}
|
||||
if (length > 60) {
|
||||
return (
|
||||
braces[0] +
|
||||
(base === "" ? "" : base + "\n ") +
|
||||
" " +
|
||||
output.join(",\n ") +
|
||||
" " +
|
||||
braces[1]
|
||||
);
|
||||
}
|
||||
|
||||
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
||||
return braces[0] + base + " " + output.join(", ") + " " + braces[1];
|
||||
}
|
||||
|
||||
function _extend<T extends Y, Y>(origin: T, add: Y) {
|
||||
// Don't do anything if add isn't an object
|
||||
if (!add || !isObject(add)) return origin;
|
||||
// Don't do anything if add isn't an object
|
||||
if (!add || !isObject(add)) return origin;
|
||||
|
||||
var keys = Object.keys(add);
|
||||
var i = keys.length;
|
||||
while (i--) {
|
||||
origin[keys[i]] = add[keys[i]];
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
var keys = Object.keys(add);
|
||||
var i = keys.length;
|
||||
while (i--) {
|
||||
origin[keys[i]] = add[keys[i]];
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
152
src/types.ts
152
src/types.ts
@ -1,119 +1,119 @@
|
||||
import { ObservableInterface } from "@hibas123/utils";
|
||||
|
||||
export enum LoggingTypes {
|
||||
Debug,
|
||||
Log,
|
||||
Warning,
|
||||
Error
|
||||
Debug,
|
||||
Log,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
|
||||
export const TerminalFormats = {
|
||||
Reset: "\x1b[0m",
|
||||
Bold: "\x1b[1m",
|
||||
Underscore: "\x1b[4m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
Hidden: "\x1b[8m",
|
||||
Reset: "\x1b[0m",
|
||||
Bold: "\x1b[1m",
|
||||
Underscore: "\x1b[4m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
Hidden: "\x1b[8m",
|
||||
|
||||
FgBlack: "\x1b[30m",
|
||||
FgRed: "\x1b[31m",
|
||||
FgGreen: "\x1b[32m",
|
||||
FgYellow: "\x1b[33m",
|
||||
FgBlue: "\x1b[34m",
|
||||
FgMagenta: "\x1b[35m",
|
||||
FgCyan: "\x1b[36m",
|
||||
FgWhite: "\x1b[37m",
|
||||
|
||||
BgBlack: "\x1b[40m",
|
||||
BgRed: "\x1b[41m",
|
||||
BgGreen: "\x1b[42m",
|
||||
BgYellow: "\x1b[43m",
|
||||
BgBlue: "\x1b[44m",
|
||||
BgMagenta: "\x1b[45m",
|
||||
BgCyan: "\x1b[46m",
|
||||
BgWhite: "\x1b[47m"
|
||||
}
|
||||
FgBlack: "\x1b[30m",
|
||||
FgRed: "\x1b[31m",
|
||||
FgGreen: "\x1b[32m",
|
||||
FgYellow: "\x1b[33m",
|
||||
FgBlue: "\x1b[34m",
|
||||
FgMagenta: "\x1b[35m",
|
||||
FgCyan: "\x1b[36m",
|
||||
FgWhite: "\x1b[37m",
|
||||
|
||||
BgBlack: "\x1b[40m",
|
||||
BgRed: "\x1b[41m",
|
||||
BgGreen: "\x1b[42m",
|
||||
BgYellow: "\x1b[43m",
|
||||
BgBlue: "\x1b[44m",
|
||||
BgMagenta: "\x1b[45m",
|
||||
BgCyan: "\x1b[46m",
|
||||
BgWhite: "\x1b[47m",
|
||||
};
|
||||
|
||||
export enum FormatTypes {
|
||||
COLOR,
|
||||
BOLD,
|
||||
UNDERSCORE,
|
||||
BLINK
|
||||
COLOR,
|
||||
BOLD,
|
||||
UNDERSCORE,
|
||||
BLINK,
|
||||
}
|
||||
|
||||
export enum Colors {
|
||||
NONE,
|
||||
RED,
|
||||
GREEN,
|
||||
YELLOW,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
CYAN,
|
||||
WHITE
|
||||
NONE,
|
||||
RED,
|
||||
GREEN,
|
||||
YELLOW,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
CYAN,
|
||||
WHITE,
|
||||
}
|
||||
|
||||
export interface FormatConfig {
|
||||
error: Format[];
|
||||
warning: Format[];
|
||||
log: Format[];
|
||||
debug: Format[];
|
||||
error: Format[];
|
||||
warning: Format[];
|
||||
log: Format[];
|
||||
debug: Format[];
|
||||
|
||||
date: Format[];
|
||||
file: Format[];
|
||||
date: Format[];
|
||||
file: Format[];
|
||||
}
|
||||
|
||||
function colorFormat(color: Colors) {
|
||||
return {
|
||||
type: FormatTypes.COLOR,
|
||||
color
|
||||
}
|
||||
return {
|
||||
type: FormatTypes.COLOR,
|
||||
color,
|
||||
};
|
||||
}
|
||||
|
||||
const boldFormat = {
|
||||
type: FormatTypes.BOLD
|
||||
type: FormatTypes.BOLD,
|
||||
};
|
||||
|
||||
export class DefaultFormatConfig implements FormatConfig {
|
||||
error = [colorFormat(Colors.RED), boldFormat];
|
||||
warning = [colorFormat(Colors.YELLOW), boldFormat];
|
||||
log = [colorFormat(Colors.NONE), boldFormat];
|
||||
debug = [colorFormat(Colors.CYAN), boldFormat];
|
||||
error = [colorFormat(Colors.RED), boldFormat];
|
||||
warning = [colorFormat(Colors.YELLOW), boldFormat];
|
||||
log = [colorFormat(Colors.NONE), boldFormat];
|
||||
debug = [colorFormat(Colors.CYAN), boldFormat];
|
||||
|
||||
date = [colorFormat(Colors.NONE)];
|
||||
file = [colorFormat(Colors.NONE)];
|
||||
date = [colorFormat(Colors.NONE)];
|
||||
file = [colorFormat(Colors.NONE)];
|
||||
}
|
||||
|
||||
export interface Format {
|
||||
type: FormatTypes;
|
||||
color?: Colors;
|
||||
type: FormatTypes;
|
||||
color?: Colors;
|
||||
}
|
||||
|
||||
export interface FormattedText {
|
||||
text: string;
|
||||
formats: Format[];
|
||||
text: string;
|
||||
formats: Format[];
|
||||
}
|
||||
|
||||
export type FormattedLine = FormattedText[];
|
||||
|
||||
export interface Message {
|
||||
type: LoggingTypes;
|
||||
name?: string;
|
||||
text: {
|
||||
raw: string[],
|
||||
formatted: FormattedLine[]
|
||||
};
|
||||
date: Date;
|
||||
file: string;
|
||||
type: LoggingTypes;
|
||||
name?: string;
|
||||
text: {
|
||||
raw: string[];
|
||||
formatted: FormattedLine[];
|
||||
};
|
||||
date: Date;
|
||||
file: string;
|
||||
}
|
||||
|
||||
export interface Adapter {
|
||||
init(observable: ObservableInterface<Message>, name?: string): void | Promise<void>;
|
||||
init(
|
||||
observable: ObservableInterface<Message>,
|
||||
name?: string
|
||||
): void | Promise<void>;
|
||||
|
||||
flush(sync: true): void;
|
||||
flush(sync: false): void | Promise<void>;
|
||||
flush(sync: true): void;
|
||||
flush(sync: false): void | Promise<void>;
|
||||
|
||||
|
||||
close?(): void;
|
||||
}
|
||||
close?(): void;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user