Skip to content

util.styleText() doesn't restore outer styles after nested calls #59035

@outslept

Description

@outslept

Version

v23.5.0

Platform

Microsoft Windows NT 10.0.19045.0 x64

Subsystem

util

What steps will reproduce the bug?

node -e "import('node:util').then(({styleText}) => console.log(styleText('red', 'A ' + styleText('blue', 'B') + ' C')))"

How often does it reproduce? Is there a required condition?

Nesting styleText() calls one inside another

What is the expected behavior? Why is that the expected behavior?

After a nested styleText() call ends, the text should return to the outer style, not to the default/unstyled state.

The why:

  1. Major styling libraries (e.g. chalk) handle nesting this way. Devs would expect consistent behavior when migrating to native APIs.
  2. Without proper nesting, styleText() cannot handle "complex" formatting scenarios that are standard in CLI applications

What do you see instead?

When running:

styleText('red', `A ${styleText('blue', 'B')} C`)

Expected output: A(red) B(blue) C(red)
Actual output: A(red) B(blue) C(default color)

The text "C" appears in the terminal's default color instead of returning to red after the nested blue styling ends.

We can inspect the codes with

node -e "import('node:util').then(({styleText}) => console.log(JSON.stringify(styleText('red', 'A ' + styleText('blue', 'B') + ' C'))))"
"\u001b[31mA \u001b[34mB\u001b[39m C\u001b[39m"

The issue is \u001b[39m (def) instead of \u001b[31m (red).

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    utilIssues and PRs related to the built-in util module.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions