object-storage-js
Version:
Object storage SDK for browser — supports server upload, MinIO, OBS, OSS, AWS S3, Qiniu Kodo, and Baidu BOS
9 lines (8 loc) • 13.8 kB
JavaScript
/*!
* object-storage-js v0.0.4
* Object storage SDK for browser — supports server upload, MinIO, OBS, OSS, AWS S3, Qiniu Kodo, and Baidu BOS
* https://gitee.com/lilele01/object-storage-js
* Released under the MIT License.
*/
;var e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.ObjectStorageType=void 0,(e=exports.ObjectStorageType||(exports.ObjectStorageType={})).NORMAL="normal",e.OSS="oss",e.OBS="obs",e.MINIO="minio",e.AWS="aws",e.QINIU="qiniu",e.BOS="bos";function t(e){if(!e)throw new Error("ObjectStorage: file is required");return e}function r(e){const t=null==e?void 0:e.trim();if(!t)throw new Error("ObjectStorage: bucketName is required");return t}function n(e){var t,r;const n=(null===(t=e.fileName)||void 0===t?void 0:t.trim())||(null===(r=e.file.name)||void 0===r?void 0:r.trim());if(!n)throw new Error("ObjectStorage: fileName could not be resolved");return n}function o(e,t){return Number.isFinite(t)&&t>0&&e.size>t}function a(e){if(null==e)return 5242880;if(!Number.isFinite(e)||e<=0)throw new Error("ObjectStorage: partSize must be a positive number");return Math.floor(e)}function s(e){if(null==e)return 4;if(!Number.isFinite(e)||e<=0)throw new Error("ObjectStorage: concurrency must be a positive number");return Math.floor(e)}function i(e){const t={instance:null,cancel(){var e;null===(e=t.instance)||void 0===e||e.abort()}};return null==e||e(t),t}function l(e,t){const r=Math.max(Math.floor(e),0),n=Math.max(Math.floor(t),0),o=n>0?Math.min(r,n):r;return{loaded:o,total:n,percent:n>0?Number((o/n*100).toFixed(2)):0}}async function c(e,t,r){if(0===e.length)return;let n=0;const o=Array.from({length:Math.min(Math.max(t,1),e.length)},()=>async function(){for(;n<e.length;){const t=n++;await r(e[t],t)}}());await Promise.all(o)}function u(e,i,u){const p=e,h=t(i.file),b=r(u),m=n(i);return o(h,i.maxSize)?async function(e,t,r,n,o){var i,u,p,h;const b=a(o.partSize),m=s(o.queueLength),g=function(e,t){const r=[];let n=0,o=1;for(;n<e.size;){const a=Math.min(n+t,e.size);r.push({partNumber:o,start:n,end:a,size:a-n}),n=a,o+=1}return r}(t,b),f=[],S={"Content-Type":o.contentType||t.type||void 0,...null!==(i=o.sdkUploadParams)&&void 0!==i?i:{}};let v="",y=0,O=!1;const w={instance:null,cancel(){O=!0,v&&e.abortMultipartUpload&&e.abortMultipartUpload(n,r,v)}};null===(u=o.onCancel)||void 0===u||u.call(o,w);try{const a=await e.initiateMultipartUpload(n,r,S);if(v=null!==(h=null===(p=a.body)||void 0===p?void 0:p.uploadId)&&void 0!==h?h:"",!v)throw new Error("ObjectStorage: failed to initiate Baidu BOS multipart upload");if(await c(g,m,async a=>{var s;if(O)throw new Error("ObjectStorage: Baidu BOS multipart upload canceled");const i=t.slice(a.start,a.end),c=await e.uploadPartFromBlob(n,r,v,a.partNumber,a.size,i);f.push({partNumber:a.partNumber,eTag:d(c)}),y+=a.size,null===(s=o.onUploadProgress)||void 0===s||s.call(o,l(y,t.size))}),O)throw new Error("ObjectStorage: Baidu BOS multipart upload canceled");return e.completeMultipartUpload(n,r,v,f.sort((e,t)=>e.partNumber-t.partNumber))}catch(t){throw v&&e.abortMultipartUpload&&await e.abortMultipartUpload(n,r,v),t}}(p,h,m,b,i):function(e,t,r,n,o){var a;return e.on("progress",e=>{var r,n,a;!1!==e.lengthComputable&&(null===(r=o.onUploadProgress)||void 0===r||r.call(o,l(null!==(n=e.loaded)&&void 0!==n?n:0,null!==(a=e.total)&&void 0!==a?a:t.size)))}),e.putObjectFromBlob(n,r,t,{"Content-Type":o.contentType||t.type||void 0,...null!==(a=o.sdkUploadParams)&&void 0!==a?a:{}})}(p,h,m,b,i)}function d(e){var t,r,n,o,a,s,i;const l=null!==(r=null!==(t=e.http_headers)&&void 0!==t?t:e.httpHeaders)&&void 0!==r?r:e.headers,c=null!==(s=null!==(o=null!==(n=null==l?void 0:l.etag)&&void 0!==n?n:null==l?void 0:l.ETag)&&void 0!==o?o:null===(a=e.body)||void 0===a?void 0:a.eTag)&&void 0!==s?s:null===(i=e.body)||void 0===i?void 0:i.etag;if(!c)throw new Error("ObjectStorage: failed to resolve Baidu BOS part ETag");return c}function p(e,t){var r;const n=function(e){if(null==e||"object"!=typeof e)throw new Error('ObjectStorage: sdkObject is required for type "bos"');return e}(e),o=new n.BosClient({endpoint:t.endPoint,credentials:{ak:t.accessKey,sk:t.secretKey},...null!==(r=t.sdkOtherParams)&&void 0!==r?r:{}});return t.signatureUrl&&(o.createSignature=function(e,t){return(r,n,o,a,s)=>{var i;const l=null===(i=e.Q)||void 0===i?void 0:i.defer();if(!l)throw new Error("ObjectStorage: Baidu BOS SDK Q.defer is required");const c=new XMLHttpRequest;return c.open("POST",t,!0),c.setRequestHeader("Content-Type","application/json"),c.onload=()=>{c.status>=200&&c.status<300?l.resolve(c.responseText):l.reject(new Error(`ObjectStorage: Baidu BOS signature failed with status ${c.status}`))},c.onerror=()=>{l.reject(new Error("ObjectStorage: Baidu BOS signature network error"))},c.send(JSON.stringify({httpMethod:n,path:o,params:a,headers:s})),l.promise}}(n,t.signatureUrl)),o}class h extends Error{constructor(e,t){super(e),this.name="HttpRequestError",this.status=t.status,this.statusText=t.statusText,this.responseText=t.responseText,this.url=t.url,this.isAborted=Boolean(t.isAborted)}}function b(e){return new Promise((t,r)=>{var n;const o=new XMLHttpRequest;!function(e,t){e&&"object"==typeof e&&(e.instance=t)}(e.xhrInstance,o),o.open(e.method,e.url,!0),o.upload.onprogress=t=>{e.onProgress&&t.lengthComputable&&e.onProgress(l(t.loaded,t.total))},o.onabort=()=>{m(e.xhrInstance,o),r(new h("Request aborted",{url:e.url,status:o.status,statusText:o.statusText,responseText:o.responseText,isAborted:!0}))},o.onload=()=>{m(e.xhrInstance,o),o.status>=200&&o.status<300?t(o.responseText):r(new h(`Request failed with status ${o.status}`,{url:e.url,status:o.status,statusText:o.statusText,responseText:o.responseText}))},o.onerror=()=>{m(e.xhrInstance,o),r(new h("Network error",{url:e.url,status:o.status,statusText:o.statusText,responseText:o.responseText}))},o.send(null!==(n=e.data)&&void 0!==n?n:null)})}function m(e,t){(null==e?void 0:e.instance)===t&&(e.instance=null)}async function g(e){const r=t(e.file),{uploadUrl:u="",mergeUrl:d=""}=e;if(!u)throw new Error("ObjectStorage: uploadUrl is required for normal upload");const p=n(e);return o(r,e.maxSize)?async function(e,t,r,n,o){var u;if(!n)throw new Error("ObjectStorage: mergeUrl is required for multipart upload");const d=a(o.partSize),p=s(o.queueLength),h=Math.ceil(e.size/d),m=function(){var e,t,r;return null!==(r=null===(t=null===(e=globalThis.crypto)||void 0===e?void 0:e.randomUUID)||void 0===t?void 0:t.call(e))&&void 0!==r?r:`${Date.now()}-${Math.floor(1e6*Math.random())}`}(),g=i();let f=0;const S=[],v={instance:null,cancel(){S.forEach(e=>e.abortHandle.cancel()),g.cancel()}};null===(u=o.onCancel)||void 0===u||u.call(o,v);for(let t=1;t<=h;t++){const r=(t-1)*d,n=Math.min(r+d,e.size),o=e.slice(r,n);S.push({index:t,blob:o,size:o.size,loaded:0,uploadId:m,abortHandle:i()})}const y=()=>{var t;null===(t=o.onUploadProgress)||void 0===t||t.call(o,l(f,e.size))};try{await c(S,p,async e=>{const n=new FormData;n.append("file",e.blob),n.append("uploadId",e.uploadId),n.append("chunk",e.index.toString()),n.append("chunks",h.toString()),n.append("fileName",t),await b({url:r,method:"post",data:n,xhrInstance:e.abortHandle,onProgress:t=>{const r=Math.min(t.loaded,e.size);r!==e.loaded&&(f+=r-e.loaded,e.loaded=r,y())}}),e.loaded!==e.size&&(f+=e.size-e.loaded,e.loaded=e.size,y())})}catch(e){throw v.cancel(),e}const O=new URLSearchParams({uploadId:m,fileName:t});return b({url:`${n}?${O.toString()}`,method:"get",xhrInstance:g})}(r,p,u,d,e):async function(e,t,r,n){const o=i(n.onCancel),a=new FormData;return a.append("file",e),a.append("fileName",t),b({url:r,method:"post",data:a,onProgress:n.onUploadProgress,xhrInstance:o})}(r,p,u,e)}async function f(e,c,u){const d=e,p=t(c.file),h=r(u),m=n(c);return o(p,c.maxSize)?function(e,t,r,n,o){const i=a(o.partSize),c=s(o.queueLength);return new Promise((a,s)=>{e.uploadFile({Bucket:n,Key:r,SourceFile:t,PartSize:i,TaskNum:c,ProgressCallback(e,t){var r;null===(r=o.onUploadProgress)||void 0===r||r.call(o,l(e,t))},ResumeCallback(e){var t;const r=e;null===(t=o.onCancel)||void 0===t||t.call(o,{instance:null,cancel:()=>null==r?void 0:r()})}},(e,t)=>{e?s(e):a(t)})})}(d,p,m,h,c):async function(e,t,r,n,o){const a=i(o.onCancel),s=e.createV4SignedUrlSync({Bucket:n,Key:r,Expires:86400,Method:"PUT"});if(!(null==s?void 0:s.SignedUrl))throw new Error("ObjectStorage: failed to generate OBS presigned URL");return b({url:s.SignedUrl,method:"put",data:t,xhrInstance:a,onProgress:o.onUploadProgress})}(d,p,m,h,c)}async function S(e,l,c){const u=e,d=t(l.file),p=r(c),h=n(l);return o(d,l.maxSize)?function(e,t,r,n,o){const i=a(o.partSize),l=s(o.queueLength);return new Promise((o,a)=>{e.upload({Bucket:n,Key:r,Body:t,PartSize:i,QueueSize:l},(e,t)=>{e?a(e):o(t)})})}(u,d,h,p,l):async function(e,t,r,n,o){const a=i(o.onCancel),s=e.getSignedUrl("putObject",{Bucket:n,Key:r,Expires:86400});if(!s)throw new Error("ObjectStorage: failed to generate S3 presigned URL");return b({url:s,method:"put",data:t,xhrInstance:a,onProgress:o.onUploadProgress})}(u,d,h,p,l)}class v{}class y extends v{constructor(){super(...arguments),this.type=exports.ObjectStorageType.NORMAL,this.instance=void 0}upload(e){return g(e)}}class O extends v{constructor(e){var t;super(),this.type=exports.ObjectStorageType.OBS;const n=null!==(t=e.sdkOtherParams)&&void 0!==t?t:{},o=j(e.sdkObject,exports.ObjectStorageType.OBS);this.bucketName=r(e.bucketName),this.instance=new o({...n,access_key_id:e.accessKey,secret_access_key:e.secretKey,server:P(e.endPoint),...e.securityToken?{security_token:e.securityToken}:{}})}upload(e){return f(this.instance,e,this.bucketName)}}class w extends v{constructor(e){var t;super(),this.type=exports.ObjectStorageType.OSS;const n=P(e.endPoint),o=null!==(t=e.sdkOtherParams)&&void 0!==t?t:{},a=j(e.sdkObject,exports.ObjectStorageType.OSS);this.instance=new a({...o,accessKeyId:e.accessKey,accessKeySecret:e.secretKey,authorizationV4:!0,endpoint:n,bucket:r(e.bucketName),region:z(n,e.region),...e.securityToken?{stsToken:e.securityToken}:{}})}upload(e){return async function(e,r){var i;const c=e,u=t(r.file),d=n(r),p=o(u,r.maxSize);return null===(i=r.onCancel)||void 0===i||i.call(r,{instance:null,cancel:()=>c.cancel()}),c.multipartUpload(d,u,{progress:e=>{var t;null===(t=r.onUploadProgress)||void 0===t||t.call(r,l(e*u.size,u.size))},parallel:p?s(r.queueLength):1,partSize:p?a(r.partSize):u.size})}(this.instance,e)}cancel(){var e;const t=this.instance;null===(e=t.cancel)||void 0===e||e.call(t)}}class x extends v{constructor(e){var t;super();const n=null!==(t=e.sdkOtherParams)&&void 0!==t?t:{},o=j(e.sdkObject,e.type);this.type=e.type,this.bucketName=r(e.bucketName),this.instance=new o.S3({...n,accessKeyId:e.accessKey,secretAccessKey:e.secretKey,endpoint:e.endPoint,region:e.region,signatureVersion:"v4",...e.type===exports.ObjectStorageType.MINIO?{s3ForcePathStyle:!0}:{},...e.securityToken?{sessionToken:e.securityToken}:{}})}upload(e){return S(this.instance,e,this.bucketName)}}class T extends v{constructor(e){var t;super(),this.type=exports.ObjectStorageType.QINIU,this.instance=j(e.sdkObject,exports.ObjectStorageType.QINIU),this.uploadToken=e.uploadToken,this.sdkOtherParams=null!==(t=e.sdkOtherParams)&&void 0!==t?t:{}}upload(e){return function(e,r,i,c={}){var u;const d=e,p=t(r.file),h=n(r),b=r.uploadToken||i;if(!b)throw new Error("ObjectStorage: uploadToken is required for qiniu upload");const m=o(p,r.maxSize),g={fname:p.name,mimeType:r.contentType||p.type||void 0,...null!==(u=r.sdkUploadParams)&&void 0!==u?u:{}},f={...c,...r.maxSize?{forceDirect:!m}:{},chunkSize:(S=a(r.partSize),Math.max(1,Math.ceil(S/1024/1024))),concurrentRequestLimit:s(r.queueLength)};var S;return new Promise((e,t)=>{var n;let o=null;const a={instance:null,cancel(){null==o||o.unsubscribe()}};o=d.upload(p,h,b,g,f).subscribe({next(e){var t,n,o,a,s;const i=null!==(n=null===(t=e.total)||void 0===t?void 0:t.total)&&void 0!==n?n:p.size,c=null!==(a=null===(o=e.total)||void 0===o?void 0:o.loaded)&&void 0!==a?a:0;null===(s=r.onUploadProgress)||void 0===s||s.call(r,l(c,i))},error(e){t(e)},complete(t){e(t)}}),null===(n=r.onCancel)||void 0===n||n.call(r,a)})}(this.instance,e,this.uploadToken,this.sdkOtherParams)}}class k extends v{constructor(e){super(),this.type=exports.ObjectStorageType.BOS,this.bucketName=r(e.bucketName),this.instance=p(e.sdkObject,{accessKey:e.accessKey,secretKey:e.secretKey,endPoint:P(e.endPoint),signatureUrl:e.signatureUrl,sdkOtherParams:e.sdkOtherParams})}upload(e){return u(this.instance,e,this.bucketName)}}function j(e,t){if(null==e)throw new Error(`ObjectStorage: sdkObject is required for type "${t}"`);return e}function P(e){const t=null==e?void 0:e.trim();if(!t)throw new Error("ObjectStorage: endPoint is required");return t}function z(e,t){if(t)return t;const r=e.match(/https?:\/\/([a-zA-Z0-9-]+)\.aliyuncs\.com/);if(null==r?void 0:r[1])return r[1];throw new Error("ObjectStorage: failed to resolve OSS region from endPoint")}class N{constructor(e){if(!(null==e?void 0:e.type))throw new Error("ObjectStorage: config.type is required");this.adapter=function(e){switch(e.type){case exports.ObjectStorageType.NORMAL:return new y;case exports.ObjectStorageType.OBS:return new O(e);case exports.ObjectStorageType.OSS:return new w(e);case exports.ObjectStorageType.MINIO:case exports.ObjectStorageType.AWS:return new x(e);case exports.ObjectStorageType.QINIU:return new T(e);case exports.ObjectStorageType.BOS:return new k(e);default:throw new Error(`ObjectStorage: unsupported type "${e.type}"`)}}(e),this.instance=this.adapter.instance,this.bucketName="bucketName"in e?e.bucketName:void 0,this.uploadType=e.type}upload(e){return this.adapter.upload(e)}cancel(){var e,t;null===(t=(e=this.adapter).cancel)||void 0===t||t.call(e)}}exports.ObjectStorage=N,exports.default=N;
//# sourceMappingURL=index.cjs.js.map