Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
@poppinss/cliui
Advanced tools
Command line UI Kit used by AdonisJS
This repo is a command line UI Kit used by the AdonisJS framework to design its command line interfaces.
The kit is highly opinionated and we will not allow configurable settings in the near future. We want to be consistent with our UI's without worrying about the configuration. It's like getting in the prettier mindset.
Read this official blog post to learn more about it.
Install the package from the npm registry by running following command.
npm i @poppinss/cliui
# Yarn users
yarn add @poppinss/cliui
Import the components you want to use from the package.
import {
logger,
instructions,
sticker,
tasks,
table,
} from '@poppinss/cliui'
logger.info('hello world')
const spinner = logger.await('downloading')
await someTimeConsumingTask()
spinner.stop()
The logger exposes the following methods.
success(message, prefix?, suffix?)
Log success message. The message is printed to stdout
.
logger.success('Account created')
// ✔ Account created
Optional prefix
logger.success('Account created', 'ap-south-1')
// [ap-south-1] ✔ Account created
Optional suffix
logger.success('Account created', undefined, 'ap-south-1')
// ✔ Account created (ap-south-1)
The prefix and suffix are support on all logger methods except
logger.action
error(message, prefix?, suffix?)
Log an error message. The message is printed to stderr
.
logger.error('Unable to write. Disk full')
// Or log error object
logger.error(new Error('Unable to write. Disk full'))
// ✖ Unable to write. Disk full
fatal(message, prefix?, suffix?)
The logger.error
does not print the error stack. You must use logger.fatal
to print the error stack.
logger.fatal(new Error('Unable to write. Disk full'))
warning(message, prefix?, suffix?)
Print a warning message. Message is written to stdout
.
logger.warning('Running out of disk space')
// ⚠ Running out of disk space
info(message, prefix?, suffix?)
Print an info message. Message is again written to stdout
.
logger.info('Your account is has been updated')
// ℹ Your account is has been updated
debug(message, prefix?, suffix?)
Print a debug message. Message is printed to stdout
.
logger.debug('Something just happened')
// ● Something just happened
log(message)
Similar to console.log
, but instead uses the Logger renderer.
We will talk about renderers later in this document, since they make testing of log message little bit easier.
logger.log('hello world')
logError(message)
Similar to console.error
, but instead use the Logger renderer.
log.logError('this is an error message')
logUpdate(message)
Log a message that overwrites the previously logged message. The method is helpful for building progress bars or animations.
logger.logUpdate(`downloading ${i}%`)
// Once completed, persist the message on console
logger.logUpdatePersist()
Here is a complete example of showing the downloading progress.
const sleep = () => new Promise((resolve) => setTimeout(resolve, 50))
async function run () {
for (let i = 0; i <= 100; i = i + 2) {
await sleep()
logger.logUpdate(`downloading ${i}%`)
}
logger.logUpdatePersist()
}
run()
In order to log results of an action/task, we make use of the action
method.
const action = logger.action('create')
action.succeeded('config/auth.ts')
An action can end in one of the following states.
action.succeeded(message)
Action completed successfully
const action = logger.action('create')
action.succeeded('config/auth.ts')
action.skipped(message)
Skipped action
const action = logger.action('create')
action.skipped('app/Models/User.ts')
action.failed(message, errorMessage)
Action failed, an error message is required to share more context
const action = logger.action('create')
action.failed('server.ts', 'File already exists')
Instructions are mainly the steps we want someone to perform in order to achieve something. For example:
import { instructions, logger } from '@poppinss/cliui'
instructions()
.add(`cd ${logger.colors.cyan('hello-world')}`)
.add(`Run ${logger.colors.cyan('node ace serve --watch')} to start the server`)
.render()
instructions()
begins a new instructions block.add()
method.render()
method to render it on the console.Similar to the instructions, a sticker does not prefix the lines, with a pointer >
arrow. Rest is all same.
It is helpful for displaying a message that needs the most attention. For example:
import { sticker, logger } from '@poppinss/cliui'
sticker()
.add('Started HTTP server')
.add('')
.add(`Local address: ${logger.colors.cyan('http://localhost:3333')}`)
.add(`Network address: ${logger.colors.cyan('http://localhost:3333')}`)
.render()
We make use of tasks when performing multiple actions in respond to a command. For example:
The UI for the tasks is designed to only handle tasks running in sequence.
Task has two renderers minimal
and verbose
. The minimal renderer is the default choice and switch to verbose
in one of the following situations.
Following is a very simple example of creating and running multiple tasks.
import { tasks } from '@poppinss/cliui'
await tasks()
.add('clone repo', async (logger, task) => {
logger.info(`cloning ${someRepoUrl}`)
await performClone()
await task.complete()
})
.add('install dependencies', async (logger, task) => {
const spinner = logger.await('running npm install')
await performInstall()
spinner.stop()
await task.complete()
})
.run()
The add
method accepts the task title and the callback function to invoke in order to perform the task
Once, you are done with the task jobs, you must call await task.complete()
to complete the task. The await
is important here.
In order to mark task as failed, you can call the task.fail
method. All upcoming tasks will be stopped in case of a failure.
await task.fail(new Error('Network error'))
By default, the minimal
renderer is used and pivots to the verbose renderer only when terminal is not interactive.
In order to run tasks explicitly in the verbose mode, you can create the tasks instance using tasks.verbose()
method.
tasks.verbose()
.add()
.add()
.run()
FAQs
Opinionated UI KIT for Command Line apps
The npm package @poppinss/cliui receives a total of 41,645 weekly downloads. As such, @poppinss/cliui popularity was classified as popular.
We found that @poppinss/cliui demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.