utcli
Version:
An unofficial uploadthing cli tool
194 lines (186 loc) • 6.58 kB
JavaScript
;
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/upload.ts
var import_promises = require("fs/promises");
var import_server2 = require("uploadthing/server");
// src/shared.ts
var import_server = require("uploadthing/server");
var import_node_process = require("process");
function createUTApi() {
if (!("UPLOADTHING_TOKEN" in process.env)) {
console.error(
"Please export an UPLOADTHING_TOKEN before using this command"
);
(0, import_node_process.exit)(1);
}
return new import_server.UTApi();
}
function safeParseInt(text) {
try {
const result = parseInt(text);
if (isNaN(result)) throw new Error("Got NaN");
return result;
} catch (err) {
console.error(`${JSON.stringify(text)} is not a valid number`);
(0, import_node_process.exit)(1);
}
}
// src/upload.ts
function loadUploadCommand(program2) {
program2.command("upload").description("Upload a list of files").option("-m, --manifest <path>", "A JSON file to write upload details to").argument("<filepaths...>", "A list of files to upload").action(function(filepaths, options) {
const utapi = createUTApi();
const manifest = [];
let i = 0;
filepaths.forEach((filepath) => __async(this, null, function* () {
const file = yield readUTFile(filepath);
const result = yield utapi.uploadFiles(file);
if (result.data) {
logUploadedFileData(result.data, ++i, filepaths.length);
manifest.push(result.data);
} else {
logFailedFileUpload(filepath, ++i, filepaths.length);
}
if (options.manifest) {
yield (0, import_promises.writeFile)(options.manifest, JSON.stringify(manifest, null, 2));
}
}));
});
}
function readUTFile(path) {
return __async(this, null, function* () {
const buffer = yield (0, import_promises.readFile)(path);
return new import_server2.UTFile([new Blob([buffer])], path);
});
}
function logUploadedFileData(uploadedFileData, i, n) {
console.log(
`Successfully uploaded ${JSON.stringify(uploadedFileData.name)} [${i}/${n}]`
);
console.log(`Key: ${uploadedFileData.key}`);
console.log(`URL: ${uploadedFileData.url}`);
console.log(`App URL: ${uploadedFileData.appUrl}`);
console.log(`MIME Type: ${uploadedFileData.type}
`);
}
function logFailedFileUpload(filepath, i, n) {
console.error(`Could not upload ${JSON.stringify(filepath)} [${i}/${n}]`);
}
// src/delete.ts
function loadDeleteCommand(program2) {
program2.command("delete").description("Delete a list of files by key").argument("<keys...>", "The list of file keys to delete").action((keys) => __async(this, null, function* () {
const utapi = createUTApi();
let n = 0;
keys.forEach((key) => __async(this, null, function* () {
const result = yield utapi.deleteFiles(key);
if (result.success && result.deletedCount) {
console.log(
`Successfully deleted ${JSON.stringify(key)} [${++n}/${keys.length}]
`
);
} else {
console.error(
`Failed to delete ${JSON.stringify(key)} [${++n}/${keys.length}]`
);
}
}));
}));
}
// src/clean.ts
var import_promises2 = require("fs/promises");
var import_zod = require("zod");
var import_node_process2 = require("process");
var manifestSchema = import_zod.z.array(
import_zod.z.object({
key: import_zod.z.string()
})
);
function loadCleanCommand(program2) {
program2.command("clean").description("Deletes every file").option("--confirm", "Go through with the deletion").option("-k, --keep-manifest <path>", "Keep files recorded in the manifest").action((options) => __async(this, null, function* () {
const utapi = createUTApi();
const deleteKeys = [];
const keepKeys = /* @__PURE__ */ new Set();
if (options.keepManifest) {
const manifest = yield readManifest(options.keepManifest);
manifest.forEach(({ key }) => keepKeys.add(key));
}
const limit = 500;
let hasMore = true;
let offset = 0;
while (hasMore) {
const result = yield utapi.listFiles({ offset, limit });
result.files.forEach(({ key }) => {
if (!keepKeys.has(key)) deleteKeys.push(key);
});
hasMore = result.hasMore;
offset += limit;
}
console.log(`Found ${deleteKeys.length} files to delete`);
if (options.confirm) {
const { deletedCount } = yield utapi.deleteFiles(deleteKeys);
console.log(`Deleted ${deletedCount} files
`);
} else {
console.log("Run with --confirm to go through with the deletion");
}
}));
}
function readManifest(path) {
return __async(this, null, function* () {
try {
const content = yield (0, import_promises2.readFile)(path);
const data = JSON.parse(content.toString());
const manifest = manifestSchema.parse(data);
return manifest;
} catch (_) {
console.error(`${JSON.stringify(path)} is not a valid JSON manifest`);
(0, import_node_process2.exit)(1);
}
});
}
// src/list.ts
function loadListCommand(program2) {
program2.command("list").description("Get a list of all files in utfs").option(
"-l, --limit [count]",
"The maximum amount of files to list",
safeParseInt
).option("-o, --offset [count]", "The number of files to skip", safeParseInt).action((options) => __async(this, null, function* () {
const utapi = createUTApi();
const { files, hasMore } = yield utapi.listFiles(options);
files.forEach((file, index) => {
var _a;
console.log(`Name: ${JSON.stringify(file.name)}`);
console.log(`Key: ${file.key}`);
console.log(`Offset: ${index + ((_a = options.offset) != null ? _a : 0)}
`);
});
hasMore && console.log("More available...\n");
}));
}
// src/main.ts
var import_commander = require("commander");
import_commander.program.version("0.0.0");
loadUploadCommand(import_commander.program);
loadListCommand(import_commander.program);
loadDeleteCommand(import_commander.program);
loadCleanCommand(import_commander.program);
import_commander.program.parse(process.argv);