webapp/api/upload.ts
2022-12-03 14:00:29 +03:00

81 lines
2.0 KiB
TypeScript

// pages/api/upload.ts
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { createPresignedPost } from '@aws-sdk/s3-presigned-post'
import formidable from 'formidable'
import fs from 'fs'
const putObject = async (s3Client, key, body, contentType) => {
// workaround for the issue: https://github.com/aws/aws-sdk-js-v3/issues/1800
s3Client.middlewareStack.add(
(next, _context) => (args) => {
delete args.request.headers['content-type']
return next(args)
},
{
step: 'build'
}
)
const objectParams = {
ACL: 'public-read',
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
Body: body,
ContentType: contentType
}
const results = await s3Client.send(new PutObjectCommand(objectParams))
return results
}
const parseFormData = (req) => {
return new Promise((resolve, reject) => {
const form = new formidable.IncomingForm({
multiples: true,
keepExtensions: true
})
form.parse(req, (err, fields, files) => {
if (err) {
reject(err)
}
resolve({ fields, files })
})
})
}
export async function handler(req, res) {
const s3Client = new S3Client({
region: process.env.S3_REGION || 'eu-west-1',
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY
}
})
if (req.method === 'POST') {
const data: any = await parseFormData(req)
const files = data?.files
const image = files.image
const body = fs.readFileSync(image.path)
// const resp = await putObject(s3Client, image.name, body, image.type)
const resp = await createPresignedPost(s3Client, {
Bucket: process.env.S3_BUCKET_NAME || 'discours-io',
Key: image.path,
Fields: {
acl: 'public-read',
'Content-Type': image.type
},
Expires: 600, // seconds
Conditions: [
['content-length-range', 0, 22 * 1048576] // up to 22 MB
]
})
return res.status(200).json(resp)
}
return res.status(405).end()
}