83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { NextApiRequest, NextApiResponse } from 'next'
|
|
import { IncomingForm, File as FormidableFile } from 'formidable'
|
|
import FormData from 'form-data'
|
|
import fs from 'fs'
|
|
|
|
const TARGET_ENDPOINT = 'https://nostr.build/api/v2/upload'
|
|
const MAX_FILE_SIZE = 50 * 1024 * 1024 // 50MB
|
|
|
|
export const config = {
|
|
api: {
|
|
bodyParser: false, // Disable bodyParser to handle multipart
|
|
},
|
|
}
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
if (req.method !== 'POST') {
|
|
return res.status(405).json({ error: 'Method not allowed' })
|
|
}
|
|
|
|
try {
|
|
// Parse multipart form data
|
|
const form = new IncomingForm({
|
|
maxFileSize: MAX_FILE_SIZE,
|
|
keepExtensions: true,
|
|
})
|
|
|
|
const [fields, files] = await new Promise<[Record<string, string[]>, Record<string, FormidableFile[]>>>(
|
|
(resolve, reject) => {
|
|
form.parse(req, (err, fields, files) => {
|
|
if (err) reject(err)
|
|
else resolve([fields as Record<string, string[]>, files as Record<string, FormidableFile[]>])
|
|
})
|
|
}
|
|
)
|
|
|
|
// Get the file from the parsed form
|
|
const fileField = files.file?.[0]
|
|
if (!fileField) {
|
|
return res.status(400).json({ error: 'No file provided' })
|
|
}
|
|
|
|
// Create FormData for the target endpoint
|
|
const formData = new FormData()
|
|
const fileStream = fs.createReadStream(fileField.filepath)
|
|
formData.append('file', fileStream, {
|
|
filename: fileField.originalFilename || fileField.newFilename || 'upload',
|
|
contentType: fileField.mimetype || 'application/octet-stream',
|
|
})
|
|
|
|
// Forward to target endpoint
|
|
const response = await fetch(TARGET_ENDPOINT, {
|
|
method: 'POST',
|
|
body: formData as unknown as BodyInit,
|
|
headers: {
|
|
...formData.getHeaders(),
|
|
},
|
|
})
|
|
|
|
// Clean up temporary file
|
|
try {
|
|
fs.unlinkSync(fileField.filepath)
|
|
} catch (unlinkError) {
|
|
console.error('Error deleting temp file:', unlinkError)
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text()
|
|
return res.status(response.status).json({
|
|
error: errorText || `Upload failed: ${response.status} ${response.statusText}`,
|
|
})
|
|
}
|
|
|
|
const result = await response.json()
|
|
return res.status(200).json(result)
|
|
} catch (error) {
|
|
console.error('NIP-95 proxy error:', error)
|
|
return res.status(500).json({
|
|
error: error instanceof Error ? error.message : 'Internal server error',
|
|
})
|
|
}
|
|
}
|
|
|