@floehq/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/cli.js +476 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cancel.js +13 -0
- package/dist/commands/doctor.js +24 -0
- package/dist/commands/status.js +13 -0
- package/dist/commands/upload.js +28 -0
- package/dist/core/api/client.js +38 -0
- package/dist/core/api/uploads.js +10 -0
- package/dist/core/auth/headers.js +14 -0
- package/dist/core/config/env.js +10 -0
- package/dist/core/config/paths.js +11 -0
- package/dist/core/output/logger.js +8 -0
- package/dist/index.js +47 -0
- package/dist/types/api.js +1 -0
- package/dist/util/errors.js +8 -0
- package/package.json +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Floe CLI
|
|
2
|
+
|
|
3
|
+
`@floehq/cli` is the official command-line interface for the Floe API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @floehq/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run without a global install:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @floehq/cli --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
floe upload ./video.mp4
|
|
21
|
+
floe upload status <uploadId>
|
|
22
|
+
floe upload cancel <uploadId>
|
|
23
|
+
floe upload complete <uploadId>
|
|
24
|
+
floe upload wait <uploadId>
|
|
25
|
+
floe file metadata <fileId>
|
|
26
|
+
floe file manifest <fileId>
|
|
27
|
+
floe file stream-url <fileId>
|
|
28
|
+
floe ops health
|
|
29
|
+
floe config show
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Shortcuts are also supported for the most common lookups:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
floe status <uploadId>
|
|
36
|
+
floe cancel <uploadId>
|
|
37
|
+
floe metadata <fileId>
|
|
38
|
+
floe manifest <fileId>
|
|
39
|
+
floe stream-url <fileId>
|
|
40
|
+
```
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { FloeApiError, FloeClient, createNodeFileResumeStore } from "@floehq/sdk";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
function printHelp(topic) {
|
|
6
|
+
const normalized = (topic ?? "").toLowerCase();
|
|
7
|
+
if (normalized === "upload") {
|
|
8
|
+
process.stdout.write(`Floe CLI: upload
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
floe upload <file> [options]
|
|
12
|
+
floe upload status <uploadId> [options]
|
|
13
|
+
floe upload cancel <uploadId> [options]
|
|
14
|
+
floe upload complete <uploadId> [options]
|
|
15
|
+
floe upload wait <uploadId> [options]
|
|
16
|
+
|
|
17
|
+
Notes:
|
|
18
|
+
upload resume is automatic by default through the local resume store
|
|
19
|
+
use --no-resume to disable that behavior
|
|
20
|
+
`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (normalized === "file") {
|
|
24
|
+
process.stdout.write(`Floe CLI: file
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
floe file metadata <fileId> [options]
|
|
28
|
+
floe file manifest <fileId> [options]
|
|
29
|
+
floe file stream-url <fileId> [options]
|
|
30
|
+
`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (normalized === "ops") {
|
|
34
|
+
process.stdout.write(`Floe CLI: ops
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
floe ops health [options]
|
|
38
|
+
`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
process.stdout.write(`Floe CLI
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
floe <group> <command> [args] [options]
|
|
45
|
+
|
|
46
|
+
Groups:
|
|
47
|
+
upload upload, status, cancel, complete, and wait flows
|
|
48
|
+
file metadata, manifest, and stream URL lookups
|
|
49
|
+
ops health and operator-friendly checks
|
|
50
|
+
config show the effective local CLI configuration
|
|
51
|
+
help show top-level or group help
|
|
52
|
+
|
|
53
|
+
Primary Commands:
|
|
54
|
+
floe upload <file>
|
|
55
|
+
floe upload status <uploadId>
|
|
56
|
+
floe upload cancel <uploadId>
|
|
57
|
+
floe upload complete <uploadId>
|
|
58
|
+
floe upload wait <uploadId>
|
|
59
|
+
floe file metadata <fileId>
|
|
60
|
+
floe file manifest <fileId>
|
|
61
|
+
floe file stream-url <fileId>
|
|
62
|
+
floe ops health
|
|
63
|
+
floe config show
|
|
64
|
+
|
|
65
|
+
Shortcuts:
|
|
66
|
+
floe status <uploadId>
|
|
67
|
+
floe cancel <uploadId>
|
|
68
|
+
floe metadata <fileId>
|
|
69
|
+
floe manifest <fileId>
|
|
70
|
+
floe stream-url <fileId>
|
|
71
|
+
|
|
72
|
+
Global Options:
|
|
73
|
+
--base-url <url> Floe API base URL
|
|
74
|
+
--api-key <key> x-api-key auth
|
|
75
|
+
--bearer <token> Authorization bearer token
|
|
76
|
+
--owner-address <addr> x-owner-address auth hint
|
|
77
|
+
--wallet-address <addr> x-wallet-address auth hint
|
|
78
|
+
--auth-user <id> x-auth-user auth hint
|
|
79
|
+
--json Print JSON only
|
|
80
|
+
--include-blob-id Ask Floe to include blobId when supported
|
|
81
|
+
|
|
82
|
+
Upload Options:
|
|
83
|
+
--chunk-size <bytes> Upload chunk size in bytes
|
|
84
|
+
--epochs <n> Walrus epochs for upload create
|
|
85
|
+
--parallel <n> Parallel chunk uploads (default: 3)
|
|
86
|
+
--no-resume Disable resume-store lookup for uploads
|
|
87
|
+
--poll-interval-ms <n> Finalize wait poll interval
|
|
88
|
+
--max-wait-ms <n> Finalize max wait time
|
|
89
|
+
|
|
90
|
+
Examples:
|
|
91
|
+
floe upload ./movie.mp4 --base-url http://127.0.0.1:3001/v1
|
|
92
|
+
floe upload wait 123e4567-e89b-12d3-a456-426614174000
|
|
93
|
+
floe file metadata 0xabc...
|
|
94
|
+
floe ops health
|
|
95
|
+
floe config show
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
98
|
+
function inferContentType(filePath) {
|
|
99
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
100
|
+
if (ext === ".mp4")
|
|
101
|
+
return "video/mp4";
|
|
102
|
+
if (ext === ".webm")
|
|
103
|
+
return "video/webm";
|
|
104
|
+
if (ext === ".mov")
|
|
105
|
+
return "video/quicktime";
|
|
106
|
+
if (ext === ".json")
|
|
107
|
+
return "application/json";
|
|
108
|
+
if (ext === ".txt")
|
|
109
|
+
return "text/plain";
|
|
110
|
+
if (ext === ".mkv")
|
|
111
|
+
return "video/x-matroska";
|
|
112
|
+
return "application/octet-stream";
|
|
113
|
+
}
|
|
114
|
+
function parseIntFlag(value) {
|
|
115
|
+
const n = Number(value);
|
|
116
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
117
|
+
return undefined;
|
|
118
|
+
return Math.floor(n);
|
|
119
|
+
}
|
|
120
|
+
function parseArgs(argv) {
|
|
121
|
+
const tokens = [];
|
|
122
|
+
const options = {
|
|
123
|
+
baseUrl: process.env.FLOE_BASE_URL || "http://127.0.0.1:3001/v1",
|
|
124
|
+
apiKey: process.env.FLOE_API_KEY,
|
|
125
|
+
bearerToken: process.env.FLOE_BEARER_TOKEN,
|
|
126
|
+
ownerAddress: process.env.FLOE_OWNER_ADDRESS,
|
|
127
|
+
authUser: process.env.FLOE_AUTH_USER,
|
|
128
|
+
walletAddress: process.env.FLOE_WALLET_ADDRESS,
|
|
129
|
+
json: false,
|
|
130
|
+
parallel: 3,
|
|
131
|
+
};
|
|
132
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
133
|
+
const arg = argv[i];
|
|
134
|
+
if (!arg.startsWith("--")) {
|
|
135
|
+
tokens.push(arg);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const readValue = () => {
|
|
139
|
+
const value = argv[i + 1];
|
|
140
|
+
i += 1;
|
|
141
|
+
return value;
|
|
142
|
+
};
|
|
143
|
+
switch (arg) {
|
|
144
|
+
case "--base-url":
|
|
145
|
+
options.baseUrl = readValue() || options.baseUrl;
|
|
146
|
+
break;
|
|
147
|
+
case "--api-key":
|
|
148
|
+
options.apiKey = readValue() || "";
|
|
149
|
+
break;
|
|
150
|
+
case "--bearer":
|
|
151
|
+
options.bearerToken = readValue() || "";
|
|
152
|
+
break;
|
|
153
|
+
case "--owner-address":
|
|
154
|
+
options.ownerAddress = readValue() || "";
|
|
155
|
+
break;
|
|
156
|
+
case "--wallet-address":
|
|
157
|
+
options.walletAddress = readValue() || "";
|
|
158
|
+
break;
|
|
159
|
+
case "--auth-user":
|
|
160
|
+
options.authUser = readValue() || "";
|
|
161
|
+
break;
|
|
162
|
+
case "--chunk-size":
|
|
163
|
+
options.chunkSize = parseIntFlag(readValue());
|
|
164
|
+
break;
|
|
165
|
+
case "--epochs":
|
|
166
|
+
options.epochs = parseIntFlag(readValue());
|
|
167
|
+
break;
|
|
168
|
+
case "--parallel":
|
|
169
|
+
options.parallel = parseIntFlag(readValue());
|
|
170
|
+
break;
|
|
171
|
+
case "--poll-interval-ms":
|
|
172
|
+
options.pollIntervalMs = parseIntFlag(readValue());
|
|
173
|
+
break;
|
|
174
|
+
case "--max-wait-ms":
|
|
175
|
+
options.maxWaitMs = parseIntFlag(readValue());
|
|
176
|
+
break;
|
|
177
|
+
case "--include-blob-id":
|
|
178
|
+
options.includeBlobId = true;
|
|
179
|
+
break;
|
|
180
|
+
case "--no-resume":
|
|
181
|
+
options.noResume = true;
|
|
182
|
+
break;
|
|
183
|
+
case "--json":
|
|
184
|
+
options.json = true;
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const [first, second, third] = tokens.map((v) => v.toLowerCase());
|
|
191
|
+
let command;
|
|
192
|
+
switch (first ?? "help") {
|
|
193
|
+
case "upload":
|
|
194
|
+
switch (second) {
|
|
195
|
+
case "status":
|
|
196
|
+
command = { kind: "upload.status", uploadId: tokens[2] };
|
|
197
|
+
break;
|
|
198
|
+
case "cancel":
|
|
199
|
+
command = { kind: "upload.cancel", uploadId: tokens[2] };
|
|
200
|
+
break;
|
|
201
|
+
case "complete":
|
|
202
|
+
command = { kind: "upload.complete", uploadId: tokens[2] };
|
|
203
|
+
break;
|
|
204
|
+
case "wait":
|
|
205
|
+
command = { kind: "upload.wait", uploadId: tokens[2] };
|
|
206
|
+
break;
|
|
207
|
+
case "help":
|
|
208
|
+
command = { kind: "help", topic: "upload" };
|
|
209
|
+
break;
|
|
210
|
+
default:
|
|
211
|
+
command = { kind: "upload.upload", filePath: tokens[1] ?? tokens[0] };
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
214
|
+
case "file":
|
|
215
|
+
switch (second) {
|
|
216
|
+
case "metadata":
|
|
217
|
+
command = { kind: "file.metadata", fileId: tokens[2] };
|
|
218
|
+
break;
|
|
219
|
+
case "manifest":
|
|
220
|
+
command = { kind: "file.manifest", fileId: tokens[2] };
|
|
221
|
+
break;
|
|
222
|
+
case "stream-url":
|
|
223
|
+
command = { kind: "file.stream-url", fileId: tokens[2] };
|
|
224
|
+
break;
|
|
225
|
+
case "help":
|
|
226
|
+
command = { kind: "help", topic: "file" };
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
command = { kind: "help", topic: "file" };
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
case "ops":
|
|
233
|
+
command = second === "health" ? { kind: "ops.health" } : { kind: "help", topic: "ops" };
|
|
234
|
+
break;
|
|
235
|
+
case "config":
|
|
236
|
+
command = second === "show" ? { kind: "config.show" } : { kind: "help" };
|
|
237
|
+
break;
|
|
238
|
+
case "status":
|
|
239
|
+
command = { kind: "upload.status", uploadId: tokens[1] };
|
|
240
|
+
break;
|
|
241
|
+
case "cancel":
|
|
242
|
+
command = { kind: "upload.cancel", uploadId: tokens[1] };
|
|
243
|
+
break;
|
|
244
|
+
case "metadata":
|
|
245
|
+
command = { kind: "file.metadata", fileId: tokens[1] };
|
|
246
|
+
break;
|
|
247
|
+
case "manifest":
|
|
248
|
+
command = { kind: "file.manifest", fileId: tokens[1] };
|
|
249
|
+
break;
|
|
250
|
+
case "stream-url":
|
|
251
|
+
command = { kind: "file.stream-url", fileId: tokens[1] };
|
|
252
|
+
break;
|
|
253
|
+
case "help":
|
|
254
|
+
command = { kind: "help", topic: tokens[1] };
|
|
255
|
+
break;
|
|
256
|
+
default:
|
|
257
|
+
command = { kind: "help" };
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
return { command, options };
|
|
261
|
+
}
|
|
262
|
+
function printResult(value, json) {
|
|
263
|
+
const text = JSON.stringify(value, null, 2);
|
|
264
|
+
process.stdout.write(`${text}\n`);
|
|
265
|
+
}
|
|
266
|
+
async function readFileAsBlob(filePath, contentType) {
|
|
267
|
+
const openAsBlob = fs.openAsBlob;
|
|
268
|
+
if (typeof openAsBlob === "function") {
|
|
269
|
+
return await openAsBlob(filePath, { type: contentType });
|
|
270
|
+
}
|
|
271
|
+
const bytes = await fs.readFile(filePath);
|
|
272
|
+
return new Blob([bytes], { type: contentType });
|
|
273
|
+
}
|
|
274
|
+
async function buildClient(options) {
|
|
275
|
+
const resumeStore = options.noResume ? undefined : await createNodeFileResumeStore();
|
|
276
|
+
return new FloeClient({
|
|
277
|
+
baseUrl: options.baseUrl,
|
|
278
|
+
auth: {
|
|
279
|
+
...(options.apiKey ? { apiKey: options.apiKey } : {}),
|
|
280
|
+
...(options.bearerToken ? { bearerToken: options.bearerToken } : {}),
|
|
281
|
+
...(options.ownerAddress ? { ownerAddress: options.ownerAddress } : {}),
|
|
282
|
+
...(options.authUser ? { authUser: options.authUser } : {}),
|
|
283
|
+
...(options.walletAddress ? { walletAddress: options.walletAddress } : {}),
|
|
284
|
+
},
|
|
285
|
+
resumeStore,
|
|
286
|
+
userAgent: "@floehq/cli",
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function requireValue(value, label) {
|
|
290
|
+
if (!value)
|
|
291
|
+
throw new Error(`${label} is required`);
|
|
292
|
+
return value;
|
|
293
|
+
}
|
|
294
|
+
function rootApiUrl(baseUrl) {
|
|
295
|
+
return baseUrl.replace(/\/v1\/?$/, "");
|
|
296
|
+
}
|
|
297
|
+
async function fetchJson(url, options) {
|
|
298
|
+
const headers = new Headers();
|
|
299
|
+
if (options.apiKey)
|
|
300
|
+
headers.set("x-api-key", options.apiKey);
|
|
301
|
+
if (options.bearerToken)
|
|
302
|
+
headers.set("authorization", `Bearer ${options.bearerToken}`);
|
|
303
|
+
if (options.authUser)
|
|
304
|
+
headers.set("x-auth-user", options.authUser);
|
|
305
|
+
if (options.ownerAddress)
|
|
306
|
+
headers.set("x-owner-address", options.ownerAddress);
|
|
307
|
+
if (options.walletAddress)
|
|
308
|
+
headers.set("x-wallet-address", options.walletAddress);
|
|
309
|
+
headers.set("x-floe-sdk", "@floehq/cli");
|
|
310
|
+
const response = await fetch(url, { headers });
|
|
311
|
+
const text = await response.text();
|
|
312
|
+
const data = text ? JSON.parse(text) : null;
|
|
313
|
+
if (!response.ok) {
|
|
314
|
+
throw new Error(`Request failed (${response.status}): ${text}`);
|
|
315
|
+
}
|
|
316
|
+
return data;
|
|
317
|
+
}
|
|
318
|
+
async function runUpload(filePathRaw, options) {
|
|
319
|
+
const rawFile = requireValue(filePathRaw, "file path");
|
|
320
|
+
const filePath = path.resolve(rawFile);
|
|
321
|
+
const stat = await fs.stat(filePath);
|
|
322
|
+
if (!stat.isFile())
|
|
323
|
+
throw new Error(`Not a file: ${filePath}`);
|
|
324
|
+
const contentType = inferContentType(filePath);
|
|
325
|
+
const blob = await readFileAsBlob(filePath, contentType);
|
|
326
|
+
const client = await buildClient(options);
|
|
327
|
+
const result = await client.uploadBlob(blob, {
|
|
328
|
+
filename: path.basename(filePath),
|
|
329
|
+
contentType,
|
|
330
|
+
...(options.chunkSize ? { chunkSize: options.chunkSize } : {}),
|
|
331
|
+
...(options.epochs ? { epochs: options.epochs } : {}),
|
|
332
|
+
...(options.parallel ? { parallel: options.parallel } : {}),
|
|
333
|
+
...(options.includeBlobId ? { includeBlobId: true } : {}),
|
|
334
|
+
...(options.pollIntervalMs ? { finalizePollIntervalMs: options.pollIntervalMs } : {}),
|
|
335
|
+
...(options.maxWaitMs ? { finalizeMaxWaitMs: options.maxWaitMs } : {}),
|
|
336
|
+
onProgress(progress) {
|
|
337
|
+
if (options.json)
|
|
338
|
+
return;
|
|
339
|
+
process.stderr.write(`uploaded ${progress.uploadedChunks}/${progress.totalChunks} chunks (${progress.uploadedBytes}/${progress.totalBytes} bytes)\n`);
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
printResult(result, options.json);
|
|
343
|
+
}
|
|
344
|
+
async function runUploadStatus(uploadIdRaw, options) {
|
|
345
|
+
const uploadId = requireValue(uploadIdRaw, "uploadId");
|
|
346
|
+
const client = await buildClient(options);
|
|
347
|
+
const result = await client.getUploadStatus(uploadId, {
|
|
348
|
+
...(options.includeBlobId ? { query: { includeBlobId: 1 } } : {}),
|
|
349
|
+
});
|
|
350
|
+
printResult(result, options.json);
|
|
351
|
+
}
|
|
352
|
+
async function runUploadCancel(uploadIdRaw, options) {
|
|
353
|
+
const uploadId = requireValue(uploadIdRaw, "uploadId");
|
|
354
|
+
const client = await buildClient(options);
|
|
355
|
+
const result = await client.cancelUpload(uploadId);
|
|
356
|
+
printResult(result, options.json);
|
|
357
|
+
}
|
|
358
|
+
async function runUploadComplete(uploadIdRaw, options) {
|
|
359
|
+
const uploadId = requireValue(uploadIdRaw, "uploadId");
|
|
360
|
+
const client = await buildClient(options);
|
|
361
|
+
const result = await client.completeUpload(uploadId, {
|
|
362
|
+
...(options.includeBlobId ? { includeBlobId: true } : {}),
|
|
363
|
+
});
|
|
364
|
+
printResult(result, options.json);
|
|
365
|
+
}
|
|
366
|
+
async function runUploadWait(uploadIdRaw, options) {
|
|
367
|
+
const uploadId = requireValue(uploadIdRaw, "uploadId");
|
|
368
|
+
const client = await buildClient(options);
|
|
369
|
+
const result = await client.waitForUploadReady(uploadId, {
|
|
370
|
+
...(options.includeBlobId ? { includeBlobId: true } : {}),
|
|
371
|
+
...(options.pollIntervalMs ? { pollIntervalMs: options.pollIntervalMs } : {}),
|
|
372
|
+
...(options.maxWaitMs ? { maxWaitMs: options.maxWaitMs } : {}),
|
|
373
|
+
});
|
|
374
|
+
printResult(result, options.json);
|
|
375
|
+
}
|
|
376
|
+
async function runFileMetadata(fileIdRaw, options) {
|
|
377
|
+
const fileId = requireValue(fileIdRaw, "fileId");
|
|
378
|
+
const client = await buildClient(options);
|
|
379
|
+
const result = await client.getFileMetadata(fileId, {
|
|
380
|
+
...(options.includeBlobId ? { includeBlobId: true } : {}),
|
|
381
|
+
});
|
|
382
|
+
printResult(result, options.json);
|
|
383
|
+
}
|
|
384
|
+
async function runFileManifest(fileIdRaw, options) {
|
|
385
|
+
const fileId = requireValue(fileIdRaw, "fileId");
|
|
386
|
+
const client = await buildClient(options);
|
|
387
|
+
const result = await client.getFileManifest(fileId);
|
|
388
|
+
printResult(result, options.json);
|
|
389
|
+
}
|
|
390
|
+
async function runFileStreamUrl(fileIdRaw, options) {
|
|
391
|
+
const fileId = requireValue(fileIdRaw, "fileId");
|
|
392
|
+
const client = await buildClient(options);
|
|
393
|
+
printResult({ fileId, streamUrl: client.getFileStreamUrl(fileId) }, options.json);
|
|
394
|
+
}
|
|
395
|
+
async function runOpsHealth(options) {
|
|
396
|
+
const result = await fetchJson(`${rootApiUrl(options.baseUrl)}/health`, options);
|
|
397
|
+
printResult(result, options.json);
|
|
398
|
+
}
|
|
399
|
+
async function runConfigShow(options) {
|
|
400
|
+
printResult({
|
|
401
|
+
baseUrl: options.baseUrl,
|
|
402
|
+
auth: {
|
|
403
|
+
apiKey: options.apiKey ? "[configured]" : null,
|
|
404
|
+
bearerToken: options.bearerToken ? "[configured]" : null,
|
|
405
|
+
ownerAddress: options.ownerAddress ?? null,
|
|
406
|
+
authUser: options.authUser ?? null,
|
|
407
|
+
walletAddress: options.walletAddress ?? null,
|
|
408
|
+
},
|
|
409
|
+
upload: {
|
|
410
|
+
chunkSize: options.chunkSize ?? null,
|
|
411
|
+
epochs: options.epochs ?? null,
|
|
412
|
+
parallel: options.parallel ?? null,
|
|
413
|
+
includeBlobId: options.includeBlobId ?? false,
|
|
414
|
+
noResume: options.noResume ?? false,
|
|
415
|
+
pollIntervalMs: options.pollIntervalMs ?? null,
|
|
416
|
+
maxWaitMs: options.maxWaitMs ?? null,
|
|
417
|
+
},
|
|
418
|
+
}, options.json);
|
|
419
|
+
}
|
|
420
|
+
async function main() {
|
|
421
|
+
const { command, options } = parseArgs(process.argv.slice(2));
|
|
422
|
+
switch (command.kind) {
|
|
423
|
+
case "help":
|
|
424
|
+
printHelp(command.topic);
|
|
425
|
+
return;
|
|
426
|
+
case "upload.upload":
|
|
427
|
+
await runUpload(command.filePath, options);
|
|
428
|
+
return;
|
|
429
|
+
case "upload.status":
|
|
430
|
+
await runUploadStatus(command.uploadId, options);
|
|
431
|
+
return;
|
|
432
|
+
case "upload.cancel":
|
|
433
|
+
await runUploadCancel(command.uploadId, options);
|
|
434
|
+
return;
|
|
435
|
+
case "upload.complete":
|
|
436
|
+
await runUploadComplete(command.uploadId, options);
|
|
437
|
+
return;
|
|
438
|
+
case "upload.wait":
|
|
439
|
+
await runUploadWait(command.uploadId, options);
|
|
440
|
+
return;
|
|
441
|
+
case "file.metadata":
|
|
442
|
+
await runFileMetadata(command.fileId, options);
|
|
443
|
+
return;
|
|
444
|
+
case "file.manifest":
|
|
445
|
+
await runFileManifest(command.fileId, options);
|
|
446
|
+
return;
|
|
447
|
+
case "file.stream-url":
|
|
448
|
+
await runFileStreamUrl(command.fileId, options);
|
|
449
|
+
return;
|
|
450
|
+
case "ops.health":
|
|
451
|
+
await runOpsHealth(options);
|
|
452
|
+
return;
|
|
453
|
+
case "config.show":
|
|
454
|
+
await runConfigShow(options);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
main().catch((err) => {
|
|
459
|
+
if (err instanceof FloeApiError) {
|
|
460
|
+
process.stderr.write(`${JSON.stringify({
|
|
461
|
+
error: {
|
|
462
|
+
message: err.message,
|
|
463
|
+
status: err.status,
|
|
464
|
+
code: err.code,
|
|
465
|
+
retryable: err.retryable,
|
|
466
|
+
requestId: err.requestId,
|
|
467
|
+
details: err.details,
|
|
468
|
+
},
|
|
469
|
+
}, null, 2)}\n`);
|
|
470
|
+
process.exitCode = 1;
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
process.stderr.write(`${String(err instanceof Error ? err.message : err)}\n`);
|
|
474
|
+
process.exitCode = 1;
|
|
475
|
+
});
|
|
476
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAgC7B,SAAS,SAAS,CAAC,KAAc;IAC/B,MAAM,UAAU,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;CAYxB,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;CAMxB,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;CAIxB,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDtB,CAAC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IACvC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,YAAY,CAAC;IACzC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,iBAAiB,CAAC;IAC7C,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,kBAAkB,CAAC;IAC/C,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,YAAY,CAAC;IACxC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,kBAAkB,CAAC;IAC9C,OAAO,0BAA0B,CAAC;AACpC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAI/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAe;QAC1B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,0BAA0B;QAChE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAChC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC1C,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC5C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QACpC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC9C,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC;KACZ,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,YAAY;gBACf,OAAO,CAAC,OAAO,GAAG,SAAS,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC;gBACjD,MAAM;YACR,KAAK,WAAW;gBACd,OAAO,CAAC,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;gBACnC,MAAM;YACR,KAAK,UAAU;gBACb,OAAO,CAAC,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;gBACxC,MAAM;YACR,KAAK,iBAAiB;gBACpB,OAAO,CAAC,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;gBACzC,MAAM;YACR,KAAK,kBAAkB;gBACrB,OAAO,CAAC,aAAa,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;gBAC1C,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,CAAC,QAAQ,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;gBACrC,MAAM;YACR,KAAK,cAAc;gBACjB,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC9C,MAAM;YACR,KAAK,UAAU;gBACb,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,YAAY;gBACf,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,oBAAoB;gBACvB,OAAO,CAAC,cAAc,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;gBACnD,MAAM;YACR,KAAK,eAAe;gBAClB,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC9C,MAAM;YACR,KAAK,mBAAmB;gBACtB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC7B,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACxB,MAAM;YACR,KAAK,QAAQ;gBACX,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAClE,IAAI,OAAwB,CAAC;IAE7B,QAAQ,KAAK,IAAI,MAAM,EAAE,CAAC;QACxB,KAAK,QAAQ;YACX,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,QAAQ;oBACX,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,MAAM;gBACR,KAAK,QAAQ;oBACX,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,MAAM;gBACR,KAAK,UAAU;oBACb,OAAO,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3D,MAAM;gBACR,KAAK,MAAM;oBACT,OAAO,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvD,MAAM;gBACR,KAAK,MAAM;oBACT,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;oBAC5C,MAAM;gBACR;oBACE,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,CAAC;YACD,MAAM;QACR,KAAK,MAAM;YACT,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,UAAU;oBACb,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvD,MAAM;gBACR,KAAK,UAAU;oBACb,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvD,MAAM;gBACR,KAAK,YAAY;oBACf,OAAO,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,MAAM;gBACR,KAAK,MAAM;oBACT,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;oBAC1C,MAAM;gBACR;oBACE,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAC9C,CAAC;YACD,MAAM;QACR,KAAK,KAAK;YACR,OAAO,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACxF,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACzE,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM;QACR,KAAK,UAAU;YACb,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM;QACR,KAAK,UAAU;YACb,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM;QACR,KAAK,YAAY;YACf,OAAO,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM;QACR,KAAK,MAAM;YACT,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM;QACR;YACE,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC3B,MAAM;IACV,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAa;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,WAAmB;IACjE,MAAM,UAAU,GACd,EAGD,CAAC,UAAU,CAAC;IACb,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE,CAAC;QACrC,OAAO,MAAM,UAAU,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAmB;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,yBAAyB,EAAE,CAAC;IAErF,OAAO,IAAI,UAAU,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE;YACJ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3E;QACD,WAAW;QACX,SAAS,EAAE,aAAa;KACzB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAyB,EAAE,KAAa;IAC5D,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,OAAe;IACjC,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,GAAW,EACX,OAAmB;IAEnB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACvF,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/E,IAAI,OAAO,CAAC,aAAa;QAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,WAA+B,EAAE,OAAmB;IAC3E,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE;QAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjC,WAAW;QACX,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,UAAU,CAAC,QAAQ;YACjB,IAAI,OAAO,CAAC,IAAI;gBAAE,OAAO;YACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,YAAY,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,WAAW,YAAY,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,UAAU,WAAW,CAChI,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,WAA+B,EAAE,OAAmB;IACjF,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE;QACpD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,CAAC;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,WAA+B,EAAE,OAAmB;IACjF,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnD,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,WAA+B,EAAE,OAAmB;IACnF,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE;QACnD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1D,CAAC,CAAC;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,WAA+B,EAAE,OAAmB;IAC/E,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE;QACvD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC,CAAC;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAA6B,EAAE,OAAmB;IAC/E,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE;QAClD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1D,CAAC,CAAC;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAA6B,EAAE,OAAmB;IAC/E,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACpD,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,SAA6B,EAAE,OAAmB;IAChF,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpF,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAmB;IAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjF,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,OAAmB;IAC9C,WAAW,CACT;QACE,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE;YACJ,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;YAC9C,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;YACxD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;YAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI;SAC7C;QACD,MAAM,EAAE;YACN,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;YACpC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK;YAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;YACnC,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI;YAC9C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;SACrC;KACF,EACD,OAAO,CAAC,IAAI,CACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9D,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzB,OAAO;QACT,KAAK,eAAe;YAClB,MAAM,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC3C,OAAO;QACT,KAAK,eAAe;YAClB,MAAM,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,OAAO;QACT,KAAK,eAAe;YAClB,MAAM,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,OAAO;QACT,KAAK,iBAAiB;YACpB,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,OAAO;QACT,KAAK,aAAa;YAChB,MAAM,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO;QACT,KAAK,eAAe;YAClB,MAAM,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO;QACT,KAAK,eAAe;YAClB,MAAM,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO;QACT,KAAK,iBAAiB;YACpB,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO;QACT,KAAK,YAAY;YACf,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO;QACT,KAAK,aAAa;YAChB,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO;IACX,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CACf;YACE,KAAK,EAAE;gBACL,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB;SACF,EACD,IAAI,EACJ,CAAC,CACF,IAAI,CACN,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApiClient } from "../core/api/client.js";
|
|
2
|
+
import { cancelUpload } from "../core/api/uploads.js";
|
|
3
|
+
import { readEnv } from "../core/config/env.js";
|
|
4
|
+
import { CliError } from "../util/errors.js";
|
|
5
|
+
export async function runCancel(args) {
|
|
6
|
+
const uploadId = args[0];
|
|
7
|
+
if (!uploadId) {
|
|
8
|
+
throw new CliError("Usage: floe cancel <uploadId>");
|
|
9
|
+
}
|
|
10
|
+
const client = new ApiClient(readEnv());
|
|
11
|
+
const result = await cancelUpload(client, uploadId);
|
|
12
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { readEnv } from "../core/config/env.js";
|
|
4
|
+
import { getLegacyUploadScriptPath } from "../core/config/paths.js";
|
|
5
|
+
export async function runDoctor() {
|
|
6
|
+
const env = readEnv();
|
|
7
|
+
const checks = {
|
|
8
|
+
apiBase: env.apiBase,
|
|
9
|
+
authConfigured: Boolean(env.apiKey || env.bearerToken || env.authUser || env.walletAddress || env.ownerAddress),
|
|
10
|
+
legacyUploadScript: await isExecutable(getLegacyUploadScriptPath()),
|
|
11
|
+
ffmpeg: Boolean(process.env.PATH),
|
|
12
|
+
ffprobe: Boolean(process.env.PATH),
|
|
13
|
+
};
|
|
14
|
+
process.stdout.write(`${JSON.stringify(checks, null, 2)}\n`);
|
|
15
|
+
}
|
|
16
|
+
async function isExecutable(filePath) {
|
|
17
|
+
try {
|
|
18
|
+
await access(filePath, constants.X_OK);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApiClient } from "../core/api/client.js";
|
|
2
|
+
import { getUploadStatus } from "../core/api/uploads.js";
|
|
3
|
+
import { readEnv } from "../core/config/env.js";
|
|
4
|
+
import { CliError } from "../util/errors.js";
|
|
5
|
+
export async function runStatus(args) {
|
|
6
|
+
const uploadId = args[0];
|
|
7
|
+
if (!uploadId) {
|
|
8
|
+
throw new CliError("Usage: floe status <uploadId>");
|
|
9
|
+
}
|
|
10
|
+
const client = new ApiClient(readEnv());
|
|
11
|
+
const status = await getUploadStatus(client, uploadId);
|
|
12
|
+
process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { CliError } from "../util/errors.js";
|
|
5
|
+
import { getLegacyUploadScriptPath, getRepoRoot } from "../core/config/paths.js";
|
|
6
|
+
export async function runUpload(args) {
|
|
7
|
+
const scriptPath = getLegacyUploadScriptPath();
|
|
8
|
+
await access(scriptPath, constants.X_OK);
|
|
9
|
+
await new Promise((resolve, reject) => {
|
|
10
|
+
const child = spawn(scriptPath, args, {
|
|
11
|
+
cwd: getRepoRoot(),
|
|
12
|
+
stdio: "inherit",
|
|
13
|
+
env: process.env,
|
|
14
|
+
});
|
|
15
|
+
child.on("error", (error) => reject(error));
|
|
16
|
+
child.on("exit", (code, signal) => {
|
|
17
|
+
if (signal) {
|
|
18
|
+
reject(new CliError(`upload interrupted by ${signal}`, 1));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if ((code ?? 1) !== 0) {
|
|
22
|
+
reject(new CliError(`upload command exited with code ${code ?? 1}`, code ?? 1));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CliError } from "../../util/errors.js";
|
|
2
|
+
import { buildAuthHeaders } from "../auth/headers.js";
|
|
3
|
+
export class ApiClient {
|
|
4
|
+
env;
|
|
5
|
+
constructor(env) {
|
|
6
|
+
this.env = env;
|
|
7
|
+
}
|
|
8
|
+
async request(pathname, init) {
|
|
9
|
+
const url = new URL(pathname, withTrailingSlash(this.env.apiBase));
|
|
10
|
+
const headers = buildAuthHeaders(this.env);
|
|
11
|
+
if (init?.headers) {
|
|
12
|
+
const extra = new Headers(init.headers);
|
|
13
|
+
extra.forEach((value, key) => headers.set(key, value));
|
|
14
|
+
}
|
|
15
|
+
const response = await fetch(url, {
|
|
16
|
+
...init,
|
|
17
|
+
headers,
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
const payload = (await safeJson(response));
|
|
21
|
+
const code = payload?.error?.code ? ` ${payload.error.code}` : "";
|
|
22
|
+
const message = payload?.error?.message ?? response.statusText;
|
|
23
|
+
throw new CliError(`HTTP ${response.status}${code} ${message}`, 1);
|
|
24
|
+
}
|
|
25
|
+
return (await response.json());
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function withTrailingSlash(value) {
|
|
29
|
+
return value.endsWith("/") ? value : `${value}/`;
|
|
30
|
+
}
|
|
31
|
+
async function safeJson(response) {
|
|
32
|
+
try {
|
|
33
|
+
return await response.json();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function getUploadStatus(client, uploadId) {
|
|
2
|
+
return client.request(`${uploadId}/status`, {
|
|
3
|
+
method: "GET",
|
|
4
|
+
});
|
|
5
|
+
}
|
|
6
|
+
export async function cancelUpload(client, uploadId) {
|
|
7
|
+
return client.request(`${uploadId}`, {
|
|
8
|
+
method: "DELETE",
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function buildAuthHeaders(env) {
|
|
2
|
+
const headers = new Headers();
|
|
3
|
+
if (env.apiKey)
|
|
4
|
+
headers.set("x-api-key", env.apiKey);
|
|
5
|
+
if (env.bearerToken)
|
|
6
|
+
headers.set("authorization", `Bearer ${env.bearerToken}`);
|
|
7
|
+
if (env.authUser)
|
|
8
|
+
headers.set("x-auth-user", env.authUser);
|
|
9
|
+
if (env.walletAddress)
|
|
10
|
+
headers.set("x-wallet-address", env.walletAddress);
|
|
11
|
+
if (env.ownerAddress)
|
|
12
|
+
headers.set("x-owner-address", env.ownerAddress);
|
|
13
|
+
return headers;
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function readEnv() {
|
|
2
|
+
return {
|
|
3
|
+
apiBase: process.env.FLOE_API_BASE ?? "http://localhost:3001/v1/uploads",
|
|
4
|
+
apiKey: process.env.FLOE_API_KEY ?? "",
|
|
5
|
+
bearerToken: process.env.FLOE_BEARER_TOKEN ?? "",
|
|
6
|
+
authUser: process.env.FLOE_AUTH_USER ?? "",
|
|
7
|
+
walletAddress: process.env.FLOE_WALLET_ADDRESS ?? "",
|
|
8
|
+
ownerAddress: process.env.FLOE_OWNER_ADDRESS ?? "",
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = path.dirname(__filename);
|
|
5
|
+
const repoRoot = path.resolve(__dirname, "../../../../../");
|
|
6
|
+
export function getRepoRoot() {
|
|
7
|
+
return repoRoot;
|
|
8
|
+
}
|
|
9
|
+
export function getLegacyUploadScriptPath() {
|
|
10
|
+
return path.join(repoRoot, "scripts", "floe.sh");
|
|
11
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runUpload } from "./commands/upload.js";
|
|
3
|
+
import { runStatus } from "./commands/status.js";
|
|
4
|
+
import { runCancel } from "./commands/cancel.js";
|
|
5
|
+
import { runDoctor } from "./commands/doctor.js";
|
|
6
|
+
import { CliError } from "./util/errors.js";
|
|
7
|
+
const COMMANDS = new Set(["upload", "status", "cancel", "doctor", "help", "--help", "-h"]);
|
|
8
|
+
async function main() {
|
|
9
|
+
const argv = process.argv.slice(2);
|
|
10
|
+
const first = argv[0];
|
|
11
|
+
if (!first || first === "help" || first === "--help" || first === "-h") {
|
|
12
|
+
printHelp();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!COMMANDS.has(first)) {
|
|
16
|
+
await runUpload(argv);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
switch (first) {
|
|
20
|
+
case "upload":
|
|
21
|
+
await runUpload(argv.slice(1));
|
|
22
|
+
return;
|
|
23
|
+
case "status":
|
|
24
|
+
await runStatus(argv.slice(1));
|
|
25
|
+
return;
|
|
26
|
+
case "cancel":
|
|
27
|
+
await runCancel(argv.slice(1));
|
|
28
|
+
return;
|
|
29
|
+
case "doctor":
|
|
30
|
+
await runDoctor();
|
|
31
|
+
return;
|
|
32
|
+
default:
|
|
33
|
+
printHelp();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function printHelp() {
|
|
37
|
+
process.stdout.write(`Floe CLI\n\nCommands:\n floe upload <file> [options]\n floe status <uploadId>\n floe cancel <uploadId>\n floe doctor\n\nWhen no explicit command is provided, arguments are treated as upload arguments for compatibility.\n`);
|
|
38
|
+
}
|
|
39
|
+
main().catch((error) => {
|
|
40
|
+
if (error instanceof CliError) {
|
|
41
|
+
process.stderr.write(`${error.message}\n`);
|
|
42
|
+
process.exit(error.exitCode);
|
|
43
|
+
}
|
|
44
|
+
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
45
|
+
process.stderr.write(`${message}\n`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@floehq/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command-line interface for the Floe API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"floe": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=20.0.0"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@floehq/sdk": "^0.1.0"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
}
|
|
24
|
+
}
|