Skip to content

Commit 659d780

Browse files
jason-rlclaude
andcommitted
feat: support stdin for object upload via - path
- When path is `-`, read upload data from stdin - Require --name and --content-type for stdin uploads since they cannot be inferred from a filename - Update command description to document stdin support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b3bf76d commit 659d780

2 files changed

Lines changed: 33 additions & 6 deletions

File tree

src/commands/object/upload.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,40 @@ const CONTENT_TYPE_MAP: Record<string, ContentType> = {
3232
".tar.gz": "tgz",
3333
};
3434

35+
async function readStdinBuffer(): Promise<Buffer> {
36+
const chunks: Buffer[] = [];
37+
for await (const chunk of process.stdin) {
38+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
39+
}
40+
return Buffer.concat(chunks);
41+
}
42+
3543
export async function uploadObject(options: UploadObjectOptions) {
3644
try {
3745
const client = getClient();
46+
const isStdin = options.path === "-";
47+
48+
if (isStdin) {
49+
if (!options.name) {
50+
outputError("--name is required when uploading from stdin");
51+
}
52+
if (!options.contentType) {
53+
outputError("--content-type is required when uploading from stdin");
54+
}
55+
}
56+
57+
// Read file data
58+
let fileBuffer: Buffer;
59+
let fileSize: number;
3860

39-
// Check if file exists and get stats
40-
const stats = await stat(options.path);
41-
const fileBuffer = await readFile(options.path);
61+
if (isStdin) {
62+
fileBuffer = await readStdinBuffer();
63+
fileSize = fileBuffer.length;
64+
} else {
65+
const stats = await stat(options.path);
66+
fileSize = stats.size;
67+
fileBuffer = await readFile(options.path);
68+
}
4269

4370
// Auto-detect content type if not provided
4471
let detectedContentType: ContentType = options.contentType as ContentType;
@@ -73,7 +100,7 @@ export async function uploadObject(options: UploadObjectOptions) {
73100
id: createResponse.id,
74101
name: options.name,
75102
contentType: detectedContentType,
76-
size: stats.size,
103+
size: fileSize,
77104
};
78105

79106
// Default: just output the ID for easy scripting

src/utils/commands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,8 @@ export function createProgram(): Command {
651651

652652
object
653653
.command("upload <path>")
654-
.description("Upload a file as an object")
655-
.option("--name <name>", "Object name (required)")
654+
.description("Upload a file as an object (use - to read from stdin)")
655+
.option("--name <name>", "Object name (required; mandatory for stdin)")
656656
.option(
657657
"--content-type <type>",
658658
"Content type: unspecified|text|binary|gzip|tar|tgz",

0 commit comments

Comments
 (0)