@aws-amplify/storage
Version:
Storage category of aws-amplify
418 lines • 21.7 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
* Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
var core_1 = require("@aws-amplify/core");
var S3 = require("aws-sdk/clients/s3");
var logger = new core_1.ConsoleLogger('AWSS3Provider');
var AMPLIFY_SYMBOL = ((typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') ?
Symbol.for('amplify_default') : '@@amplify_default');
var dispatchStorageEvent = function (track, event, attrs, metrics, message) {
if (track) {
core_1.Hub.dispatch('storage', {
event: event,
data: { attrs: attrs, metrics: metrics },
message: message
}, 'Storage', AMPLIFY_SYMBOL);
}
};
/**
* Provide storage methods to use AWS S3
*/
var AWSS3Provider = /** @class */ (function () {
/**
* Initialize Storage with AWS configurations
* @param {Object} config - Configuration object for storage
*/
function AWSS3Provider(config) {
this._config = config ? config : {};
logger.debug('Storage Options', this._config);
}
/**
* get the category of the plugin
*/
AWSS3Provider.prototype.getCategory = function () {
return AWSS3Provider.CATEGORY;
};
/**
* get provider name of the plugin
*/
AWSS3Provider.prototype.getProviderName = function () {
return AWSS3Provider.PROVIDER_NAME;
};
/**
* Configure Storage part with aws configuration
* @param {Object} config - Configuration of the Storage
* @return {Object} - Current configuration
*/
AWSS3Provider.prototype.configure = function (config) {
logger.debug('configure Storage', config);
if (!config)
return this._config;
var amplifyConfig = core_1.Parser.parseMobilehubConfig(config);
this._config = Object.assign({}, this._config, amplifyConfig.Storage);
if (!this._config.bucket) {
logger.debug('Do not have bucket yet');
}
return this._config;
};
/**
* Get a presigned URL of the file or the object data when download:true
*
* @param {String} key - key of the object
* @param {Object} [config] - { level : private|protected|public, download: true|false }
* @return - A promise resolves to Amazon S3 presigned URL on success
*/
AWSS3Provider.prototype.get = function (key, config) {
return __awaiter(this, void 0, void 0, function () {
var credentialsOK, opt, bucket, region, credentials, level, download, track, expires, prefix, final_key, s3, params;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._ensureCredentials()];
case 1:
credentialsOK = _a.sent();
if (!credentialsOK) {
return [2 /*return*/, Promise.reject('No credentials')];
}
opt = Object.assign({}, this._config, config);
bucket = opt.bucket, region = opt.region, credentials = opt.credentials, level = opt.level, download = opt.download, track = opt.track, expires = opt.expires;
prefix = this._prefix(opt);
final_key = prefix + key;
s3 = this._createS3(opt);
logger.debug('get ' + key + ' from ' + final_key);
params = {
Bucket: bucket,
Key: final_key
};
if (download === true) {
return [2 /*return*/, new Promise(function (res, rej) {
s3.getObject(params, function (err, data) {
if (err) {
dispatchStorageEvent(track, 'download', {
method: 'get',
result: 'failed'
}, null, "Download failed with " + err.message);
rej(err);
}
else {
dispatchStorageEvent(track, 'download', { method: 'get', result: 'success' }, { fileSize: Number(data.Body['length']) }, "Download success for " + key);
res(data);
}
});
})];
}
if (expires) {
params.Expires = expires;
}
return [2 /*return*/, new Promise(function (res, rej) {
try {
var url = s3.getSignedUrl('getObject', params);
dispatchStorageEvent(track, 'getSignedUrl', { method: 'get', result: 'success' }, null, "Signed URL: " + url);
res(url);
}
catch (e) {
logger.warn('get signed url error', e);
dispatchStorageEvent(track, 'getSignedUrl', { method: 'get', result: 'failed' }, null, "Could not get a signed URL for " + key);
rej(e);
}
})];
}
});
});
};
/**
* Put a file in S3 bucket specified to configure method
* @param {String} key - key of the object
* @param {Object} object - File to be put in Amazon S3 bucket
* @param {Object} [config] - { level : private|protected|public, contentType: MIME Types,
* progressCallback: function }
* @return - promise resolves to object on success
*/
AWSS3Provider.prototype.put = function (key, object, config) {
return __awaiter(this, void 0, void 0, function () {
var credentialsOK, opt, bucket, region, credentials, level, track, progressCallback, contentType, contentDisposition, cacheControl, expires, metadata, tagging, serverSideEncryption, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId, type, prefix, final_key, s3, params, upload, data, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._ensureCredentials()];
case 1:
credentialsOK = _a.sent();
if (!credentialsOK) {
return [2 /*return*/, Promise.reject('No credentials')];
}
opt = Object.assign({}, this._config, config);
bucket = opt.bucket, region = opt.region, credentials = opt.credentials, level = opt.level, track = opt.track, progressCallback = opt.progressCallback;
contentType = opt.contentType, contentDisposition = opt.contentDisposition, cacheControl = opt.cacheControl, expires = opt.expires, metadata = opt.metadata, tagging = opt.tagging;
serverSideEncryption = opt.serverSideEncryption, SSECustomerAlgorithm = opt.SSECustomerAlgorithm, SSECustomerKey = opt.SSECustomerKey, SSECustomerKeyMD5 = opt.SSECustomerKeyMD5, SSEKMSKeyId = opt.SSEKMSKeyId;
type = contentType ? contentType : 'binary/octet-stream';
prefix = this._prefix(opt);
final_key = prefix + key;
s3 = this._createS3(opt);
logger.debug('put ' + key + ' to ' + final_key);
params = {
Bucket: bucket,
Key: final_key,
Body: object,
ContentType: type
};
if (cacheControl) {
params.CacheControl = cacheControl;
}
if (contentDisposition) {
params.ContentDisposition = contentDisposition;
}
if (expires) {
params.Expires = expires;
}
if (metadata) {
params.Metadata = metadata;
}
if (tagging) {
params.Tagging = tagging;
}
if (serverSideEncryption) {
params.ServerSideEncryption = serverSideEncryption;
if (SSECustomerAlgorithm) {
params.SSECustomerAlgorithm = SSECustomerAlgorithm;
}
if (SSECustomerKey) {
params.SSECustomerKey = SSECustomerKey;
}
if (SSECustomerKeyMD5) {
params.SSECustomerKeyMD5 = SSECustomerKeyMD5;
}
if (SSEKMSKeyId) {
params.SSEKMSKeyId = SSEKMSKeyId;
}
}
_a.label = 2;
case 2:
_a.trys.push([2, 4, , 5]);
upload = s3
.upload(params)
.on('httpUploadProgress', function (progress) {
if (progressCallback) {
if (typeof progressCallback === 'function') {
progressCallback(progress);
}
else {
logger.warn('progressCallback should be a function, not a ' + typeof progressCallback);
}
}
});
return [4 /*yield*/, upload.promise()];
case 3:
data = _a.sent();
logger.debug('upload result', data);
dispatchStorageEvent(track, 'upload', { method: 'put', result: 'success' }, null, "Upload success for " + key);
return [2 /*return*/, {
key: data.Key.substr(prefix.length)
}];
case 4:
e_1 = _a.sent();
logger.warn("error uploading", e_1);
dispatchStorageEvent(track, 'upload', { method: 'put', result: 'failed' }, null, "Error uploading " + key);
throw e_1;
case 5: return [2 /*return*/];
}
});
});
};
/**
* Remove the object for specified key
* @param {String} key - key of the object
* @param {Object} [config] - { level : private|protected|public }
* @return - Promise resolves upon successful removal of the object
*/
AWSS3Provider.prototype.remove = function (key, config) {
return __awaiter(this, void 0, void 0, function () {
var credentialsOK, opt, bucket, region, credentials, level, track, prefix, final_key, s3, params;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._ensureCredentials()];
case 1:
credentialsOK = _a.sent();
if (!credentialsOK) {
return [2 /*return*/, Promise.reject('No credentials')];
}
opt = Object.assign({}, this._config, config);
bucket = opt.bucket, region = opt.region, credentials = opt.credentials, level = opt.level, track = opt.track;
prefix = this._prefix(opt);
final_key = prefix + key;
s3 = this._createS3(opt);
logger.debug('remove ' + key + ' from ' + final_key);
params = {
Bucket: bucket,
Key: final_key
};
return [2 /*return*/, new Promise(function (res, rej) {
s3.deleteObject(params, function (err, data) {
if (err) {
dispatchStorageEvent(track, 'delete', { method: 'remove', result: 'failed' }, null, "Deletion of " + key + " failed with " + err);
rej(err);
}
else {
dispatchStorageEvent(track, 'delete', { method: 'remove', result: 'success' }, null, "Deleted " + key + " successfully");
res(data);
}
});
})];
}
});
});
};
/**
* List bucket objects relative to the level and prefix specified
* @param {String} path - the path that contains objects
* @param {Object} [config] - { level : private|protected|public }
* @return - Promise resolves to list of keys for all objects in path
*/
AWSS3Provider.prototype.list = function (path, config) {
return __awaiter(this, void 0, void 0, function () {
var credentialsOK, opt, bucket, region, credentials, level, download, track, prefix, final_path, s3, params;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._ensureCredentials()];
case 1:
credentialsOK = _a.sent();
if (!credentialsOK) {
return [2 /*return*/, Promise.reject('No credentials')];
}
opt = Object.assign({}, this._config, config);
bucket = opt.bucket, region = opt.region, credentials = opt.credentials, level = opt.level, download = opt.download, track = opt.track;
prefix = this._prefix(opt);
final_path = prefix + path;
s3 = this._createS3(opt);
logger.debug('list ' + path + ' from ' + final_path);
params = {
Bucket: bucket,
Prefix: final_path
};
return [2 /*return*/, new Promise(function (res, rej) {
s3.listObjects(params, function (err, data) {
if (err) {
logger.warn('list error', err);
dispatchStorageEvent(track, 'list', { method: 'list', result: 'failed' }, null, "Listing items failed: " + err.message);
rej(err);
}
else {
var list = data.Contents.map(function (item) {
return {
key: item.Key.substr(prefix.length),
eTag: item.ETag,
lastModified: item.LastModified,
size: item.Size
};
});
dispatchStorageEvent(track, 'list', { method: 'list', result: 'success' }, null, list.length + " items returned from list operation");
logger.debug('list', list);
res(list);
}
});
})];
}
});
});
};
/**
* @private
*/
AWSS3Provider.prototype._ensureCredentials = function () {
var _this = this;
return core_1.Credentials.get()
.then(function (credentials) {
if (!credentials)
return false;
var cred = core_1.Credentials.shear(credentials);
logger.debug('set credentials for storage', cred);
_this._config.credentials = cred;
return true;
})
.catch(function (err) {
logger.warn('ensure credentials error', err);
return false;
});
};
/**
* @private
*/
AWSS3Provider.prototype._prefix = function (config) {
var credentials = config.credentials, level = config.level;
var customPrefix = config.customPrefix || {};
var identityId = config.identityId || credentials.identityId;
var privatePath = (customPrefix.private !== undefined ? customPrefix.private : 'private/') + identityId + '/';
var protectedPath = (customPrefix.protected !== undefined ?
customPrefix.protected : 'protected/') + identityId + '/';
var publicPath = customPrefix.public !== undefined ? customPrefix.public : 'public/';
switch (level) {
case 'private':
return privatePath;
case 'protected':
return protectedPath;
default:
return publicPath;
}
};
/**
* @private
*/
AWSS3Provider.prototype._createS3 = function (config) {
var bucket = config.bucket, region = config.region, credentials = config.credentials;
return new S3({
apiVersion: '2006-03-01',
params: { Bucket: bucket },
signatureVersion: 'v4',
region: region,
credentials: credentials
});
};
AWSS3Provider.CATEGORY = 'Storage';
AWSS3Provider.PROVIDER_NAME = 'AWSS3';
return AWSS3Provider;
}());
exports.default = AWSS3Provider;
//# sourceMappingURL=AWSS3Provider.js.map