aboutsummaryrefslogtreecommitdiff
path: root/services/files/files.class.ts
diff options
context:
space:
mode:
Diffstat (limited to 'services/files/files.class.ts')
-rw-r--r--services/files/files.class.ts69
1 files changed, 64 insertions, 5 deletions
diff --git a/services/files/files.class.ts b/services/files/files.class.ts
index e2f9df3..f2a0960 100644
--- a/services/files/files.class.ts
+++ b/services/files/files.class.ts
@@ -1,27 +1,86 @@
import { Application } from '@feathersjs/express';
import { Params } from '@feathersjs/feathers';
import { v4 } from 'uuid';
+import axios from 'axios';
+import fs from 'fs';
// Use require to avoid bug
// https://stackoverflow.com/questions/62611373/heroku-crashes-when-importing-aws-sdk
+// TODO: use import statement
+// eslint-disable-next-line
const S3 = require('aws-sdk/clients/s3');
export default class Files {
- app!: Application;
- s3!: any;
- bucket!: string;
+ public app!: Application;
+
+ private s3!: typeof S3;
+
+ private bucket!: string;
async find(params: Params): Promise<string> {
+ const path = this.generateS3Path(params.user?.username);
+ return this.getUploadUrl(path);
+ }
+
+ public isS3url(url: string): boolean {
+ return url.startsWith(`https://${this.bucket}.s3`);
+ }
+
+ public generateS3Path(prefix = '', ext = 'png'): string {
+ const key = v4();
+ const fileName = `${key}.${ext}`;
+ return prefix ? `${prefix}/${fileName}` : fileName;
+ }
+
+ async getUploadUrl(path: string): Promise<string> {
// Return signed upload URL
return this.s3.getSignedUrl('putObject', {
Bucket: this.bucket,
- Key: `${params.user?.username}/${v4()}.png`,
+ Key: path,
ContentType: 'image/*',
- Expires: 300,
+ Expires: 300
});
}
+ async getDownloadUrl(path: string): Promise<string> {
+ return this.getUploadUrl(path).then((url: string) => {
+ const queryIndex = url.indexOf('?');
+ return url.slice(0, queryIndex);
+ });
+ }
+
+ private createTmpDir() {
+ if (!fs.existsSync('tmp')) fs.mkdirSync('tmp');
+ }
+
+ async downloadFile(url: string): Promise<string> {
+ return new Promise((resolve, reject) => {
+ this.createTmpDir();
+ const filePath = `tmp/${v4()}`;
+ const fileStream = fs.createWriteStream(filePath);
+ axios.get(url, { responseType: 'stream' })
+ .then(response => {
+ response.data.pipe(fileStream)
+ .on('error', reject)
+ .on('close', () => resolve(filePath));
+ })
+ .catch(error => reject(error));
+ });
+ }
+
+ async uploadFileToS3(filePath: string, s3Path: string): Promise<string> {
+ const fileStream = fs.createReadStream(filePath);
+ await this.s3.upload({
+ Bucket: this.bucket,
+ Key: s3Path,
+ Body: fileStream,
+ ContentType: 'image/png'
+ }).promise();
+ fs.unlinkSync(filePath);
+ return this.getDownloadUrl(s3Path);
+ }
+
setup(app: Application): void {
this.app = app;
this.s3 = new S3({