72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
import * as readline from 'node:readline';
|
|
import {exec} from 'child_process';
|
|
|
|
export function $(str, ...args) {
|
|
let cmd = str.reduce((acc, part, i) => acc + part + (args[i] || ''), '');
|
|
return new Promise((res, rej) => exec(cmd, (err, stdout, stderr) => {
|
|
if(err || stderr) return rej(err || stderr);
|
|
return res(stdout);
|
|
}))
|
|
}
|
|
|
|
export function ask(prompt, hide = false) {
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
terminal: true
|
|
});
|
|
|
|
return new Promise((resolve) => {
|
|
if (!hide) {
|
|
rl.question(prompt, (answer) => {
|
|
rl.close();
|
|
resolve(answer);
|
|
});
|
|
} else {
|
|
rl.output.write(prompt);
|
|
let input = '';
|
|
|
|
// Listen for 'keypress' to handle masking
|
|
rl.input.on('keypress', (char, key) => {
|
|
if (key && key.name === 'return') {
|
|
rl.output.write('\n'); // Submit on new line
|
|
rl.close();
|
|
resolve(input);
|
|
} else if (key && key.name === 'backspace') {
|
|
if (input.length > 0) {
|
|
input = input.slice(0, -1);
|
|
rl.output.write(`\r${prompt}${input.replaceAll(/./g, '*')} \b`);
|
|
}
|
|
} else {
|
|
input += char;
|
|
rl.output.write('\b*'); // Mask the input with '*'
|
|
}
|
|
});
|
|
|
|
// Restore settings
|
|
rl.input.setRawMode(true);
|
|
rl.input.resume();
|
|
}
|
|
});
|
|
}
|
|
|
|
export function poll(cb, ms) {
|
|
let cancel = false, timeout = null;
|
|
const p = async () => {
|
|
if(cancel) return;
|
|
const start = new Date().getTime();
|
|
await cb();
|
|
const end = new Date().getTime();
|
|
timeout = setTimeout(() => p(), ms - (end - start));
|
|
};
|
|
p();
|
|
return () => {
|
|
cancel = true;
|
|
if(timeout) clearTimeout(timeout);
|
|
}
|
|
}
|
|
|
|
export function sleep(ms) {
|
|
return new Promise(res => setTimeout(res, ms));
|
|
}
|