-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
121 lines (105 loc) · 4.22 KB
/
index.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
109
110
111
112
113
114
115
116
117
118
119
120
121
'use strict';
const AWS = require('aws-sdk/global'),
AWS_S3 = require('aws-sdk/clients/s3'),
S3 = new AWS_S3({ signatureVersion: 'v4' }),
Sharp = require('sharp');
exports.handler = (event, context, callback) => {
console.log('Started event:', event);
const { attachment, copy_original, path, storages, versions } = event,
originalBucket = storages[attachment.storage],
originalKey = originalBucket.prefix ? `${originalBucket.prefix}/${attachment.id}` : attachment.id,
targetStorage = event.target_storage,
targetBucket = storages[targetStorage];
S3.getObject({ Bucket: originalBucket.name, Key: originalKey }).promise()
.then(data => {
const versionPromises = [];
if (versions)
for(const version of versions) {
versionPromises.push(resizeToBucket(data, storages, path, version)
.catch(reason => console.log(`Error on version: ${version.name}, reason: ${reason}`))
)
}
if (copy_original && copy_original === true)
versionPromises.push(bufferToBucket(data.Body, targetBucket,
formPath(targetBucket.prefix, path, attachment),
'original',
targetStorage,
attachment.metadata));
Promise.all(versionPromises)
.then(function(values) {
const payload = { context: event.context };
if (versions)
payload.versions = values;
else
payload.original = values[0].original;
sendResult(event.callbackURL, attachment.metadata.key, payload);
})
})
.catch(err => callback(err));
};
function resizeToBucket(data, storages, path, version) {
return new Promise(resolve => {
const pipeline = Sharp(data.Body).resize(version.width, version.height),
format = version.format,
storage = version.storage,
bucket = storages[storage];
if (format)
pipeline.toFormat(format);
pipeline.toBuffer()
.then((buffer) => {
resolve(bufferToBucket(buffer, bucket, formPath(bucket.prefix, path, version), version.name, storage));
})
});
}
function bufferToBucket(buffer, bucket, key, version_name, storage, metadata = {}) {
return new Promise(resolve => {
S3.putObject({
ACL: bucket.upload_options.acl,
Body : buffer,
Bucket : bucket.name,
Key : key },
() => {
console.log('Buffer stored:', key);
const prefix = bucket.prefix;
// If the key is starting with the bucket.prefix, remove the prefix - it is a storage property
if (key.indexOf(prefix) === 0)
key = key.slice(prefix.length + 1);
resolve({ [`${version_name}`]: { storage : storage, id : key, metadata : metadata } })
}
);
})
}
function formPath(prefix = null, path, { format = null, name = null }) {
let result = prefix ? `${prefix}/${path}` : path;
if (name) {
result = result.split('/');
const lastElementIndex = result.length - 1;
let filename = `${name}-${result[lastElementIndex]}`;
if (format)
filename = `${filename}.${format}`;
result[lastElementIndex] = filename;
result = result.join('/');
}
return result;
}
function sendResult (callbackURL, key, payload) {
console.log('Starting PUT request to callbackURL:', callbackURL);
const endpoint = new AWS.Endpoint(callbackURL);
let request = new AWS.HttpRequest(endpoint);
request.region = process.env.AWS_REGION;
request.method = 'PUT';
request.headers['Content-Type'] = 'application/json';
request.headers['Host'] = endpoint.host;
request.body = JSON.stringify(payload);
const signer = new AWS.Signers.V4(request, process.env.AWS_LAMBDA_FUNCTION_NAME);
signer.addAuthorization({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: key }, new Date());
console.log('Request:', request);
const send = new AWS.NodeHttpClient();
send.handleRequest(request, null, response => {
let respBody = '';
response.on('data', chunk => { respBody += chunk; });
response.on('end', () => { console.log('RESPONSE: ', respBody); });
}, err => {
console.log(`Error: ${err}`);
});
}