-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphotoStorage.ts
65 lines (52 loc) · 1.8 KB
/
photoStorage.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import aws from 'aws-sdk'
import fs from 'node:fs'
import path from 'node:path'
import { PHOTO_ACCESS_KEY_ID, PHOTO_SECRET_ACCESS_KEY, PHOTO_ENDPOINT, PHOTO_BUCKET, PHOTO_STORAGE } from '../env'
type PhotoLocation =
| {
type: 'S3'
bucket: string
endpoint: string
key: string
}
| { type: 'localfile' }
type UUID = string
let downloadPhoto: (photoId: UUID) => NodeJS.ReadableStream = downloadPhotoLocally
let uploadPhoto: (args: UploadPhotoArgs) => Promise<PhotoLocation> = uploadPhotoLocally
if (PHOTO_STORAGE === 'S3') {
const credentials = new aws.Credentials(PHOTO_ACCESS_KEY_ID, PHOTO_SECRET_ACCESS_KEY)
const s3client = new aws.S3({ credentials, endpoint: PHOTO_ENDPOINT })
downloadPhoto = (photoId: UUID) => {
return s3client.getObject({ Bucket: PHOTO_BUCKET, Key: photoId }).createReadStream()
}
uploadPhoto = async ({ contents, id }: UploadPhotoArgs) => {
await s3client.upload({ Bucket: PHOTO_BUCKET, Key: id, Body: contents }).promise()
return {
type: 'S3',
bucket: PHOTO_BUCKET,
endpoint: PHOTO_ENDPOINT,
key: id,
}
}
}
export { downloadPhoto, uploadPhoto }
const localFilePath = (photoId: UUID) => path.join(__dirname, '../../temp/photos', photoId)
function downloadPhotoLocally(photoId: UUID) {
return fs.createReadStream(localFilePath(photoId))
}
type UploadPhotoArgs = {
contents: NodeJS.ReadableStream
id: UUID
}
async function uploadPhotoLocally({ contents, id }: UploadPhotoArgs) {
const filePath = localFilePath(id)
await new Promise((resolve, reject) => {
const uploadWriteStream = fs.createWriteStream(filePath, {
autoClose: true,
})
uploadWriteStream.on('error', reject)
uploadWriteStream.on('close', resolve)
contents.pipe(uploadWriteStream)
})
return { type: 'localfile' as const }
}