Skip to content

Commit f08e2a3

Browse files
committed
feat: File service logic
1 parent 6d50d2e commit f08e2a3

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

services/files/files.class.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { Application } from '@feathersjs/express';
22
import { Params } from '@feathersjs/feathers';
33
import { v4 } from 'uuid';
4+
import axios from 'axios';
5+
import fs from 'fs';
6+
import path from 'path';
7+
import { User } from 'which-types';
48

59
// Use require to avoid bug
610
// https://stackoverflow.com/questions/62611373/heroku-crashes-when-importing-aws-sdk
@@ -13,15 +17,68 @@ export default class Files {
1317
bucket!: string;
1418

1519
async find(params: Params): Promise<string> {
20+
const path = this.generateS3Path(params.user?.username);
21+
return this.getUploadUrl(path);
22+
}
23+
24+
public isS3url(url: string): boolean {
25+
return url.startsWith('https://${this.bucket}.s3');
26+
}
27+
28+
public generateS3Path(prefix='', ext='png'): string {
29+
const key = v4();
30+
const fileName = `${key}.${ext}`;
31+
return prefix ? `${prefix}/${fileName}` : fileName;
32+
}
33+
34+
async getUploadUrl(path: string): Promise<string> {
1635
// Return signed upload URL
1736
return this.s3.getSignedUrl('putObject', {
1837
Bucket: this.bucket,
19-
Key: `${params.user?.username}/${v4()}.png`,
38+
Key: path,
2039
ContentType: 'image/*',
2140
Expires: 300,
2241
});
2342
}
2443

44+
async getDownloadUrl(path: string): Promise<string> {
45+
return this.getUploadUrl(path).then((url: string) => {
46+
const queryIndex = url.indexOf('?');
47+
return url.slice(0, queryIndex);
48+
})
49+
}
50+
51+
private createTmpDir() {
52+
if (!fs.existsSync('tmp')) fs.mkdirSync('tmp');
53+
}
54+
55+
async downloadFile(url: string): Promise<string> {
56+
return new Promise(async (resolve, reject) => {
57+
this.createTmpDir();
58+
const filePath = `tmp/${v4()}`;
59+
const fileStream = fs.createWriteStream(filePath);
60+
const response = await axios.get(url, { responseType: 'stream' })
61+
response.data.pipe(fileStream)
62+
.on('error', reject)
63+
.on('close', () => resolve(filePath));
64+
});
65+
}
66+
67+
async uploadFileToS3(filePath: string, s3Path: string) {
68+
const fileStream = fs.createReadStream(filePath);
69+
const request = this.s3.upload({
70+
Bucket: this.bucket,
71+
Key: s3Path,
72+
Body: fileStream,
73+
ContentType: 'image/png'
74+
});
75+
request.on('httpUploadProgress', progress => {
76+
console.log('progress', progress);
77+
})
78+
await request.promise();
79+
return this.getDownloadUrl(s3Path);
80+
}
81+
2582
setup(app: Application): void {
2683
this.app = app;
2784
this.s3 = new S3({

0 commit comments

Comments
 (0)