console: allow per-stream inspectOptions option

We (correctly) allow different streams to be specified for `stdout`
and `stderr`, so we should also allow different inspect options for
these streams.

PR-URL: https://github.com/nodejs/node/pull/60082
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
This commit is contained in:
Anna Henningsen 2025-10-01 14:30:22 +02:00
parent bb04959818
commit 79f1999531
No known key found for this signature in database
3 changed files with 46 additions and 8 deletions

View File

@ -102,6 +102,9 @@ const { Console } = console;
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/60082
description: The `inspectOptions` option can be a `Map` from stream to options.
- version:
- v14.2.0
- v12.17.0
@ -131,8 +134,9 @@ changes:
and the value returned by `getColorDepth()` on the respective stream. This
option can not be used, if `inspectOptions.colors` is set as well.
**Default:** `'auto'`.
* `inspectOptions` {Object} Specifies options that are passed along to
[`util.inspect()`][].
* `inspectOptions` {Object|Map} Specifies options that are passed along to
[`util.inspect()`][]. Can be an options object or, if different options
for stdout and stderr are desired, a `Map` from stream objects to options.
* `groupIndentation` {number} Set group indentation.
**Default:** `2`.

View File

@ -12,6 +12,8 @@ const {
Boolean,
ErrorCaptureStackTrace,
FunctionPrototypeBind,
MapPrototypeGet,
MapPrototypeValues,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectKeys,
@ -139,12 +141,20 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
if (inspectOptions !== undefined) {
validateObject(inspectOptions, 'options.inspectOptions');
const inspectOptionsMap = isMap(inspectOptions) ?
inspectOptions : new SafeMap([
[stdout, inspectOptions],
[stderr, inspectOptions],
]);
for (const inspectOptions of MapPrototypeValues(inspectOptionsMap)) {
if (inspectOptions.colors !== undefined &&
options.colorMode !== undefined) {
throw new ERR_INCOMPATIBLE_OPTION_PAIR(
'options.inspectOptions.color', 'colorMode');
}
optionsMap.set(this, inspectOptions);
}
optionsMap.set(this, inspectOptionsMap);
}
// Bind the prototype functions to this Console instance
@ -316,7 +326,8 @@ ObjectDefineProperties(Console.prototype, {
color = lazyUtilColors().shouldColorize(stream);
}
const options = optionsMap.get(this);
const inspectOptionsMap = optionsMap.get(this);
const options = inspectOptionsMap ? MapPrototypeGet(inspectOptionsMap, stream) : undefined;
if (options) {
if (options.colors === undefined) {
options.colors = color;

View File

@ -0,0 +1,23 @@
'use strict';
require('../common');
const { Console } = require('console');
const { PassThrough } = require('stream');
const { strict: assert } = require('assert');
const stdout = new PassThrough().setEncoding('utf8');
const stderr = new PassThrough().setEncoding('utf8');
const console = new Console({
stdout,
stderr,
inspectOptions: new Map([
[stdout, { colors: true }],
[stderr, { colors: false }],
]),
});
console.log('Hello', 42);
console.warn('Hello', 42);
assert.strictEqual(stdout.read(), 'Hello \x1B[33m42\x1B[39m\n');
assert.strictEqual(stderr.read(), 'Hello 42\n');