npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dwbinns/terminal

v1.9.1

Published

Node terminal library

Downloads

53

Readme

Node Terminal Library

Formatting and keyboard input handling for the terminal in NodeJS.

import { red, magentaBG } from "@dwbinns/terminal/colour";
import { underline } from "@dwbinns/terminal/format";
console.log(`${magentaBG("Magenta")} ${underline(`underline ${red("red")}`)}`);

Formatting example

Installation

npm install @dwbinns/terminal

Alternatively clone the git repository to try the examples:

git clone https://github.com/dwbinns/terminal.git

Notes

This library is ES module (import/export) only. CommonJS (require) is not supported.

Only ANSI compatible terminals are supported.

British English spelling is used (note the spelling of colour and grey).

Format

Function to format strings.

import { underline, doubleUnderline, wavyUnderline } from "@dwbinns/terminal/format";

console.log(underline('underlined text'), 'normal');
console.log(doubleUnderline('double underlined text'), 'normal');
console.log(wavyUnderline('wavy underlined text'), 'normal');

Colours

Functions to apply colouring to strings.

import { cyan, cyanBG, rgb, rgbBG, underlineRGB, hslBG } from "@dwbinns/terminal/colour";
import { underline } from "@dwbinns/terminal/format";

console.log(cyan('cyan text'), 'normal');
console.log(cyanBG('cyan background'), 'normal');

const red = 255;
const green = 128;
const blue = 0;
console.log(rgb(red, green, blue)('orange text'), 'normal');

console.log(rgbBG(red, green, blue)('orange background'), 'normal');
console.log(underline(underlineRGB(red, green, blue)('orange underline')), 'normal');

console.log([...new Array(60)].map((_, index) => hslBG(index * 6, 1, 0.5)(" ")).join(""));

formats a string with a given background colour.

RGB colours are specified with R, G and B in the range 0 - 255. HSL colours are specified with H in the range 0 - 360, S and L in the range 0 - 1.

RGB colours will be rendered as 3 bit, 8 bit or 24 bit depending on terminal capabilites.

Hyperlink

hyperlink - create a clickable link to a URL

import {hyperlink} from "@dwbinns/terminal/hyperlink";
const options = {};
const url = "https://github.com/dwbinns/terminal";
const text = "dwbinns/terminal";

console.log(hyperlink(options, url, text));

Keyboard

decodeKeys - an async generator which takes a stream and yields objects describing keyboard events.

A stream which is passed in will be set to raw mode.

Alternatively any async iterable yielding buffers or strings may be supplied.

Each object may contain fields:

  • text
  • keyName
  • shift
  • alt
  • ctrl

Not all keys are distinguishable, for example [ctrl]+[m] is the same as [return]. For some keys the modifiers (ctrl, shift, alt) cannot be determined.

import { decodeKeys } from "@dwbinns/terminal/keyboard";
for await (let input of decodeKeys(process.stdin)) {
  console.log(input);
  if (input.keyName == "escape") break;
}

Example output:

{ text: '4', keyName: '4' }
{ keyName: 'pageup', shift: false, alt: true, ctrl: false }
{ keyName: 'tab', shift: true }
{ text: '8', keyName: '8' }
{ keyName: '*', alt: true }

Box drawing characters

import { box } from "@dwbinns/terminal/box";
const up = "single";
const down = "single";
const left = "double";
const right = "double";
console.log(box(up, right, down, left));

box - return a single box drawing character where up, right, down and left represent the line styles in the specified direction and can be "none", "single", "double" or "heavy".

Limitations:

  • "heavy" and "double" cannot be combined
  • "single" and "double" cannot be combined on the same axis

In these cases "double" will be replaced with "heavy".

examples/box.js

import { box } from "@dwbinns/terminal/box";
let lines = [
  "heavy",
  "none",
  "single",
  "double",
  "double",
  "single",
  "none",
  "heavy",
];
for (let horizontal of lines) {
  for (let vertical of lines) {
    process.stdout.write(box(vertical, horizontal, vertical, horizontal));
  }
  process.stdout.write("\n");
}

Box drawing

import { rounded } from "@dwbinns/terminal/box";
const up = true;
const down = false;
const left = true;
const right = false;
console.log(rounded(up, right, down, left));

Returns a single box drawing character with rounded corners where up, right, down and left can be true (to draw a line) or false (to draw nothing).

Format aware string functions

String functions that are aware of the visible length of the string, not including formatting characters.

import { visiblePadEnd, visiblePadStart, visibleLength } from "@dwbinns/terminal/string";
let string = "hello";
let length = 20;
let fill = " ";

// Pad a string at the end to the specified visible length with the optional fill character.
visiblePadEnd(string, length, fill);

// Pad a string at the start to the specified visible length with the optional fill character.
visiblePadStart(string, length, fill);

// Get the visible length of a string.
visibleLength(string);

Table formatting

table - format tables in aligned columns, even if cells contain formatting characters.

Data should be an array of rows each of which is an array of cells for that row.

import table from "@dwbinns/terminal/table";
import { red, green } from "@dwbinns/terminal/colour";

console.log(
  table([
    ["Heading", "Information"],
    ["Row1", red("red")],
    ["Row2", green("green")],
  ])
);

Table

Tree formatting

import tree from "@dwbinns/terminal/tree";
import { rounded } from "@dwbinns/terminal/box";
const node = {
  description: "parent",
  children: [{ description: "child" }],
};
const getChildren = (node) => node.children || [];
const getDescription = (node) => node.description;
const indent = 2;
const style = rounded;
console.log(tree({ node, getChildren, getDescription, indent, style }));

tree - format a tree:

  • node: top level node
  • getChildren: function returning array of children for each node (default: node => node.children)
  • getDescription: function returning a string as a label for each node (default: node => node.toString())
  • indent: number of characters of indent (default: 2)
  • style: box drawing characters to use (default: rounded)
import tree from "@dwbinns/terminal/tree";
import { statSync, readdirSync } from "node:fs";
import { basename, join } from "node:path";

function getChildren(path) {
  if (!statSync(path).isDirectory()) return [];
  return readdirSync(path)
    .filter((item) => !item.startsWith("."))
    .map((item) => join(path, item));
}

function getDescription(path) {
  return basename(path);
}

console.log(tree({ node: ".", getChildren, getDescription }));

Tree