import{O as e,T as t,b as n,h as r,m as i,p as a,w as o}from"./dist-DPmmj29U.js";import{t as s}from"./useMutation-Du3NQIud.js";import{t as c}from"./useAppContext-ZpOJAKgd.js";import{t as l}from"./useCurrentUser-boOMG5Xx.js";import{n as u}from"./appBlossom-CsMDSd4h.js";var d=class a{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 a.sha256(e),r=await this.authorizer({verb:`upload`,content:`Upload ${e.name}`,x:n});return Promise.any(this.servers.map(async i=>{let o=await r(i),s=await this.fetch(new URL(`/upload`,i),{method:`PUT`,body:e,headers:{authorization:o,"content-type":e.type,"x-sha-256":n},signal:t?.signal});return a.parse(s,n)}))}async media(e,t){let n=await a.sha256(e),r=await this.authorizer({verb:`media`,content:`Optimize ${e.name}`,x:n});return Promise.any(this.servers.map(async i=>{let o=await r(i),s=await this.fetch(new URL(`/media`,i),{method:`PUT`,body:e,headers:{authorization:o,"content-type":e.type,"x-sha-256":n},signal:t?.signal});return a.parse(s,n)}))}async mirror(e,t){let n=t?.sha256??a.hashFromUrl(e),r=await this.authorizer({verb:`upload`,content:`Mirror ${e}`,x:n});return Promise.any(this.servers.map(async i=>{let o=await r(i),s=await this.fetch(new URL(`/mirror`,i),{method:`PUT`,body:JSON.stringify({url:e}),headers:{authorization:o,"content-type":`application/json`},signal:t?.signal});return a.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 a=await this.signer.signEvent({kind:24242,content:e.content,created_at:Math.floor(n/1e3),tags:r});return`Nostr ${i.encodeEventUrl(a)}`}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 i=a.schema.parse(r);if(i.nip94?.length){let e=i.nip94.find(([e])=>e===`url`)?.[1],t=e===void 0?i.url:a.urlSchema.parse(e),n=i.nip94.filter(([e])=>e!==`url`);return[[`url`,t],...n]}let o=[[`url`,i.url],[`x`,i.sha256],[`ox`,t??i.sha256],[`size`,i.size.toString()]];return i.dim&&o.push([`dim`,i.dim]),i.type&&o.push([`m`,i.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=e().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=t({url:a.urlSchema,sha256:e(),size:o(),type:e().optional(),uploaded:o().optional(),dim:e().regex(/^\d+x\d+$/).optional().catch(void 0),nip94:n(n(e())).optional().catch(void 0)})};(class n{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(e,t){let r=new FormData;r.append(`fileToUpload`,e);let o=new Request(this.endpoint,{method:`POST`,body:r,signal:t?.signal});if(this.signer){let e=await a.template(o),t=await this.signer.signEvent(e);o.headers.set(`authorization`,`Nostr ${i.encodeEvent(t)}`)}let s=await(await this.fetch(o)).json(),[c]=n.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=t({data:t({url:e().url(),blurhash:e().optional().catch(void 0),sha256:e(),original_sha256:e(),mime:e(),size:o(),dimensions:t({width:o().positive(),height:o().positive()}).optional().catch(void 0)}).array().min(1)})});function f(){let{user:e}=l(),{config:t}=c();return s({mutationFn:async n=>{if(!e)throw Error(`Must be logged in to upload files`);let r=u(t.blossomServerMetadata,t.useAppBlossomServers),i=await new d({servers:r,signer:e.signer,fetch:(e,t)=>globalThis.fetch(e,{...t,signal:AbortSignal.any([t?.signal??AbortSignal.timeout(3e4),AbortSignal.timeout(3e4)])})}).upload(n),a=p(n.name);a&&(i[0][1]=m(i[0][1],a));let o=i[0][1],s=r.find(e=>o.startsWith(e)),c=r.filter(e=>e!==s);return c.length>0&&h(o,c,e.signer).catch(()=>{}),i}})}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(),a=await n.signEvent({kind:24242,content:`Mirror blob`,created_at:Math.floor(r/1e3),tags:[[`t`,`mirror`],[`expiration`,Math.floor((r+6e4)/1e3).toString()]]}),o=`Nostr ${i.encodeEvent(a)}`;await Promise.allSettled(t.map(t=>fetch(new URL(`/mirror`,t),{method:`PUT`,headers:{"Content-Type":`application/json`,Authorization:o},body:JSON.stringify({url:e})})))}export{f as t};