1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-27 16:10:57 -05:00
denoland-deno/ext/node/polyfills/internal/util/inspect.mjs
Ryan Dahl a3529d0232
refactor(ext/node): Use Deno.inspect (#17960)
No need for two almost identical implementations of the same thing

---------

Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
Co-authored-by: Aapo Alasuutari <aapo.alasuutari@gmail.com>
2023-03-23 10:01:07 -04:00

200 lines
6.3 KiB
JavaScript

// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// 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.
import { inspect as denoInspect, getStringWidth as denoGetStringWidth, inspectArgs } from "ext:deno_console/02_console.js";
import { validateObject, validateString } from "ext:deno_node/internal/validators.mjs";
import { codes } from "ext:deno_node/internal/error_codes.ts";
const inspectDefaultOptions = {
showHidden: false,
depth: 3,
colors: false,
customInspect: true,
showProxy: false,
maxArrayLength: 100,
maxStringLength: 10000,
breakLength: 80,
compact: true,
sorted: false,
getters: false,
};
/**
* Echos the value of any input. Tries to print the value out
* in the best way possible given the different types.
*/
/* Legacy: value, showHidden, depth, colors */
export function inspect(value, opts = {}) {
if (typeof opts === "boolean") {
opts = {
showHidden: opts,
depth: arguments[2],
colors: arguments[3],
}
}
return denoInspect(value, Object.assign({}, opts, { quotes: ["'", '"', "`"], depth: 3 }));
}
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
inspect.custom = customInspectSymbol;
Object.defineProperty(inspect, "defaultOptions", {
get() {
return inspectDefaultOptions;
},
set(options) {
validateObject(options, "options");
return Object.assign(inspectDefaultOptions, options);
},
});
// Set Graphics Rendition https://en.wikipedia.org/wiki/ANSI_escape_code#graphics
// Each color consists of an array with the color code as first entry and the
// reset code as second entry.
const defaultFG = 39;
const defaultBG = 49;
inspect.colors = Object.assign(Object.create(null), {
reset: [0, 0],
bold: [1, 22],
dim: [2, 22], // Alias: faint
italic: [3, 23],
underline: [4, 24],
blink: [5, 25],
// Swap foreground and background colors
inverse: [7, 27], // Alias: swapcolors, swapColors
hidden: [8, 28], // Alias: conceal
strikethrough: [9, 29], // Alias: strikeThrough, crossedout, crossedOut
doubleunderline: [21, 24], // Alias: doubleUnderline
black: [30, defaultFG],
red: [31, defaultFG],
green: [32, defaultFG],
yellow: [33, defaultFG],
blue: [34, defaultFG],
magenta: [35, defaultFG],
cyan: [36, defaultFG],
white: [37, defaultFG],
bgBlack: [40, defaultBG],
bgRed: [41, defaultBG],
bgGreen: [42, defaultBG],
bgYellow: [43, defaultBG],
bgBlue: [44, defaultBG],
bgMagenta: [45, defaultBG],
bgCyan: [46, defaultBG],
bgWhite: [47, defaultBG],
framed: [51, 54],
overlined: [53, 55],
gray: [90, defaultFG], // Alias: grey, blackBright
redBright: [91, defaultFG],
greenBright: [92, defaultFG],
yellowBright: [93, defaultFG],
blueBright: [94, defaultFG],
magentaBright: [95, defaultFG],
cyanBright: [96, defaultFG],
whiteBright: [97, defaultFG],
bgGray: [100, defaultBG], // Alias: bgGrey, bgBlackBright
bgRedBright: [101, defaultBG],
bgGreenBright: [102, defaultBG],
bgYellowBright: [103, defaultBG],
bgBlueBright: [104, defaultBG],
bgMagentaBright: [105, defaultBG],
bgCyanBright: [106, defaultBG],
bgWhiteBright: [107, defaultBG],
});
function defineColorAlias(target, alias) {
Object.defineProperty(inspect.colors, alias, {
get() {
return this[target];
},
set(value) {
this[target] = value;
},
configurable: true,
enumerable: false,
});
}
defineColorAlias("gray", "grey");
defineColorAlias("gray", "blackBright");
defineColorAlias("bgGray", "bgGrey");
defineColorAlias("bgGray", "bgBlackBright");
defineColorAlias("dim", "faint");
defineColorAlias("strikethrough", "crossedout");
defineColorAlias("strikethrough", "strikeThrough");
defineColorAlias("strikethrough", "crossedOut");
defineColorAlias("hidden", "conceal");
defineColorAlias("inverse", "swapColors");
defineColorAlias("inverse", "swapcolors");
defineColorAlias("doubleunderline", "doubleUnderline");
// Regex used for ansi escape code splitting
// Adopted from https://github.com/chalk/ansi-regex/blob/HEAD/index.js
// License: MIT, authors: @sindresorhus, Qix-, arjunmehta and LitoMore
// Matches all ansi escape code sequences in a string
const ansiPattern = "[\\u001B\\u009B][[\\]()#;?]*" +
"(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*" +
"|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)" +
"|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))";
const ansi = new RegExp(ansiPattern, "g");
/**
* Returns the number of columns required to display the given string.
*/
export function getStringWidth(str, removeControlChars = true) {
let width = 0;
if (removeControlChars) {
str = stripVTControlCharacters(str);
}
return denoGetStringWidth(str);
}
export function format(...args) {
return inspectArgs(args);
}
export function formatWithOptions(inspectOptions, ...args) {
if (typeof inspectOptions !== "object" || inspectOptions === null) {
throw new codes.ERR_INVALID_ARG_TYPE(
"inspectOptions",
"object",
inspectOptions,
);
}
return inspectArgs(args, inspectOptions);
}
/**
* Remove all VT control characters. Use to estimate displayed string width.
*/
export function stripVTControlCharacters(str) {
validateString(str, "str");
return str.replace(ansi, "");
}
export default {
format,
getStringWidth,
inspect,
stripVTControlCharacters,
formatWithOptions,
};