import{ct as e,ft as t,ht as n,it as r,nt as i,pt as a,rt as o}from"./useAuthor-K0SVHIbr.js";import{t as s}from"./useMutation-B3AB1JC6.js";import{t as c}from"./useAppContext-DVsgK-HT.js";import{n as l}from"./appBlossom-CsMDSd4h.js";import{t as u}from"./useCurrentUser-CgUH2vq7.js";var d=class i{servers;signer;fetch;expiresIn;scopeToServer;constructor(e){this.servers=e.servers,this.signer=e.signer,this.fetch=e.fetch??globalThis.fetch.bind(globalThis),this.expiresIn=e.expiresIn??6e4,this.scopeToServer=e.scopeToServer??!1}async upload(e,t){let n=await i.sha256(e),r=await this.authorizer({verb:`upload`,content:`Upload ${e.name}`,x:n});return Promise.any(this.servers.map(async a=>{let o=await r(a),s=await this.fetch(new URL(`/upload`,a),{method:`PUT`,body:e,headers:{authorization:o,"content-type":e.type,"x-sha-256":n},signal:t?.signal});return i.parse(s,n)}))}async media(e,t){let n=await i.sha256(e),r=await this.authorizer({verb:`media`,content:`Optimize ${e.name}`,x:n});return Promise.any(this.servers.map(async a=>{let o=await r(a),s=await this.fetch(new URL(`/media`,a),{method:`PUT`,body:e,headers:{authorization:o,"content-type":e.type,"x-sha-256":n},signal:t?.signal});return i.parse(s,n)}))}async mirror(e,t){let n=t?.sha256??i.hashFromUrl(e),r=await this.authorizer({verb:`upload`,content:`Mirror ${e}`,x:n});return Promise.any(this.servers.map(async a=>{let o=await r(a),s=await this.fetch(new URL(`/mirror`,a),{method:`PUT`,body:JSON.stringify({url:e}),headers:{authorization:o,"content-type":`application/json`},signal:t?.signal});return i.parse(s,n)}))}async authorizer(e){if(this.scopeToServer)return t=>this.authorize(e,t);let t=await this.authorize(e);return()=>Promise.resolve(t)}async authorize(e,t){let n=Date.now(),r=[[`t`,e.verb],[`expiration`,Math.floor((n+this.expiresIn)/1e3).toString()]];e.x&&r.push([`x`,e.x]),t&&r.push([`server`,new URL(t).hostname]);let i=await this.signer.signEvent({kind:24242,content:e.content,created_at:Math.floor(n/1e3),tags:r});return`Nostr ${o.encodeEventUrl(i)}`}static async parse(e,t){let n=await e.text();if(!e.ok){let t=e.headers.get(`x-reason`);throw Error(`Blossom request failed (${e.status}): ${t??n}`)}let r;try{r=JSON.parse(n)}catch{throw Error(`Blossom server returned non-JSON response: ${n}`)}let a=i.schema.parse(r);if(a.nip94?.length){let e=a.nip94.find(([e])=>e===`url`)?.[1],t=e===void 0?a.url:i.urlSchema.parse(e),n=a.nip94.filter(([e])=>e!==`url`);return[[`url`,t],...n]}let o=[[`url`,a.url],[`x`,a.sha256],[`ox`,t??a.sha256],[`size`,a.size.toString()]];return a.dim&&o.push([`dim`,a.dim]),a.type&&o.push([`m`,a.type]),o}static async sha256(e){let t=await crypto.subtle.digest(`SHA-256`,await e.arrayBuffer());return r(new Uint8Array(t))}static hashFromUrl(e){return new URL(e).pathname.match(/[0-9a-f]{64}/)?.[0]}static urlSchema=n().refine(e=>{try{let{protocol:t}=new URL(e);return t===`http:`||t===`https:`}catch{return!1}},{message:`Expected an http(s) URL`});static schema=a({url:i.urlSchema,sha256:n(),size:t(),type:n().optional(),uploaded:t().optional(),dim:n().regex(/^\d+x\d+$/).optional().catch(void 0),nip94:e(e(n())).optional().catch(void 0)})};(class e{endpoint;signer;fetch;constructor(e){this.endpoint=e?.endpoint??`https://nostr.build/api/v2/upload/files`,this.signer=e?.signer,this.fetch=e?.fetch??globalThis.fetch.bind(globalThis)}async upload(t,n){let r=new FormData;r.append(`fileToUpload`,t);let a=new Request(this.endpoint,{method:`POST`,body:r,signal:n?.signal});if(this.signer){let e=await i.template(a),t=await this.signer.signEvent(e);a.headers.set(`authorization`,`Nostr ${o.encodeEvent(t)}`)}let s=await(await this.fetch(a)).json(),[c]=e.schema.parse(s).data,l=[[`url`,c.url],[`m`,c.mime],[`x`,c.sha256],[`ox`,c.original_sha256],[`size`,c.size.toString()]];return c.dimensions&&l.push([`dim`,`${c.dimensions.width}x${c.dimensions.height}`]),c.blurhash&&l.push([`blurhash`,c.blurhash]),l}static schema=a({data:a({url:n().url(),blurhash:n().optional().catch(void 0),sha256:n(),original_sha256:n(),mime:n(),size:t(),dimensions:a({width:t().positive(),height:t().positive()}).optional().catch(void 0)}).array().min(1)})});function f(e){let{user:t}=u(),{config:n}=c();return s({mutationFn:async r=>{let i=e??t?.signer;if(!i)throw Error(`Must be logged in to upload files`);let a=l(n.blossomServerMetadata,n.useAppBlossomServers),o=await new d({servers:a,signer:i,fetch:(e,t)=>globalThis.fetch(e,{...t,signal:AbortSignal.any([t?.signal??AbortSignal.timeout(3e4),AbortSignal.timeout(3e4)])})}).upload(r),s=p(r.name);s&&(o[0][1]=m(o[0][1],s));let c=o[0][1],u=a.find(e=>c.startsWith(e)),f=a.filter(e=>e!==u);return f.length>0&&h(c,f,i).catch(()=>{}),o}})}function p(e){let t=e.lastIndexOf(`.`);return t<=0?``:e.slice(t).toLowerCase()}function m(e,t){let n=new URL(e);return(n.pathname.split(`/`).pop()??``).includes(`.`)?e:(n.pathname+=t,n.toString())}async function h(e,t,n){let r=Date.now(),i=await n.signEvent({kind:24242,content:`Mirror blob`,created_at:Math.floor(r/1e3),tags:[[`t`,`mirror`],[`expiration`,Math.floor((r+6e4)/1e3).toString()]]}),a=`Nostr ${o.encodeEvent(i)}`;await Promise.allSettled(t.map(t=>fetch(new URL(`/mirror`,t),{method:`PUT`,headers:{"Content-Type":`application/json`,Authorization:a},body:JSON.stringify({url:e})})))}export{f as t};