Use the style and utilities of the Symfony Console in Node.js.
Since Symfony is, for good reason, a registered trademark, please take note that I'm in no way associated with the Symfony brand or the SensioLabs organization. Therefore I don't represent or speak for any of them.
While developing a PHP project using the Symfony framework, I found myself in the need of writing some Composer
post-install-cmd scripts in Node.js.
Sadly, they did not visually align to the output from PHP which was using the
Symfony\Component\Console\Style\SymfonyStyle class. So I decided to port that class and its environment to TypeScript to be able to use that style in Node.js.
Since style is always more or less closely coupled to different features, this package actually contains some nice utility the Symfony folks built into their console.
First, of course, you need to install this package:
# With Yarnyarn add symfony-style-console# With npmnpm install --save symfony-style-console
Then, pull the
SymfonyStyle class from the package and instantiate it:
const SymfonyStyle =// Or the more verbose way, in case you use Node.js v4:const SymfonyStyle = SymfonyStyleconst io =
Since ES modules are coming to more and more engines, this package offers an alternative build using ES2015 modules.
You can use it like this (note that you'll currently still need a Babel-like build chain to resolve those modules):
const io =
io instance now offers several different methods. If you know the Symfony console—Since this package aims to get as close to 100% API compatibility with the original PHP class as it can get—you may already be familiar with them.
Protip: Because this package is written in TypeScript, you can get type hints for the
io instance if you use an editor with support für
*.d.ts declaration files.
Back to topic, the available methods on the
io instance are:
// Put out a stylish titleiotitle'Symfony Style'// Similar to `title`, but less showyio// The plain old `writeln` method. Does what you'd expect it to do.io// Equivalent to `writeln`, but doesn't put a line break afterio// Put 2 blank lines on the screen.// The argument is optional and defaults to 1io// `text` blocks get indented by one character.iotext'This gets indented by one character.'// `comment` blocks are also indented and preceded// by a double slash "//"io// `block` serves to group content, with a certain styling.io// `success`, `warning`, `caution` and `error` are really// just predefined `block` statements.// Doesn't make them less useful though.ioioioio// Questions// Please do gently ignore the fact that I haven't added// an `async` wrapper function to the following methods.// I just wanted to omit the visual noise. Also note that// async/await is only available in Node.js 7.6 and above.// Ask for stringsconst name = await io// Ask for strings without showing themconst passwd = await io// Ask for picking from a collectionconst language = await io// Ask for confirmationconst submit = await io// Last but not least: Progress bars!// Create one!io// Advance it!io// Set it!io// Finish it!io
A screenshot of the result is below. Look at this beautiful terminal.
You can set the verbosity of the
io instance to only print what you need:
constSymfonyStyleVERBOSITY_NORMALVERBOSITY_VERBOSEVERBOSITY_DEBUG} =// Default verbosity is VERBOSITY_NORMAL...const io =// ...so this won't be printed:io// Set the verbosity real highio// Now the same message will suddenly appear:io
The available verbosity options are (in this order, from least to most verbose):
VERBOSITY_QUIET(no output at all)
Using verbosity programmatically
Note that the verbosity options are only available on the
VERBOSITY_* constants are just numbers and you can compare them as you need:
// Verbosity setting is at least VERBOSITY_VERBOSEif io > VERBOSITY_NORMALio
Or to make that even more comfortable, use the builtin methods:
// Checks if output is completely turned offio// The following do always read as "is AT LEAST ****"ioioio
Setting verbosity via command line flags
Symfony itself ties those verbosity levels to certain command line flags (
This package does not aim to be a CLI framework though, so if you want to use those flags, you'd have to bind them to the verbosity manually.
The following code would mimic Symfony's behaviour:
constSymfonyStyleVERBOSITY_QUIETVERBOSITY_VERBOSEVERBOSITY_VERY_VERBOSEVERBOSITY_DEBUG} =const io =const flagMap ='-q': VERBOSITY_QUIET'--quiet': VERBOSITY_QUIET'-v': VERBOSITY_VERBOSE'-vv': VERBOSITY_VERY_VERBOSE'-vvv': VERBOSITY_DEBUGconst argv = processargvfor const flag in flagMapif argv !== -1iobreak
You can style your console output in a markup-like fashion:
Styles can be a combination of foreground (
fg) and background color (
bg) as well as a comma-separated list of additional
Want a fully fledged example? Observe:
Note that you can nest stylings, but nested styling markup will not inherit parent styles.
The following code block does explain what that means:
// Style the phrase: "This text is green with an underlined word."io
The following colors are available:
Supported styles include (support for each may vary):
Styles are escaped in
block() output and in all output derived from
error). This is a design decision by the Symfony team and I'm not going to interfere with that.
There are some small things that differ from Symfony's original API.
Since the questions part is not actually a port of the original code but a completely custom implementation, there are no
Question objects and thus no need or functionality for an
askQuestion method on the
As opposed to the original, this package's
SymfonyStyle class has no public
That method is integrated more deeply into the Symfony ecosystem than this project aims to support, and it's not necessary for the user facing API.
It still exists though, could be called and provide the same functionality, but it has been marked as
private in source code so it doesn't appear in the TypeScript Definition files.
I was missing a method to set the value of a progress bar to a certain step instead of just advancing it.
That's why I added the
progressSet(step) method. This is not present in the original
dim style option
I personally find the
dim style pretty appealing, so I added it to the style options.
However, be aware that support is not too widespread (does not work on Windows as far as I know).
Return type: Questions
confirm methods on the original
SymfonyStyle class do return their results directly.
Also, the original class allows numeric values for the