var b=Object.defineProperty;var $=(d,i,e)=>i in d?b(d,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[i]=e;var a=(d,i,e)=>$(d,typeof i!="symbol"?i+"":i,e);import{d4 as k,bR as S,br as O}from"./Co0rzPff.js";import{u as s,M as m}from"./DweEgKYS.js";class w{constructor(i){a(this,"server");this.server=i}get serverId(){return this.server.serverId}}class T extends w{constructor(){super(...arguments);a(this,"data",[])}async fetch(){this.data=await s(`servers/${this.serverId}/backups`,{},"backups")}async create(e){const t=await s(`servers/${this.serverId}/backups`,{method:"POST",body:{name:e}});return await this.fetch(),t.id}async rename(e,t){await s(`servers/${this.serverId}/backups/${e}/rename`,{method:"POST",body:{name:t}}),await this.fetch()}async delete(e){await s(`servers/${this.serverId}/backups/${e}`,{method:"DELETE"}),await this.fetch()}async restore(e){await s(`servers/${this.serverId}/backups/${e}/restore`,{method:"POST"}),await this.fetch()}async prepare(e){await s(`servers/${this.serverId}/backups/${e}/prepare-download`,{method:"POST"})}async lock(e){await s(`servers/${this.serverId}/backups/${e}/lock`,{method:"POST"}),await this.fetch()}async unlock(e){await s(`servers/${this.serverId}/backups/${e}/unlock`,{method:"POST"}),await this.fetch()}async retry(e){await s(`servers/${this.serverId}/backups/${e}/retry`,{method:"POST"})}async updateAutoBackup(e,t){await s(`servers/${this.serverId}/autobackup`,{method:"POST",body:{set:e,interval:t}})}async getAutoBackup(){return await s(`servers/${this.serverId}/autobackup`)}}class I extends w{constructor(){super(...arguments);a(this,"data",[])}async fetch(){const e=await s(`servers/${this.serverId}/mods`,{},"content");this.data=e.sort((t,r)=>((t==null?void 0:t.name)??"").localeCompare((r==null?void 0:r.name)??""))}async install(e,t,r){await s(`servers/${this.serverId}/mods`,{method:"POST",body:{rinth_ids:{project_id:t,version_id:r},install_as:e}})}async remove(e){await s(`servers/${this.serverId}/deleteMod`,{method:"POST",body:{path:e}})}async reinstall(e,t,r){await s(`servers/${this.serverId}/mods/update`,{method:"POST",body:{replace:e,project_id:t,version_id:r}})}}class P extends w{constructor(){super(...arguments);a(this,"auth");a(this,"ops",[]);a(this,"queuedOps",[]);a(this,"opsQueuedForModification",[])}async fetch(){this.auth=await s(`servers/${this.serverId}/fs`,{},"fs"),this.ops=[],this.queuedOps=[],this.opsQueuedForModification=[]}async retryWithAuth(e,t=!1){try{return await e()}catch(r){if(r instanceof m&&r.statusCode===401)return console.debug("Auth failed, refreshing JWT and retrying"),await this.fetch(),await e();throw!await this.server.testNodeReachability()&&!t&&(this.server.moduleErrors.general={error:new m("Unable to reach node. FS operation failed and subsequent ping test failed.",500,r,"fs"),timestamp:Date.now()}),r}}listDirContents(e,t,r,o=!1){return this.retryWithAuth(async()=>{const c=encodeURIComponent(e);return await s(`/list?path=${c}&page=${t}&page_size=${r}`,{override:this.auth,retry:!1})},o)}createFileOrFolder(e,t){return this.retryWithAuth(async()=>{const r=encodeURIComponent(e);await s(`/create?path=${r}&type=${t}`,{method:"POST",contentType:"application/octet-stream",override:this.auth})})}uploadFile(e,t){const r=encodeURIComponent(e),o=new EventTarget,c=new AbortController;return{promise:new Promise((u,h)=>{const n=new XMLHttpRequest;n.upload.addEventListener("progress",p=>{if(p.lengthComputable){const v=p.loaded/p.total*100;o.dispatchEvent(new CustomEvent("progress",{detail:{loaded:p.loaded,total:p.total,progress:v}}))}}),n.onload=()=>{n.status>=200&&n.status<300?u(n.response):h(new Error(`Upload failed with status ${n.status}`))},n.onerror=()=>h(new Error("Upload failed")),n.onabort=()=>h(new Error("Upload cancelled")),n.open("POST",`https://${this.auth.url}/create?path=${r}&type=file`),n.setRequestHeader("Authorization",`Bearer ${this.auth.token}`),n.setRequestHeader("Content-Type","application/octet-stream"),n.send(t),c.signal.addEventListener("abort",()=>n.abort())}),onProgress:u=>{o.addEventListener("progress",h=>{u(h.detail)})},cancel:()=>c.abort()}}renameFileOrFolder(e,t){const r=e.split("/").slice(0,-1).join("/")+"/"+t;return this.retryWithAuth(async()=>{await s("/move",{method:"POST",override:this.auth,body:{source:e,destination:r}})})}updateFile(e,t){const r=new Blob([t],{type:"application/octet-stream"});return this.retryWithAuth(async()=>{await s(`/update?path=${e}`,{method:"PUT",contentType:"application/octet-stream",body:r,override:this.auth})})}moveFileOrFolder(e,t){return this.retryWithAuth(async()=>{await this.server.createMissingFolders(t.substring(0,t.lastIndexOf("/"))),await s("/move",{method:"POST",override:this.auth,body:{source:e,destination:t}})})}deleteFileOrFolder(e,t){const r=encodeURIComponent(e);return this.retryWithAuth(async()=>{await s(`/delete?path=${r}&recursive=${t}`,{method:"DELETE",override:this.auth})})}downloadFile(e,t=!1,r=!1){return this.retryWithAuth(async()=>{const o=encodeURIComponent(e),c=await s(`/download?path=${o}`,{override:this.auth});return c instanceof Blob?t?c:await c.text():c},r)}extractFile(e,t=!0,r=!1,o=!1){return this.retryWithAuth(async()=>{const c=encodeURIComponent(e);o||(this.queuedOps.push({op:"unarchive",src:e}),setTimeout(()=>this.removeQueuedOp("unarchive",e),4e3));try{return await s(`/unarchive?src=${c}&trg=/&override=${t}&dry=${r}`,{method:"POST",override:this.auth,version:1},void 0,"Error extracting file")}catch(l){throw this.removeQueuedOp("unarchive",e),l}})}modifyOp(e,t){return this.retryWithAuth(async()=>{await s(`/ops/${t}?id=${e}`,{method:"POST",override:this.auth,version:1},void 0,`Error ${t==="dismiss"?"dismissing":"cancelling"} filesystem operation`),this.opsQueuedForModification=this.opsQueuedForModification.filter(r=>r!==e),this.ops=this.ops.filter(r=>r.id!==e)})}removeQueuedOp(e,t){this.queuedOps=this.queuedOps.filter(r=>r.op!==e||r.src!==t)}clearQueuedOps(){this.queuedOps=[]}}class E extends w{constructor(){super(...arguments);a(this,"server_id");a(this,"name");a(this,"owner_id");a(this,"net");a(this,"game");a(this,"backup_quota");a(this,"used_backup_quota");a(this,"status");a(this,"suspension_reason");a(this,"loader");a(this,"loader_version");a(this,"mc_version");a(this,"upstream");a(this,"motd");a(this,"image");a(this,"project");a(this,"sftp_username");a(this,"sftp_password");a(this,"sftp_host");a(this,"datacenter");a(this,"notices");a(this,"node");a(this,"flows");a(this,"is_medal")}async fetch(){var t,r,o;const e=await s(`servers/${this.serverId}`,{},"general");if((t=e.upstream)!=null&&t.project_id){const c=await k(`https://api.modrinth.com/v2/project/${e.upstream.project_id}`);e.project=c}e.image=await this.server.processImage((r=e.project)==null?void 0:r.icon_url)??void 0;try{const c=await this.getMotd();c==="A Minecraft Server"&&await this.setMotd(`§b${((o=e.project)==null?void 0:o.title)||e.loader+" "+e.mc_version} §f♦ §aModrinth Servers`),e.motd=c}catch{console.error("[Modrinth Servers] [General] Failed to fetch MOTD."),e.motd=void 0}Object.assign(this,e)}async updateName(e){await s(`servers/${this.serverId}/name`,{method:"POST",body:{name:e}})}async power(e){await s(`servers/${this.serverId}/power`,{method:"POST",body:{action:e}}),await new Promise(t=>setTimeout(t,1e3)),await this.fetch()}async reinstall(e,t,r,o,c=!1){const l=c?"true":"false";e?(t.toLowerCase()==="neoforge"&&(t="NeoForge"),await s(`servers/${this.serverId}/reinstall?hard=${l}`,{method:"POST",body:{loader:t,loader_version:o,game_version:r}})):await s(`servers/${this.serverId}/reinstall?hard=${l}`,{method:"POST",body:{project_id:t,version_id:r}})}reinstallFromMrpack(e,t=!1){const r=t?"true":"false",o=new EventTarget;return{promise:(async()=>{try{const l=await s(`servers/${this.serverId}/reinstallFromMrpack`);await new Promise((u,h)=>{const n=new XMLHttpRequest;n.upload.addEventListener("progress",v=>{v.lengthComputable&&o.dispatchEvent(new CustomEvent("progress",{detail:{loaded:v.loaded,total:v.total,progress:v.loaded/v.total*100}}))}),n.onload=()=>n.status>=200&&n.status<300?u():h(new Error(`[pyroservers] XHR error status: ${n.status}`)),n.onerror=()=>h(new Error("[pyroservers] .mrpack upload failed")),n.onabort=()=>h(new Error("[pyroservers] .mrpack upload cancelled")),n.ontimeout=()=>h(new Error("[pyroservers] .mrpack upload timed out")),n.timeout=30*60*1e3,n.open("POST",`https://${l.url}/reinstallMrpackMultiparted?hard=${r}`),n.setRequestHeader("Authorization",`Bearer ${l.token}`);const p=new FormData;p.append("file",e),n.send(p)})}catch(l){throw console.error("Error reinstalling from mrpack:",l),l}})(),onProgress:l=>o.addEventListener("progress",u=>l(u.detail))}}async suspend(e){await s(`servers/${this.serverId}/suspend`,{method:"POST",body:{suspended:e}})}async endIntro(){await s(`servers/${this.serverId}/flows/intro`,{method:"DELETE",version:1}),await this.fetch()}async getMotd(){try{const e=await this.server.fs.downloadFile("/server.properties",!1,!0);if(e){const t=e.split(` `);for(const r of t)if(r.startsWith("motd="))return r.slice(5)}}catch{return}}async setMotd(e){try{const t=await this.server.fetchConfigFile("ServerProperties");if(t){t.motd=e;const r=this.server.constructServerProperties(t),o=new Blob([r],{type:"application/octet-stream"}),c=await s(`servers/${this.serverId}/fs`);await s("/update?path=/server.properties",{method:"PUT",contentType:"application/octet-stream",body:o,override:c})}}catch{console.error("[Modrinth Servers] [General] Failed to set MOTD due to lack of server properties file.")}}}class F extends w{constructor(){super(...arguments);a(this,"allocations",[])}async fetch(){this.allocations=await s(`servers/${this.serverId}/allocations`,{},"network")}async reserveAllocation(e){return await s(`servers/${this.serverId}/allocations?name=${e}`,{method:"POST"})}async updateAllocation(e,t){await s(`servers/${this.serverId}/allocations/${e}?name=${t}`,{method:"PUT"})}async deleteAllocation(e){await s(`servers/${this.serverId}/allocations/${e}`,{method:"DELETE"})}async checkSubdomainAvailability(e){return(await s(`subdomains/${e}/isavailable`)).available}async changeSubdomain(e){await s(`servers/${this.serverId}/subdomain`,{method:"POST",body:{subdomain:e}})}}class M extends w{constructor(){super(...arguments);a(this,"invocation");a(this,"original_invocation");a(this,"jdk_version");a(this,"jdk_build")}async fetch(){const e=await s(`servers/${this.serverId}/startup`,{},"startup");Object.assign(this,e)}async update(e,t,r){await s(`servers/${this.serverId}/startup`,{method:"POST",body:{invocation:e||null,jdk_version:t||null,jdk_build:r||null}})}}class R extends w{constructor(){super(...arguments);a(this,"url");a(this,"token")}async fetch(){const e=await s(`servers/${this.serverId}/ws`,{},"ws");Object.assign(this,e)}}function A(d,i){var e;d instanceof m&&d.v1Error?i.addNotification({title:((e=d.v1Error)==null?void 0:e.context)??"An error occurred",type:"error",text:d.v1Error.description,errorCode:d.v1Error.error}):i.addNotification({title:"An error occurred",type:"error",text:d.message??(d.data?d.data.description:d)})}class C{constructor(i){a(this,"serverId");a(this,"errors",{});a(this,"general");a(this,"content");a(this,"backups");a(this,"network");a(this,"startup");a(this,"ws");a(this,"fs");this.serverId=i,this.general=new E(this),this.content=new I(this),this.backups=new T(this),this.network=new F(this),this.startup=new M(this),this.ws=new R(this),this.fs=new P(this)}async createMissingFolders(i){i.startsWith("/")&&(i=i.substring(1));const e=i.split("/");let t="";for(const r of e){t+="/"+r;try{await this.fs.createFileOrFolder(t,"directory")}catch{}}}async fetchConfigFile(i){return await s(`servers/${this.serverId}/config/${i}`)}constructServerProperties(i){let e=`#Minecraft server properties #${new Date().toUTCString()} `;for(const[t,r]of Object.entries(i))typeof r=="object"?e+=`${t}=${JSON.stringify(r)} `:typeof r=="boolean"?e+=`${t}=${r?"true":"false"} `:e+=`${t}=${r} `;return e}async processImage(i){const e=O(`server-icon-${this.serverId}`);if(e.value)return e.value;try{const t=await s(`servers/${this.serverId}/fs`);try{const r=await s("/download?path=/server-icon-original.png",{override:t,retry:1});if(r instanceof Blob)return await new Promise(c=>{const l=document.createElement("canvas"),u=l.getContext("2d"),h=new Image;h.onload=()=>{l.width=512,l.height=512,u==null||u.drawImage(h,0,0,512,512);const n=l.toDataURL("image/png");e.value=n,c(n),URL.revokeObjectURL(h.src)},h.src=URL.createObjectURL(r)})}catch(r){if(r instanceof m){if(r.statusCode&&r.statusCode>=500){console.debug("Service unavailable, skipping icon processing"),e.value=void 0;return}if(r.statusCode===404&&i)try{const o=await fetch(i);if(!o.ok)throw new Error("Failed to fetch icon");const c=await o.blob(),l=new File([c],"server-icon-original.png",{type:"image/png"});return await new Promise(h=>{const n=document.createElement("canvas"),p=n.getContext("2d"),v=new Image;v.onload=()=>{n.width=64,n.height=64,p==null||p.drawImage(v,0,0,64,64),n.toBlob(async y=>{if(y){const g=new File([y],"server-icon.png",{type:"image/png"});await s("/create?path=/server-icon.png&type=file",{method:"POST",contentType:"application/octet-stream",body:g,override:t}),await s("/create?path=/server-icon-original.png&type=file",{method:"POST",contentType:"application/octet-stream",body:l,override:t})}},"image/png");const f=n.toDataURL("image/png");e.value=f,h(f),URL.revokeObjectURL(v.src)},v.src=URL.createObjectURL(c)})}catch(o){console.debug("Could not process external icon:",o.message)}}else throw r}}catch(t){console.debug("Icon processing failed:",t.message)}e.value=void 0}async testNodeReachability(){var e,t;if(!((t=(e=this.general)==null?void 0:e.node)!=null&&t.instance))return console.warn("No node instance available for ping test"),!1;const i=`wss://${this.general.node.instance}/pingtest`;try{return await new Promise(r=>{const o=new WebSocket(i),c=setTimeout(()=>{o.close(),r(!1)},5e3);o.onopen=()=>{clearTimeout(c),o.send(performance.now().toString())},o.onmessage=()=>{clearTimeout(c),o.close(),r(!0)},o.onerror=()=>{clearTimeout(c),r(!1)}})}catch(r){return console.error(`Failed to ping node ${i}:`,r),!1}}async refresh(i=[],e){const t=i.length>0?i:["general","content","backups","network","startup","ws","fs"];for(const r of t){this.errors[r]=void 0;try{switch(r){case"general":{if(e!=null&&e.preserveConnection){const o=this.general.image,c=this.general.motd,l=this.general.status;await this.general.fetch(),o&&(this.general.image=o),c&&(this.general.motd=c),e.preserveInstallState&&l==="installing"&&(this.general.status="installing")}else await this.general.fetch();break}case"content":await this.content.fetch();break;case"backups":await this.backups.fetch();break;case"network":await this.network.fetch();break;case"startup":await this.startup.fetch();break;case"ws":await this.ws.fetch();break;case"fs":await this.fs.fetch();break}}catch(o){if(o instanceof m){if(o.statusCode===404&&["fs","content"].includes(r)){console.debug(`Optional ${r} resource not found:`,o.message);continue}if(o.statusCode&&o.statusCode>=500){console.debug(`Temporary ${r} unavailable:`,o.message);continue}}this.errors[r]={error:o instanceof m?o:new m("Unknown error",void 0,o),timestamp:Date.now()}}}}get moduleErrors(){return this.errors}}const j=async(d,i=["general"])=>{const e=new C(d);return await e.refresh(i),S(e)};export{A as h,j as u};