-
Notifications
You must be signed in to change notification settings - Fork 40
/
GetOrCreateImage.js
108 lines (96 loc) · 2.78 KB
/
GetOrCreateImage.js
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
'use strict'
const AWS = require('aws-xray-sdk').captureAWS(require('aws-sdk'))
const Sharp = require('sharp')
const { parse } = require('querystring')
const S3 = new AWS.S3()
const GetOrCreateImage = async event => {
const {
cf: {
request: {
origin: {
s3: {
domainName
}
},
querystring,
uri
},
response,
response: {
status
}
}
} = event.Records[0]
if (!['403', '404'].includes(status)) return response
let { height, nextExtension,sourceImage, width } = parse(querystring)
const [bucket] = domainName.match(/.+(?=\.s3\.amazonaws\.com)/i)
const contentType = 'image/' + nextExtension
const key = uri.replace(/^\//, '')
const sourceKey = sourceImage.replace(/^\//, '')
height = parseInt(height, 10) || null
width = parseInt(width, 10)
if (!width) return response
return S3.getObject({ Bucket: bucket, Key: sourceKey })
.promise()
.then(imageObj => {
let resizedImage
const errorMessage = `Error while resizing "${sourceKey}" to "${key}":`
// Required try/catch because Sharp.catch() doesn't seem to actually catch anything.
try {
resizedImage = Sharp(imageObj.Body)
.resize(width, height)
.toFormat(nextExtension, {
/**
* @see https://sharp.pixelplumbing.com/api-output#webp for a list of options.
*/
quality: 95
})
.toBuffer()
.catch(error => {
throw new Error(`${errorMessage} ${error}`)
})
} catch(error) {
throw new Error(`${errorMessage} ${error}`)
}
return resizedImage
})
.then(async imageBuffer => {
await S3.putObject({
Body: imageBuffer,
Bucket: bucket,
ContentType: contentType,
Key: key,
StorageClass: 'STANDARD'
})
.promise()
.catch(error => {
throw new Error(`Error while putting resized image '${uri}' into bucket: ${error}`)
})
return {
...response,
status: 200,
statusDescription: 'Found',
body: imageBuffer.toString('base64'),
bodyEncoding: 'base64',
headers: {
...response.headers,
'content-type': [{ key: 'Content-Type', value: contentType }]
}
}
})
.catch(error => {
const errorMessage = `Error while getting source image object "${sourceKey}": ${error}`
return {
...response,
status: 404,
statusDescription: 'Not Found',
body: errorMessage,
bodyEncoding: 'text',
headers: {
...response.headers,
'content-type': [{ key: 'Content-Type', value: 'text/plain' }]
}
}
})
}
module.exports = GetOrCreateImage