feat: use @void-cat/api package
This commit is contained in:
@ -14,6 +14,7 @@
|
|||||||
"@scure/bip39": "^1.1.1",
|
"@scure/bip39": "^1.1.1",
|
||||||
"@snort/nostr": "^1.0.0",
|
"@snort/nostr": "^1.0.0",
|
||||||
"@szhsin/react-menu": "^3.3.1",
|
"@szhsin/react-menu": "^3.3.1",
|
||||||
|
"@void-cat/api": "^1.0.4",
|
||||||
"base32-decode": "^1.0.0",
|
"base32-decode": "^1.0.0",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
"dexie": "^3.2.2",
|
"dexie": "^3.2.2",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as utils from "@noble/curves/abstract/utils";
|
|
||||||
import { EventKind } from "@snort/nostr";
|
import { EventKind } from "@snort/nostr";
|
||||||
|
import { VoidApi } from "@void-cat/api";
|
||||||
|
|
||||||
import { FileExtensionRegex, VoidCatHost } from "Const";
|
import { FileExtensionRegex, VoidCatHost } from "Const";
|
||||||
import { EventPublisher } from "System/EventPublisher";
|
import { EventPublisher } from "System/EventPublisher";
|
||||||
import { UploadResult } from "Upload";
|
import { UploadResult } from "Upload";
|
||||||
@ -9,98 +10,54 @@ import { magnetURIDecode } from "Util";
|
|||||||
* Upload file to void.cat
|
* Upload file to void.cat
|
||||||
* https://void.cat/swagger/index.html
|
* https://void.cat/swagger/index.html
|
||||||
*/
|
*/
|
||||||
export default async function VoidCat(
|
export default async function VoidCatUpload(
|
||||||
file: File | Blob,
|
file: File | Blob,
|
||||||
filename: string,
|
filename: string,
|
||||||
publisher?: EventPublisher
|
publisher?: EventPublisher
|
||||||
): Promise<UploadResult> {
|
): Promise<UploadResult> {
|
||||||
const buf = await file.arrayBuffer();
|
const api = new VoidApi(VoidCatHost);
|
||||||
const digest = await crypto.subtle.digest("SHA-256", buf);
|
const uploader = api.getUploader(file);
|
||||||
|
|
||||||
const req = await fetch(`${VoidCatHost}/upload`, {
|
const rsp = await uploader.upload({
|
||||||
mode: "cors",
|
"V-Strip-Metadata": "true",
|
||||||
method: "POST",
|
|
||||||
body: buf,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/octet-stream",
|
|
||||||
"V-Content-Type": file.type,
|
|
||||||
"V-Filename": filename,
|
|
||||||
"V-Full-Digest": utils.bytesToHex(new Uint8Array(digest)),
|
|
||||||
"V-Description": "Upload from https://snort.social",
|
|
||||||
"V-Strip-Metadata": "true",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
if (rsp.ok) {
|
||||||
if (req.ok) {
|
let ext = filename.match(FileExtensionRegex);
|
||||||
const rsp: VoidUploadResponse = await req.json();
|
if (rsp.file?.metadata?.mimeType === "image/webp") {
|
||||||
if (rsp.ok) {
|
ext = ["", "webp"];
|
||||||
let ext = filename.match(FileExtensionRegex);
|
|
||||||
if (rsp.file?.metadata?.mimeType === "image/webp") {
|
|
||||||
ext = ["", "webp"];
|
|
||||||
}
|
|
||||||
const resultUrl = rsp.file?.metadata?.url ?? `${VoidCatHost}/d/${rsp.file?.id}${ext ? `.${ext[1]}` : ""}`;
|
|
||||||
|
|
||||||
const ret = {
|
|
||||||
url: resultUrl,
|
|
||||||
} as UploadResult;
|
|
||||||
|
|
||||||
if (publisher) {
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
const resultUrl = rsp.file?.metadata?.url ?? `${VoidCatHost}/d/${rsp.file?.id}${ext ? `.${ext[1]}` : ""}`;
|
||||||
|
|
||||||
|
const ret = {
|
||||||
|
url: resultUrl,
|
||||||
|
} as UploadResult;
|
||||||
|
|
||||||
|
if (publisher) {
|
||||||
|
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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
error: "Upload failed",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type VoidUploadResponse = {
|
|
||||||
ok: boolean;
|
|
||||||
file?: VoidFile;
|
|
||||||
errorMessage?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VoidFile = {
|
|
||||||
id: string;
|
|
||||||
metadata?: VoidFileMeta;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VoidFileMeta = {
|
|
||||||
version: number;
|
|
||||||
id: string;
|
|
||||||
name?: string;
|
|
||||||
size: number;
|
|
||||||
uploaded: Date;
|
|
||||||
description?: string;
|
|
||||||
mimeType?: string;
|
|
||||||
digest?: string;
|
|
||||||
url?: string;
|
|
||||||
expires?: Date;
|
|
||||||
storage?: string;
|
|
||||||
encryptionParams?: string;
|
|
||||||
magnetLink?: string;
|
|
||||||
};
|
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -2587,6 +2587,13 @@
|
|||||||
"@typescript-eslint/types" "5.59.0"
|
"@typescript-eslint/types" "5.59.0"
|
||||||
eslint-visitor-keys "^3.3.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
|
"@void-cat/api@^1.0.4":
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://git.v0l.io/api/packages/Kieran/npm/%40void-cat%2Fapi/-/1.0.4/api-1.0.4.tgz#2e2f6eddc198fcf64d7e8b1fe7326641a6ce0d43"
|
||||||
|
integrity sha512-xGAGTWrra1UxoCAvbHLUQc/ibp7/tzgUay/F3fOklVpRPzFs8bdgc35v+EEQKHT7U5RXzCkdWjyfs+5NMESlxg==
|
||||||
|
dependencies:
|
||||||
|
sjcl "^1.0.8"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.11.1":
|
"@webassemblyjs/ast@1.11.1":
|
||||||
version "1.11.1"
|
version "1.11.1"
|
||||||
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz"
|
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz"
|
||||||
@ -8209,6 +8216,11 @@ sirv@^1.0.7:
|
|||||||
mrmime "^1.0.0"
|
mrmime "^1.0.0"
|
||||||
totalist "^1.0.0"
|
totalist "^1.0.0"
|
||||||
|
|
||||||
|
sjcl@^1.0.8:
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/sjcl/-/sjcl-1.0.8.tgz#f2ec8d7dc1f0f21b069b8914a41a8f236b0e252a"
|
||||||
|
integrity sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==
|
||||||
|
|
||||||
slash@^3.0.0:
|
slash@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
|
||||||
|
Reference in New Issue
Block a user