UNPKG

bknd

Version:

Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.

2 lines 22.7 kB
import {AwsClient}from'aws4fetch';import {XMLParser}from'fast-xml-parser';import'hono/adapter';import*as T from'@sinclair/typebox';import {SetErrorFunction,DefaultErrorFunction,Errors}from'@sinclair/typebox/errors';import {Default,Check}from'@sinclair/typebox/value';import ue from'dayjs';import $e from'dayjs/plugin/weekOfYear.js';import {transform}from'lodash-es';var Te=Object.create;var U=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Ae=Object.prototype.hasOwnProperty;var Re=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),X=(r,e)=>{for(var t in e)U(r,t,{get:e[t],enumerable:true});},Ce=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Oe(e))!Ae.call(r,s)&&s!==t&&U(r,s,{get:()=>e[s],enumerable:!(n=we(e,s))||n.enumerable});return r};var _e=(r,e,t)=>(t=r!=null?Te(ve(r)):{},Ce(U(t,"default",{value:r,enumerable:true}),r));var oe=Re((ut,V)=>{var c=String,ie=function(){return {isColorSupported:false,reset:c,bold:c,dim:c,italic:c,underline:c,inverse:c,hidden:c,strikethrough:c,black:c,red:c,green:c,yellow:c,blue:c,magenta:c,cyan:c,white:c,gray:c,bgBlack:c,bgRed:c,bgGreen:c,bgYellow:c,bgBlue:c,bgMagenta:c,bgCyan:c,bgWhite:c,blackBright:c,redBright:c,greenBright:c,yellowBright:c,blueBright:c,magentaBright:c,cyanBright:c,whiteBright:c,bgBlackBright:c,bgRedBright:c,bgGreenBright:c,bgYellowBright:c,bgBlueBright:c,bgMagentaBright:c,bgCyanBright:c,bgWhiteBright:c}};V.exports=ie();V.exports.createColors=ie;});function je(r){return r?{...Object.fromEntries(r.entries())}:{}}function H(r,e){let t=je(r),n={};for(let s of e)t[s]&&(n[s]=t[s]);return n}function ee(r,e){let t=new Headers;for(let n of e)r.has(n)&&t.set(n,r.get(n));return t}var S=(r,e)=>typeof r=="string"?[1,"1","true"].includes(r):!!(r||e);function M(){try{return S(0)}catch{return false}}var ke={cli_log_level:{key:"BKND_CLI_LOG_LEVEL",validate:r=>{if(typeof r=="string"&&["log","info","warn","error","debug"].includes(r.toLowerCase()))return r.toLowerCase()}},cli_create_ref:{key:"BKND_CLI_CREATE_REF",validate:r=>typeof r=="string"?r:void 0},cli_telemetry:{key:"BKND_CLI_TELEMETRY",validate:r=>{if(!(typeof r>"u"))return S(r,true)}},modules_debug:{key:"BKND_MODULES_DEBUG",validate:S}},B=(r,e,t)=>{try{let n=t?.source??process.env,s=ke[r],i=n[s.key],o=s.validate(i);if(typeof o<"u")return t?.onValid?.(o),o;t?.onFallback?.(i);}catch{}return e};function k(r,e=false){let s="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"+(e?"!@#$%^&*()_+{}:\"<>?|[];',./`~":""),i="";for(let o=0;o<r;o++)i+=s[Math.floor(Math.random()*s.length)];return i}function te(r){return r.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function P(r,e=[]){return r===null||typeof r!="object"?r:Array.isArray(r)?r.map(t=>P(t,e)):Object.keys(r).reduce((t,n)=>{let s=e.includes(n)?n:te(n);return t[s]=P(r[n],e),t},{})}function re(r){return new XMLParser().parse(r)}var A=class extends AwsClient{#e;constructor(e,t){super(e),this.#e=t??{responseType:"json"};}convertParams(e){switch(this.#e.convertParams){case "pascalToKebab":return P(e);default:return e}}getUrl(e="/",t={}){let n=new URL(e),s=this.convertParams(t);return Object.entries(s).forEach(([i,o])=>{n.searchParams.append(i,o);}),n.toString()}updateKeysRecursively(e,t){return e==null?e:Array.isArray(e)?e.map(n=>this.updateKeysRecursively(n,t)):typeof e=="object"?Object.keys(e).reduce((n,s)=>{let i=s;return s.indexOf(" ")===-1&&(i=s.charAt(0)[t]()+s.slice(1)),n[i]=this.updateKeysRecursively(e[s],t),n},{}):e}async fetchJson(e,t){let n=await this.fetch(e,t);if(this.#e.responseType==="xml"){if(!n.ok){let o=await n.text();throw new Error(o)}let i=await n.text();return re(i)}if(!n.ok){let i=await n.json();throw new Error(i.message)}let s=await n.json();return this.#e.responseKeysToUpper?this.updateKeysRecursively(s,"toUpperCase"):s}};var $={video:["mp4","webm"],audio:["ogg"],image:["jpeg","png","gif","webp","bmp","tiff","avif","heic","heif"],text:["html","css","mdx","yaml","vcard","csv","vtt"],application:["zip","xml","toml","json","json5"],font:["woff","woff2","ttf","otf"]},l={vnd:"vnd.openxmlformats-officedocument",z:"application/x-7z-compressed",t:(r="plain")=>`text/${r}`,a:(r="octet-stream")=>`application/${r}`,i:r=>`image/${r}`,v:r=>`video/${r}`},z=new Map([["7z",l.z],["7zip",l.z],["ai",l.a("pdf")],["apk",l.a("vnd.android.package-archive")],["doc",l.a("msword")],["docx",`${l.vnd}.wordprocessingml.document`],["eps",l.a("postscript")],["epub",l.a("epub+zip")],["ini",l.t()],["jar",l.a("java-archive")],["jsonld",l.a("ld+json")],["jpg",l.i("jpeg")],["log",l.t()],["m3u",l.t()],["m3u8",l.a("vnd.apple.mpegurl")],["manifest",l.t("cache-manifest")],["md",l.t("markdown")],["mkv",l.v("x-matroska")],["mp3",l.a("mpeg")],["mobi",l.a("x-mobipocket-ebook")],["ppt",l.a("powerpoint")],["pptx",`${l.vnd}.presentationml.presentation`],["qt",l.v("quicktime")],["svg",l.i("svg+xml")],["tif",l.i("tiff")],["tsv",l.t("tab-separated-values")],["tgz",l.a("x-tar")],["txt",l.t()],["text",l.t()],["vcd",l.a("x-cdlink")],["vcs",l.t("x-vcalendar")],["wav",l.a("x-wav")],["webmanifest",l.a("manifest+json")],["xls",l.a("vnd.ms-excel")],["xlsx",`${l.vnd}.spreadsheetml.sheet`],["yml",l.t("yaml")]]);function Le(r){try{let e=r.split(".").pop();if(!e)return l.a();for(let[t,n]of Object.entries($))if(n.includes(e))return `${t}/${e}`;return z.get(e)}catch{return l.a()}}function ne(r,e=[]){let t=r.toLowerCase();if(e.includes(t))return false;if(Object.entries($).flatMap(([n,s])=>s.map(i=>`${n}/${i}`)).includes(t))return true;for(let[n,s]of z.entries())if(s===t&&!e.includes(n))return true;return false}function se(r){let e=r.toLowerCase();for(let[t,n]of Object.entries($))for(let s of n)if(e===`${t}/${s}`)return s;for(let[t,n]of z.entries())if(n===e)return t;return ""}function K(r,e){if(!r)throw new Error(e)}var d=_e(oe());function Ie(){try{let r=process||{},e=r.argv||[],t=r.env||{};return !(t.NO_COLOR||e.includes("--no-color"))&&(!!t.FORCE_COLOR||e.includes("--color")||r.platform==="win32"||(r.stdout||{}).isTTY&&t.TERM!=="dumb"||!!t.CI)}catch{return false}}var q={critical:{prefix:"CRT",color:d.default.red,args_color:d.default.red,original:console.error},error:{prefix:"ERR",color:d.default.red,args_color:d.default.red,original:console.error},warn:{prefix:"WRN",color:d.default.yellow,args_color:d.default.yellow,original:console.warn},info:{prefix:"INF",color:d.default.cyan,original:console.info},log:{prefix:"LOG",color:d.default.dim,args_color:d.default.dim,original:console.log},debug:{prefix:"DBG",color:d.default.yellow,args_color:d.default.dim,original:console.debug}};function Ne(r,e){let t=Ie(),n=q[r],s=n.color(`[${n.prefix}]`),i=e.map(o=>"args_color"in n&&t&&typeof o=="string"?n.args_color(o):o);return n.original(s,d.default.gray(le()),...i)}var ce=B("cli_log_level","log"),F=globalThis.__consoleConfig??={level:ce},ae=Object.keys(q),E=new Proxy(F,{get:(r,e)=>{switch(e){case "original":return console;case "setLevel":return s=>{F.level=s;};case "resetLevel":return ()=>{F.level=ce;}}let t=ae.indexOf(F.level),n=ae.indexOf(e);return e in q&&n<=t?(...s)=>Ne(e,s):()=>null}});function De(r){return typeof r=="object"&&r!==null&&typeof r.arrayBuffer=="function"&&typeof r.type=="string"}function m(r){return De(r)&&typeof r.name=="string"&&typeof r.lastModified=="number"}async function fe(r,e){let t=m(r),n=t?r.type:e;K(n&&typeof n=="string"&&n.startsWith("image/"),"type must be image/*");let s=t?await r.arrayBuffer():r;K(s.byteLength>=128,"Buffer must be at least 128 bytes");let i=new DataView(s);if(n==="image/jpeg"){let o=2;for(;o<i.byteLength;){let a=i.getUint16(o);if(o+=2,a===65472||a===65474)return {width:i.getUint16(o+5),height:i.getUint16(o+3)};o+=i.getUint16(o);}}else {if(n==="image/png")return {width:i.getUint32(16),height:i.getUint32(20)};if(n==="image/gif")return {width:i.getUint16(6),height:i.getUint16(8)};if(n==="image/tiff"){let o=i.getUint16(0)===18761,a=i.getUint32(4,o),g=i.getUint32(a+18,o),f=i.getUint32(a+10,o);return {width:g,height:f}}}throw new Error("Unsupported image format")}var G=Symbol("tb-parse-validation"),Y=class extends Error{constructor(t,n,s){super(s??`Invalid: ${JSON.stringify(n)}`);this.schema=t;this.data=n;this.errors=[...Errors(t,n)];}errors;first(){return this.errors[0]}firstToString(){let t=this.first();return `${t.message} at "${t.path}"`}toJSON(){return {message:this.message,schema:this.schema,data:this.data,errors:this.errors}}};function pe(r,e=true){if(typeof r=="object"&&r!==null&&!Array.isArray(r)){e?r[G]=true:delete r[G];for(let t in r)typeof r[t]=="object"&&r[t]!==null&&pe(r[t],e);}}function L(r,e,t){if(typeof e=="object"&&G in e)return t?.useDefaults===false?e:Default(r,e);let n=t?.useDefaults===false?e:Default(r,e);if(Check(r,n))return pe(n,true),n;throw new Y(r,e)}function Be(r){r.Set("StringEnum",(e,t)=>typeof t=="string"&&e.enum.includes(t));}Be(T.TypeRegistry);T.Type.String({pattern:"^[a-zA-Z_][a-zA-Z0-9_]*$",minLength:2,maxLength:150});SetErrorFunction(r=>r?.schema?.errorMessage?r.schema.errorMessage:r?.schema?.[T.Kind]==="StringEnum"?`Expected: ${r.schema.enum.map(e=>`"${e}"`).join(", ")}`:DefaultErrorFunction(r));ue.extend($e);function le(r){return ue(r).format("YYYY-MM-DD HH:mm:ss")}var ze=["SHA-1","SHA-256","SHA-384","SHA-512"];async function me(r,e,t,n){if(!ze.includes(r))throw new Error(`Invalid hash algorithm: ${r}`);let s=new TextEncoder().encode((t??"")+e+(n??"")),i=await crypto.subtle.digest(r,s);return Array.from(new Uint8Array(i)).map(a=>a.toString(16).padStart(2,"0")).join("")}var ye={sha256:async(r,e,t)=>me("SHA-256",r,e,t),sha1:async(r,e,t)=>me("SHA-1",r,e,t)};var u=class{constructor(e){this.name=e;this.name=e;}toJSON(){return {name:this.name}}};var R=class{constructor(e){this.registerFn=e;}is_set=false;items={};set(e){if(this.is_set)throw new Error("Registry is already set");return this.items=e,this.is_set=true,this}add(e,t){return this.items[e]=t,this}register(e,t){if(this.registerFn){let n=this.registerFn(t);return this.items[e]=n,this}return this.add(e,t)}get(e){return this.items[e]}has(e){return e in this.items}all(){return this.items}};var y=class{_returning;static slug="untitled-event";params;returned=false;validate(e){throw new W(this,e)}clone(e){let t=new this.constructor(e);return t.returned=true,t}constructor(e){this.params=e;}};var h=class extends Error{constructor(e,t){super(`Expected "${e}", got "${t}"`);}},W=class extends Error{constructor(t,n){super(`Event "${t.constructor.slug}" returned without validation`);this.data=n;}};var I=class{mode="async";event;handler;once=false;id;constructor(e,t,n="async",s){this.event=e,this.handler=t,this.mode=n,this.id=s;}};var C=class{constructor(e,t){this.options=t;e&&this.registerEvents(e),t?.listeners?.forEach(n=>this.addListener(n));}events=[];listeners=[];enabled=true;asyncs=[];enable(){return this.enabled=true,this}disable(){return this.enabled=false,this}clearEvents(){return this.events=[],this}clearAll(){return this.clearEvents(),this.listeners=[],this}getListeners(){return [...this.listeners]}get Events(){return new Proxy(this,{get:(e,t)=>this.events.find(n=>n.slug===t)})}eventExists(e){let t;return typeof e=="string"?t=e:t=e.constructor?.slug??e.slug,!!this.events.find(n=>t===n.slug)}throwIfEventNotRegistered(e){if(!this.eventExists(e)){let t=e.constructor?.slug??e.slug??e;throw new Error(`Event "${t}" not registered`)}}registerEvent(e,t=false){if(this.eventExists(e)){if(t)return this;throw new Error(`Event "${e.name}" already registered.`)}return this.events.push(e),this}registerEvents(e){return (typeof e=="object"?Object.values(e):e).forEach(n=>this.registerEvent(n,true)),this}addListener(e){return this.throwIfEventNotRegistered(e.event),e.id&&this.listeners.find(n=>n.id===e.id)?(E.debug(`Listener with id "${e.id}" already exists.`),this):(this.listeners.push(e),this)}createEventListener(e,t,n="async"){let s=typeof e=="string"?this.events.find(a=>a.slug===e):e,i=typeof n=="string"?{mode:n}:n,o=new I(s,t,i.mode);i.once&&(o.once=true),i.id&&(o.id=`${s.slug}-${i.id}`),this.addListener(o);}onEvent(e,t,n){this.createEventListener(e,t,n);}on(e,t,n){this.createEventListener(e,t,n);}onAny(e,t){this.events.forEach(n=>this.onEvent(n,e,t));}collectAsyncs(e){this.asyncs.push(...e);}async executeAsyncs(e=t=>Promise.all(t)){if(this.asyncs.length===0)return;let t=[...this.asyncs];this.asyncs=[],await e(t.map(n=>n()));}async emit(e){let t=e.constructor.slug;if(!this.enabled)return E.debug("EventManager disabled, not emitting",t),e;if(!this.eventExists(e))throw new Error(`Event "${t}" not registered`);let n=[],s=[];this.listeners=this.listeners.filter(o=>o.event.slug!==t?true:(o.mode==="sync"?n.push(o):s.push(async()=>await o.handler(e,o.event.slug)),!o.once)),this.collectAsyncs(s);let i=e;for(let o of n)try{let a=await o.handler(i,o.event.slug);if(typeof a<"u"){let g=i.validate(a);if(g&&g.constructor.slug===t){if(!g.returned)throw new Error(`Returned event ${g.constructor.slug} must be marked as returned.`);i=g;}}}catch(a){if(a instanceof h)this.options?.onInvalidReturn?.(i,a),E.warn(`Invalid return of event listener for "${t}": ${a.message}`);else if(this.options?.onError)this.options.onError(i,a);else throw a}return i}};var N={};X(N,{FileAccessEvent:()=>J,FileDeletedEvent:()=>j,FileUploadedEvent:()=>_});var _=class extends y{static slug="file-uploaded";validate(e){if(typeof e!="object")throw new h("object",typeof e);return this.clone({...e,...this.params})}},j=class extends y{static slug="file-deleted"},J=class extends y{static slug="file-access"};var Q=class r{#e;static Events=N;emgr;config;constructor(e,t={},n){this.#e=e,this.config={...t,body_max_size:t.body_max_size},this.emgr=n??new C,this.emgr.registerEvents(r.Events);}getAdapter(){return this.#e}async objectMetadata(e){return await this.#e.getObjectMeta(e)}getConfig(){return this.config}async uploadFile(e,t,n){let s=await this.#e.putObject(t,e);if(typeof s>"u")throw new Error("Failed to upload file");let i={name:t,meta:{size:0,type:"application/octet-stream"},etag:typeof s=="string"?s:""};if(typeof s=="object"?i=s:m(e)&&(i.meta.size=e.size,i.meta.type=e.type),!ne(i.meta.type,["application/octet-stream","application/json"])){let a=await this.#e.getObjectMeta(t);if(!a)throw new Error("Failed to get object meta");i.meta=a;}if(i.meta.type.startsWith("image")&&(!i.meta.width||!i.meta.height))try{let a=await fe(e);i.meta={...i.meta,...a};}catch(a){E.warn("Failed to get image dimensions",a);}let o={file:e,...i,state:{name:i.name,path:i.name}};if(!n){let a=await this.emgr.emit(new _(o));if(a.returned)return a.params}return o}async deleteFile(e){await this.#e.deleteObject(e),await this.emgr.emit(new j({name:e}));}async fileExists(e){return await this.#e.objectExists(e)}};var he=Symbol.for("bknd:storage"),b=class{constructor(){this[he]=true;}static isAdapter(e){return e?e[he]===true:false}};var {Type:w}=T,be=w.Object({cloud_name:w.String(),api_key:w.String(),api_secret:w.String(),upload_preset:w.Optional(w.String())},{title:"Cloudinary",description:"Cloudinary media storage"}),O=class extends b{config;constructor(e){super(),this.config=L(be,e);}getSchema(){return be}getMimeType(e){switch(true){case(e.format==="jpeg"||e.format==="jpg"):return "image/jpeg"}return `${e.resource_type}/${e.format}`}getName(){return "cloudinary"}getAuthorizationHeader(){return {Authorization:`Basic ${btoa(`${this.config.api_key}:${this.config.api_secret}`)}`}}async putObject(e,t){let n=e.replace(/\.[a-z0-9]{2,5}$/,""),s=new FormData;s.append("file",t),s.append("public_id",n),s.append("api_key",this.config.api_key),this.config.upload_preset&&s.append("upload_preset",this.config.upload_preset);let i=await fetch(`https://api.cloudinary.com/v1_1/${this.config.cloud_name}/auto/upload`,{method:"POST",headers:{Accept:"application/json"},body:s});if(!i.ok)return;let o=await i.json();return {name:o.public_id+"."+o.format,etag:o.etag,meta:{type:this.getMimeType(o),size:o.bytes}}}async listObjects(e){let t=await fetch(`https://api.cloudinary.com/v1_1/${this.config.cloud_name}/resources/search`,{method:"GET",headers:{Accept:"application/json","Cache-Control":"no-cache",...this.getAuthorizationHeader()}});if(!t.ok)throw new Error("Failed to list objects");return (await t.json()).resources.map(i=>({key:i.public_id,last_modified:new Date(i.uploaded_at),size:i.bytes}))}async headObject(e){let t=this.getObjectUrl(e);return await fetch(t,{method:"HEAD",headers:{"Cache-Control":"no-cache, no-store, must-revalidate",Pragma:"no-cache",Expires:"0",Range:"bytes=0-1"}})}async objectExists(e){return (await this.headObject(e)).ok}async getObjectMeta(e){let t=await this.headObject(e);if(t.ok){let n=t.headers.get("content-type"),s=Number(t.headers.get("content-range")?.split("/")[1]);return {type:n,size:s}}throw new Error("Cannot get object meta")}guessType(e){let t={image:["jpg","jpeg","png","gif","webp","svg"],video:["mp4","webm","ogg"]},n=e.split(".").pop();return Object.keys(t).find(s=>t[s].includes(n))}getObjectUrl(e){let t=this.guessType(e)??"image";return `https://res.cloudinary.com/${this.config.cloud_name}/${t}/upload/${e}`}async generateSignature(e,t){let n=e.timestamp??Math.floor(Date.now()/1e3),s=Object.entries({...e,timestamp:n}).sort(([o],[a])=>o.localeCompare(a)).map(([o,a])=>`${o}=${a}`).join("&");return {signature:await ye.sha1(s+(t??this.config.api_secret)),timestamp:n}}filenameToPublicId(e){return e.split(".").slice(0,-1).join(".")}async getObject(e,t){let n=await fetch(this.getObjectUrl(e),{method:"GET",headers:H(t,["range"])});return new Response(n.body,{status:n.status,statusText:n.statusText,headers:n.headers})}async deleteObject(e){let t=this.guessType(e)??"image",n=this.filenameToPublicId(e),{timestamp:s,signature:i}=await this.generateSignature({public_id:n}),o=new FormData;o.append("public_id",n),o.append("timestamp",String(s)),o.append("signature",i),o.append("api_key",this.config.api_key);let a=`https://api.cloudinary.com/v1_1/${this.config.cloud_name}/${t}/destroy`,g=await fetch(a,{headers:{Accept:"application/json","Cache-Control":"no-cache",...this.getAuthorizationHeader()},method:"POST",body:o});if(!g.ok)throw new Error(`Failed to delete object: ${g.status} ${g.statusText}`)}toJSON(e){return {type:"cloudinary",config:e?this.config:{cloud_name:this.config.cloud_name}}}};var {Type:D}=T,xe=D.Object({access_key:D.String(),secret_access_key:D.String(),url:D.String({pattern:"^https?://(?:.*)?[^/.]+$",description:"URL to S3 compatible endpoint without trailing slash",examples:["https://{account_id}.r2.cloudflarestorage.com/{bucket}","https://{bucket}.s3.{region}.amazonaws.com"]})},{title:"AWS S3",description:"AWS S3 or compatible storage"}),v=class extends b{#e;client;constructor(e){super(),this.client=new A({accessKeyId:e.access_key,secretAccessKey:e.secret_access_key,retries:M()?0:10},{convertParams:"pascalToKebab",responseType:"xml"}),this.#e=L(xe,e);}getName(){return "s3"}getSchema(){return xe}getUrl(e="",t={}){let n=this.getObjectUrl("").slice(0,-1);return e.length>0&&(n+=`/${e}`),this.client.getUrl(n,t)}getObjectUrl(e){return `${this.#e.url}/${e}`}async listObjects(e=""){let t={ListType:2,Prefix:e},n=this.getUrl("",t),s=await this.client.fetchJson(n,{method:"GET"}),{Contents:i}=s.ListBucketResult,o=i?Array.isArray(i)?i:[i]:[];return transform(o,(g,f)=>{f.Key&&f.LastModified&&f.Size&&g.push({key:f.Key,last_modified:f.LastModified,size:f.Size});},[])}async putObject(e,t,n={}){let s=this.getUrl(e,{}),i=await this.client.fetch(s,{method:"PUT",body:t,headers:m(t)?{"Content-Length":String(t.size)}:{}});if(!i.ok)throw new Error(`Failed to upload object: ${i.status} ${i.statusText}`);return String(i.headers.get("etag"))}async headObject(e,t={}){let n=this.getUrl(e,{});return await this.client.fetch(n,{method:"HEAD",headers:{Range:"bytes=0-1"}})}async getObjectMeta(e){let t=await this.headObject(e),n=String(t.headers.get("content-type")),s=Number(String(t.headers.get("content-range")?.split("/")[1]));return {type:n,size:s}}async objectExists(e,t={}){return (await this.headObject(e)).ok}async getObject(e,t){let n=this.getUrl(e),s=await this.client.fetch(n,{method:"GET",headers:ee(t,["if-none-match","accept-encoding","accept","if-modified-since"])});return new Response(s.body,{status:s.status,statusText:s.statusText,headers:s.headers})}async deleteObject(e,t={}){let n=this.getUrl(e,t);await this.client.fetch(n,{method:"DELETE"});}toJSON(e){return {type:this.getName(),config:e?this.#e:void 0}}};var Ee={};X(Ee,{deleteFile:()=>Je,listFiles:()=>Ye,readFile:()=>Ge,uploadFile:()=>We});var Ge=new u("media.file.read"),Ye=new u("media.file.list"),We=new u("media.file.upload"),Je=new u("media.file.delete");function Qe(r){if(!r.includes("."))return;let e=r.split(".");return e[e.length-1]?.toLowerCase()}function pr(r,e=16){let t=typeof r=="string"?r:r.name;if(typeof t!="string")throw console.error("Couldn't extract filename from",r),new Error("Invalid file name");let n=Qe(t);if(!n&&m(r)&&r.type){let s=se(r.type);s.length>0&&(n=s);}return [k(e),n].filter(Boolean).join(".")}async function Z(r,e,t,n){let s=null;for(let i=0;i<t;i++)try{let o=await r();if(e(o))return o;await new Promise(a=>setTimeout(a,n));}catch(o){s=o,await new Promise(a=>setTimeout(a,n));}throw s}async function Ze(r,e,t,n){let{test:s,expect:i}=r,o={retries:n?.retries??1,retryTimeout:n?.retryTimeout??1e3},a=0,f=`${k(10)}.png`;await s("puts an object",async()=>{a=(await e.listObjects()).length;let p=await e.putObject(f,t);i(p).toBeDefined(),i(typeof p).toBeOneOf(["string","object"]),typeof p=="object"&&(i(Object.keys(p).sort()).toEqual(["etag","meta","name"]),i(p.meta.type).toBe(t.type));}),await s("lists objects",async()=>{let p=await Z(()=>e.listObjects().then(x=>x.length),x=>x>a,o.retries,o.retryTimeout);i(p).toBe(a+1);}),await s("file exists",async()=>{i(await e.objectExists(f)).toBe(true);}),await s("gets an object",async()=>{let p=await e.getObject(f,new Headers);i(p.ok).toBe(true);}),await s("gets object meta",async()=>{i(await e.getObjectMeta(f)).toEqual({type:t.type,size:t.size});}),await s("deletes an object",async()=>{if(i(await e.deleteObject(f)).toBeUndefined(),n?.skipExistsAfterDelete!==true){let p=await Z(()=>e.objectExists(f),x=>x===!1,o.retries,o.retryTimeout);i(p).toBe(false);}});}var Or=new R(r=>({cls:r,schema:r.prototype.getSchema()})).register("s3",v).register("cloudinary",O),vr={s3:{cls:v,schema:v.prototype.getSchema()},cloudinary:{cls:O,schema:O.prototype.getSchema()}}; export{vr as Adapters,Or as MediaAdapterRegistry,Ee as MediaPermissions,Q as Storage,b as StorageAdapter,O as StorageCloudinaryAdapter,N as StorageEvents,v as StorageS3Adapter,Ze as adapterTestSuite,Qe as getExtensionFromName,pr as getRandomizedFilename,Le as guessMimeType};