upload endpoint moved from vercel to backend (#119)
This commit is contained in:
parent
9504fada02
commit
cf0c4455f3
|
@ -1,14 +0,0 @@
|
|||
import formidable from 'formidable'
|
||||
|
||||
export const formidablePromise = async (request, options) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const form = formidable(options)
|
||||
|
||||
form.parse(request, (err, fields, files) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
return resolve({ fields, files })
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
import { S3Client } from '@aws-sdk/client-s3'
|
||||
import { Upload } from '@aws-sdk/lib-storage'
|
||||
import formidable from 'formidable'
|
||||
import { Writable } from 'stream'
|
||||
import path from 'path'
|
||||
import crypto from 'crypto'
|
||||
import { formidablePromise } from './_shared/formidablePromise.js'
|
||||
|
||||
const { STORJ_ACCESS_KEY, STORJ_SECRET_KEY, STORJ_END_POINT, STORJ_BUCKET_NAME, CDN_DOMAIN } = process.env
|
||||
|
||||
const storjS3Client = new S3Client({
|
||||
endpoint: STORJ_END_POINT,
|
||||
credentials: {
|
||||
accessKeyId: STORJ_ACCESS_KEY,
|
||||
secretAccessKey: STORJ_SECRET_KEY
|
||||
}
|
||||
})
|
||||
|
||||
const fileConsumer = (acc) => {
|
||||
return new Writable({
|
||||
write: (chunk, _enc, next) => {
|
||||
acc.push(chunk)
|
||||
next()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const formidableConfig = {
|
||||
keepExtensions: true,
|
||||
maxFileSize: 10_000_000,
|
||||
maxFieldsSize: 10_000_000,
|
||||
maxFields: 7,
|
||||
allowEmptyFiles: false,
|
||||
multiples: false
|
||||
}
|
||||
|
||||
const handleFileUpload = async (request) => {
|
||||
const chunks = []
|
||||
const { files } = await formidablePromise(request, {
|
||||
...formidableConfig,
|
||||
// consume this, otherwise formidable tries to save the file to disk
|
||||
fileWriteStreamHandler: () => fileConsumer(chunks)
|
||||
})
|
||||
|
||||
const data = Buffer.concat(chunks)
|
||||
|
||||
const { originalFilename, mimetype } = files.file
|
||||
|
||||
const fileExtension = path.extname(originalFilename)
|
||||
|
||||
const filename = crypto.randomUUID() + fileExtension
|
||||
|
||||
const params = {
|
||||
Bucket: STORJ_BUCKET_NAME,
|
||||
Key: filename,
|
||||
Body: data,
|
||||
ContentType: mimetype
|
||||
}
|
||||
|
||||
const upload = new Upload({ params, client: storjS3Client })
|
||||
await upload.done()
|
||||
|
||||
return `http://${CDN_DOMAIN}/${filename}`
|
||||
}
|
||||
|
||||
const handler = async (request, response) => {
|
||||
try {
|
||||
const location = await handleFileUpload(request)
|
||||
return response.status(200).json(location)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
response.status(500).json({ error: error.message })
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
12
package.json
12
package.json
|
@ -29,18 +29,11 @@
|
|||
"typecheck:watch": "tsc --noEmit --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/abort-controller": "3.303.0",
|
||||
"@aws-sdk/client-s3": "3.303.0",
|
||||
"@aws-sdk/lib-storage": "3.303.0",
|
||||
"@hocuspocus/provider": "2.0.6",
|
||||
"@solid-primitives/media": "2.2.3",
|
||||
"form-data": "4.0.0",
|
||||
"formidable": "2.1.1",
|
||||
"i18next": "22.4.15",
|
||||
"mailgun.js": "8.2.1",
|
||||
"node-fetch": "3.3.1",
|
||||
"solid-popper": "0.3.0",
|
||||
"typograf": "7.1.0"
|
||||
"node-fetch": "3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.21.8",
|
||||
|
@ -54,6 +47,7 @@
|
|||
"@nanostores/router": "0.8.3",
|
||||
"@nanostores/solid": "0.3.2",
|
||||
"@popperjs/core": "2.11.7",
|
||||
"@solid-primitives/media": "2.2.3",
|
||||
"@solid-primitives/memo": "1.2.4",
|
||||
"@solid-primitives/share": "2.0.4",
|
||||
"@solid-primitives/storage": "1.3.9",
|
||||
|
@ -155,6 +149,7 @@
|
|||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"sass": "1.62.1",
|
||||
"solid-js": "1.7.5",
|
||||
"solid-popper": "0.3.0",
|
||||
"solid-tiptap": "0.6.0",
|
||||
"solid-transition-group": "0.2.2",
|
||||
"sort-package-json": "2.4.1",
|
||||
|
@ -165,6 +160,7 @@
|
|||
"swiper": "9.4.1",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "5.0.4",
|
||||
"typograf": "7.1.0",
|
||||
"undici": "5.21.0",
|
||||
"uniqolor": "1.1.0",
|
||||
"unique-names-generator": "4.7.1",
|
||||
|
|
|
@ -26,8 +26,8 @@ export const UploadModalContent = (props: Props) => {
|
|||
const runUpload = async (file) => {
|
||||
try {
|
||||
setIsUploading(true)
|
||||
const fileUrl = await handleFileUpload(file)
|
||||
props.onClose(fileUrl)
|
||||
const result = await handleFileUpload(file)
|
||||
props.onClose(result.url)
|
||||
setIsUploading(false)
|
||||
} catch (error) {
|
||||
setIsUploading(false)
|
||||
|
|
|
@ -29,7 +29,7 @@ export const DropArea = (props: Props) => {
|
|||
const results: string[] = []
|
||||
for (const file of files) {
|
||||
const result = await handleFileUpload(file)
|
||||
results.push(result)
|
||||
results.push(result.url)
|
||||
}
|
||||
props.onUpload(results)
|
||||
setLoading(false)
|
||||
|
|
|
@ -106,7 +106,7 @@ export const SolidSwiper = (props: Props) => {
|
|||
const results: string[] = []
|
||||
for (const file of selectedFiles) {
|
||||
const result = await handleFileUpload(file)
|
||||
results.push(result)
|
||||
results.push(result.url)
|
||||
}
|
||||
props.onImagesAdd(composeMediaItem(results))
|
||||
setLoading(false)
|
||||
|
|
|
@ -61,8 +61,8 @@ export const ProfileSettingsPage = () => {
|
|||
await selectFiles(async ([uploadFile]) => {
|
||||
try {
|
||||
setIsUserpicUpdating(true)
|
||||
const fileUrl = await handleFileUpload(uploadFile)
|
||||
updateFormField('userpic', fileUrl)
|
||||
const result = await handleFileUpload(uploadFile)
|
||||
updateFormField('userpic', result.url)
|
||||
setIsUserpicUpdating(false)
|
||||
} catch (error) {
|
||||
console.error('[upload avatar] error', error)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { UploadFile } from '@solid-primitives/upload'
|
||||
import { isDev } from './config'
|
||||
import { apiBaseUrl } from './config'
|
||||
|
||||
const api = isDev ? 'https://new.discours.io/api/upload' : '/api/upload'
|
||||
const apiUrl = `${apiBaseUrl}/upload`
|
||||
|
||||
export const handleFileUpload = async (uploadFile: UploadFile) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', uploadFile.file, uploadFile.name)
|
||||
const response = await fetch(api, {
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user