
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Простая работа с консолью.
Библиотка javascript/typescript (ES6) для node.js.
Нужно понимать, что библиотека написана для простой и быстрой работы. Она не является заменой curses из c и c++.
Если вам нужен более мощный функционал, то стоит обратить внимание на другие библиотеки.
npm install lib-curses
или
yarn add lib-curses
Можно импортировать методы как с отдельные функции:
import { initScreen, print } from 'lib-curses';
initScreen();
print('Hello world');
или вызывать их как статические методы объекта:
import * as curses from 'lib-curses';
curses.initScreen();
curses.print('Hello world');
addch(string: any, x = -1, y = -1): void
Вывод символов в консоль.
Вторым и третьим необязательными параметрами можно задать смещение по осям x и y относительно верхнего левого угла.
Отсчет начинается с нуля. Любые значения меньше нуля игнорируют смещение. И таким образом, вывод идет в текущем месте расположения курсора.
clearLine(y: number): void
Очищает строку.
clearScreen(): void
Очищает экран.
async getch(): Promise
Считывает ввод с клавиатуры. Возвращает объект Buffer.
Обратите внимание, что любые сочетания клавиш (ctrl + c) и специальные вызовы (SIGINT) не будут обработаны автоматически. Поэтому вам придется обрабатывать их самостоятельно.
hideCursor(): void
Скрывает курсор.
initScreen(): void
Подготовка экрана консоли к работе.
async input(printedString = '', callback: (key: string) => string = (key) => key): Promise
Требует ввод строки в консоль. Возвращает введенное пользователем значение.
Первым необязательным параметром можно передать строку, которая будет выведена перед запросом ввода.
Вторым необязательным параметром можно задать callback-функцию, которая будет обрабатывать полученное значение и возвращать его.
async inputch(printedString = '', callback: (key: string) => string = (key) => key): Promise
Требует ввод символа в консоль.
Отличие от input только в том, что ввод ожидает нажатия любой клавиши и возвращает ее значение.
position(x = -1, y = -1): void
Задает позицию курсора по осям x и y относительно верхнего левого угла.
Отсчет начинается с нуля. Любые значения меньше нуля игнорируют смещение. И таким образом, вывод идет в текущем месте расположения курсора.
print(string: any, x = -1, y = -1): void
Вывод строки в консоль.
Отличие от addch только в том, что в конце вывода добавляется символ перевода строки.
showCursor(): void
Возвращает показ курсора.
Все вызовы возвращают ошибки как есть, без дополнительных перехватов и обработки. Поэтому оборачиваем в try/catch самостоятельно.
async function customInput(question) {
try {
const userInput = await input(question);
return { userInput };
} catch (error) {
return { error };
}
}
Вывод символов:
addch('Hello world');
Вывод строки:
print('Hello world');
Посмотрим как это работает, если повторить несколько вызовов последовательно.
Например:
addch('1');
addch('2');
print('3');
print('4');
addch('5');
addch('6');
print('7');
print('8');
выведет в консоль:
123
4
567
8
Такой пример со счетчиком:
let count = 0;
setInterval(() => {
clearLine(4);
print(`Counter: ${count}`, 0, 4);
count++;
}, 1000);
выведет в консоль:
Counter: 0
const userInput = input();
Выведет в консоль:
> _
Можно задать первый параметр. Например:
const userInput = input('What is your name: ');
Выведет в консоль:
> What is your name: _
Следующий пример будет передавать только числа от 1 до 100 и 0 как неверное значение.
const string = await input('Input 1-100: ', (string) => {
let answer = parseInt(string, 10) || 0;
if (answer < 1) {
answer = 0;
}
if (answer > 100) {
answer = 0;
}
process.stdout.write(answer + '\n');
return String(answer);
});
console.log(`Input: ${string}`);
Следующий пример задает ввод по-умолчанию, если никакой символ не был введен. По клавише Esc он прерывает выполнение программы.
const key = await inputch('(Y)es or (N)o: ', (key) => {
if (key === '\x1B') {
process.exit();
}
let answer = key.toString().trim().toLowerCase();
if (!answer || /[^a-z]+/iu.test(answer)) {
answer = 'y';
}
process.stdout.write(answer + '\n');
return answer;
});
console.log(`Input: ${key}`);
Следующий пример задает ввод на пятой строке. Важно помнить, что смещение работает только после инициализации экрана консоли.
initScreen();
position(0, 4)
const string = await input('Write something: ');
console.log(`Input: ${string}`);
В данном примере предлагается ввести максимум 5 символов. Ввод будет прерван после нажатия клавиши Enter.
let inputString = '';
let readyString = '';
initScreen();
const handler = (key: string) => {
if (key === '\x0d') {
readyString = inputString;
}
if (/\W/iu.test(key)) {
return '';
}
inputString += key;
if (inputString.length > 5) {
inputString = key;
}
return key;
};
while (!readyString) {
position(0, 0);
const printedString = `Input max 5 symbols: ${`${inputString}_____`.slice(0, 5)}`;
const key = await inputch(printedString, (key) => {
position(printedString.length, 0);
return handler(key);
});
}
print(`> ${readyString}`, 0, 1);
Ввод с клавиатуры обрабатывается таким образом:
const key = await getch();
console.log(key);
Важно помнить, что метод getch не обрабатывает отдельно специальные вызовы (например SIGINT). Поэтому вам придется самостоятельно предусмотреть выход из программы.
Например, если вызывать getch в цикле, можно обработать прерывание так:
let infinite = true;
while (infinite) {
const key = await getch();
console.log({
uint8: new Uint8Array(key),
x16: [...new Uint8Array(key)].map((code) =>
`${'0' + code.toString(16)}`.slice(-2),
),
utf8: key.toString(),
hex: key.toString('hex'),
});
if (key === '\x03') {
infinite = false;
}
}
В данном примере мы будем управлять символом @ с помощью курсора.
Нажатие клавиш Enter, Esc или Ctrl + C прервет процесс.
const keys = {
enter: '\x0d',
esc: '\x1b',
sigint: '\x03',
up: '\x1B[A',
down: '\x1B[B',
left: '\x1B[D',
right: '\x1B[C',
};
const w = 10, h = 10;
let x = 0, y = 0;
initScreen();
hideCursor();
addch('@', x, y);
let infinite = true;
while (infinite) {
const code = await getch();
const key = code.toString();
const oldX = x, oldY = y;
if (key === keys.up) { y -= 1; }
if (key === keys.down) { y += 1; }
if (key === keys.left) { x -= 1; }
if (key === keys.right) { x += 1; }
if (x < 0) { x = 0; }
if (x > w) { x = w; }
if (y < 0) { y = 0; }
if (y > h) { y = h; }
if (x !== oldX || y !== oldY) {
addch(' ', oldX, oldY);
addch('@', x, y);
}
if ([keys.enter, keys.esc, keys.sigint].includes(key)) {
infinite = false;
}
}
Лицензия MIT, 2025
FAQs
Simple node.js library for work with console
We found that lib-curses demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.