pushduck
Version:
The fastest way to add file uploads to any web application. Enterprise security, edge-ready. Works with 16+ frameworks and 5+ storage providers. No heavy AWS SDK required.
22 lines (19 loc) • 22.8 kB
JavaScript
const e=require(`./client-T7N63eRp.js`);function t(e){return(t={})=>{let n={provider:e.provider};for(let[r]of Object.entries(e.configKeys))n[r]=t[r]||e.defaults[r]||``;e.customLogic&&Object.assign(n,e.customLogic(t,n));let r=i(n);if(!r.valid)throw Error(`Provider validation failed: ${r.errors.join(`, `)}`);return n}}const n={aws:{provider:`aws`,configKeys:{region:[`AWS_REGION`,`S3_REGION`],bucket:[`AWS_S3_BUCKET`,`S3_BUCKET`,`S3_BUCKET_NAME`],accessKeyId:[`AWS_ACCESS_KEY_ID`,`S3_ACCESS_KEY_ID`],secretAccessKey:[`AWS_SECRET_ACCESS_KEY`,`S3_SECRET_ACCESS_KEY`],sessionToken:[`AWS_SESSION_TOKEN`],acl:[`S3_ACL`],customDomain:[`S3_CUSTOM_DOMAIN`],forcePathStyle:[`S3_FORCE_PATH_STYLE`]},defaults:{region:`us-east-1`,acl:`private`}},cloudflareR2:{provider:`cloudflare-r2`,configKeys:{accountId:[`CLOUDFLARE_ACCOUNT_ID`,`R2_ACCOUNT_ID`],bucket:[`CLOUDFLARE_R2_BUCKET`,`R2_BUCKET`],accessKeyId:[`CLOUDFLARE_R2_ACCESS_KEY_ID`,`R2_ACCESS_KEY_ID`],secretAccessKey:[`CLOUDFLARE_R2_SECRET_ACCESS_KEY`,`R2_SECRET_ACCESS_KEY`],endpoint:[`CLOUDFLARE_R2_ENDPOINT`,`R2_ENDPOINT`],customDomain:[`R2_CUSTOM_DOMAIN`],acl:[]},defaults:{region:`auto`,acl:`private`},customLogic:(e,t)=>({endpoint:t.endpoint||(t.accountId?`https://${t.accountId}.r2.cloudflarestorage.com`:``)})},digitalOceanSpaces:{provider:`digitalocean-spaces`,configKeys:{region:[`DO_SPACES_REGION`,`DIGITALOCEAN_SPACES_REGION`],bucket:[`DO_SPACES_BUCKET`,`DIGITALOCEAN_SPACES_BUCKET`],accessKeyId:[`DO_SPACES_ACCESS_KEY_ID`,`DIGITALOCEAN_SPACES_ACCESS_KEY_ID`],secretAccessKey:[`DO_SPACES_SECRET_ACCESS_KEY`,`DIGITALOCEAN_SPACES_SECRET_ACCESS_KEY`],endpoint:[`DO_SPACES_ENDPOINT`,`DIGITALOCEAN_SPACES_ENDPOINT`],customDomain:[`DO_SPACES_CUSTOM_DOMAIN`],acl:[]},defaults:{region:`nyc3`,acl:`private`},customLogic:(e,t)=>({endpoint:t.endpoint||`https://${t.region}.digitaloceanspaces.com`})},minio:{provider:`minio`,configKeys:{endpoint:[`MINIO_ENDPOINT`],bucket:[`MINIO_BUCKET`],accessKeyId:[`MINIO_ACCESS_KEY_ID`,`MINIO_ACCESS_KEY`],secretAccessKey:[`MINIO_SECRET_ACCESS_KEY`,`MINIO_SECRET_KEY`],region:[`MINIO_REGION`],customDomain:[`MINIO_CUSTOM_DOMAIN`],acl:[]},defaults:{endpoint:`localhost:9000`,region:`us-east-1`,acl:`private`},customLogic:(e,t)=>({useSSL:e.useSSL??!1,port:e.port?Number(e.port):void 0})},gcs:{provider:`gcs`,configKeys:{projectId:[`GOOGLE_CLOUD_PROJECT_ID`,`GCS_PROJECT_ID`],bucket:[`GCS_BUCKET`,`GOOGLE_CLOUD_STORAGE_BUCKET`],keyFilename:[`GOOGLE_APPLICATION_CREDENTIALS`,`GCS_KEY_FILE`],region:[`GCS_REGION`],customDomain:[`GCS_CUSTOM_DOMAIN`],acl:[]},defaults:{region:`us-central1`,acl:`private`},customLogic:e=>({credentials:e.credentials})},s3Compatible:{provider:`s3-compatible`,configKeys:{endpoint:[`S3_ENDPOINT`,`S3_COMPATIBLE_ENDPOINT`],bucket:[`S3_BUCKET`,`S3_BUCKET_NAME`],accessKeyId:[`S3_ACCESS_KEY_ID`,`ACCESS_KEY_ID`],secretAccessKey:[`S3_SECRET_ACCESS_KEY`,`SECRET_ACCESS_KEY`],region:[`S3_REGION`,`REGION`],customDomain:[`S3_CUSTOM_DOMAIN`],acl:[`S3_ACL`]},defaults:{region:`us-east-1`,acl:`private`,forcePathStyle:!0}}};function r(e,r={}){let i=n[e];if(!i)throw Error(`Unknown provider type: ${e}`);return t(i)(r)}function i(e){let t=[];switch(e.bucket||t.push(`Bucket name is required`),e.provider){case`aws`:e.accessKeyId||t.push(`AWS Access Key ID is required`),e.secretAccessKey||t.push(`AWS Secret Access Key is required`),e.region||t.push(`AWS Region is required`);break;case`cloudflare-r2`:e.accountId||t.push(`Cloudflare Account ID is required`),e.accessKeyId||t.push(`R2 Access Key ID is required`),e.secretAccessKey||t.push(`R2 Secret Access Key is required`);break;case`digitalocean-spaces`:e.accessKeyId||t.push(`DigitalOcean Spaces Access Key ID is required`),e.secretAccessKey||t.push(`DigitalOcean Spaces Secret Access Key is required`),e.region||t.push(`DigitalOcean Spaces Region is required`);break;case`minio`:e.endpoint||t.push(`MinIO Endpoint is required`),e.accessKeyId||t.push(`MinIO Access Key ID is required`),e.secretAccessKey||t.push(`MinIO Secret Access Key is required`);break;case`gcs`:e.projectId||t.push(`Google Cloud Project ID is required`),!e.keyFilename&&!e.credentials&&t.push(`Google Cloud credentials (keyFilename or credentials object) are required`);break;case`s3-compatible`:e.endpoint||t.push(`S3-compatible endpoint is required`),e.accessKeyId||t.push(`Access Key ID is required`),e.secretAccessKey||t.push(`Secret Access Key is required`);break}return{valid:t.length===0,errors:t}}function a(e){switch(e.provider){case`aws`:return`https://s3.${e.region}.amazonaws.com`;case`cloudflare-r2`:return e.endpoint||`https://${e.accountId}.r2.cloudflarestorage.com`;case`digitalocean-spaces`:return e.endpoint||`https://${e.region}.digitaloceanspaces.com`;case`minio`:{let t=e.useSSL===!1?`http`:`https`,n=e.port?`:${e.port}`:``;return`${t}://${e.endpoint}${n}`}case`gcs`:return`https://storage.googleapis.com`;case`s3-compatible`:return e.endpoint;default:return``}}function o(e,t){async function n(n){try{let t=new URL(n.url),r=t.searchParams.get(`route`),i=t.searchParams.get(`action`)||`presign`;if(!r)return new Response(JSON.stringify({error:`Route parameter is required`}),{status:400,headers:{"Content-Type":`application/json`}});if(!e.getRouteNames().includes(r))return new Response(JSON.stringify({error:`Route "${r}" not found`}),{status:404,headers:{"Content-Type":`application/json`}});let a=await n.json();if(i===`presign`){let{files:t,metadata:i}=a;if(!Array.isArray(t))return new Response(JSON.stringify({error:`Files array is required`}),{status:400,headers:{"Content-Type":`application/json`}});let o=await e.generatePresignedUrls(r,n,t,i);return new Response(JSON.stringify({success:!0,results:o}),{status:200,headers:{"Content-Type":`application/json`}})}else if(i===`complete`){let{completions:t}=a;if(!Array.isArray(t))return new Response(JSON.stringify({error:`Completions array is required`}),{status:400,headers:{"Content-Type":`application/json`}});let i=await e.handleUploadComplete(r,n,t);return new Response(JSON.stringify({success:!0,results:i}),{status:200,headers:{"Content-Type":`application/json`}})}else return new Response(JSON.stringify({error:`Unknown action: ${i}`}),{status:400,headers:{"Content-Type":`application/json`}})}catch(e){let n=e instanceof Error?e:Error(`Unknown error`);return console.error(`S3 Handler Error:`,n),new Response(JSON.stringify({success:!1,error:n.message,details:t.debug?e:void 0}),{status:500,headers:{"Content-Type":`application/json`}})}}async function r(t){let n=e.getRouteNames();return new Response(JSON.stringify({success:!0,routes:n.map(e=>({name:e,type:`s3-upload`}))}),{status:200,headers:{"Content-Type":`application/json`}})}return{GET:r,POST:n}}var s=class e{constructor(e,t={}){this.schema=e,this.config=t}middleware(t){let n={middleware:[...this.config.middleware||[],t]};return new e(this.schema,n)}paths(e){return this.config.paths={...this.config.paths,...e},this}onUploadStart(e){return this.config.onUploadStart=e,this}onUploadProgress(e){return this.config.onUploadProgress=e,this}onUploadComplete(e){return this.config.onUploadComplete=e,this}onUploadError(e){return this.config.onUploadError=e,this}_getConfig(){return{...this.config,schema:this.schema}}};function c(t,n,r,i,a,o){let s={file:t,metadata:n,globalConfig:a||{},routeName:r};if(i?.generateKey)return i.generateKey(s);let c=[],l=a?.prefix||`uploads`;c.push(l),i?.prefix&&c.push(i.prefix);let u;return a?.generateKey?(u=a.generateKey(t,n),u.startsWith(l+`/`)&&(u=u.substring(l.length+1))):u=e.s(o,{originalName:t.name,userId:n?.userId||n?.user?.id,prefix:``}),c.push(u),i?.suffix&&c.push(i.suffix),c.join(`/`).replace(/\/+/g,`/`)}var l=class{constructor(t,n){e.H(this,`config`,void 0),e.H(this,`routes`,void 0),this.routes=t,this.config=n}getRoute(e){return this.routes[e]}getRouteNames(){return Object.keys(this.routes)}get handlers(){return o(this,this.config)}async generatePresignedUrls(t,n,r,i){let a=this.getRoute(t);if(!a)throw Error(`Route "${String(t)}" not found`);let o=a._getConfig(),s=this.config,l=[];for(let a of r){let r=i||{};try{let i=o.middleware||[];for(let e of i)r=await e({req:n,file:a,metadata:r});let u=new File([],a.name,{type:a.type});Object.defineProperty(u,`size`,{value:a.size});let d=await o.schema.validate(u);if(!d.success)throw Error(d.error?.message||`Validation failed`);o.onUploadStart&&await o.onUploadStart({file:a,metadata:r});let f=await e.l(s,{key:c({name:a.name,type:a.type},r,String(t),o.paths,s.paths,s),contentType:a.type,contentLength:a.size,metadata:{originalName:a.name,userId:r.userId||r.user?.id||`anonymous`,routeName:String(t)}});l.push({success:!0,file:a,presignedUrl:f.url,key:f.key,metadata:r})}catch(e){let t=e instanceof Error?e:Error(`Failed to generate presigned URL`);o.onUploadError&&await o.onUploadError({file:a,metadata:r,error:t}),l.push({success:!1,file:a,error:t.message})}}return l}async handleUploadComplete(t,n,r){let i=this.getRoute(t);if(!i)throw Error(`Route "${String(t)}" not found`);let a=i._getConfig(),o=[];for(let t of r)try{let n=e.g(this.config,t.key),r=await e.c(this.config,t.key,3600);a.onUploadComplete&&await a.onUploadComplete({file:t.file,metadata:t.metadata||{},url:n,key:t.key}),o.push({success:!0,key:t.key,url:n,presignedUrl:r,file:t.file})}catch(e){let n=e instanceof Error?e:Error(`Upload completion failed`);a.onUploadError&&await a.onUploadError({file:t.file,metadata:t.metadata||{},error:n}),o.push({success:!1,key:t.key,error:n.message})}return o}};function u(e,t){return new l(e,t)}var d=class{constructor(){e.H(this,`_constraints`,{}),e.H(this,`_transforms`,[]),e.H(this,`_validators`,[]),e.H(this,`_optional`,!1)}async validate(e,t){try{if(this._optional&&e==null)return{success:!0,data:void 0};let n=await this._parse(e);if(!n.success)return n;for(let n of this._validators){let r=await n({file:e,fieldName:t?.fieldName||`unknown`,allFiles:t?.allFiles});if(!r.success)return r}let r=n.data;for(let n of this._transforms)r=await n({file:e,metadata:t,originalData:r});return{success:!0,data:r}}catch(e){return{success:!1,error:{code:`VALIDATION_ERROR`,message:e instanceof Error?e.message:`Unknown validation error`,path:[t?.fieldName||`unknown`]}}}}optional(){let e=this._clone();return e._optional=!0,e}transform(e){let t=this._clone();return t._transforms.push(e),t}refine(e,t){let n=this._clone();return n._validators.push(async n=>await e(n)?{success:!0}:{success:!1,error:{code:`CUSTOM_VALIDATION`,message:t,path:[n.fieldName]}}),n}},f=class t extends d{constructor(t={}){super(),this.constraints=t,e.H(this,`_type`,`file`),this._constraints={...t}}_parse(e){if(!(e instanceof File))return{success:!1,error:{code:`INVALID_TYPE`,message:`Expected File object`,path:[]}};if(this.constraints.maxSize){let t=this._parseSize(this.constraints.maxSize);if(e.size>t)return{success:!1,error:{code:`FILE_TOO_LARGE`,message:`File size ${this._formatSize(e.size)} exceeds maximum ${this._formatSize(t)}`,path:[]}}}if(this.constraints.minSize){let t=this._parseSize(this.constraints.minSize);if(e.size<t)return{success:!1,error:{code:`FILE_TOO_SMALL`,message:`File size ${this._formatSize(e.size)} is below minimum ${this._formatSize(t)}`,path:[]}}}if(this.constraints.allowedTypes?.length&&!this.constraints.allowedTypes.some(t=>t.endsWith(`/*`)?e.type.startsWith(t.slice(0,-1)):e.type===t))return{success:!1,error:{code:`INVALID_FILE_TYPE`,message:`File type ${e.type} is not allowed. Allowed types: ${this.constraints.allowedTypes.join(`, `)}`,path:[]}};if(this.constraints.allowedExtensions?.length){let t=e.name.split(`.`).pop()?.toLowerCase();if(!t||!this.constraints.allowedExtensions.includes(t))return{success:!1,error:{code:`INVALID_FILE_EXTENSION`,message:`File extension .${t} is not allowed. Allowed extensions: ${this.constraints.allowedExtensions.join(`, `)}`,path:[]}}}return{success:!0,data:e}}max(e){return console.warn("⚠️ The `max()` method is deprecated. Use `maxFileSize()` instead."),new t({...this.constraints,maxSize:e})}maxFileSize(e){return new t({...this.constraints,maxSize:e})}min(e){return new t({...this.constraints,minSize:e})}types(e){return new t({...this.constraints,allowedTypes:e})}extensions(e){return new t({...this.constraints,allowedExtensions:e})}maxFiles(e){return new m(this,{max:e})}_clone(){return new t(this.constraints)}middleware(e){return new s(this).middleware(e)}onUploadStart(e){return new s(this).onUploadStart(e)}onUploadComplete(e){return new s(this).onUploadComplete(e)}onUploadError(e){return new s(this).onUploadError(e)}_parseSize(e){if(typeof e==`number`)return e;let t=e.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)?$/i);if(!t)throw Error(`Invalid size format: ${e}`);return parseFloat(t[1])*({B:1,KB:1024,MB:1024**2,GB:1024**3,TB:1024**4}[(t[2]||`B`).toUpperCase()]||1)}_formatSize(e){let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return`${n.toFixed(r===0?0:1)}${t[r]}`}},p=class e extends f{constructor(e={}){let t={allowedTypes:[`image/*`],...e};super(t)}formats(t){let n=t.map(e=>({jpg:`image/jpeg`,jpeg:`image/jpeg`,png:`image/png`,gif:`image/gif`,webp:`image/webp`,avif:`image/avif`,svg:`image/svg+xml`})[e.toLowerCase()]||`image/${e}`);return new e({...this.constraints,allowedTypes:n})}max(t){return console.warn("⚠️ The `max()` method is deprecated. Use `maxFileSize()` instead."),new e({...this.constraints,maxSize:t})}maxFileSize(t){return new e({...this.constraints,maxSize:t})}min(t){return new e({...this.constraints,minSize:t})}types(t){return new e({...this.constraints,allowedTypes:t})}extensions(t){return new e({...this.constraints,allowedExtensions:t})}maxFiles(e){return new m(this,{max:e})}_clone(){return new e(this.constraints)}},m=class t extends d{constructor(t,n={}){super(),this.elementSchema=t,this.arrayConstraints=n,e.H(this,`_type`,`array`)}async _parse(e){if(!Array.isArray(e))return{success:!1,error:{code:`INVALID_TYPE`,message:`Expected array of files`,path:[]}};if(this.arrayConstraints.min!==void 0&&e.length<this.arrayConstraints.min)return{success:!1,error:{code:`ARRAY_TOO_SHORT`,message:`Array must have at least ${this.arrayConstraints.min} items`,path:[]}};if(this.arrayConstraints.max!==void 0&&e.length>this.arrayConstraints.max)return{success:!1,error:{code:`ARRAY_TOO_LONG`,message:`Array must have at most ${this.arrayConstraints.max} items`,path:[]}};if(this.arrayConstraints.length!==void 0&&e.length!==this.arrayConstraints.length)return{success:!1,error:{code:`ARRAY_WRONG_LENGTH`,message:`Array must have exactly ${this.arrayConstraints.length} items`,path:[]}};let t=[];for(let n=0;n<e.length;n++){let r=await this.elementSchema.validate(e[n],{fieldName:`[${n}]`});if(!r.success)return{success:!1,error:{...r.error,path:[`[${n}]`,...r.error.path]}};t.push(r.data)}return{success:!0,data:t}}min(e){return new t(this.elementSchema,{...this.arrayConstraints,min:e})}max(e){return new t(this.elementSchema,{...this.arrayConstraints,max:e})}length(e){return new t(this.elementSchema,{...this.arrayConstraints,length:e})}_clone(){return new t(this.elementSchema,this.arrayConstraints)}},h=class t extends d{constructor(t){super(),this.shape=t,e.H(this,`_type`,`object`)}async _parse(e){if(!e||typeof e!=`object`)return{success:!1,error:{code:`INVALID_TYPE`,message:`Expected object`,path:[]}};let t={},n=e;for(let[e,r]of Object.entries(this.shape)){let i=await r.validate(n[e],{fieldName:e,allFiles:n});if(!i.success)return{success:!1,error:{...i.error,path:[e,...i.error.path]}};i.data!==void 0&&(t[e]=i.data)}return{success:!0,data:t}}_clone(){return new t(this.shape)}},g=class{constructor(t){if(e.H(this,`config`,void 0),e.H(this,`list`,{files:t=>e.y(this.config,t),paginated:t=>e.C(this.config,t),byExtension:(t,n)=>e.x(this.config,t,n),bySize:(t,n,r)=>e.S(this.config,t,n,r),byDate:(t,n,r)=>e.b(this.config,t,n,r),directories:t=>e.v(this.config,t),paginatedGenerator:t=>e.w(this.config,t)}),e.H(this,`metadata`,{getInfo:t=>e.f(this.config,t),getBatch:t=>e._(this.config,t),getSize:t=>e.h(this.config,t),getContentType:t=>e.d(this.config,t),getLastModified:t=>e.p(this.config,t),getCustom:t=>e.m(this.config,t),setCustom:(t,n)=>e.E(this.config,t,n)}),e.H(this,`download`,{presignedUrl:(t,n)=>e.c(this.config,t,n),url:t=>e.g(this.config,t)}),e.H(this,`upload`,{file:(t,n,r)=>e.D(this.config,t,n,r),presignedUrl:t=>e.l(this.config,t),presignedBatch:t=>e.u(this.config,t),generateKey:t=>e.s(this.config,t)}),e.H(this,`validation`,{exists:t=>e.t(this.config,t),existsWithInfo:t=>e.o(this.config,t),validateFile:(t,n)=>e.O(this.config,t,n),validateFiles:(t,n)=>e.k(this.config,t,n),connection:()=>e.A(this.config)}),e.H(this,`delete`,{file:t=>e.r(this.config,t),files:t=>e.i(this.config,t),byPrefix:(t,n)=>e.a(this.config,t,n)}),!t)throw Error(`StorageInstance requires a valid configuration`);this.config=Object.freeze(t)}getConfig(){return this.config}getProviderInfo(){return{provider:this.config.provider.provider,bucket:this.config.provider.bucket,region:this.config.provider.region}}};function _(e){return new g(e)}var v=class{constructor(t={}){e.H(this,`metrics`,[]),e.H(this,`maxMetricsHistory`,1e3),e.H(this,`isEnabled`,void 0),this.isEnabled=t.enabled??!1}startOperation(e,t){if(!this.isEnabled)return``;let n=`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,r={operation:e,startTime:performance.now(),success:!1,metadata:{operationId:n,...t}};return this.metrics.push(r),this.trimMetricsHistory(),n}endOperation(e,t,n){if(!this.isEnabled||!e)return;let r=this.metrics.find(t=>t.metadata?.operationId===e);if(!r)return;let i=performance.now();r.endTime=i,r.duration=i-r.startTime,r.success=t,r.fileSize=n?.fileSize,r.provider=n?.provider,r.errorCode=n?.errorCode,n?.metadata&&(r.metadata={...r.metadata,...n.metadata})}recordOperation(e,t,n,r){if(!this.isEnabled)return;let i={operation:e,startTime:performance.now()-t,endTime:performance.now(),duration:t,success:n,fileSize:r?.fileSize,provider:r?.provider,errorCode:r?.errorCode,metadata:r?.metadata};this.metrics.push(i),this.trimMetricsHistory()}getAggregatedMetrics(e){let t=e?Date.now()-e:0,n=this.metrics.filter(e=>e.endTime&&e.startTime>=t),r=n.length,i=n.filter(e=>e.success).length,a=r-i,o=r>0?i/r*100:0,s=n.filter(e=>e.duration!==void 0).map(e=>e.duration);return{totalOperations:r,successfulOperations:i,failedOperations:a,successRate:o,averageDuration:s.length>0?s.reduce((e,t)=>e+t,0)/s.length:0,totalDataTransferred:n.filter(e=>e.fileSize!==void 0).reduce((e,t)=>e+(t.fileSize||0),0),operationsByType:n.reduce((e,t)=>(e[t.operation]=(e[t.operation]||0)+1,e),{}),errorsByCode:n.filter(e=>!e.success&&e.errorCode).reduce((e,t)=>(e[t.errorCode]=(e[t.errorCode]||0)+1,e),{}),providerUsage:n.filter(e=>e.provider).reduce((e,t)=>(e[t.provider]=(e[t.provider]||0)+1,e),{})}}getRawMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getPerformanceSummary(){let e=this.getAggregatedMetrics();return`
📊 Pushduck Performance Summary
================================
Total Operations: ${e.totalOperations}
Success Rate: ${e.successRate.toFixed(1)}%
Average Duration: ${e.averageDuration.toFixed(1)}ms
Data Transferred: ${this.formatBytes(e.totalDataTransferred)}
Operations by Type:
${Object.entries(e.operationsByType).map(([e,t])=>` ${e}: ${t}`).join(`
`)}
${Object.keys(e.errorsByCode).length>0?`
Errors by Code:
${Object.entries(e.errorsByCode).map(([e,t])=>` ${e}: ${t}`).join(`
`)}
`:``}
Provider Usage:
${Object.entries(e.providerUsage).map(([e,t])=>` ${e}: ${t}`).join(`
`)}
`.trim()}trimMetricsHistory(){this.metrics.length>this.maxMetricsHistory&&(this.metrics=this.metrics.slice(-this.maxMetricsHistory))}formatBytes(e){if(e===0)return`0 Bytes`;let t=1024,n=[`Bytes`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]}setEnabled(e){this.isEnabled=e}isMetricsEnabled(){return this.isEnabled}};const y=new v,b=(e,t)=>y.startOperation(e,t),x=(e,t,n)=>y.endOperation(e,t,n),S=(e,t,n,r)=>y.recordOperation(e,t,n,r);function C(e){return function(t,n,r){let i=r.value;return r.value=async function(...t){let r=b(e,{method:n,args:t.length});try{let e=await i.apply(this,t);return x(r,!0),e}catch(e){throw x(r,!1,{errorCode:e instanceof Error?e.name:`UNKNOWN_ERROR`}),e}},r}}function w(e,t){let n={};for(let[t,r]of Object.entries(e))r instanceof f||r instanceof p||r instanceof h?n[t]=new s(r):n[t]=r;return u(n,t)}function T(e){return{file:e=>new f(e),image:e=>new p(e),object:e=>new h(e),createRouter:t=>w(t,e)}}var E=class{constructor(){e.H(this,`config`,{})}provider(e,t){return typeof e==`string`?this.config.provider=r(e,t):this.config.provider=e,this}defaults(e){return this.config.defaults={...this.config.defaults,...e},this}paths(e){return this.config.paths={...this.config.paths,...e},this}security(e){return this.config.security={...this.config.security,...e},this}hooks(e){return this.config.hooks={...this.config.hooks,...e},this}debug(e=!0){return this.config.debug=e,this}metrics(e=!0){return this.config.enableMetrics=e,this}build(){if(!this.config.provider)throw Error(`Provider configuration is required`);let t=i(this.config.provider);if(!t.valid)throw Error(`Invalid provider configuration: ${t.errors.join(`, `)}`);let n=this.config;return n.debug!==void 0&&e.j.setDebugMode(n.debug),n.enableMetrics!==void 0&&y.setEnabled(n.enableMetrics),e.j.info(`📦 Upload configuration initialized`,{provider:n.provider.provider}),{config:n,storage:_(n),s3:T(n)}}};function D(){return new E}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return i}});