@mason-api/javascript-sdk
Version:
Mason component rendering library
90 lines (85 loc) • 3.14 kB
JavaScript
import _ from 'lodash';
import update from 'immutability-helper';
import { CONFIG, UUID } from '@mason-api/utils';
const BUCKET_NAME = 'bucketName';
const IDENTITY_POOL_ID = 'identityPoolId';
const REGION = 'region';
export const schema = {
id: 's3',
name: 'S3',
keys: {
BUCKET_NAME,
IDENTITY_POOL_ID,
REGION,
},
requiredKeys: [BUCKET_NAME, IDENTITY_POOL_ID, REGION],
spec: [
{ key: BUCKET_NAME, value: '' },
{ key: IDENTITY_POOL_ID, value: '' },
{ key: REGION, value: '' },
],
};
const s3 = {};
export default {
has: config => _.every(schema.requiredKeys, key => !_.isEmpty(CONFIG.getValueForIntegration(config, schema.id, key))),
init: getContext => next => config => {
const bucket = CONFIG.getValueForIntegration(config, schema.id, BUCKET_NAME);
if (!_.has(s3, bucket)) {
if (!_.isObject(AWS)) {
throw new Error('AWS not found. Please include AWS SDK script, visit https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-the-jssdk.html for more details');
} else {
AWS.config.update({
region: CONFIG.getValueForIntegration(config, schema.id, REGION),
credentials: new AWS.CognitoIdentityCredentials({
IdentityPoolId: CONFIG.getValueForIntegration(config, schema.id, IDENTITY_POOL_ID),
}),
});
s3[bucket] = new AWS.S3({
apiVersion: '2006-03-01',
params: { Bucket: bucket },
});
}
}
return next(config);
},
render: getContext => next => (config, configSubpath, target, props) => {
return next(config, configSubpath, target, {
...props,
willSendData: (form, formName) => {
const bucket = CONFIG.getValueForIntegration(config, schema.id, BUCKET_NAME);
const fileInputs = form.querySelectorAll('input[type="file"]');
const files = _.reduce(fileInputs, (result, input) => {
if (input.files.length) { // accept single files for now
return _.concat(result, {
file: input.files[0],
name: input.getAttribute('name'),
required: input.getAttribute('required'),
});
}
return result;
}, []);
if (!_.isEmpty(files)) {
return Promise.all(_.map(files, ({ file, name, required }) => s3[bucket].upload({
Key: `${UUID.uuidv4()}-${file.name}`,
Body: file,
ACL: 'bucket-owner-full-control',
}).promise()
.then(({ Location }) => Promise.resolve({ [name]: Location }))
.catch(() => {
if (required) {
return Promise.reject(false);
}
return Promise.resolve({});
})))
.then(uploads => _.get(props, 'willSendData', _.identity)(_.reduce(uploads, (result, upload) =>
update(result, {
data: {
$merge: upload,
},
}), form)), formName, componentId);
}
return _.get(props, 'willSendData', _.identity)(form, formName, componentId);
},
});
}
};