ci/woodpecker/pr/ci Pipeline failed
ensureSession credential resolution when sign-in is needed, in order: 1. explicit --email flag (highest) 2. non-TTY stdin: line 1 email, line 2 password (printf 'email\npassword\n' | …) — for headless callers without argv access 3. interactive prompt (TTY only) Precedence documented on ensureSession and in --help; headless with NO credentials exits 2 with guidance instead of hanging on prompts. Password never read from argv (ps-visible); stdin line kept untrimmed. New piped-credentials.ts module so the reader is testable against real streams (4 stream specs) while token-ops specs mock the seam (5 specs).
27 lines
961 B
TypeScript
27 lines
961 B
TypeScript
import { createInterface } from 'node:readline';
|
|
|
|
/**
|
|
* Read email + password as two lines from non-TTY stdin (the headless dual
|
|
* path for callers that cannot pass argv: printf 'email\npassword\n' | …).
|
|
* Caller gates on !isTTY; the password line is kept as-is (no trim —
|
|
* whitespace may be intentional).
|
|
*
|
|
* Separate module (not login.ts) so tests can exercise the REAL reader
|
|
* against real streams while token-ops specs mock this seam cleanly.
|
|
*/
|
|
export function readCredentialsFromPipedStdin(
|
|
input: NodeJS.ReadableStream = process.stdin,
|
|
): Promise<{ email: string | null; password: string | null }> {
|
|
return new Promise((resolve) => {
|
|
const lines: string[] = [];
|
|
const rl = createInterface({ input });
|
|
rl.on('line', (l) => {
|
|
lines.push(l);
|
|
if (lines.length >= 2) rl.close();
|
|
});
|
|
rl.on('close', () => {
|
|
resolve({ email: (lines[0] ?? '').trim() || null, password: lines[1] ?? null });
|
|
});
|
|
});
|
|
}
|