mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 05:12:11 +03:00
* fix(cli): non-interactive-safe prompts + singular `context` alias Two CLI-polish follow-ups (the third — an async-warn refactor for #2807 — is moot: #4373 replaced the Gemini remote-URL drop+warn with fileData pass-through, so no async warn remains). 1) createPrompt (io.mjs) — the shared interactive helper used rl.question with no EOF guard, so a non-interactive stdin (pipe, CI, `< /dev/null`) left the await pending and Node warned about an 'unsettled top-level await' while the command hung. ask/askSecret now resolve on the readline `close` event (fired on EOF) with the default / empty string. A genuinely piped line still arrives via the question callback first, so `echo value | omniroute …` keeps working — only the no-input EOF case falls back. This fixes every command that prompts, centrally (mirrors the contexts `confirm()` fix from #4397). 2) `contexts` gains a singular `context` alias — the connect output and older docs said `omniroute context current`; the alias keeps that muscle-memory working. Tests: cli-io.test.ts (ask default/empty + askSecret resolve on EOF, no hang) and a cli-contexts.test.ts case asserting the `context` alias is registered. 11/11. * test(cli): mock .alias() in the fake program for the contexts subcommand test The existing 'registers a current subcommand' test uses a minimal fake commander program; registerContexts now calls .alias("context"), so the fake needs an alias() stub (returns this) or the chain throws. Add it. (Self-introduced by the alias in this branch; my 4 new tests already pass in CI.)
34 lines
1.3 KiB
TypeScript
34 lines
1.3 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
// Regression: the shared interactive prompt helper (createPrompt) used rl.question
|
|
// without an EOF guard, so a non-interactive stdin (pipe, CI, `< /dev/null`) left
|
|
// the promise pending — Node then warned about an "unsettled top-level await" at
|
|
// exit and the command hung. ask/askSecret now resolve on the readline `close`
|
|
// event (fired on EOF) with the default / empty string instead of hanging. close()
|
|
// here simulates that EOF/non-interactive close.
|
|
|
|
test("createPrompt.ask resolves the default on EOF (non-interactive, no hang)", async () => {
|
|
const { createPrompt } = await import("../../bin/cli/io.mjs");
|
|
const p = createPrompt();
|
|
const pending = p.ask("Name", "fallback");
|
|
p.close();
|
|
assert.equal(await pending, "fallback");
|
|
});
|
|
|
|
test("createPrompt.ask resolves empty when there is no default on EOF", async () => {
|
|
const { createPrompt } = await import("../../bin/cli/io.mjs");
|
|
const p = createPrompt();
|
|
const pending = p.ask("Name");
|
|
p.close();
|
|
assert.equal(await pending, "");
|
|
});
|
|
|
|
test("createPrompt.askSecret resolves empty on EOF (no hang)", async () => {
|
|
const { createPrompt } = await import("../../bin/cli/io.mjs");
|
|
const p = createPrompt();
|
|
const pending = p.askSecret("Secret");
|
|
p.close();
|
|
assert.equal(await pending, "");
|
|
});
|