diff --git a/api/_shared/formidablePromise.js b/api/_shared/formidablePromise.js deleted file mode 100644 index 4b40f687..00000000 --- a/api/_shared/formidablePromise.js +++ /dev/null @@ -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 }) - }) - }) -} diff --git a/api/upload.mjs b/api/upload.mjs deleted file mode 100644 index 04ae86d2..00000000 --- a/api/upload.mjs +++ /dev/null @@ -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 diff --git a/package.json b/package.json index 867fa707..dfc1287a 100644 --- a/package.json +++ b/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", diff --git a/src/components/Editor/UploadModalContent/UploadModalContent.tsx b/src/components/Editor/UploadModalContent/UploadModalContent.tsx index b01b91e9..0e7fb83c 100644 --- a/src/components/Editor/UploadModalContent/UploadModalContent.tsx +++ b/src/components/Editor/UploadModalContent/UploadModalContent.tsx @@ -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) diff --git a/src/components/_shared/DropArea/DropArea.tsx b/src/components/_shared/DropArea/DropArea.tsx index b827368e..2a2fbe24 100644 --- a/src/components/_shared/DropArea/DropArea.tsx +++ b/src/components/_shared/DropArea/DropArea.tsx @@ -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) diff --git a/src/components/_shared/SolidSwiper/SolidSwiper.tsx b/src/components/_shared/SolidSwiper/SolidSwiper.tsx index e6802a3a..39ece589 100644 --- a/src/components/_shared/SolidSwiper/SolidSwiper.tsx +++ b/src/components/_shared/SolidSwiper/SolidSwiper.tsx @@ -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) diff --git a/src/pages/profile/profileSettings.page.tsx b/src/pages/profile/profileSettings.page.tsx index 9dbc5324..f636f774 100644 --- a/src/pages/profile/profileSettings.page.tsx +++ b/src/pages/profile/profileSettings.page.tsx @@ -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) diff --git a/src/utils/handleFileUpload.ts b/src/utils/handleFileUpload.ts index 2eecde03..c9c925d4 100644 --- a/src/utils/handleFileUpload.ts +++ b/src/utils/handleFileUpload.ts @@ -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 })