Refactor runtime around isolated bot instances
This commit is contained in:
+20
-1
@@ -1,8 +1,10 @@
|
||||
import readline from "node:readline/promises";
|
||||
import { stdin as input, stdout as output } from "node:process";
|
||||
import { Writable } from "node:stream";
|
||||
|
||||
export interface PromptSession {
|
||||
ask(question: string, defaultValue?: string): Promise<string>;
|
||||
askSecret(question: string, hasExisting?: boolean): Promise<string>;
|
||||
askBoolean(question: string, defaultValue?: boolean): Promise<boolean>;
|
||||
askList(question: string, defaultValues?: string[]): Promise<string[]>;
|
||||
choose<T>(question: string, choices: Choice<T>[], defaultIndex?: number): Promise<T>;
|
||||
@@ -16,9 +18,14 @@ export interface Choice<T> {
|
||||
}
|
||||
|
||||
export function createPromptSession(): PromptSession {
|
||||
const rl = readline.createInterface({ input, output });
|
||||
let rl = readline.createInterface({ input, output });
|
||||
return {
|
||||
ask: (question, defaultValue) => ask(rl, question, defaultValue),
|
||||
askSecret: async (question, hasExisting) => {
|
||||
rl.close();
|
||||
try { return await askSecret(question, hasExisting); }
|
||||
finally { rl = readline.createInterface({ input, output }); }
|
||||
},
|
||||
askBoolean: (question, defaultValue) => askBoolean(rl, question, defaultValue),
|
||||
askList: (question, defaultValues) => askList(rl, question, defaultValues),
|
||||
choose: (question, choices, defaultIndex) => choose(rl, question, choices, defaultIndex),
|
||||
@@ -26,6 +33,18 @@ export function createPromptSession(): PromptSession {
|
||||
};
|
||||
}
|
||||
|
||||
async function askSecret(question: string, hasExisting = false): Promise<string> {
|
||||
if (!input.isTTY || !output.isTTY) throw new Error("Secret input requires an interactive terminal");
|
||||
const muted = new Writable({ write(_chunk, _encoding, callback) { callback(); } });
|
||||
const secretRl = readline.createInterface({ input, output: muted, terminal: true });
|
||||
output.write(`${question}${hasExisting ? " (leave blank to keep existing)" : ""}: `);
|
||||
try {
|
||||
const answer = (await secretRl.question("")).trim();
|
||||
output.write("\n");
|
||||
return answer;
|
||||
} finally { secretRl.close(); }
|
||||
}
|
||||
|
||||
export async function ask(rl: readline.Interface, question: string, defaultValue?: string): Promise<string> {
|
||||
const suffix = defaultValue !== undefined && defaultValue !== "" ? ` [${defaultValue}]` : "";
|
||||
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
||||
|
||||
Reference in New Issue
Block a user