Сценарий здесь:
Шаг 1: Получить загруженное изображение из GraphQL (Итак, это ReadableStream)
Шаг 2: Использовать Sharp для генерации размеров изображения
Шаг 3: Загрузить все размеры изображения на S3
Вот мой код
UploadRepository.ts
import {FileUpload} from "graphql-upload";
import {S3Client} from "../../services/aws-s3-client";
import uuid from "uuid/v4";
import {MediaUpload} from "../../entity/MediaUpload";
import sharp from "sharp";
const resizeImageWidth = [200, 408, 560, 692, 800];
export class UploadRepository {
protected s3client: S3Client;
constructor() {
this.s3client = new S3Client()
}
async uploadImage(fileUpload: FileUpload): Promise<MediaUpload> {
try {
const extension = fileUpload.filename.split('.').slice(-1)[0];
const fileNamePrefix = uuid();
const transform = sharp();
for (const imageSize of resizeImageWidth) {
const fileNameWithSizeAndExtenstion = `${fileNamePrefix}_${imageSize}.${extension}`;
transform
.clone()
.resize(imageSize)
.webp()
.pipe(this.s3client)
.put(fileNameWithSizeAndExtenstion, fileUpload.mimetype, fileUpload.encoding);
}
fileUpload.createReadStream().pipe(transform);
// Trying the get the response from the S3 Promises provided to the transform
return {
fileName: fileUpload.filename,
mimeType: fileUpload.mimetype,
urls: ['', '']
};
} catch (e) {
console.log(e);
throw new Error(e)
}
}
}
s3Client.ts
import {default as S3} from "aws-sdk/clients/s3";
import {ManagedUpload} from "aws-sdk/lib/s3/managed_upload";
import moment from "moment";
import {Writable, WritableOptions} from "stream";
export class S3Client extends Writable{
protected client: S3;
protected data: any;
constructor(opts?: WritableOptions) {
super(opts);
this.client = new S3({
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.S3_REGION
})
}
_write(chunk: any) {
this.data += chunk;
}
public put(fileName: string, mimeType: string, encoding: string): Promise<ManagedUpload.SendData> {
return this.client.upload({
Bucket: `${process.env.S3_BUCKET}/${this.getLocaiton()}`,
Key: fileName,
Body: this.data,
ContentType: `${mimeType}; charset=utf-8`,
ACL: 'public-read',
CacheControl: 'max-age=60',
ContentEncoding: encoding
}).promise();
}
getLocaiton(): string {
const yearMonthFolder = moment().format('YYYY/MM');
return `uploads/${yearMonthFolder}`;
}
}
Я застрял здесь в том, как собрать ответ на все обещания и вернуть Местоположение S3.
Заранее спасибо.