Files
toon/packages/cli/src/utils.ts
2025-11-03 11:39:10 +01:00

80 lines
1.7 KiB
TypeScript

import type { InputSource } from './types'
import * as fsp from 'node:fs/promises'
import * as path from 'node:path'
import process from 'node:process'
export function detectMode(
input: InputSource,
encodeFlag?: boolean,
decodeFlag?: boolean,
): 'encode' | 'decode' {
// Explicit flags take precedence
if (encodeFlag)
return 'encode'
if (decodeFlag)
return 'decode'
// Auto-detect based on file extension
if (input.type === 'file') {
if (input.path.endsWith('.json'))
return 'encode'
if (input.path.endsWith('.toon'))
return 'decode'
}
// Default to encode
return 'encode'
}
export async function readInput(source: InputSource): Promise<string> {
if (source.type === 'stdin')
return readFromStdin()
return fsp.readFile(source.path, 'utf-8')
}
export function formatInputLabel(source: InputSource): string {
if (source.type === 'stdin')
return 'stdin'
const relativePath = path.relative(process.cwd(), source.path)
return relativePath || path.basename(source.path)
}
function readFromStdin(): Promise<string> {
const { stdin } = process
if (stdin.readableEnded)
return Promise.resolve('')
return new Promise((resolve, reject) => {
let data = ''
const onData = (chunk: string) => {
data += chunk
}
function cleanup() {
stdin.off('data', onData)
stdin.off('error', onError)
stdin.off('end', onEnd)
}
function onError(error: Error) {
cleanup()
reject(error)
}
function onEnd() {
cleanup()
resolve(data)
}
stdin.setEncoding('utf-8')
stdin.on('data', onData)
stdin.once('error', onError)
stdin.once('end', onEnd)
stdin.resume()
})
}