import { createReadStream, readFileSync, statSync, writeFileSync } from "node:fs"; import { basename } from "node:path"; import { createInterface } from "node:readline"; import { apiFetch, getBaseUrl } from "../api.mjs"; import { emit } from "../output.mjs"; import { t } from "../i18n.mjs"; function fmtTs(v) { if (!v) return "-"; return new Date(typeof v === "number" ? v * 1000 : v).toLocaleString(); } function fmtBytes(n) { if (n == null) return "-"; if (n < 1024) return `${n} B`; if (n < 1024 ** 2) return `${(n / 1024).toFixed(1)} KB`; if (n < 1024 ** 3) return `${(n / 1024 ** 2).toFixed(1)} MB`; return `${(n / 1024 ** 3).toFixed(2)} GB`; } async function confirm(q) { const rl = createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { rl.question(`${q} [y/N] `, (a) => { rl.close(); resolve(a.trim().toLowerCase() === "y"); }); }); } function authHeaders(opts) { const h = { accept: "application/json" }; if (opts.apiKey) h["Authorization"] = `Bearer ${opts.apiKey}`; return h; } const fileSchema = [ { key: "id", header: "File ID", width: 30 }, { key: "filename", header: "Filename", width: 35 }, { key: "purpose", header: "Purpose", width: 14 }, { key: "bytes", header: "Bytes", formatter: fmtBytes }, { key: "created_at", header: "Created", formatter: fmtTs }, { key: "status", header: "Status" }, ]; export function registerFiles(program) { const files = program.command("files").description(t("files.description")); files .command("list") .option("--purpose
", t("files.list.purpose"))
.option("--limit ", t("files.upload.purpose"))
.action(async (filePath, opts, cmd) => {
const stat = statSync(filePath);
if (stat.size > 100 * 1024 * 1024) {
process.stderr.write(
`Warning: file is ${fmtBytes(stat.size)} (${stat.size > 500e6 ? "very " : ""}large)\n`
);
}
const globalOpts = cmd.optsWithGlobals();
const form = new FormData();
form.append("purpose", opts.purpose);
form.append("file", new Blob([readFileSync(filePath)]), basename(filePath));
const res = await fetch(`${getBaseUrl(globalOpts)}/v1/files`, {
method: "POST",
headers: authHeaders(globalOpts),
body: form,
});
if (!res.ok) {
process.stderr.write(`Upload failed: ${res.status}\n`);
process.exit(1);
}
emit(await res.json(), globalOpts);
});
files
.command("content