- Add NEXT_PUBLIC_NIP95_UPLOAD_URL to README environment variables section - Add NIP-95 upload service documentation with examples - Create .env.example file with all required environment variables - Improve error message to guide users to README for setup instructions - All TypeScript checks pass
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import type { MediaRef } from '@/types/nostr'
|
|
|
|
const MAX_IMAGE_BYTES = 5 * 1024 * 1024
|
|
const MAX_VIDEO_BYTES = 45 * 1024 * 1024
|
|
const IMAGE_TYPES = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp']
|
|
const VIDEO_TYPES = ['video/mp4', 'video/webm', 'video/quicktime']
|
|
|
|
function assertBrowser(): void {
|
|
if (typeof window === 'undefined') {
|
|
throw new Error('NIP-95 upload is only available in the browser')
|
|
}
|
|
}
|
|
|
|
function validateFile(file: File): MediaRef['type'] {
|
|
if (IMAGE_TYPES.includes(file.type)) {
|
|
if (file.size > MAX_IMAGE_BYTES) {
|
|
throw new Error('Image exceeds 5MB limit')
|
|
}
|
|
return 'image'
|
|
}
|
|
if (VIDEO_TYPES.includes(file.type)) {
|
|
if (file.size > MAX_VIDEO_BYTES) {
|
|
throw new Error('Video exceeds 45MB limit')
|
|
}
|
|
return 'video'
|
|
}
|
|
throw new Error('Unsupported media type')
|
|
}
|
|
|
|
/**
|
|
* Upload media via NIP-95.
|
|
* This implementation validates size/type then delegates to a pluggable uploader.
|
|
* The actual upload endpoint must be provided via env/config; otherwise an error is thrown.
|
|
*/
|
|
export async function uploadNip95Media(file: File): Promise<MediaRef> {
|
|
assertBrowser()
|
|
const mediaType = validateFile(file)
|
|
|
|
const endpoint = process.env.NEXT_PUBLIC_NIP95_UPLOAD_URL
|
|
if (!endpoint) {
|
|
throw new Error(
|
|
'NIP-95 upload endpoint is not configured. Please set NEXT_PUBLIC_NIP95_UPLOAD_URL environment variable. See README.md for setup instructions.'
|
|
)
|
|
}
|
|
|
|
const formData = new FormData()
|
|
formData.append('file', file)
|
|
|
|
const response = await fetch(endpoint, {
|
|
method: 'POST',
|
|
body: formData,
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const message = await response.text().catch(() => 'Upload failed')
|
|
throw new Error(message || 'Upload failed')
|
|
}
|
|
|
|
const result = (await response.json()) as { url?: string }
|
|
if (!result.url) {
|
|
throw new Error('Upload response missing URL')
|
|
}
|
|
|
|
return { url: result.url, type: mediaType }
|
|
}
|