Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/just-cameron/tangled-cli. Automation-first CLI for Tangled.org
Something went wrong. Try again.
2.7 kB · 96 lines
TypeScript
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697import * as fs from 'node:fs/promises';import * as process from 'node:process';
/** * Read body content from various sources following GitHub CLI patterns * * @param bodyString - Direct body text from --body flag * @param bodyFilePath - File path or '-' for stdin * @returns Body content or undefined if no input provided * @throws Error if both bodyString and bodyFilePath are provided * @throws Error if file doesn't exist or cannot be read */export async function readBodyInput( bodyString?: string, bodyFilePath?: string): Promise<string | undefined> { // Error if both are provided if (bodyString !== undefined && bodyFilePath !== undefined) { throw new Error('Cannot specify both --body and --body-file. Choose one input method.'); }
// Direct string input (including empty string) if (bodyString !== undefined) { return bodyString; }
// File or stdin input if (bodyFilePath) { // Read from stdin if (bodyFilePath === '-') { return await readFromStdin(); }
// Read from file try { const stats = await fs.stat(bodyFilePath);
if (stats.isDirectory()) { throw new Error(`'${bodyFilePath}' is a directory, not a file`); }
const content = await fs.readFile(bodyFilePath, 'utf-8'); return content; } catch (error) { if (error instanceof Error) { // Re-throw our custom directory error if (error.message.includes('is a directory')) { throw error; }
// Handle ENOENT (file not found) if ('code' in error && error.code === 'ENOENT') { throw new Error(`File not found: ${bodyFilePath}`); }
// Handle EACCES (permission denied) if ('code' in error && error.code === 'EACCES') { throw new Error(`Permission denied: ${bodyFilePath}`); }
throw new Error(`Failed to read file '${bodyFilePath}': ${error.message}`); }
throw new Error(`Failed to read file '${bodyFilePath}': Unknown error`); } }
// No input provided return undefined;}
/** * Read content from stdin * @returns Content from stdin as string */async function readFromStdin(): Promise<string> { return new Promise((resolve, reject) => { const chunks: Buffer[] = [];
process.stdin.on('data', (chunk: Buffer) => { chunks.push(chunk); });
process.stdin.on('end', () => { const content = Buffer.concat(chunks).toString('utf-8'); resolve(content); });
process.stdin.on('error', (error: Error) => { reject(new Error(`Failed to read from stdin: ${error.message}`)); });
// Resume stdin in case it's paused process.stdin.resume(); });}