* @param {string | string[]} format * @param {string} text * @param {object} [options] * @param {boolean} [options.validateStream] - Whether to validate the stream. * @param {Stream} [options.stream] - The stream used for validation. * @returns {string}
(format, text, options)
| 244 | * @returns {string} |
| 245 | */ |
| 246 | function styleText(format, text, options) { |
| 247 | const validateStream = options?.validateStream ?? true; |
| 248 | |
| 249 | // Fast path: single format string with validateStream=false |
| 250 | if (!validateStream && typeof format === 'string' && typeof text === 'string') { |
| 251 | const cache = getStyleCache(); |
| 252 | if (format === 'none') return text; |
| 253 | const style = cache[format]; |
| 254 | if (style !== undefined) { |
| 255 | const processed = replaceCloseCode(text, style.closeSeq, style.openSeq, style.keepClose); |
| 256 | return style.openSeq + processed + style.closeSeq; |
| 257 | } |
| 258 | |
| 259 | if (format[0] === '#') { |
| 260 | let hexStyle = getHexStyleCache().get(format); |
| 261 | if (hexStyle === undefined && RegExpPrototypeExec(hexColorRegExp, format) !== null) { |
| 262 | hexStyle = getHexStyle(format); |
| 263 | } |
| 264 | if (hexStyle !== undefined) { |
| 265 | const processed = replaceCloseCode(text, hexStyle.closeSeq, hexStyle.openSeq, false); |
| 266 | return hexStyle.openSeq + processed + hexStyle.closeSeq; |
| 267 | } |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | validateString(text, 'text'); |
| 272 | if (options !== undefined) { |
| 273 | validateObject(options, 'options'); |
| 274 | } |
| 275 | validateBoolean(validateStream, 'options.validateStream'); |
| 276 | |
| 277 | let skipColorize; |
| 278 | if (validateStream) { |
| 279 | const stream = options?.stream ?? process.stdout; |
| 280 | if ( |
| 281 | !isReadableStream(stream) && |
| 282 | !isWritableStream(stream) && |
| 283 | !isNodeStream(stream) |
| 284 | ) { |
| 285 | throw new ERR_INVALID_ARG_TYPE('stream', ['ReadableStream', 'WritableStream', 'Stream'], stream); |
| 286 | } |
| 287 | skipColorize = !lazyUtilColors().shouldColorize(stream); |
| 288 | } |
| 289 | |
| 290 | const formatArray = ArrayIsArray(format) ? format : [format]; |
| 291 | const colors = inspect.colors; |
| 292 | |
| 293 | let openCodes = ''; |
| 294 | let closeCodes = ''; |
| 295 | let processedText = text; |
| 296 | |
| 297 | for (const key of formatArray) { |
| 298 | if (key === 'none') continue; |
| 299 | |
| 300 | if (typeof key === 'string' && key[0] === '#') { |
| 301 | if (RegExpPrototypeExec(hexColorRegExp, key) === null) { |
| 302 | throw new ERR_INVALID_ARG_VALUE('format', key, |
| 303 | 'must be a valid hex color (#RGB or #RRGGBB)'); |
no test coverage detected
searching dependent graphs…