diff options
author | eug-vs <eug-vs@keemail.me> | 2020-08-12 18:35:10 +0300 |
---|---|---|
committer | eug-vs <eug-vs@keemail.me> | 2020-08-12 18:35:10 +0300 |
commit | f08e2a37677e711cad7397c532670913645f010a (patch) | |
tree | 60b2867a7677ba5e6243e0c7da171fd64b1c18d1 | |
parent | 6d50d2ef3a64b8fe5037861cda8daab40f9a7213 (diff) | |
download | which-api-f08e2a37677e711cad7397c532670913645f010a.tar.gz |
feat: File service logic
-rw-r--r-- | services/files/files.class.ts | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/services/files/files.class.ts b/services/files/files.class.ts index e2f9df3..7e4bcbf 100644 --- a/services/files/files.class.ts +++ b/services/files/files.class.ts @@ -1,6 +1,10 @@ import { Application } from '@feathersjs/express'; import { Params } from '@feathersjs/feathers'; import { v4 } from 'uuid'; +import axios from 'axios'; +import fs from 'fs'; +import path from 'path'; +import { User } from 'which-types'; // Use require to avoid bug // https://stackoverflow.com/questions/62611373/heroku-crashes-when-importing-aws-sdk @@ -13,15 +17,68 @@ export default class Files { 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, }); } + 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(async (resolve, reject) => { + this.createTmpDir(); + const filePath = `tmp/${v4()}`; + const fileStream = fs.createWriteStream(filePath); + const response = await axios.get(url, { responseType: 'stream' }) + response.data.pipe(fileStream) + .on('error', reject) + .on('close', () => resolve(filePath)); + }); + } + + async uploadFileToS3(filePath: string, s3Path: string) { + const fileStream = fs.createReadStream(filePath); + const request = this.s3.upload({ + Bucket: this.bucket, + Key: s3Path, + Body: fileStream, + ContentType: 'image/png' + }); + request.on('httpUploadProgress', progress => { + console.log('progress', progress); + }) + await request.promise(); + return this.getDownloadUrl(s3Path); + } + setup(app: Application): void { this.app = app; this.s3 = new S3({ |