object-storage-js
Version:
js直传server、minio、obs、oss、s3系列
17 lines (14 loc) • 8.55 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).ObjectStorage=t()}(this,(function(){"use strict";var e;
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function t(e,t,n,o){return new(n||(n=Promise))((function(a,r){function s(e){try{i(o.next(e))}catch(e){r(e)}}function c(e){try{i(o.throw(e))}catch(e){r(e)}}function i(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,c)}i((o=o.apply(e,t||[])).next())}))}function n(e){return new Promise(((t,n)=>{const o=new XMLHttpRequest;e.xhrInstance&&"object"==typeof e.xhrInstance&&(e.xhrInstance.instance=o),o.open(e.method,e.url,!0),o.upload.onprogress=t=>{e.onProgress&&e.onProgress({loaded:t.loaded,total:t.total})},o.onabort=()=>{n("request aborted")},o.onload=()=>{o.status>=200&&o.status<300?t(o.responseText):n(new Error(`Request failed with status ${o.status}`))},o.onerror=e=>{n(new Error("Network error"))},e.data?o.send(e.data):o.send()}))}function o(e,t,o){return new Promise(((a,r)=>{const s=t.file;if(!s)return r("未提供上传文件");const{maxSize:c=-1,partSize:i=-1,queueLength:l=1}=t,u=c>0&&s.size>c;if(!u){let c={cancel:function(){var e;null===(e=c.instance)||void 0===e||e.abort()}};t.onCancel&&t.onCancel(c),e.getSignedUrlPromise("putObject",{Bucket:o,Key:t.fileName,Expires:86400}).then((e=>{n({url:e,method:"put",data:s,xhrInstance:c,onProgress:t.onUploadProgress}).then((e=>{a(e)})).catch((e=>{r(e)}))})).catch((e=>{r(e)}))}u&&e.createMultipartUpload({Bucket:o,Key:t.fileName}).promise().then((n=>{const c=n.UploadId;let u={cancel:function(){e.abortMultipartUpload({Bucket:o,Key:t.fileName,UploadId:c})}};t.onCancel&&t.onCancel(u);let d=[];const p=Math.ceil(s.size/i);let f=[];for(let e=1;e<=p;e++){const t=(e-1)*i,n=Math.min(t+i,s.size)-1;f.push({PartNumber:e,Body:s.slice(t,n+1)})}for(let e=0;e<l;e++)f[e].uploading=!0,h(f[e]);function h(n){(function(n){return new Promise(((a,r)=>{e.uploadPart({Bucket:o,Key:t.fileName,UploadId:c,PartNumber:n.PartNumber,Body:n.Body}).promise().then((e=>{d.push({PartNumber:n.PartNumber,ETag:e.ETag}),a(null)})).catch((e=>{r(e)}))}))})(n).then((()=>{n.uploaded=!0;let i=f.filter((e=>e.uploaded)).length;t.onUploadProgress&&t.onUploadProgress({loaded:Math.floor(i/p*s.size),total:s.size});let l=f.findIndex((e=>!e.uploading&&!e.uploaded));if(l>-1&&(f[l].uploading=!0,h(f[l])),f.every((e=>e.uploaded))){const n=d.sort(((e,t)=>e.PartNumber-t.PartNumber));e.completeMultipartUpload({Bucket:o,UploadId:c,MultipartUpload:{Parts:n},Key:t.fileName}).promise().then((e=>{a(e)})).catch((e=>{r(e)}))}})).catch((e=>{r(e)}))}})).catch((e=>{r(e)}))}))}function a(a){let{bucketName:r,uploadType:s,instance:c,params:i}=a;switch(s){case e.NORMAL:return function(e){return new Promise(((o,a)=>t(this,void 0,void 0,(function*(){const t=e.file;if(!t)return a("未提供上传文件");const{maxSize:r=-1,partSize:s=-1,mergeUrl:c="",queueLength:i=0,uploadUrl:l=""}=e;if(!l)return a("上传地址不能为空");const u=r>0&&t.size>r;if(!u){let d={instance:null},p={cancel:function(){var e;null===(e=d.instance)||void 0===e||e.abort()}};e.onCancel&&e.onCancel(p);let f=new FormData;f.append("file",t),e.fileName&&f.append("fileName",e.fileName),n({url:l,method:"post",data:f,onProgress:e.onUploadProgress,xhrInstance:d}).then((e=>{o(e)})).catch((e=>{a(e)}))}if(u){if(s<=0)return a("分片大小不能小于0");if(!c)return a("分片合并地址不能为空");const h=Math.ceil(t.size/s);let m=[],g={instance:null},b={cancel:function(){var e;m.forEach((e=>{var t;null===(t=e.instance)||void 0===t||t.abort()})),null===(e=g.instance)||void 0===e||e.abort()}};e.onCancel&&e.onCancel(b);let k=(new Date).getTime().toString()+(1e5*Math.random()).toFixed(0);for(let w=1;w<=h;w++){const N=(w-1)*s,S=Math.min(N+s,t.size)-1;m.push({chunk:w,file:t.slice(N,S+1),uploadId:k,instance:null})}for(let O=0;O<i;O++)m[O].uploading=!0,P(m[O]);function y(t){return new Promise(((o,a)=>{let r=new FormData;r.append("file",t.file),r.append("uploadId",t.uploadId),r.append("chunk",t.chunk),r.append("chunks",h.toString()),n({url:e.uploadUrl,method:"post",data:r,xhrInstance:t}).then((e=>{o(e)})).catch((e=>{a(e)}))}))}function P(r){y(r).then((()=>{r.uploaded=!0;let s=m.filter((e=>e.uploaded)).length;e.onUploadProgress&&e.onUploadProgress({loaded:Math.floor(s/h*t.size),total:t.size});let i=m.findIndex((e=>!e.uploading&&!e.uploaded));i>-1&&(m[i].uploading=!0,P(m[i])),m.every((e=>e.uploaded))&&n({url:`${c}?uploadId=${k}&fileName=${e.fileName}`,method:"get",xhrInstance:g}).then((e=>{o(e)})).catch((e=>{a(e)}))})).catch((e=>{a(e)}))}}}))))}(i);case e.OBS:return function(e,t,o){return new Promise(((a,r)=>{const s=t.file;if(!s)return r("未提供上传文件");const{maxSize:c=-1,partSize:i=-1,queueLength:l=1}=t,u=c>0&&s.size>c;if(!u){let c={instance:null,cancel:function(){var e;null===(e=c.instance)||void 0===e||e.abort()}};t.onCancel&&t.onCancel(c);let i=e.createV4SignedUrlSync({Bucket:o,Key:t.fileName,Expires:86400,Method:"PUT"});if(!i)return r("预签名生成失败");n({url:i.SignedUrl,method:"put",data:s,xhrInstance:c,onProgress:t.onUploadProgress}).then((e=>{a(e)})).catch((e=>{r(e)}))}u&&e.uploadFile({Bucket:o,Key:t.fileName,SourceFile:s,PartSize:u?i:s.size,TaskNum:u?l:1,ProgressCallback(e,n){t.onUploadProgress&&t.onUploadProgress({loaded:e,total:n})},ResumeCallback:function(e){t.onCancel&&t.onCancel(e)}},((e,t)=>{a(t),e&&r(e)}))}))}(c,i,r);case e.OSS:return function(e,t){return new Promise(((n,o)=>{const a=t.file;if(!a)return o("未提供上传文件");const{maxSize:r=-1,partSize:s=-1,queueLength:c=1}=t,i=r>0&&a.size>r;t.onCancel&&t.onCancel(e),e.multipartUpload(t.fileName,a,{progress:e=>{t.onUploadProgress&&t.onUploadProgress({loaded:Math.floor(e*a.size),total:a.size})},parallel:i?c:1,partSize:i?s:a.size}).then((e=>{n(e)})).catch((e=>{o(e)}))}))}(c,i);case e.MINIO:case e.AWS:return o(c,i,r)}}!function(e){e.NORMAL="normal",e.OSS="oss",e.OBS="obs",e.MINIO="minio",e.AWS="aws"}(e||(e={}));return class{constructor(t){this.instance=function(t){const{sdkOtherParams:n={}}=t;let o;if(!t.type)throw new Error("请选择需上传的对象存储类型");switch(t.type){case e.NORMAL:break;case e.OBS:if(!t.sdkObject)throw new Error("未传入obs skd库");if(!t.endPoint)throw new Error("未传入endpoint");if(!t.bucketName)throw new Error("未传入bucketName");let a=Object.assign(Object.assign({},n),{access_key_id:t.accessKey,secret_access_key:t.secretKey,server:t.endPoint});t.securityToken&&(a.security_token=t.securityToken),o=new t.sdkObject(a);break;case e.OSS:if(!t.sdkObject)throw new Error("未传入oss skd库");if(!t.endPoint)throw new Error("未传入endpoint");if(!t.bucketName)throw new Error("未传入bucketName");let r=Object.assign(Object.assign({},n),{accessKeyId:t.accessKey,accessKeySecret:t.secretKey,authorizationV4:!0,endpoint:t.endPoint,bucket:t.bucketName});if(t.region)r.region=t.region;else{const e=/https?:\/\/([a-zA-Z0-9-]+)\.aliyuncs\.com/,n=t.endPoint.match(e);if(!n||!n[1])throw new Error("未解析出region");t.region=n[1]}t.securityToken&&(r.stsToken=t.securityToken),o=new t.sdkObject(r);break;case e.MINIO:case e.AWS:if(!t.sdkObject)throw new Error("未传入aws v2 skd库");let s=Object.assign(Object.assign({},n),{accessKeyId:t.accessKey,secretAccessKey:t.secretKey,endpoint:t.endPoint,s3ForcePathStyle:t.type===e.MINIO||null,signatureVersion:"v4"});t.securityToken&&(s.sessionToken=t.securityToken),t.sdkObject.config.update(s),o=new t.sdkObject.S3({})}return o}(null!=t?t:{}),this.bucketName=t.bucketName,this.uploadType=t.type}upload(e){return a({uploadType:this.uploadType,instance:this.instance,bucketName:this.bucketName,params:e})}}}));