// 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, };