stow-cli 2.1.0 → 2.2.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/LICENSE +21 -0
- package/dist/app-Q6EW7VSM.js +249 -0
- package/dist/backfill-EVZT7RH6.js +67 -0
- package/dist/buckets-ZHP3LBLC.js +137 -0
- package/dist/chunk-3BLL5SQJ.js +27 -0
- package/dist/chunk-FZGOTXTE.js +45 -0
- package/dist/chunk-P2BKGBQE.js +136 -0
- package/dist/chunk-PLZFHPLC.js +52 -0
- package/dist/cli.js +77 -52
- package/dist/delete-YEXSMG4I.js +34 -0
- package/dist/describe-J4ZMUXK7.js +79 -0
- package/dist/drops-5VIEW3XZ.js +39 -0
- package/dist/files-UQODXWNT.js +206 -0
- package/dist/health-RICGWQGN.js +61 -0
- package/dist/jobs-PTV2W5PJ.js +102 -0
- package/dist/jobs-ZWSEXNFA.js +90 -0
- package/dist/maintenance-ZJW2ES4L.js +79 -0
- package/dist/profiles-CHBGKQOE.js +53 -0
- package/dist/queues-EZ2VZGXQ.js +61 -0
- package/dist/search-TRTPX2SQ.js +135 -0
- package/dist/tags-VH44BGQL.js +90 -0
- package/dist/upload-OS6Q6LW5.js +126 -0
- package/dist/whoami-TVRKBM74.js +28 -0
- package/package.json +12 -12
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/lib/validate-input.ts
|
|
2
|
+
import path from "path";
|
|
3
|
+
var InputValidationError = class extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "InputValidationError";
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
function validateInput(value, context) {
|
|
10
|
+
if (value.includes("../") || value.includes("..\\")) {
|
|
11
|
+
throw new InputValidationError(`${context}: path traversal not allowed`);
|
|
12
|
+
}
|
|
13
|
+
if (context !== "url" && value.includes("?")) {
|
|
14
|
+
throw new InputValidationError(
|
|
15
|
+
`${context}: embedded query parameters not allowed`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
if (/[\x00-\x08\x0b\x0c\x0e-\x1f]/.test(value)) {
|
|
19
|
+
throw new InputValidationError(
|
|
20
|
+
`${context}: control characters not allowed`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
if (/%25/.test(value)) {
|
|
24
|
+
throw new InputValidationError(
|
|
25
|
+
`${context}: double-encoded values not allowed`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
if (/%2[fF]/.test(value) || /%2[eE]/.test(value)) {
|
|
29
|
+
throw new InputValidationError(
|
|
30
|
+
`${context}: percent-encoded path characters not allowed`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (context !== "url" && value.includes("#")) {
|
|
34
|
+
throw new InputValidationError(
|
|
35
|
+
`${context}: embedded hash fragments not allowed`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function validateBucketName(name) {
|
|
41
|
+
return validateInput(name, "bucket name");
|
|
42
|
+
}
|
|
43
|
+
function validateFileKey(key) {
|
|
44
|
+
return validateInput(key, "file key");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
InputValidationError,
|
|
49
|
+
validateInput,
|
|
50
|
+
validateBucketName,
|
|
51
|
+
validateFileKey
|
|
52
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,15 @@ import {
|
|
|
3
3
|
CLI_DOCS,
|
|
4
4
|
renderCommandHelp
|
|
5
5
|
} from "./chunk-XJDK2CBE.js";
|
|
6
|
+
import {
|
|
7
|
+
InputValidationError
|
|
8
|
+
} from "./chunk-PLZFHPLC.js";
|
|
9
|
+
import {
|
|
10
|
+
outputError,
|
|
11
|
+
setForceHuman,
|
|
12
|
+
setGlobalFields,
|
|
13
|
+
setGlobalNdjson
|
|
14
|
+
} from "./chunk-P2BKGBQE.js";
|
|
6
15
|
|
|
7
16
|
// src/cli.ts
|
|
8
17
|
import { StowError } from "@howells/stow-server";
|
|
@@ -10,19 +19,35 @@ import { Command } from "commander";
|
|
|
10
19
|
var VERSION = "1.0.0";
|
|
11
20
|
function handleError(err) {
|
|
12
21
|
if (err instanceof StowError) {
|
|
13
|
-
|
|
22
|
+
outputError(err.message, err.code, { status: err.status });
|
|
23
|
+
} else if (err instanceof InputValidationError) {
|
|
24
|
+
outputError(err.message, "INPUT_VALIDATION");
|
|
14
25
|
} else if (err instanceof Error) {
|
|
15
|
-
|
|
26
|
+
outputError(err.message);
|
|
16
27
|
} else {
|
|
17
|
-
|
|
28
|
+
outputError(String(err));
|
|
18
29
|
}
|
|
19
|
-
process.exit(1);
|
|
20
30
|
}
|
|
21
31
|
var program = new Command();
|
|
22
|
-
program.name("stow").description(CLI_DOCS.root.description).version(VERSION).
|
|
32
|
+
program.name("stow").description(CLI_DOCS.root.description).version(VERSION).option("--human", "Force human-readable output (default when TTY)").option(
|
|
33
|
+
"--fields <fields>",
|
|
34
|
+
"Comma-separated fields to include in output (e.g. key,similarity)"
|
|
35
|
+
).option("--ndjson", "Output as newline-delimited JSON (one object per line)").addHelpText("after", renderCommandHelp("root"));
|
|
36
|
+
program.hook("preAction", () => {
|
|
37
|
+
const opts2 = program.opts();
|
|
38
|
+
if (opts2.human) {
|
|
39
|
+
setForceHuman(true);
|
|
40
|
+
}
|
|
41
|
+
if (opts2.fields) {
|
|
42
|
+
setGlobalFields(opts2.fields);
|
|
43
|
+
}
|
|
44
|
+
if (opts2.ndjson) {
|
|
45
|
+
setGlobalNdjson(true);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
23
48
|
program.command("drop").description(CLI_DOCS.drop.description).argument("<file>", "File to upload").option("-q, --quiet", "Only output the URL").addHelpText("after", renderCommandHelp("drop")).action(async (file, options) => {
|
|
24
49
|
try {
|
|
25
|
-
const { uploadDrop } = await import("./upload-
|
|
50
|
+
const { uploadDrop } = await import("./upload-OS6Q6LW5.js");
|
|
26
51
|
await uploadDrop(file, options);
|
|
27
52
|
} catch (err) {
|
|
28
53
|
handleError(err);
|
|
@@ -31,7 +56,7 @@ program.command("drop").description(CLI_DOCS.drop.description).argument("<file>"
|
|
|
31
56
|
program.command("upload").description(CLI_DOCS.upload.description).argument("<file>", "File to upload").option("-b, --bucket <name>", "Bucket name or ID").option("-q, --quiet", "Only output the URL").option("--dry-run", "Preview without uploading").addHelpText("after", renderCommandHelp("upload")).action(
|
|
32
57
|
async (file, options) => {
|
|
33
58
|
try {
|
|
34
|
-
const { uploadFile } = await import("./upload-
|
|
59
|
+
const { uploadFile } = await import("./upload-OS6Q6LW5.js");
|
|
35
60
|
await uploadFile(file, options);
|
|
36
61
|
} catch (err) {
|
|
37
62
|
handleError(err);
|
|
@@ -40,26 +65,26 @@ program.command("upload").description(CLI_DOCS.upload.description).argument("<fi
|
|
|
40
65
|
);
|
|
41
66
|
var bucketsCmd = program.command("buckets").description(CLI_DOCS.buckets.description).addHelpText("after", renderCommandHelp("buckets")).action(async () => {
|
|
42
67
|
try {
|
|
43
|
-
const { listBuckets } = await import("./buckets-
|
|
68
|
+
const { listBuckets } = await import("./buckets-ZHP3LBLC.js");
|
|
44
69
|
await listBuckets();
|
|
45
70
|
} catch (err) {
|
|
46
71
|
handleError(err);
|
|
47
72
|
}
|
|
48
73
|
});
|
|
49
|
-
bucketsCmd.command("create").description(CLI_DOCS.bucketsCreate.description).argument("<name>", "Bucket name").option("-d, --description <text>", "Bucket description").option("--public", "Make bucket public").option("--dry-run", "Preview without creating").addHelpText("after", renderCommandHelp("bucketsCreate")).action(
|
|
74
|
+
bucketsCmd.command("create").description(CLI_DOCS.bucketsCreate.description).argument("<name>", "Bucket name").option("-d, --description <text>", "Bucket description").option("--public", "Make bucket public").option("--dry-run", "Preview without creating").option("--input-json <json>", "Raw JSON payload").addHelpText("after", renderCommandHelp("bucketsCreate")).action(
|
|
50
75
|
async (name, options) => {
|
|
51
76
|
try {
|
|
52
|
-
const { createBucket } = await import("./buckets-
|
|
77
|
+
const { createBucket } = await import("./buckets-ZHP3LBLC.js");
|
|
53
78
|
await createBucket(name, options);
|
|
54
79
|
} catch (err) {
|
|
55
80
|
handleError(err);
|
|
56
81
|
}
|
|
57
82
|
}
|
|
58
83
|
);
|
|
59
|
-
bucketsCmd.command("rename").description(CLI_DOCS.bucketsRename.description).argument("<name>", "Current bucket name").argument("<new-name>", "New bucket name").option("-y, --yes", "Skip confirmation warning").option("--dry-run", "Preview without renaming").addHelpText("after", renderCommandHelp("bucketsRename")).action(
|
|
84
|
+
bucketsCmd.command("rename").description(CLI_DOCS.bucketsRename.description).argument("<name>", "Current bucket name").argument("<new-name>", "New bucket name").option("-y, --yes", "Skip confirmation warning").option("--dry-run", "Preview without renaming").option("--input-json <json>", "Raw JSON payload").addHelpText("after", renderCommandHelp("bucketsRename")).action(
|
|
60
85
|
async (name, newName, options) => {
|
|
61
86
|
try {
|
|
62
|
-
const { renameBucket } = await import("./buckets-
|
|
87
|
+
const { renameBucket } = await import("./buckets-ZHP3LBLC.js");
|
|
63
88
|
await renameBucket(name, newName, options);
|
|
64
89
|
} catch (err) {
|
|
65
90
|
handleError(err);
|
|
@@ -68,7 +93,7 @@ bucketsCmd.command("rename").description(CLI_DOCS.bucketsRename.description).arg
|
|
|
68
93
|
);
|
|
69
94
|
bucketsCmd.command("delete").description(CLI_DOCS.bucketsDelete.description).argument("<id>", "Bucket ID").option("--dry-run", "Preview without deleting").addHelpText("after", renderCommandHelp("bucketsDelete")).action(async (id, options) => {
|
|
70
95
|
try {
|
|
71
|
-
const { deleteBucket } = await import("./buckets-
|
|
96
|
+
const { deleteBucket } = await import("./buckets-ZHP3LBLC.js");
|
|
72
97
|
await deleteBucket(id, options);
|
|
73
98
|
} catch (err) {
|
|
74
99
|
handleError(err);
|
|
@@ -81,7 +106,7 @@ var filesCmd = program.command("files").description(CLI_DOCS.files.description).
|
|
|
81
106
|
return;
|
|
82
107
|
}
|
|
83
108
|
try {
|
|
84
|
-
const { listFiles } = await import("./files-
|
|
109
|
+
const { listFiles } = await import("./files-UQODXWNT.js");
|
|
85
110
|
await listFiles(bucket, options);
|
|
86
111
|
} catch (err) {
|
|
87
112
|
handleError(err);
|
|
@@ -90,16 +115,16 @@ var filesCmd = program.command("files").description(CLI_DOCS.files.description).
|
|
|
90
115
|
);
|
|
91
116
|
filesCmd.command("get").description(CLI_DOCS.filesGet.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("filesGet")).action(async (bucket, key, options) => {
|
|
92
117
|
try {
|
|
93
|
-
const { getFile } = await import("./files-
|
|
118
|
+
const { getFile } = await import("./files-UQODXWNT.js");
|
|
94
119
|
await getFile(bucket, key, options);
|
|
95
120
|
} catch (err) {
|
|
96
121
|
handleError(err);
|
|
97
122
|
}
|
|
98
123
|
});
|
|
99
|
-
filesCmd.command("update").description(CLI_DOCS.filesUpdate.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("-m, --metadata <kv...>", "Metadata key=value pairs").option("--json", "Output as JSON").option("--dry-run", "Preview without updating").addHelpText("after", renderCommandHelp("filesUpdate")).action(
|
|
124
|
+
filesCmd.command("update").description(CLI_DOCS.filesUpdate.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("-m, --metadata <kv...>", "Metadata key=value pairs").option("--json", "Output as JSON").option("--dry-run", "Preview without updating").option("--input-json <json>", "Raw JSON payload").addHelpText("after", renderCommandHelp("filesUpdate")).action(
|
|
100
125
|
async (bucket, key, options) => {
|
|
101
126
|
try {
|
|
102
|
-
const { updateFile } = await import("./files-
|
|
127
|
+
const { updateFile } = await import("./files-UQODXWNT.js");
|
|
103
128
|
await updateFile(bucket, key, options);
|
|
104
129
|
} catch (err) {
|
|
105
130
|
handleError(err);
|
|
@@ -108,7 +133,7 @@ filesCmd.command("update").description(CLI_DOCS.filesUpdate.description).argumen
|
|
|
108
133
|
);
|
|
109
134
|
filesCmd.command("enrich").description(CLI_DOCS.filesEnrich.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").addHelpText("after", renderCommandHelp("filesEnrich")).action(async (bucket, key) => {
|
|
110
135
|
try {
|
|
111
|
-
const { enrichFile } = await import("./files-
|
|
136
|
+
const { enrichFile } = await import("./files-UQODXWNT.js");
|
|
112
137
|
await enrichFile(bucket, key);
|
|
113
138
|
} catch (err) {
|
|
114
139
|
handleError(err);
|
|
@@ -117,7 +142,7 @@ filesCmd.command("enrich").description(CLI_DOCS.filesEnrich.description).argumen
|
|
|
117
142
|
filesCmd.command("missing").description(CLI_DOCS.filesMissing.description).argument("<bucket>", "Bucket name").argument("<type>", "dimensions | embeddings | colors").option("-l, --limit <count>", "Max files to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("filesMissing")).action(
|
|
118
143
|
async (bucket, type, options) => {
|
|
119
144
|
try {
|
|
120
|
-
const { listMissing } = await import("./files-
|
|
145
|
+
const { listMissing } = await import("./files-UQODXWNT.js");
|
|
121
146
|
await listMissing(bucket, type, options);
|
|
122
147
|
} catch (err) {
|
|
123
148
|
handleError(err);
|
|
@@ -126,7 +151,7 @@ filesCmd.command("missing").description(CLI_DOCS.filesMissing.description).argum
|
|
|
126
151
|
);
|
|
127
152
|
var dropsCmd = program.command("drops").description(CLI_DOCS.drops.description).addHelpText("after", renderCommandHelp("drops")).action(async () => {
|
|
128
153
|
try {
|
|
129
|
-
const { listDrops } = await import("./drops-
|
|
154
|
+
const { listDrops } = await import("./drops-5VIEW3XZ.js");
|
|
130
155
|
await listDrops();
|
|
131
156
|
} catch (err) {
|
|
132
157
|
handleError(err);
|
|
@@ -134,7 +159,7 @@ var dropsCmd = program.command("drops").description(CLI_DOCS.drops.description).
|
|
|
134
159
|
});
|
|
135
160
|
dropsCmd.command("delete").description(CLI_DOCS.dropsDelete.description).argument("<id>", "Drop ID").addHelpText("after", renderCommandHelp("dropsDelete")).action(async (id) => {
|
|
136
161
|
try {
|
|
137
|
-
const { deleteDrop } = await import("./drops-
|
|
162
|
+
const { deleteDrop } = await import("./drops-5VIEW3XZ.js");
|
|
138
163
|
await deleteDrop(id);
|
|
139
164
|
} catch (err) {
|
|
140
165
|
handleError(err);
|
|
@@ -144,7 +169,7 @@ var searchCmd = program.command("search").description(CLI_DOCS.search.descriptio
|
|
|
144
169
|
searchCmd.command("text").description(CLI_DOCS.searchText.description).argument("<query>", "Search query").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchText")).action(
|
|
145
170
|
async (query, options) => {
|
|
146
171
|
try {
|
|
147
|
-
const { textSearch } = await import("./search-
|
|
172
|
+
const { textSearch } = await import("./search-TRTPX2SQ.js");
|
|
148
173
|
await textSearch(query, options);
|
|
149
174
|
} catch (err) {
|
|
150
175
|
handleError(err);
|
|
@@ -154,7 +179,7 @@ searchCmd.command("text").description(CLI_DOCS.searchText.description).argument(
|
|
|
154
179
|
searchCmd.command("similar").description(CLI_DOCS.searchSimilar.description).requiredOption("--file <key>", "File key to search from").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchSimilar")).action(
|
|
155
180
|
async (options) => {
|
|
156
181
|
try {
|
|
157
|
-
const { similarSearch } = await import("./search-
|
|
182
|
+
const { similarSearch } = await import("./search-TRTPX2SQ.js");
|
|
158
183
|
await similarSearch(options);
|
|
159
184
|
} catch (err) {
|
|
160
185
|
handleError(err);
|
|
@@ -164,7 +189,7 @@ searchCmd.command("similar").description(CLI_DOCS.searchSimilar.description).req
|
|
|
164
189
|
searchCmd.command("color").description(CLI_DOCS.searchColor.description).requiredOption("--hex <color>", "Hex color code").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchColor")).action(
|
|
165
190
|
async (options) => {
|
|
166
191
|
try {
|
|
167
|
-
const { colorSearch } = await import("./search-
|
|
192
|
+
const { colorSearch } = await import("./search-TRTPX2SQ.js");
|
|
168
193
|
await colorSearch(options);
|
|
169
194
|
} catch (err) {
|
|
170
195
|
handleError(err);
|
|
@@ -174,7 +199,7 @@ searchCmd.command("color").description(CLI_DOCS.searchColor.description).require
|
|
|
174
199
|
searchCmd.command("diverse").description(CLI_DOCS.searchDiverse.description).option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchDiverse")).action(
|
|
175
200
|
async (options) => {
|
|
176
201
|
try {
|
|
177
|
-
const { diverseSearch } = await import("./search-
|
|
202
|
+
const { diverseSearch } = await import("./search-TRTPX2SQ.js");
|
|
178
203
|
await diverseSearch(options);
|
|
179
204
|
} catch (err) {
|
|
180
205
|
handleError(err);
|
|
@@ -183,16 +208,16 @@ searchCmd.command("diverse").description(CLI_DOCS.searchDiverse.description).opt
|
|
|
183
208
|
);
|
|
184
209
|
var tagsCmd = program.command("tags").description(CLI_DOCS.tags.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("tags")).action(async (options) => {
|
|
185
210
|
try {
|
|
186
|
-
const { listTags } = await import("./tags-
|
|
211
|
+
const { listTags } = await import("./tags-VH44BGQL.js");
|
|
187
212
|
await listTags(options);
|
|
188
213
|
} catch (err) {
|
|
189
214
|
handleError(err);
|
|
190
215
|
}
|
|
191
216
|
});
|
|
192
|
-
tagsCmd.command("create").description(CLI_DOCS.tagsCreate.description).argument("<name>", "Tag name").option("--color <hex>", "Tag color (hex)").option("--json", "Output as JSON").option("--dry-run", "Preview without creating").addHelpText("after", renderCommandHelp("tagsCreate")).action(
|
|
217
|
+
tagsCmd.command("create").description(CLI_DOCS.tagsCreate.description).argument("<name>", "Tag name").option("--color <hex>", "Tag color (hex)").option("--json", "Output as JSON").option("--dry-run", "Preview without creating").option("--input-json <json>", "Raw JSON payload").addHelpText("after", renderCommandHelp("tagsCreate")).action(
|
|
193
218
|
async (name, options) => {
|
|
194
219
|
try {
|
|
195
|
-
const { createTag } = await import("./tags-
|
|
220
|
+
const { createTag } = await import("./tags-VH44BGQL.js");
|
|
196
221
|
await createTag(name, options);
|
|
197
222
|
} catch (err) {
|
|
198
223
|
handleError(err);
|
|
@@ -201,7 +226,7 @@ tagsCmd.command("create").description(CLI_DOCS.tagsCreate.description).argument(
|
|
|
201
226
|
);
|
|
202
227
|
tagsCmd.command("delete").description(CLI_DOCS.tagsDelete.description).argument("<id>", "Tag ID").option("--dry-run", "Preview without deleting").addHelpText("after", renderCommandHelp("tagsDelete")).action(async (id, options) => {
|
|
203
228
|
try {
|
|
204
|
-
const { deleteTag } = await import("./tags-
|
|
229
|
+
const { deleteTag } = await import("./tags-VH44BGQL.js");
|
|
205
230
|
await deleteTag(id, options);
|
|
206
231
|
} catch (err) {
|
|
207
232
|
handleError(err);
|
|
@@ -211,7 +236,7 @@ var profilesCmd = program.command("profiles").description(CLI_DOCS.profiles.desc
|
|
|
211
236
|
profilesCmd.command("create").description(CLI_DOCS.profilesCreate.description).requiredOption("--name <name>", "Profile name").option("-b, --bucket <id>", "Bucket ID").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("profilesCreate")).action(
|
|
212
237
|
async (options) => {
|
|
213
238
|
try {
|
|
214
|
-
const { createProfile } = await import("./profiles-
|
|
239
|
+
const { createProfile } = await import("./profiles-CHBGKQOE.js");
|
|
215
240
|
await createProfile(options);
|
|
216
241
|
} catch (err) {
|
|
217
242
|
handleError(err);
|
|
@@ -220,7 +245,7 @@ profilesCmd.command("create").description(CLI_DOCS.profilesCreate.description).r
|
|
|
220
245
|
);
|
|
221
246
|
profilesCmd.command("get").description(CLI_DOCS.profilesGet.description).argument("<id>", "Profile ID").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("profilesGet")).action(async (id, options) => {
|
|
222
247
|
try {
|
|
223
|
-
const { getProfile } = await import("./profiles-
|
|
248
|
+
const { getProfile } = await import("./profiles-CHBGKQOE.js");
|
|
224
249
|
await getProfile(id, options);
|
|
225
250
|
} catch (err) {
|
|
226
251
|
handleError(err);
|
|
@@ -228,7 +253,7 @@ profilesCmd.command("get").description(CLI_DOCS.profilesGet.description).argumen
|
|
|
228
253
|
});
|
|
229
254
|
profilesCmd.command("delete").description(CLI_DOCS.profilesDelete.description).argument("<id>", "Profile ID").addHelpText("after", renderCommandHelp("profilesDelete")).action(async (id) => {
|
|
230
255
|
try {
|
|
231
|
-
const { deleteProfile } = await import("./profiles-
|
|
256
|
+
const { deleteProfile } = await import("./profiles-CHBGKQOE.js");
|
|
232
257
|
await deleteProfile(id);
|
|
233
258
|
} catch (err) {
|
|
234
259
|
handleError(err);
|
|
@@ -237,7 +262,7 @@ profilesCmd.command("delete").description(CLI_DOCS.profilesDelete.description).a
|
|
|
237
262
|
var jobsCmd = program.command("jobs").description(CLI_DOCS.jobs.description).requiredOption("-b, --bucket <id>", "Bucket ID (required)").option("-s, --status <status>", "Filter by status").option("-q, --queue <name>", "Filter by queue name").option("-l, --limit <count>", "Max jobs to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("jobs")).action(
|
|
238
263
|
async (options) => {
|
|
239
264
|
try {
|
|
240
|
-
const { listJobs } = await import("./jobs-
|
|
265
|
+
const { listJobs } = await import("./jobs-PTV2W5PJ.js");
|
|
241
266
|
await listJobs(options.bucket, options);
|
|
242
267
|
} catch (err) {
|
|
243
268
|
handleError(err);
|
|
@@ -246,7 +271,7 @@ var jobsCmd = program.command("jobs").description(CLI_DOCS.jobs.description).req
|
|
|
246
271
|
);
|
|
247
272
|
jobsCmd.command("retry").description(CLI_DOCS.jobsRetry.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").requiredOption("-b, --bucket <id>", "Bucket ID").addHelpText("after", renderCommandHelp("jobsRetry")).action(async (id, options) => {
|
|
248
273
|
try {
|
|
249
|
-
const { retryJob } = await import("./jobs-
|
|
274
|
+
const { retryJob } = await import("./jobs-PTV2W5PJ.js");
|
|
250
275
|
await retryJob(id, options);
|
|
251
276
|
} catch (err) {
|
|
252
277
|
handleError(err);
|
|
@@ -254,7 +279,7 @@ jobsCmd.command("retry").description(CLI_DOCS.jobsRetry.description).argument("<
|
|
|
254
279
|
});
|
|
255
280
|
jobsCmd.command("delete").description(CLI_DOCS.jobsDelete.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").requiredOption("-b, --bucket <id>", "Bucket ID").addHelpText("after", renderCommandHelp("jobsDelete")).action(async (id, options) => {
|
|
256
281
|
try {
|
|
257
|
-
const { deleteJob } = await import("./jobs-
|
|
282
|
+
const { deleteJob } = await import("./jobs-PTV2W5PJ.js");
|
|
258
283
|
await deleteJob(id, options);
|
|
259
284
|
} catch (err) {
|
|
260
285
|
handleError(err);
|
|
@@ -263,7 +288,7 @@ jobsCmd.command("delete").description(CLI_DOCS.jobsDelete.description).argument(
|
|
|
263
288
|
var adminCmd = program.command("admin").description(CLI_DOCS.admin.description).addHelpText("after", renderCommandHelp("admin"));
|
|
264
289
|
adminCmd.command("health").description(CLI_DOCS.adminHealth.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminHealth")).action(async (options) => {
|
|
265
290
|
try {
|
|
266
|
-
const { health } = await import("./health-
|
|
291
|
+
const { health } = await import("./health-RICGWQGN.js");
|
|
267
292
|
await health(options);
|
|
268
293
|
} catch (err) {
|
|
269
294
|
handleError(err);
|
|
@@ -273,7 +298,7 @@ var backfillCmd = adminCmd.command("backfill").description(CLI_DOCS.adminBackfil
|
|
|
273
298
|
backfillCmd.command("dimensions").description("Backfill image dimensions").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
|
|
274
299
|
async (options) => {
|
|
275
300
|
try {
|
|
276
|
-
const { backfillDimensions } = await import("./backfill-
|
|
301
|
+
const { backfillDimensions } = await import("./backfill-EVZT7RH6.js");
|
|
277
302
|
await backfillDimensions(options);
|
|
278
303
|
} catch (err) {
|
|
279
304
|
handleError(err);
|
|
@@ -283,7 +308,7 @@ backfillCmd.command("dimensions").description("Backfill image dimensions").optio
|
|
|
283
308
|
backfillCmd.command("colors").description("Backfill color extraction").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
|
|
284
309
|
async (options) => {
|
|
285
310
|
try {
|
|
286
|
-
const { backfillColors } = await import("./backfill-
|
|
311
|
+
const { backfillColors } = await import("./backfill-EVZT7RH6.js");
|
|
287
312
|
await backfillColors(options);
|
|
288
313
|
} catch (err) {
|
|
289
314
|
handleError(err);
|
|
@@ -293,7 +318,7 @@ backfillCmd.command("colors").description("Backfill color extraction").option("-
|
|
|
293
318
|
backfillCmd.command("embeddings").description("Backfill embedding generation").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
|
|
294
319
|
async (options) => {
|
|
295
320
|
try {
|
|
296
|
-
const { backfillEmbeddings } = await import("./backfill-
|
|
321
|
+
const { backfillEmbeddings } = await import("./backfill-EVZT7RH6.js");
|
|
297
322
|
await backfillEmbeddings(options);
|
|
298
323
|
} catch (err) {
|
|
299
324
|
handleError(err);
|
|
@@ -303,7 +328,7 @@ backfillCmd.command("embeddings").description("Backfill embedding generation").o
|
|
|
303
328
|
adminCmd.command("cleanup-drops").description(CLI_DOCS.adminCleanupDrops.description).option("--max-age-hours <hours>", "Max age in hours").option("--dry-run", "Preview without deleting").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminCleanupDrops")).action(
|
|
304
329
|
async (options) => {
|
|
305
330
|
try {
|
|
306
|
-
const { cleanupDrops } = await import("./maintenance-
|
|
331
|
+
const { cleanupDrops } = await import("./maintenance-ZJW2ES4L.js");
|
|
307
332
|
await cleanupDrops(options);
|
|
308
333
|
} catch (err) {
|
|
309
334
|
handleError(err);
|
|
@@ -312,7 +337,7 @@ adminCmd.command("cleanup-drops").description(CLI_DOCS.adminCleanupDrops.descrip
|
|
|
312
337
|
);
|
|
313
338
|
adminCmd.command("purge-events").description(CLI_DOCS.adminPurgeEvents.description).option("--dry-run", "Preview without deleting").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminPurgeEvents")).action(async (options) => {
|
|
314
339
|
try {
|
|
315
|
-
const { purgeEvents } = await import("./maintenance-
|
|
340
|
+
const { purgeEvents } = await import("./maintenance-ZJW2ES4L.js");
|
|
316
341
|
await purgeEvents(options);
|
|
317
342
|
} catch (err) {
|
|
318
343
|
handleError(err);
|
|
@@ -321,7 +346,7 @@ adminCmd.command("purge-events").description(CLI_DOCS.adminPurgeEvents.descripti
|
|
|
321
346
|
adminCmd.command("reconcile-files").description(CLI_DOCS.adminReconcileFiles.description).requiredOption("--bucket <id>", "Bucket ID").option("--dry-run", "Preview without reconciling").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminReconcileFiles")).action(
|
|
322
347
|
async (options) => {
|
|
323
348
|
try {
|
|
324
|
-
const { reconcileFiles } = await import("./maintenance-
|
|
349
|
+
const { reconcileFiles } = await import("./maintenance-ZJW2ES4L.js");
|
|
325
350
|
await reconcileFiles(options);
|
|
326
351
|
} catch (err) {
|
|
327
352
|
handleError(err);
|
|
@@ -330,7 +355,7 @@ adminCmd.command("reconcile-files").description(CLI_DOCS.adminReconcileFiles.des
|
|
|
330
355
|
);
|
|
331
356
|
adminCmd.command("retry-sync-failures").description(CLI_DOCS.adminRetrySyncFailures.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminRetrySyncFailures")).action(async (options) => {
|
|
332
357
|
try {
|
|
333
|
-
const { retrySyncFailures } = await import("./maintenance-
|
|
358
|
+
const { retrySyncFailures } = await import("./maintenance-ZJW2ES4L.js");
|
|
334
359
|
await retrySyncFailures(options);
|
|
335
360
|
} catch (err) {
|
|
336
361
|
handleError(err);
|
|
@@ -339,7 +364,7 @@ adminCmd.command("retry-sync-failures").description(CLI_DOCS.adminRetrySyncFailu
|
|
|
339
364
|
var adminJobsCmd = adminCmd.command("jobs").description(CLI_DOCS.adminJobs.description).option("--org <id>", "Filter by org ID").option("--bucket <id>", "Filter by bucket ID").option("-s, --status <status>", "Filter by status").option("-q, --queue <name>", "Filter by queue name").option("-l, --limit <count>", "Max jobs to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminJobs")).action(
|
|
340
365
|
async (options) => {
|
|
341
366
|
try {
|
|
342
|
-
const { listAdminJobs } = await import("./jobs-
|
|
367
|
+
const { listAdminJobs } = await import("./jobs-ZWSEXNFA.js");
|
|
343
368
|
await listAdminJobs(options);
|
|
344
369
|
} catch (err) {
|
|
345
370
|
handleError(err);
|
|
@@ -348,7 +373,7 @@ var adminJobsCmd = adminCmd.command("jobs").description(CLI_DOCS.adminJobs.descr
|
|
|
348
373
|
);
|
|
349
374
|
adminJobsCmd.command("retry").description(CLI_DOCS.adminJobsRetry.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").addHelpText("after", renderCommandHelp("adminJobsRetry")).action(async (id, options) => {
|
|
350
375
|
try {
|
|
351
|
-
const { retryAdminJob } = await import("./jobs-
|
|
376
|
+
const { retryAdminJob } = await import("./jobs-ZWSEXNFA.js");
|
|
352
377
|
await retryAdminJob(id, options);
|
|
353
378
|
} catch (err) {
|
|
354
379
|
handleError(err);
|
|
@@ -356,7 +381,7 @@ adminJobsCmd.command("retry").description(CLI_DOCS.adminJobsRetry.description).a
|
|
|
356
381
|
});
|
|
357
382
|
adminJobsCmd.command("delete").description(CLI_DOCS.adminJobsDelete.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").addHelpText("after", renderCommandHelp("adminJobsDelete")).action(async (id, options) => {
|
|
358
383
|
try {
|
|
359
|
-
const { deleteAdminJob } = await import("./jobs-
|
|
384
|
+
const { deleteAdminJob } = await import("./jobs-ZWSEXNFA.js");
|
|
360
385
|
await deleteAdminJob(id, options);
|
|
361
386
|
} catch (err) {
|
|
362
387
|
handleError(err);
|
|
@@ -364,7 +389,7 @@ adminJobsCmd.command("delete").description(CLI_DOCS.adminJobsDelete.description)
|
|
|
364
389
|
});
|
|
365
390
|
var adminQueuesCmd = adminCmd.command("queues").description(CLI_DOCS.adminQueues.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminQueues")).action(async (options) => {
|
|
366
391
|
try {
|
|
367
|
-
const { listQueues } = await import("./queues-
|
|
392
|
+
const { listQueues } = await import("./queues-EZ2VZGXQ.js");
|
|
368
393
|
await listQueues(options);
|
|
369
394
|
} catch (err) {
|
|
370
395
|
handleError(err);
|
|
@@ -373,7 +398,7 @@ var adminQueuesCmd = adminCmd.command("queues").description(CLI_DOCS.adminQueues
|
|
|
373
398
|
adminQueuesCmd.command("clean").description(CLI_DOCS.adminQueuesClean.description).argument("<name>", "Queue name").option("--failed", "Clean failed jobs").option("--completed", "Clean completed jobs").option("--grace <seconds>", "Grace period in seconds").addHelpText("after", renderCommandHelp("adminQueuesClean")).action(
|
|
374
399
|
async (name, options) => {
|
|
375
400
|
try {
|
|
376
|
-
const { cleanQueue } = await import("./queues-
|
|
401
|
+
const { cleanQueue } = await import("./queues-EZ2VZGXQ.js");
|
|
377
402
|
await cleanQueue(name, options);
|
|
378
403
|
} catch (err) {
|
|
379
404
|
handleError(err);
|
|
@@ -383,7 +408,7 @@ adminQueuesCmd.command("clean").description(CLI_DOCS.adminQueuesClean.descriptio
|
|
|
383
408
|
program.command("delete").description(CLI_DOCS.delete.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("--dry-run", "Preview without deleting").addHelpText("after", renderCommandHelp("delete")).action(
|
|
384
409
|
async (bucket, key, options) => {
|
|
385
410
|
try {
|
|
386
|
-
const { deleteFile } = await import("./delete-
|
|
411
|
+
const { deleteFile } = await import("./delete-YEXSMG4I.js");
|
|
387
412
|
await deleteFile(bucket, key, options);
|
|
388
413
|
} catch (err) {
|
|
389
414
|
handleError(err);
|
|
@@ -392,7 +417,7 @@ program.command("delete").description(CLI_DOCS.delete.description).argument("<bu
|
|
|
392
417
|
);
|
|
393
418
|
program.command("whoami").description(CLI_DOCS.whoami.description).addHelpText("after", renderCommandHelp("whoami")).action(async () => {
|
|
394
419
|
try {
|
|
395
|
-
const { whoami } = await import("./whoami-
|
|
420
|
+
const { whoami } = await import("./whoami-TVRKBM74.js");
|
|
396
421
|
await whoami();
|
|
397
422
|
} catch (err) {
|
|
398
423
|
handleError(err);
|
|
@@ -408,7 +433,7 @@ program.command("open").description(CLI_DOCS.open.description).argument("<bucket
|
|
|
408
433
|
});
|
|
409
434
|
program.command("describe").argument("[command]", "Command path (dot notation, e.g. search.text)").description("Show command schema for AI agents").action(async (command) => {
|
|
410
435
|
try {
|
|
411
|
-
const { describeCommand } = await import("./describe-
|
|
436
|
+
const { describeCommand } = await import("./describe-J4ZMUXK7.js");
|
|
412
437
|
describeCommand(command ?? "");
|
|
413
438
|
} catch (err) {
|
|
414
439
|
handleError(err);
|
|
@@ -427,5 +452,5 @@ program.parse();
|
|
|
427
452
|
var opts = program.opts();
|
|
428
453
|
var args = process.argv.slice(2);
|
|
429
454
|
if (args.length === 0 || args.length === 1 && opts.interactive) {
|
|
430
|
-
import("./app-
|
|
455
|
+
import("./app-Q6EW7VSM.js").then(({ startInteractive }) => startInteractive()).catch(handleError);
|
|
431
456
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateBucketName,
|
|
3
|
+
validateFileKey
|
|
4
|
+
} from "./chunk-PLZFHPLC.js";
|
|
5
|
+
import {
|
|
6
|
+
createStow
|
|
7
|
+
} from "./chunk-5LU25QZK.js";
|
|
8
|
+
import "./chunk-TOADDO2F.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/delete.ts
|
|
11
|
+
async function deleteFile(bucket, key, options = {}) {
|
|
12
|
+
validateBucketName(bucket);
|
|
13
|
+
validateFileKey(key);
|
|
14
|
+
if (options.dryRun) {
|
|
15
|
+
console.log(
|
|
16
|
+
JSON.stringify(
|
|
17
|
+
{
|
|
18
|
+
dryRun: true,
|
|
19
|
+
action: "deleteFile",
|
|
20
|
+
details: { bucket, key }
|
|
21
|
+
},
|
|
22
|
+
null,
|
|
23
|
+
2
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const stow = createStow();
|
|
29
|
+
await stow.deleteFile(key, { bucket });
|
|
30
|
+
console.log(`Deleted: ${key} from ${bucket}`);
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
deleteFile
|
|
34
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLI_DOCS
|
|
3
|
+
} from "./chunk-XJDK2CBE.js";
|
|
4
|
+
import {
|
|
5
|
+
output
|
|
6
|
+
} from "./chunk-P2BKGBQE.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/describe.ts
|
|
9
|
+
var COMMAND_MAP = {
|
|
10
|
+
upload: "upload",
|
|
11
|
+
drop: "drop",
|
|
12
|
+
delete: "delete",
|
|
13
|
+
whoami: "whoami",
|
|
14
|
+
open: "open",
|
|
15
|
+
buckets: "buckets",
|
|
16
|
+
"buckets.create": "bucketsCreate",
|
|
17
|
+
"buckets.rename": "bucketsRename",
|
|
18
|
+
"buckets.delete": "bucketsDelete",
|
|
19
|
+
files: "files",
|
|
20
|
+
"files.get": "filesGet",
|
|
21
|
+
"files.update": "filesUpdate",
|
|
22
|
+
"files.enrich": "filesEnrich",
|
|
23
|
+
"files.missing": "filesMissing",
|
|
24
|
+
search: "search",
|
|
25
|
+
"search.text": "searchText",
|
|
26
|
+
"search.similar": "searchSimilar",
|
|
27
|
+
"search.color": "searchColor",
|
|
28
|
+
"search.diverse": "searchDiverse",
|
|
29
|
+
tags: "tags",
|
|
30
|
+
"tags.create": "tagsCreate",
|
|
31
|
+
"tags.delete": "tagsDelete",
|
|
32
|
+
drops: "drops",
|
|
33
|
+
"drops.delete": "dropsDelete",
|
|
34
|
+
profiles: "profiles",
|
|
35
|
+
"profiles.create": "profilesCreate",
|
|
36
|
+
"profiles.get": "profilesGet",
|
|
37
|
+
"profiles.delete": "profilesDelete",
|
|
38
|
+
jobs: "jobs",
|
|
39
|
+
"jobs.retry": "jobsRetry",
|
|
40
|
+
"jobs.delete": "jobsDelete",
|
|
41
|
+
admin: "admin",
|
|
42
|
+
"admin.health": "adminHealth",
|
|
43
|
+
"admin.backfill": "adminBackfill",
|
|
44
|
+
"admin.cleanup-drops": "adminCleanupDrops",
|
|
45
|
+
"admin.purge-events": "adminPurgeEvents",
|
|
46
|
+
"admin.reconcile-files": "adminReconcileFiles",
|
|
47
|
+
"admin.retry-sync-failures": "adminRetrySyncFailures",
|
|
48
|
+
"admin.jobs": "adminJobs",
|
|
49
|
+
"admin.jobs.retry": "adminJobsRetry",
|
|
50
|
+
"admin.jobs.delete": "adminJobsDelete",
|
|
51
|
+
"admin.queues": "adminQueues",
|
|
52
|
+
"admin.queues.clean": "adminQueuesClean"
|
|
53
|
+
};
|
|
54
|
+
function describeCommand(commandPath) {
|
|
55
|
+
if (!commandPath) {
|
|
56
|
+
output({
|
|
57
|
+
commands: Object.keys(COMMAND_MAP).sort()
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const docKey = COMMAND_MAP[commandPath];
|
|
62
|
+
if (!(docKey && CLI_DOCS[docKey])) {
|
|
63
|
+
console.error(`Unknown command: ${commandPath}`);
|
|
64
|
+
console.error(`Available: ${Object.keys(COMMAND_MAP).sort().join(", ")}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const doc = CLI_DOCS[docKey];
|
|
69
|
+
output({
|
|
70
|
+
command: commandPath,
|
|
71
|
+
description: doc.description,
|
|
72
|
+
usage: doc.usage,
|
|
73
|
+
examples: doc.examples,
|
|
74
|
+
notes: doc.notes ?? []
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
describeCommand
|
|
79
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatBytes,
|
|
3
|
+
formatTable,
|
|
4
|
+
usageBar
|
|
5
|
+
} from "./chunk-FZGOTXTE.js";
|
|
6
|
+
import {
|
|
7
|
+
createStow
|
|
8
|
+
} from "./chunk-5LU25QZK.js";
|
|
9
|
+
import "./chunk-TOADDO2F.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/drops.ts
|
|
12
|
+
async function listDrops() {
|
|
13
|
+
const stow = createStow();
|
|
14
|
+
const data = await stow.listDrops();
|
|
15
|
+
if (data.drops.length === 0) {
|
|
16
|
+
console.log("No drops yet. Create one with: stow drop <file>");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const rows = data.drops.map((d) => [
|
|
20
|
+
d.filename,
|
|
21
|
+
formatBytes(Number(d.size)),
|
|
22
|
+
d.contentType,
|
|
23
|
+
d.url
|
|
24
|
+
]);
|
|
25
|
+
console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
|
|
26
|
+
console.log(
|
|
27
|
+
`
|
|
28
|
+
Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
async function deleteDrop(id) {
|
|
32
|
+
const stow = createStow();
|
|
33
|
+
await stow.deleteDrop(id);
|
|
34
|
+
console.log(`Deleted drop: ${id}`);
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
deleteDrop,
|
|
38
|
+
listDrops
|
|
39
|
+
};
|