100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { EventKind, EventPublisher } from "@snort/system";
|
|
import { UploadState, VoidApi } from "@void-cat/api";
|
|
|
|
import { FileExtensionRegex } from "@/Const";
|
|
import { UploadResult } from "@/Upload";
|
|
import { base64 } from "@scure/base";
|
|
import { throwIfOffline } from "@snort/shared";
|
|
|
|
/**
|
|
* Upload file to void.cat
|
|
* https://void.cat/swagger/index.html
|
|
*/
|
|
export default async function VoidCatUpload(
|
|
file: File | Blob,
|
|
filename: string,
|
|
publisher?: EventPublisher,
|
|
progress?: (n: number) => void,
|
|
stage?: (n: "starting" | "hashing" | "uploading" | "done" | undefined) => void,
|
|
): Promise<UploadResult> {
|
|
throwIfOffline();
|
|
const auth = publisher
|
|
? async (url: string, method: string) => {
|
|
const auth = await publisher.generic(eb => {
|
|
return eb.kind(EventKind.HttpAuthentication).tag(["u", url]).tag(["method", method]);
|
|
});
|
|
return `Nostr ${base64.encode(new TextEncoder().encode(JSON.stringify(auth)))}`;
|
|
}
|
|
: undefined;
|
|
const api = new VoidApi("https://void.cat", auth);
|
|
const uploader = api.getUploader(
|
|
file,
|
|
sx => {
|
|
stage?.(
|
|
(() => {
|
|
switch (sx) {
|
|
case UploadState.Starting:
|
|
return "starting";
|
|
case UploadState.Hashing:
|
|
return "hashing";
|
|
case UploadState.Uploading:
|
|
return "uploading";
|
|
case UploadState.Done:
|
|
return "done";
|
|
}
|
|
})(),
|
|
);
|
|
},
|
|
px => {
|
|
progress?.(px / file.size);
|
|
},
|
|
);
|
|
|
|
const rsp = await uploader.upload({
|
|
"V-Strip-Metadata": "true",
|
|
});
|
|
if (rsp.ok) {
|
|
let ext = filename.match(FileExtensionRegex);
|
|
if (rsp.file?.metadata?.mimeType === "image/webp") {
|
|
ext = ["", "webp"];
|
|
}
|
|
const resultUrl = rsp.file?.metadata?.url ?? `https://void.cat/d/${rsp.file?.id}${ext ? `.${ext[1]}` : ""}`;
|
|
|
|
const ret = {
|
|
url: resultUrl,
|
|
metadata: {
|
|
hash: rsp.file?.metadata?.digest,
|
|
},
|
|
} as UploadResult;
|
|
|
|
if (publisher) {
|
|
// NIP-94
|
|
/*const tags = [
|
|
["url", resultUrl],
|
|
["x", rsp.file?.metadata?.digest ?? ""],
|
|
["m", rsp.file?.metadata?.mimeType ?? "application/octet-stream"],
|
|
];
|
|
if (rsp.file?.metadata?.size) {
|
|
tags.push(["size", rsp.file.metadata.size.toString()]);
|
|
}
|
|
if (rsp.file?.metadata?.magnetLink) {
|
|
tags.push(["magnet", rsp.file.metadata.magnetLink]);
|
|
const parsedMagnet = magnetURIDecode(rsp.file.metadata.magnetLink);
|
|
if (parsedMagnet?.infoHash) {
|
|
tags.push(["i", parsedMagnet?.infoHash]);
|
|
}
|
|
}
|
|
ret.header = await publisher.generic(eb => {
|
|
eb.kind(EventKind.FileHeader).content(filename);
|
|
tags.forEach(t => eb.tag(t));
|
|
return eb;
|
|
});*/
|
|
}
|
|
return ret;
|
|
} else {
|
|
return {
|
|
error: rsp.errorMessage,
|
|
};
|
|
}
|
|
}
|