stow-cli 1.0.3 → 2.0.1
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/dist/{app-JPUDM4LJ.js → app-2A2CFVBC.js} +1 -1
- package/dist/app-2H4TLSN7.js +239 -0
- package/dist/app-DTW2LNXW.js +249 -0
- package/dist/app-HYCPA7GA.js +239 -0
- package/dist/app-IZGSPZPX.js +239 -0
- package/dist/app-UGUM75MC.js +239 -0
- package/dist/app-XPOEAZJC.js +239 -0
- package/dist/app-YITP5APT.js +233 -0
- package/dist/{backfill-QZTVNJZM.js → backfill-G57M2BRA.js} +3 -3
- package/dist/{buckets-JQKZ3PH3.js → buckets-NXIVHPW5.js} +2 -2
- package/dist/chunk-2AORPTQB.js +23 -0
- package/dist/chunk-5LU25QZK.js +17 -0
- package/dist/chunk-FEMMZ4YZ.js +125 -0
- package/dist/chunk-LYCXXF2T.js +79 -0
- package/dist/chunk-MHRMBH4Y.js +36 -0
- package/dist/{chunk-WAQSCS57.js → chunk-QF7PVPWQ.js} +1 -1
- package/dist/chunk-R5CCBTXZ.js +79 -0
- package/dist/chunk-TOADDO2F.js +23 -0
- package/dist/chunk-YRHPOFJT.js +115 -0
- package/dist/chunk-ZDVARBCV.js +43 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +43 -43
- package/dist/delete-AECEJX5W.js +18 -0
- package/dist/delete-GEX3O7YS.js +14 -0
- package/dist/delete-KYOZEODD.js +18 -0
- package/dist/delete-OLOAJRRO.js +18 -0
- package/dist/delete-V4EY4UBG.js +18 -0
- package/dist/{drops-QXGTYB5E.js → drops-RD55IDZ4.js} +2 -2
- package/dist/{files-OCYICIAM.js → files-E662TXUP.js} +3 -3
- package/dist/{health-YMZTZUFX.js → health-6LWM7KAT.js} +3 -3
- package/dist/{jobs-6JY4SVV5.js → jobs-CLXYKZ3B.js} +4 -4
- package/dist/{jobs-OKKGKSIH.js → jobs-K3LTNETU.js} +5 -5
- package/dist/list-7A3VZA2T.js +97 -0
- package/dist/list-DHXVIMRI.js +94 -0
- package/dist/list-DJEAKEZJ.js +106 -0
- package/dist/list-DQRU6QHO.js +106 -0
- package/dist/list-I5A6LTHX.js +106 -0
- package/dist/list-KEQPJY7I.js +109 -0
- package/dist/list-Z3MPT6MI.js +109 -0
- package/dist/{maintenance-EZUHQK5Q.js → maintenance-7LOAGG6J.js} +6 -6
- package/dist/open-2YNHG3MA.js +15 -0
- package/dist/open-F73Q2OHD.js +15 -0
- package/dist/{profiles-GWLBEEIT.js → profiles-C6SCFXS6.js} +2 -2
- package/dist/{queues-EQX7EJZF.js → queues-2GJAMMNF.js} +4 -4
- package/dist/{search-2PXM6XQ6.js → search-DV4VV62L.js} +2 -2
- package/dist/{tags-LSVEIIUF.js → tags-URHK2YH5.js} +2 -2
- package/dist/upload-3NS5O3UL.js +120 -0
- package/dist/upload-5RIDB2C5.js +92 -0
- package/dist/upload-B2PGW3AN.js +125 -0
- package/dist/{upload-ESYKBYHA.js → upload-DQDBDIDI.js} +1 -1
- package/dist/upload-FGNGNPC3.js +93 -0
- package/dist/upload-HKUPWTK2.js +173 -0
- package/dist/upload-JDVSJVWK.js +173 -0
- package/dist/upload-K4H7ZVRW.js +98 -0
- package/dist/upload-MI6VFGTC.js +92 -0
- package/dist/whoami-2SLCNVKP.js +27 -0
- package/dist/whoami-5IYRZKWS.js +28 -0
- package/dist/{whoami-4UYMSRVP.js → whoami-754O5IML.js} +1 -1
- package/dist/whoami-DOMX3Z5K.js +28 -0
- package/dist/whoami-IPMCUEUH.js +27 -0
- package/dist/whoami-JSQA2IDN.js +27 -0
- package/dist/whoami-RKH5HHPR.js +27 -0
- package/package.json +1 -1
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
} from "./chunk-ELSDWMEB.js";
|
|
6
6
|
import {
|
|
7
7
|
createStow
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5LU25QZK.js";
|
|
9
9
|
import {
|
|
10
10
|
getApiKey,
|
|
11
11
|
getBaseUrl
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TOADDO2F.js";
|
|
13
13
|
|
|
14
14
|
// src/commands/files.ts
|
|
15
15
|
async function listFiles(bucket, options) {
|
|
@@ -131,7 +131,7 @@ async function listMissing(bucket, type, options) {
|
|
|
131
131
|
missing: type,
|
|
132
132
|
...parsedLimit && Number.isFinite(parsedLimit) && parsedLimit > 0 ? { limit: String(parsedLimit) } : {}
|
|
133
133
|
});
|
|
134
|
-
const res = await fetch(`${baseUrl}/
|
|
134
|
+
const res = await fetch(`${baseUrl}/files?${params}`, {
|
|
135
135
|
headers: { "x-api-key": apiKey }
|
|
136
136
|
});
|
|
137
137
|
if (!res.ok) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
adminRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QF7PVPWQ.js";
|
|
4
4
|
import {
|
|
5
5
|
formatTable,
|
|
6
6
|
outputJson
|
|
7
7
|
} from "./chunk-ELSDWMEB.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-TOADDO2F.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/admin/health.ts
|
|
11
11
|
async function health(options) {
|
|
12
12
|
const result = await adminRequest({
|
|
13
13
|
method: "GET",
|
|
14
|
-
path: "/
|
|
14
|
+
path: "/health"
|
|
15
15
|
});
|
|
16
16
|
if (options.json) {
|
|
17
17
|
outputJson(result);
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
getApiKey,
|
|
7
7
|
getBaseUrl
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TOADDO2F.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/jobs.ts
|
|
11
11
|
async function bucketRequest(opts) {
|
|
@@ -41,7 +41,7 @@ async function listJobs(bucketId, options) {
|
|
|
41
41
|
params.set("limit", options.limit);
|
|
42
42
|
}
|
|
43
43
|
const qs = params.toString();
|
|
44
|
-
const path = `/
|
|
44
|
+
const path = `/buckets/${bucketId}/jobs${qs ? `?${qs}` : ""}`;
|
|
45
45
|
const result = await bucketRequest({
|
|
46
46
|
method: "GET",
|
|
47
47
|
path
|
|
@@ -69,7 +69,7 @@ async function listJobs(bucketId, options) {
|
|
|
69
69
|
async function retryJob(jobId, options) {
|
|
70
70
|
const result = await bucketRequest({
|
|
71
71
|
method: "POST",
|
|
72
|
-
path: `/
|
|
72
|
+
path: `/buckets/${options.bucket}/jobs/${jobId}/retry`,
|
|
73
73
|
body: { queue: options.queue }
|
|
74
74
|
});
|
|
75
75
|
if (result.retried) {
|
|
@@ -79,7 +79,7 @@ async function retryJob(jobId, options) {
|
|
|
79
79
|
async function deleteJob(jobId, options) {
|
|
80
80
|
const result = await bucketRequest({
|
|
81
81
|
method: "DELETE",
|
|
82
|
-
path: `/
|
|
82
|
+
path: `/buckets/${options.bucket}/jobs/${jobId}?queue=${encodeURIComponent(options.queue)}`
|
|
83
83
|
});
|
|
84
84
|
if (result.deleted) {
|
|
85
85
|
console.log(`Job ${jobId} removed.`);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
adminRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QF7PVPWQ.js";
|
|
4
4
|
import {
|
|
5
5
|
formatTable,
|
|
6
6
|
outputJson
|
|
7
7
|
} from "./chunk-ELSDWMEB.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-TOADDO2F.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/admin/jobs.ts
|
|
11
11
|
function formatTimestamp(ts) {
|
|
@@ -31,7 +31,7 @@ async function listAdminJobs(options) {
|
|
|
31
31
|
const qs = params.toString();
|
|
32
32
|
const result = await adminRequest({
|
|
33
33
|
method: "GET",
|
|
34
|
-
path: `/
|
|
34
|
+
path: `/admin/jobs${qs ? `?${qs}` : ""}`
|
|
35
35
|
});
|
|
36
36
|
if (options.json) {
|
|
37
37
|
outputJson(result.jobs);
|
|
@@ -60,7 +60,7 @@ async function listAdminJobs(options) {
|
|
|
60
60
|
async function retryAdminJob(jobId, options) {
|
|
61
61
|
const result = await adminRequest({
|
|
62
62
|
method: "POST",
|
|
63
|
-
path: `/
|
|
63
|
+
path: `/admin/jobs/${jobId}/retry`,
|
|
64
64
|
body: { queue: options.queue }
|
|
65
65
|
});
|
|
66
66
|
if (result.retried) {
|
|
@@ -70,7 +70,7 @@ async function retryAdminJob(jobId, options) {
|
|
|
70
70
|
async function deleteAdminJob(jobId, options) {
|
|
71
71
|
const result = await adminRequest({
|
|
72
72
|
method: "DELETE",
|
|
73
|
-
path: `/
|
|
73
|
+
path: `/admin/jobs/${jobId}?queue=${encodeURIComponent(options.queue)}`
|
|
74
74
|
});
|
|
75
75
|
if (result.deleted) {
|
|
76
76
|
console.log(`Job ${jobId} removed.`);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createStow
|
|
3
|
+
} from "./chunk-JYOMHKFS.js";
|
|
4
|
+
import {
|
|
5
|
+
formatBytes,
|
|
6
|
+
formatTable,
|
|
7
|
+
usageBar
|
|
8
|
+
} from "./chunk-ZDVARBCV.js";
|
|
9
|
+
import "./chunk-OZ7QQTIZ.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/list.ts
|
|
12
|
+
async function listBuckets() {
|
|
13
|
+
const stow = createStow();
|
|
14
|
+
const data = await stow.listBuckets();
|
|
15
|
+
if (data.buckets.length === 0) {
|
|
16
|
+
console.log("No buckets yet. Create one with: stow buckets create <name>");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const rows = data.buckets.map((b) => [
|
|
20
|
+
b.name,
|
|
21
|
+
b.isPublic ? "public" : "private",
|
|
22
|
+
`${b.fileCount ?? 0} files`,
|
|
23
|
+
formatBytes(b.usageBytes ?? 0),
|
|
24
|
+
b.description || ""
|
|
25
|
+
]);
|
|
26
|
+
console.log(
|
|
27
|
+
formatTable(["Name", "Access", "Files", "Size", "Description"], rows)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
async function createBucket(name, options) {
|
|
31
|
+
const stow = createStow();
|
|
32
|
+
const bucket = await stow.createBucket({
|
|
33
|
+
name,
|
|
34
|
+
...options.description ? { description: options.description } : {},
|
|
35
|
+
...options.public ? { isPublic: true } : {}
|
|
36
|
+
});
|
|
37
|
+
console.log(`Created bucket: ${bucket.name}`);
|
|
38
|
+
}
|
|
39
|
+
async function renameBucket(name, newName, options) {
|
|
40
|
+
if (!options.yes) {
|
|
41
|
+
console.error(
|
|
42
|
+
"Warning: Renaming a bucket will break any existing URLs using the old name."
|
|
43
|
+
);
|
|
44
|
+
console.error("Use --yes to skip this warning.");
|
|
45
|
+
}
|
|
46
|
+
const stow = createStow();
|
|
47
|
+
const bucket = await stow.renameBucket(name, newName);
|
|
48
|
+
console.log(`Renamed bucket: ${name} \u2192 ${bucket.name}`);
|
|
49
|
+
}
|
|
50
|
+
async function listFiles(bucket, options) {
|
|
51
|
+
const stow = createStow();
|
|
52
|
+
const parsedLimit = options.limit ? Number.parseInt(options.limit, 10) : null;
|
|
53
|
+
const data = await stow.listFiles({
|
|
54
|
+
bucket,
|
|
55
|
+
...options.search ? { prefix: options.search } : {},
|
|
56
|
+
...parsedLimit && Number.isFinite(parsedLimit) && parsedLimit > 0 ? { limit: parsedLimit } : {}
|
|
57
|
+
});
|
|
58
|
+
if (data.files.length === 0) {
|
|
59
|
+
console.log(`No files in bucket '${bucket}'.`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const rows = data.files.map((f) => [
|
|
63
|
+
f.key,
|
|
64
|
+
formatBytes(f.size),
|
|
65
|
+
f.lastModified.split("T")[0]
|
|
66
|
+
]);
|
|
67
|
+
console.log(formatTable(["Key", "Size", "Modified"], rows));
|
|
68
|
+
if (data.nextCursor) {
|
|
69
|
+
console.log("\n(more files available \u2014 use --limit to see more)");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function listDrops() {
|
|
73
|
+
const stow = createStow();
|
|
74
|
+
const data = await stow.listDrops();
|
|
75
|
+
if (data.drops.length === 0) {
|
|
76
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const rows = data.drops.map((d) => [
|
|
80
|
+
d.filename,
|
|
81
|
+
formatBytes(Number(d.size)),
|
|
82
|
+
d.contentType,
|
|
83
|
+
d.url
|
|
84
|
+
]);
|
|
85
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
86
|
+
console.log(
|
|
87
|
+
`
|
|
88
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
createBucket,
|
|
93
|
+
listBuckets,
|
|
94
|
+
listDrops,
|
|
95
|
+
listFiles,
|
|
96
|
+
renameBucket
|
|
97
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatBytes,
|
|
3
|
+
formatTable,
|
|
4
|
+
usageBar
|
|
5
|
+
} from "./chunk-MHRMBH4Y.js";
|
|
6
|
+
import {
|
|
7
|
+
apiRequest
|
|
8
|
+
} from "./chunk-YRHPOFJT.js";
|
|
9
|
+
import "./chunk-2AORPTQB.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/list.ts
|
|
12
|
+
async function listBuckets() {
|
|
13
|
+
const data = await apiRequest("/api/buckets");
|
|
14
|
+
if (data.buckets.length === 0) {
|
|
15
|
+
console.log("No buckets yet. Create one with: stow buckets create <name>");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rows = data.buckets.map((b) => [
|
|
19
|
+
b.name,
|
|
20
|
+
b.isPublic ? "public" : "private",
|
|
21
|
+
`${b.fileCount} files`,
|
|
22
|
+
formatBytes(b.usageBytes),
|
|
23
|
+
b.description || ""
|
|
24
|
+
]);
|
|
25
|
+
console.log(formatTable(["Name", "Access", "Files", "Size", "Description"], rows));
|
|
26
|
+
}
|
|
27
|
+
async function createBucket(name, options) {
|
|
28
|
+
const body = { name };
|
|
29
|
+
if (options.description) body.description = options.description;
|
|
30
|
+
if (options.public) body.isPublic = true;
|
|
31
|
+
const data = await apiRequest("/api/buckets", {
|
|
32
|
+
method: "POST",
|
|
33
|
+
body: JSON.stringify(body)
|
|
34
|
+
});
|
|
35
|
+
console.log(`Created bucket: ${data.bucket.name}`);
|
|
36
|
+
}
|
|
37
|
+
async function renameBucket(name, newName, options) {
|
|
38
|
+
if (!options.yes) {
|
|
39
|
+
console.error("Warning: Renaming a bucket will break any existing URLs using the old name.");
|
|
40
|
+
console.error("Use --yes to skip this warning.");
|
|
41
|
+
}
|
|
42
|
+
const data = await apiRequest(`/api/buckets/_?bucket=${encodeURIComponent(name)}`, {
|
|
43
|
+
method: "PATCH",
|
|
44
|
+
body: JSON.stringify({ name: newName })
|
|
45
|
+
});
|
|
46
|
+
console.log(`Renamed bucket: ${name} \u2192 ${data.bucket.name}`);
|
|
47
|
+
}
|
|
48
|
+
async function listFiles(bucket, options) {
|
|
49
|
+
const params = new URLSearchParams({ bucket });
|
|
50
|
+
if (options.search) params.set("prefix", options.search);
|
|
51
|
+
if (options.limit) params.set("limit", options.limit);
|
|
52
|
+
const data = await apiRequest(
|
|
53
|
+
`/api/files?${params}`
|
|
54
|
+
);
|
|
55
|
+
if (data.files.length === 0) {
|
|
56
|
+
console.log(`No files in bucket '${bucket}'.`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const rows = data.files.map((f) => [
|
|
60
|
+
f.key,
|
|
61
|
+
formatBytes(f.size),
|
|
62
|
+
f.lastModified.split("T")[0]
|
|
63
|
+
]);
|
|
64
|
+
console.log(formatTable(["Key", "Size", "Modified"], rows));
|
|
65
|
+
if (data.nextCursor) {
|
|
66
|
+
console.log(`
|
|
67
|
+
(more files available \u2014 use --limit to see more)`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function listDrops() {
|
|
71
|
+
const data = await apiRequest("/api/drops");
|
|
72
|
+
if (data.drops.length === 0) {
|
|
73
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const rows = data.drops.map((d) => [
|
|
77
|
+
d.filename,
|
|
78
|
+
formatBytes(Number(d.size)),
|
|
79
|
+
d.contentType,
|
|
80
|
+
d.url
|
|
81
|
+
]);
|
|
82
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
83
|
+
console.log(
|
|
84
|
+
`
|
|
85
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
createBucket,
|
|
90
|
+
listBuckets,
|
|
91
|
+
listDrops,
|
|
92
|
+
listFiles,
|
|
93
|
+
renameBucket
|
|
94
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatBytes,
|
|
3
|
+
formatTable,
|
|
4
|
+
usageBar
|
|
5
|
+
} from "./chunk-ZDVARBCV.js";
|
|
6
|
+
import {
|
|
7
|
+
apiRequest
|
|
8
|
+
} from "./chunk-FEMMZ4YZ.js";
|
|
9
|
+
import "./chunk-2AORPTQB.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/list.ts
|
|
12
|
+
async function listBuckets() {
|
|
13
|
+
const data = await apiRequest("/api/buckets");
|
|
14
|
+
if (data.buckets.length === 0) {
|
|
15
|
+
console.log("No buckets yet. Create one with: stow buckets create <name>");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rows = data.buckets.map((b) => [
|
|
19
|
+
b.name,
|
|
20
|
+
b.isPublic ? "public" : "private",
|
|
21
|
+
`${b.fileCount} files`,
|
|
22
|
+
formatBytes(b.usageBytes),
|
|
23
|
+
b.description || ""
|
|
24
|
+
]);
|
|
25
|
+
console.log(
|
|
26
|
+
formatTable(["Name", "Access", "Files", "Size", "Description"], rows)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
async function createBucket(name, options) {
|
|
30
|
+
const body = { name };
|
|
31
|
+
if (options.description) {
|
|
32
|
+
body.description = options.description;
|
|
33
|
+
}
|
|
34
|
+
if (options.public) {
|
|
35
|
+
body.isPublic = true;
|
|
36
|
+
}
|
|
37
|
+
const data = await apiRequest("/api/buckets", {
|
|
38
|
+
method: "POST",
|
|
39
|
+
body: JSON.stringify(body)
|
|
40
|
+
});
|
|
41
|
+
console.log(`Created bucket: ${data.bucket.name}`);
|
|
42
|
+
}
|
|
43
|
+
async function renameBucket(name, newName, options) {
|
|
44
|
+
if (!options.yes) {
|
|
45
|
+
console.error(
|
|
46
|
+
"Warning: Renaming a bucket will break any existing URLs using the old name."
|
|
47
|
+
);
|
|
48
|
+
console.error("Use --yes to skip this warning.");
|
|
49
|
+
}
|
|
50
|
+
const data = await apiRequest(
|
|
51
|
+
`/api/buckets/_?bucket=${encodeURIComponent(name)}`,
|
|
52
|
+
{
|
|
53
|
+
method: "PATCH",
|
|
54
|
+
body: JSON.stringify({ name: newName })
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
console.log(`Renamed bucket: ${name} \u2192 ${data.bucket.name}`);
|
|
58
|
+
}
|
|
59
|
+
async function listFiles(bucket, options) {
|
|
60
|
+
const params = new URLSearchParams({ bucket });
|
|
61
|
+
if (options.search) {
|
|
62
|
+
params.set("prefix", options.search);
|
|
63
|
+
}
|
|
64
|
+
if (options.limit) {
|
|
65
|
+
params.set("limit", options.limit);
|
|
66
|
+
}
|
|
67
|
+
const data = await apiRequest(`/api/files?${params}`);
|
|
68
|
+
if (data.files.length === 0) {
|
|
69
|
+
console.log(`No files in bucket '${bucket}'.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rows = data.files.map((f) => [
|
|
73
|
+
f.key,
|
|
74
|
+
formatBytes(f.size),
|
|
75
|
+
f.lastModified.split("T")[0]
|
|
76
|
+
]);
|
|
77
|
+
console.log(formatTable(["Key", "Size", "Modified"], rows));
|
|
78
|
+
if (data.nextCursor) {
|
|
79
|
+
console.log("\n(more files available \u2014 use --limit to see more)");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function listDrops() {
|
|
83
|
+
const data = await apiRequest("/api/drops");
|
|
84
|
+
if (data.drops.length === 0) {
|
|
85
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const rows = data.drops.map((d) => [
|
|
89
|
+
d.filename,
|
|
90
|
+
formatBytes(Number(d.size)),
|
|
91
|
+
d.contentType,
|
|
92
|
+
d.url
|
|
93
|
+
]);
|
|
94
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
95
|
+
console.log(
|
|
96
|
+
`
|
|
97
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
createBucket,
|
|
102
|
+
listBuckets,
|
|
103
|
+
listDrops,
|
|
104
|
+
listFiles,
|
|
105
|
+
renameBucket
|
|
106
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatBytes,
|
|
3
|
+
formatTable,
|
|
4
|
+
usageBar
|
|
5
|
+
} from "./chunk-ZDVARBCV.js";
|
|
6
|
+
import {
|
|
7
|
+
apiRequest
|
|
8
|
+
} from "./chunk-R5CCBTXZ.js";
|
|
9
|
+
import "./chunk-2AORPTQB.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/list.ts
|
|
12
|
+
async function listBuckets() {
|
|
13
|
+
const data = await apiRequest("/api/buckets");
|
|
14
|
+
if (data.buckets.length === 0) {
|
|
15
|
+
console.log("No buckets yet. Create one with: stow buckets create <name>");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rows = data.buckets.map((b) => [
|
|
19
|
+
b.name,
|
|
20
|
+
b.isPublic ? "public" : "private",
|
|
21
|
+
`${b.fileCount} files`,
|
|
22
|
+
formatBytes(b.usageBytes),
|
|
23
|
+
b.description || ""
|
|
24
|
+
]);
|
|
25
|
+
console.log(
|
|
26
|
+
formatTable(["Name", "Access", "Files", "Size", "Description"], rows)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
async function createBucket(name, options) {
|
|
30
|
+
const body = { name };
|
|
31
|
+
if (options.description) {
|
|
32
|
+
body.description = options.description;
|
|
33
|
+
}
|
|
34
|
+
if (options.public) {
|
|
35
|
+
body.isPublic = true;
|
|
36
|
+
}
|
|
37
|
+
const data = await apiRequest("/api/buckets", {
|
|
38
|
+
method: "POST",
|
|
39
|
+
body: JSON.stringify(body)
|
|
40
|
+
});
|
|
41
|
+
console.log(`Created bucket: ${data.bucket.name}`);
|
|
42
|
+
}
|
|
43
|
+
async function renameBucket(name, newName, options) {
|
|
44
|
+
if (!options.yes) {
|
|
45
|
+
console.error(
|
|
46
|
+
"Warning: Renaming a bucket will break any existing URLs using the old name."
|
|
47
|
+
);
|
|
48
|
+
console.error("Use --yes to skip this warning.");
|
|
49
|
+
}
|
|
50
|
+
const data = await apiRequest(
|
|
51
|
+
`/api/buckets/_?bucket=${encodeURIComponent(name)}`,
|
|
52
|
+
{
|
|
53
|
+
method: "PATCH",
|
|
54
|
+
body: JSON.stringify({ name: newName })
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
console.log(`Renamed bucket: ${name} \u2192 ${data.bucket.name}`);
|
|
58
|
+
}
|
|
59
|
+
async function listFiles(bucket, options) {
|
|
60
|
+
const params = new URLSearchParams({ bucket });
|
|
61
|
+
if (options.search) {
|
|
62
|
+
params.set("prefix", options.search);
|
|
63
|
+
}
|
|
64
|
+
if (options.limit) {
|
|
65
|
+
params.set("limit", options.limit);
|
|
66
|
+
}
|
|
67
|
+
const data = await apiRequest(`/api/files?${params}`);
|
|
68
|
+
if (data.files.length === 0) {
|
|
69
|
+
console.log(`No files in bucket '${bucket}'.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rows = data.files.map((f) => [
|
|
73
|
+
f.key,
|
|
74
|
+
formatBytes(f.size),
|
|
75
|
+
f.lastModified.split("T")[0]
|
|
76
|
+
]);
|
|
77
|
+
console.log(formatTable(["Key", "Size", "Modified"], rows));
|
|
78
|
+
if (data.nextCursor) {
|
|
79
|
+
console.log("\n(more files available \u2014 use --limit to see more)");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function listDrops() {
|
|
83
|
+
const data = await apiRequest("/api/drops");
|
|
84
|
+
if (data.drops.length === 0) {
|
|
85
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const rows = data.drops.map((d) => [
|
|
89
|
+
d.filename,
|
|
90
|
+
formatBytes(Number(d.size)),
|
|
91
|
+
d.contentType,
|
|
92
|
+
d.url
|
|
93
|
+
]);
|
|
94
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
95
|
+
console.log(
|
|
96
|
+
`
|
|
97
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
createBucket,
|
|
102
|
+
listBuckets,
|
|
103
|
+
listDrops,
|
|
104
|
+
listFiles,
|
|
105
|
+
renameBucket
|
|
106
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatBytes,
|
|
3
|
+
formatTable,
|
|
4
|
+
usageBar
|
|
5
|
+
} from "./chunk-ZDVARBCV.js";
|
|
6
|
+
import {
|
|
7
|
+
apiRequest
|
|
8
|
+
} from "./chunk-LYCXXF2T.js";
|
|
9
|
+
import "./chunk-OZ7QQTIZ.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/list.ts
|
|
12
|
+
async function listBuckets() {
|
|
13
|
+
const data = await apiRequest("/api/buckets");
|
|
14
|
+
if (data.buckets.length === 0) {
|
|
15
|
+
console.log("No buckets yet. Create one with: stow buckets create <name>");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rows = data.buckets.map((b) => [
|
|
19
|
+
b.name,
|
|
20
|
+
b.isPublic ? "public" : "private",
|
|
21
|
+
`${b.fileCount} files`,
|
|
22
|
+
formatBytes(b.usageBytes),
|
|
23
|
+
b.description || ""
|
|
24
|
+
]);
|
|
25
|
+
console.log(
|
|
26
|
+
formatTable(["Name", "Access", "Files", "Size", "Description"], rows)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
async function createBucket(name, options) {
|
|
30
|
+
const body = { name };
|
|
31
|
+
if (options.description) {
|
|
32
|
+
body.description = options.description;
|
|
33
|
+
}
|
|
34
|
+
if (options.public) {
|
|
35
|
+
body.isPublic = true;
|
|
36
|
+
}
|
|
37
|
+
const data = await apiRequest("/api/buckets", {
|
|
38
|
+
method: "POST",
|
|
39
|
+
body: JSON.stringify(body)
|
|
40
|
+
});
|
|
41
|
+
console.log(`Created bucket: ${data.bucket.name}`);
|
|
42
|
+
}
|
|
43
|
+
async function renameBucket(name, newName, options) {
|
|
44
|
+
if (!options.yes) {
|
|
45
|
+
console.error(
|
|
46
|
+
"Warning: Renaming a bucket will break any existing URLs using the old name."
|
|
47
|
+
);
|
|
48
|
+
console.error("Use --yes to skip this warning.");
|
|
49
|
+
}
|
|
50
|
+
const data = await apiRequest(
|
|
51
|
+
`/api/buckets/_?bucket=${encodeURIComponent(name)}`,
|
|
52
|
+
{
|
|
53
|
+
method: "PATCH",
|
|
54
|
+
body: JSON.stringify({ name: newName })
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
console.log(`Renamed bucket: ${name} \u2192 ${data.bucket.name}`);
|
|
58
|
+
}
|
|
59
|
+
async function listFiles(bucket, options) {
|
|
60
|
+
const params = new URLSearchParams({ bucket });
|
|
61
|
+
if (options.search) {
|
|
62
|
+
params.set("prefix", options.search);
|
|
63
|
+
}
|
|
64
|
+
if (options.limit) {
|
|
65
|
+
params.set("limit", options.limit);
|
|
66
|
+
}
|
|
67
|
+
const data = await apiRequest(`/api/files?${params}`);
|
|
68
|
+
if (data.files.length === 0) {
|
|
69
|
+
console.log(`No files in bucket '${bucket}'.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rows = data.files.map((f) => [
|
|
73
|
+
f.key,
|
|
74
|
+
formatBytes(f.size),
|
|
75
|
+
f.lastModified.split("T")[0]
|
|
76
|
+
]);
|
|
77
|
+
console.log(formatTable(["Key", "Size", "Modified"], rows));
|
|
78
|
+
if (data.nextCursor) {
|
|
79
|
+
console.log("\n(more files available \u2014 use --limit to see more)");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function listDrops() {
|
|
83
|
+
const data = await apiRequest("/api/drops");
|
|
84
|
+
if (data.drops.length === 0) {
|
|
85
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const rows = data.drops.map((d) => [
|
|
89
|
+
d.filename,
|
|
90
|
+
formatBytes(Number(d.size)),
|
|
91
|
+
d.contentType,
|
|
92
|
+
d.url
|
|
93
|
+
]);
|
|
94
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
95
|
+
console.log(
|
|
96
|
+
`
|
|
97
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
createBucket,
|
|
102
|
+
listBuckets,
|
|
103
|
+
listDrops,
|
|
104
|
+
listFiles,
|
|
105
|
+
renameBucket
|
|
106
|
+
};
|