leancloud-storage
Version:
LeanCloud JavaScript SDK.
501 lines (396 loc) • 15.5 kB
JavaScript
"use strict";
var _sliceInstanceProperty2 = require("@babel/runtime-corejs3/core-js-stable/instance/slice");
var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from");
var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol");
var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method");
var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { var _context9; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty2(_context9 = Object.prototype.toString.call(o)).call(_context9, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var _require = require('../adapter'),
getAdapter = _require.getAdapter;
var debug = require('debug')('leancloud:qiniu');
var ajax = require('../utils/ajax');
var btoa = require('../utils/btoa');
var SHARD_THRESHOLD = 1024 * 1024 * 64;
var CHUNK_SIZE = 1024 * 1024 * 16;
function upload(uploadInfo, data, file) {
var saveOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
// Get the uptoken to upload files to qiniu.
var uptoken = uploadInfo.token;
var url = uploadInfo.upload_url || 'https://upload.qiniup.com';
var fileFormData = {
field: 'file',
data: data,
name: file.attributes.name
};
var options = {
headers: file._uploadHeaders,
data: {
name: file.attributes.name,
key: uploadInfo.key,
token: uptoken
},
onprogress: saveOptions.onprogress
};
debug('url: %s, file: %o, options: %o', url, fileFormData, options);
var upload = getAdapter('upload');
return upload(url, fileFormData, options).then(function (response) {
debug(response.status, response.data);
if (response.ok === false) {
var message = response.status;
if (response.data) {
if (response.data.error) {
message = response.data.error;
} else {
message = (0, _stringify.default)(response.data);
}
}
var error = new Error(message);
error.response = response;
throw error;
}
file.attributes.url = uploadInfo.url;
file._bucket = uploadInfo.bucket;
file.id = uploadInfo.objectId;
return file;
}, function (error) {
var response = error.response;
if (response) {
debug(response.status, response.data);
error.statusCode = response.status;
error.response = response.data;
}
throw error;
});
}
function urlSafeBase64(string) {
var base64 = btoa(unescape(encodeURIComponent(string)));
var result = '';
var _iterator = _createForOfIteratorHelper(base64),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var ch = _step.value;
switch (ch) {
case '+':
result += '-';
break;
case '/':
result += '_';
break;
default:
result += ch;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return result;
}
var ShardUploader = /*#__PURE__*/function () {
function ShardUploader(uploadInfo, data, file, saveOptions) {
var _context,
_context2,
_this = this;
(0, _classCallCheck2.default)(this, ShardUploader);
this.uploadInfo = uploadInfo;
this.data = data;
this.file = file;
this.size = undefined;
this.offset = 0;
this.uploadedChunks = 0;
var key = urlSafeBase64(uploadInfo.key);
var uploadURL = uploadInfo.upload_url || 'https://upload.qiniup.com';
this.baseURL = (0, _concat.default)(_context = (0, _concat.default)(_context2 = "".concat(uploadURL, "/buckets/")).call(_context2, uploadInfo.bucket, "/objects/")).call(_context, key, "/uploads");
this.upToken = 'UpToken ' + uploadInfo.token;
this.uploaded = 0;
if (saveOptions && saveOptions.onprogress) {
this.onProgress = function (_ref) {
var loaded = _ref.loaded;
loaded += _this.uploadedChunks * CHUNK_SIZE;
if (loaded <= _this.uploaded) {
return;
}
if (_this.size) {
saveOptions.onprogress({
loaded: loaded,
total: _this.size,
percent: loaded / _this.size * 100
});
} else {
saveOptions.onprogress({
loaded: loaded
});
}
_this.uploaded = loaded;
};
}
}
/**
* @returns {Promise<string>}
*/
(0, _createClass2.default)(ShardUploader, [{
key: "getUploadId",
value: function getUploadId() {
return ajax({
method: 'POST',
url: this.baseURL,
headers: {
Authorization: this.upToken
}
}).then(function (res) {
return res.uploadId;
});
}
}, {
key: "getChunk",
value: function getChunk() {
throw new Error('Not implemented');
}
/**
* @param {string} uploadId
* @param {number} partNumber
* @param {any} data
* @returns {Promise<{ partNumber: number, etag: string }>}
*/
}, {
key: "uploadPart",
value: function uploadPart(uploadId, partNumber, data) {
var _context3, _context4;
return ajax({
method: 'PUT',
url: (0, _concat.default)(_context3 = (0, _concat.default)(_context4 = "".concat(this.baseURL, "/")).call(_context4, uploadId, "/")).call(_context3, partNumber),
headers: {
Authorization: this.upToken
},
data: data,
onprogress: this.onProgress
}).then(function (_ref2) {
var etag = _ref2.etag;
return {
partNumber: partNumber,
etag: etag
};
});
}
}, {
key: "stopUpload",
value: function stopUpload(uploadId) {
var _context5;
return ajax({
method: 'DELETE',
url: (0, _concat.default)(_context5 = "".concat(this.baseURL, "/")).call(_context5, uploadId),
headers: {
Authorization: this.upToken
}
});
}
}, {
key: "upload",
value: function upload() {
var _this2 = this;
var parts = [];
return this.getUploadId().then(function (uploadId) {
var uploadPart = function uploadPart() {
return _promise.default.resolve(_this2.getChunk()).then(function (chunk) {
if (!chunk) {
return;
}
var partNumber = parts.length + 1;
return _this2.uploadPart(uploadId, partNumber, chunk).then(function (part) {
parts.push(part);
_this2.uploadedChunks++;
return uploadPart();
});
}).catch(function (error) {
return _this2.stopUpload(uploadId).then(function () {
return _promise.default.reject(error);
});
});
};
return uploadPart().then(function () {
var _context6;
return ajax({
method: 'POST',
url: (0, _concat.default)(_context6 = "".concat(_this2.baseURL, "/")).call(_context6, uploadId),
headers: {
Authorization: _this2.upToken
},
data: {
parts: parts,
fname: _this2.file.attributes.name,
mimeType: _this2.file.attributes.mime_type
}
});
});
}).then(function () {
_this2.file.attributes.url = _this2.uploadInfo.url;
_this2.file._bucket = _this2.uploadInfo.bucket;
_this2.file.id = _this2.uploadInfo.objectId;
return _this2.file;
});
}
}]);
return ShardUploader;
}();
var BlobUploader = /*#__PURE__*/function (_ShardUploader) {
(0, _inherits2.default)(BlobUploader, _ShardUploader);
var _super = _createSuper(BlobUploader);
function BlobUploader(uploadInfo, data, file, saveOptions) {
var _this3;
(0, _classCallCheck2.default)(this, BlobUploader);
_this3 = _super.call(this, uploadInfo, data, file, saveOptions);
_this3.size = data.size;
return _this3;
}
/**
* @returns {Blob | null}
*/
(0, _createClass2.default)(BlobUploader, [{
key: "getChunk",
value: function getChunk() {
var _context7;
if (this.offset >= this.size) {
return null;
}
var chunk = (0, _slice.default)(_context7 = this.data).call(_context7, this.offset, this.offset + CHUNK_SIZE);
this.offset += chunk.size;
return chunk;
}
}]);
return BlobUploader;
}(ShardUploader);
/* NODE-ONLY:start */
var BufferUploader = /*#__PURE__*/function (_ShardUploader2) {
(0, _inherits2.default)(BufferUploader, _ShardUploader2);
var _super2 = _createSuper(BufferUploader);
function BufferUploader(uploadInfo, data, file, saveOptions) {
var _this4;
(0, _classCallCheck2.default)(this, BufferUploader);
_this4 = _super2.call(this, uploadInfo, data, file, saveOptions);
_this4.size = data.length;
return _this4;
}
/**
* @returns {Buffer | null}
*/
(0, _createClass2.default)(BufferUploader, [{
key: "getChunk",
value: function getChunk() {
var _context8;
if (this.offset >= this.size) {
return null;
}
var chunk = (0, _slice.default)(_context8 = this.data).call(_context8, this.offset, this.offset + CHUNK_SIZE);
this.offset += chunk.length;
return chunk;
}
}]);
return BufferUploader;
}(ShardUploader);
/* NODE-ONLY:end */
/* NODE-ONLY:start */
var StreamUploader = /*#__PURE__*/function (_ShardUploader3) {
(0, _inherits2.default)(StreamUploader, _ShardUploader3);
var _super3 = _createSuper(StreamUploader);
function StreamUploader() {
(0, _classCallCheck2.default)(this, StreamUploader);
return _super3.apply(this, arguments);
}
(0, _createClass2.default)(StreamUploader, [{
key: "_read",
value:
/**
* @param {number} [size]
* @returns {Buffer | null}
*/
function _read(size) {
var chunk = this.data.read(size);
if (chunk) {
this.offset += chunk.length;
}
return chunk;
}
/**
* @returns {Buffer | null | Promise<Buffer | null>}
*/
}, {
key: "getChunk",
value: function getChunk() {
var _this5 = this;
if (this.data.readableLength >= CHUNK_SIZE) {
return this._read(CHUNK_SIZE);
}
if (this.data.readableEnded) {
if (this.data.readable) {
return this._read();
}
return null;
}
return new _promise.default(function (resolve, reject) {
var onReadable = function onReadable() {
var chunk = _this5._read(CHUNK_SIZE);
if (chunk !== null) {
resolve(chunk);
removeListeners();
}
};
var onError = function onError(error) {
reject(error);
removeListeners();
};
var removeListeners = function removeListeners() {
_this5.data.off('readable', onReadable);
_this5.data.off('error', onError);
};
_this5.data.on('readable', onReadable);
_this5.data.on('error', onError);
});
}
}]);
return StreamUploader;
}(ShardUploader);
/* NODE-ONLY:end */
function isBlob(data) {
return typeof Blob !== 'undefined' && data instanceof Blob;
}
/* NODE-ONLY:start */
function isBuffer(data) {
return typeof Buffer !== 'undefined' && Buffer.isBuffer(data);
}
/* NODE-ONLY:end */
/* NODE-ONLY:start */
function isStream(data) {
return typeof require === 'function' && data instanceof require('stream');
}
/* NODE-ONLY:end */
module.exports = function (uploadInfo, data, file) {
var saveOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (isBlob(data) && data.size >= SHARD_THRESHOLD) {
return new BlobUploader(uploadInfo, data, file, saveOptions).upload();
}
/* NODE-ONLY:start */
if (isBuffer(data) && data.length >= SHARD_THRESHOLD) {
return new BufferUploader(uploadInfo, data, file, saveOptions).upload();
}
if (isStream(data)) {
return new StreamUploader(uploadInfo, data, file, saveOptions).upload();
}
/* NODE-ONLY:end */
return upload(uploadInfo, data, file, saveOptions);
};