Add a nostr.build uploader
This commit is contained in:
parent
1c4dbc9520
commit
c89be75e5b
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Upload successful.",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"input_name": "APIv2",
|
||||||
|
"name": "e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"sha256": "0a71f1c9dd982079bc52e96403368209cbf9507c5f6956134686f56e684b6377",
|
||||||
|
"original_sha256": "e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3",
|
||||||
|
"type": "picture",
|
||||||
|
"mime": "image/gif",
|
||||||
|
"size": 1796276,
|
||||||
|
"blurhash": "LGH-S^Vwm]x]04kX-qR-R]SL5FxZ",
|
||||||
|
"dimensions": {
|
||||||
|
"width": 360,
|
||||||
|
"height": 216
|
||||||
|
},
|
||||||
|
"dimensionsString": "360x216",
|
||||||
|
"url": "https://image.nostr.build/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"thumbnail": "https://image.nostr.build/thumb/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"responsive": {
|
||||||
|
"240p": "https://image.nostr.build/resp/240p/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"360p": "https://image.nostr.build/resp/360p/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"480p": "https://image.nostr.build/resp/480p/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"720p": "https://image.nostr.build/resp/720p/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif",
|
||||||
|
"1080p": "https://image.nostr.build/resp/1080p/e5f6e0e380536780efa774e8d3c8a5a040e3f9f99dbb48910b261c32872ee3a3.gif"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"date:create": "2024-05-18T02:11:39+00:00",
|
||||||
|
"date:modify": "2024-05-18T02:11:39+00:00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Upload successful.",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"input_name": "APIv2",
|
||||||
|
"name": "f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"url": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"thumbnail": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"responsive": {
|
||||||
|
"240p": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"360p": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"480p": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"720p": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3",
|
||||||
|
"1080p": "https://media.nostr.build/av/f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725.mp3"
|
||||||
|
},
|
||||||
|
"blurhash": "",
|
||||||
|
"sha256": "f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725",
|
||||||
|
"original_sha256": "f94665e6877741feb3fa3031342f95ae2ee00caae1cc651ce31ed6d524e05725",
|
||||||
|
"type": "video",
|
||||||
|
"mime": "audio/mpeg",
|
||||||
|
"size": 1519616,
|
||||||
|
"metadata": [],
|
||||||
|
"dimensions": [],
|
||||||
|
"dimensionsString": "0x0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -136,6 +136,10 @@ class Conf {
|
||||||
return Deno.env.get('IPFS_API_URL') || 'http://localhost:5001';
|
return Deno.env.get('IPFS_API_URL') || 'http://localhost:5001';
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
/** nostr.build API endpoint when the `nostrbuild` uploader is used. */
|
||||||
|
static get nostrbuildEndpoint(): string {
|
||||||
|
return Deno.env.get('NOSTRBUILD_ENDPOINT') || 'https://nostr.build/api/v2/upload/files';
|
||||||
|
}
|
||||||
/** Module to upload files with. */
|
/** Module to upload files with. */
|
||||||
static get uploader() {
|
static get uploader() {
|
||||||
return Deno.env.get('DITTO_UPLOADER');
|
return Deno.env.get('DITTO_UPLOADER');
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const nostrbuildFileSchema = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
url: z.string().url(),
|
||||||
|
thumbnail: z.string(),
|
||||||
|
blurhash: z.string(),
|
||||||
|
sha256: z.string(),
|
||||||
|
mime: z.string(),
|
||||||
|
dimensions: z.object({
|
||||||
|
width: z.number(),
|
||||||
|
height: z.number(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const nostrbuildSchema = z.object({
|
||||||
|
data: nostrbuildFileSchema.array().min(1),
|
||||||
|
});
|
|
@ -16,7 +16,7 @@ async function uploadFile(file: File, meta: FileMeta, signal?: AbortSignal): Pro
|
||||||
throw new Error('File size is too large.');
|
throw new Error('File size is too large.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { url, sha256, cid } = await uploader.upload(file, { signal });
|
const { url, sha256, cid, blurhash } = await uploader.upload(file, { signal });
|
||||||
|
|
||||||
const data: string[][] = [
|
const data: string[][] = [
|
||||||
['url', url],
|
['url', url],
|
||||||
|
@ -32,6 +32,10 @@ async function uploadFile(file: File, meta: FileMeta, signal?: AbortSignal): Pro
|
||||||
data.push(['cid', cid]);
|
data.push(['cid', cid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blurhash) {
|
||||||
|
data.push(['blurhash', blurhash]);
|
||||||
|
}
|
||||||
|
|
||||||
if (description) {
|
if (description) {
|
||||||
data.push(['alt', description]);
|
data.push(['alt', description]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Conf } from '@/config.ts';
|
||||||
|
|
||||||
import { ipfsUploader } from '@/uploaders/ipfs.ts';
|
import { ipfsUploader } from '@/uploaders/ipfs.ts';
|
||||||
import { localUploader } from '@/uploaders/local.ts';
|
import { localUploader } from '@/uploaders/local.ts';
|
||||||
|
import { nostrbuildUploader } from '@/uploaders/nostrbuild.ts';
|
||||||
import { s3Uploader } from '@/uploaders/s3.ts';
|
import { s3Uploader } from '@/uploaders/s3.ts';
|
||||||
|
|
||||||
import type { Uploader } from './types.ts';
|
import type { Uploader } from './types.ts';
|
||||||
|
@ -25,6 +26,8 @@ function uploader() {
|
||||||
return ipfsUploader;
|
return ipfsUploader;
|
||||||
case 'local':
|
case 'local':
|
||||||
return localUploader;
|
return localUploader;
|
||||||
|
case 'nostrbuild':
|
||||||
|
return nostrbuildUploader;
|
||||||
default:
|
default:
|
||||||
throw new Error('No `DITTO_UPLOADER` configured. Uploads are disabled.');
|
throw new Error('No `DITTO_UPLOADER` configured. Uploads are disabled.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Conf } from '@/config.ts';
|
||||||
|
import { nostrbuildSchema } from '@/schemas/nostrbuild.ts';
|
||||||
|
|
||||||
|
import type { Uploader } from './types.ts';
|
||||||
|
|
||||||
|
/** nostr.build uploader. */
|
||||||
|
export const nostrbuildUploader: Uploader = {
|
||||||
|
async upload(file) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('fileToUpload', file);
|
||||||
|
|
||||||
|
const response = await fetch(Conf.nostrbuildEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await response.json();
|
||||||
|
console.log(JSON.stringify(json));
|
||||||
|
|
||||||
|
const [data] = nostrbuildSchema.parse(json).data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: data.url,
|
||||||
|
sha256: data.sha256,
|
||||||
|
url: data.url,
|
||||||
|
blurhash: data.blurhash,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// deno-lint-ignore require-await
|
||||||
|
async delete(): Promise<void> {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
|
@ -14,6 +14,8 @@ interface UploadResult {
|
||||||
url: string;
|
url: string;
|
||||||
/** SHA-256 hash of the file. */
|
/** SHA-256 hash of the file. */
|
||||||
sha256?: string;
|
sha256?: string;
|
||||||
|
/** Blurhash of the file. */
|
||||||
|
blurhash?: string;
|
||||||
/** IPFS CID of the file. */
|
/** IPFS CID of the file. */
|
||||||
cid?: string;
|
cid?: string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue