UNPKG

@mason-api/javascript-sdk

Version:

Mason component rendering library

90 lines (85 loc) 3.14 kB
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); }, }); } };