@spatulox/discord-interaction-manager 2.0.5 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/MainCLI.js +1 -1
  2. package/package.json +1 -1
package/dist/MainCLI.js CHANGED
@@ -87,7 +87,7 @@ Must be one of: ${oF.join(", ")}`);let s=new URL(`${n}${t}.${r}`);return o!==voi
87
87
  ${n}`:A.message||n||"Unknown Error"):A.error_description??"No Description"}static*flattenDiscordError(A,n=""){if(wF(A))return yield`${n.length?`${n}[${A.code}]`:`${A.code}`}: ${A.message}`.trim();for(let[r,i]of Object.entries(A)){let o=r.startsWith("_")?n:n?Number.isNaN(Number(r))?`${n}.${r}`:`${n}[${r}]`:r;if(typeof i=="string")yield i;else if(yF(i))for(let s of i._errors)yield*this.flattenDiscordError(s,o);else yield*this.flattenDiscordError(i,o)}}},Oe(Di,"DiscordAPIError"),Di),mo,_q=(mo=class extends Error{constructor(A,n,r,i,o){super(n);V(this,"requestBody");V(this,"name",mo.name);this.status=A,this.method=r,this.url=i,this.requestBody={files:o.files,json:o.body}}},Oe(mo,"HTTPError"),mo),dg=0,Eg=null;function ud(e){(!Eg||Eg<Date.now())&&(Eg=Date.now()+1e3*60*10,dg=0),dg++,e.options.invalidRequestWarningInterval>0&&dg%e.options.invalidRequestWarningInterval===0&&e.emit("invalidRequestWarning",{count:dg,remainingTime:Eg-Date.now()})}Oe(ud,"incrementInvalidCount");async function gd(e,t,A,n,r,i){let o=new AbortController,s=setTimeout(()=>o.abort(),e.options.timeout);r.signal&&(r.signal.aborted?o.abort():r.signal.addEventListener("abort",()=>o.abort()));let a;try{a=await e.options.makeRequest(A,{...n,signal:o.signal})}catch(l){if(!(l instanceof Error))throw l;if(fF(l)&&i!==e.options.retries)return null;throw l}finally{clearTimeout(s)}return e.listenerCount("response")&&e.emit("response",{method:n.method??"get",path:t.original,route:t.bucketRoute,options:n,data:r,retries:i},a instanceof Response?a.clone():{...a}),a}Oe(gd,"makeNetworkRequest");async function hd(e,t,A,n,r,i){let o=t.status;if(o>=500&&o<600){if(i!==e.options.retries)return null;throw new _q(o,t.statusText,A,n,r)}else{if(o>=400&&o<500){o===401&&r.auth&&e.setToken(null);let s=await ld(t);throw new Vq(s,"code"in s?s.code:s.error,o,A,n,r)}return t}}Oe(hd,"handleErrors");var aa,qq=(aa=class{constructor(t,A,n){V(this,"id");V(this,"inactive",!1);this.manager=t,this.hash=A,this.majorParameter=n,this.id=`${A}:${n}`}debug(t){this.manager.emit("restDebug",`[REST ${this.id}] ${t}`)}async queueRequest(t,A,n,r){return this.runRequest(t,A,n,r)}async runRequest(t,A,n,r,i=0){let o=n.method??"get",s=await gd(this.manager,t,A,n,r,i);if(s===null)return this.runRequest(t,A,n,r,++i);let a=s.status,l=0,I=s.headers.get("Retry-After"),h=oa(this.manager.options.offset,t.bucketRoute);if(I&&(l=Number(I)*1e3+h),(a===401||a===403||a===429)&&ud(this.manager),a>=200&&a<300)return s;if(a===429){let d=s.headers.has("X-RateLimit-Global"),C=s.headers.get("X-RateLimit-Scope")??"user";return await Cg(this.manager,{global:d,method:o,url:A,route:t.bucketRoute,majorParameter:this.majorParameter,hash:this.hash,limit:Number.POSITIVE_INFINITY,timeToReset:l,retryAfter:l,sublimitTimeout:0,scope:C}),this.debug(["Encountered unexpected 429 rate limit",` Global : ${d}`,` Method : ${o}`,` URL : ${A}`,` Bucket : ${t.bucketRoute}`,` Major parameter: ${t.majorParameter}`,` Hash : ${this.hash}`,` Limit : ${Number.POSITIVE_INFINITY}`,` Retry After : ${l}ms`," Sublimit : None",` Scope : ${C}`].join(`
88
88
  `)),await vc(l),this.runRequest(t,A,n,r,i)}else{let d=await hd(this.manager,s,o,A,r,i);return d===null?this.runRequest(t,A,n,r,++i):d}}},Oe(aa,"BurstHandler"),aa),bi,lA,Ur,ca,la,Wq=(la=class{constructor(t,A,n){V(this,"id");V(this,"reset",-1);V(this,"remaining",1);V(this,"limit",Number.POSITIVE_INFINITY);P(this,bi,new sd);P(this,lA,null);P(this,Ur,null);P(this,ca,!1);this.manager=t,this.hash=A,this.majorParameter=n,this.id=`${A}:${n}`}get inactive(){return u(this,bi).remaining===0&&(u(this,lA)===null||u(this,lA).remaining===0)&&!this.limited}get globalLimited(){return this.manager.globalRemaining<=0&&Date.now()<this.manager.globalReset}get localLimited(){return this.remaining<=0&&Date.now()<this.reset}get limited(){return this.globalLimited||this.localLimited}getTimeToReset(t){let A=oa(this.manager.options.offset,t.bucketRoute);return this.reset+A-Date.now()}debug(t){this.manager.emit("restDebug",`[REST ${this.id}] ${t}`)}async globalDelayFor(t){await vc(t),this.manager.globalDelay=null}async queueRequest(t,A,n,r){let i=u(this,bi),o=0;if(u(this,lA)&&cd(t.bucketRoute,r.body,n.method)&&(i=u(this,lA),o=1),await i.wait({signal:r.signal}),o===0)if(u(this,lA)&&cd(t.bucketRoute,r.body,n.method)){i=u(this,lA);let s=i.wait();u(this,bi).shift(),await s}else u(this,Ur)&&await u(this,Ur).promise;try{return await this.runRequest(t,A,n,r)}finally{i.shift(),u(this,ca)&&(v(this,ca,!1),u(this,lA)?.shift()),u(this,lA)?.remaining===0&&(u(this,Ur)?.resolve(),v(this,lA,null))}}async runRequest(t,A,n,r,i=0){for(;this.limited;){let M=this.globalLimited,N,H,q;if(M){let le=oa(this.manager.options.offset,t.bucketRoute);N=this.manager.options.globalRequestsPerSecond,H=this.manager.globalReset+le-Date.now(),this.manager.globalDelay||(this.manager.globalDelay=this.globalDelayFor(H)),q=this.manager.globalDelay}else N=this.limit,H=this.getTimeToReset(t),q=vc(H);let K={global:M,method:n.method??"get",url:A,route:t.bucketRoute,majorParameter:this.majorParameter,hash:this.hash,limit:N,timeToReset:H,retryAfter:H,sublimitTimeout:0,scope:"user"};this.manager.emit("rateLimited",K),await Cg(this.manager,K),M?this.debug(`Global rate limit hit, blocking all requests for ${H}ms`):this.debug(`Waiting ${H}ms for rate limit to pass`),await q}(!this.manager.globalReset||this.manager.globalReset<Date.now())&&(this.manager.globalReset=Date.now()+1e3,this.manager.globalRemaining=this.manager.options.globalRequestsPerSecond),this.manager.globalRemaining--;let o=n.method??"get",s=await gd(this.manager,t,A,n,r,i);if(s===null)return this.runRequest(t,A,n,r,++i);let a=s.status,l=0,I=s.headers.get("X-RateLimit-Limit"),h=s.headers.get("X-RateLimit-Remaining"),d=s.headers.get("X-RateLimit-Reset-After"),C=s.headers.get("X-RateLimit-Bucket"),y=s.headers.get("Retry-After"),D=s.headers.get("X-RateLimit-Scope")??"user",g=oa(this.manager.options.offset,t.bucketRoute);if(this.limit=I?Number(I):Number.POSITIVE_INFINITY,this.remaining=h?Number(h):1,this.reset=d?Number(d)*1e3+Date.now()+g:Date.now(),y&&(l=Number(y)*1e3+g),C&&C!==this.hash)this.debug(["Received bucket hash update",` Old Hash : ${this.hash}`,` New Hash : ${C}`].join(`
89
89
  `)),this.manager.hashes.set(`${o}:${t.bucketRoute}`,{value:C,lastAccess:Date.now()});else if(C){let M=this.manager.hashes.get(`${o}:${t.bucketRoute}`);M&&(M.lastAccess=Date.now())}let w=null;if(l>0&&(s.headers.has("X-RateLimit-Global")?(this.manager.globalRemaining=0,this.manager.globalReset=Date.now()+l):this.localLimited||(w=l)),(a===401||a===403||a===429)&&ud(this.manager),s.ok)return s;if(a===429){let M=this.globalLimited,N,H;if(M){let q=oa(this.manager.options.offset,t.bucketRoute);N=this.manager.options.globalRequestsPerSecond,H=this.manager.globalReset+q-Date.now()}else N=this.limit,H=this.getTimeToReset(t);if(await Cg(this.manager,{global:M,method:o,url:A,route:t.bucketRoute,majorParameter:this.majorParameter,hash:this.hash,limit:N,timeToReset:H,retryAfter:l,sublimitTimeout:w??0,scope:D}),this.debug(["Encountered unexpected 429 rate limit",` Global : ${M.toString()}`,` Method : ${o}`,` URL : ${A}`,` Bucket : ${t.bucketRoute}`,` Major parameter: ${t.majorParameter}`,` Hash : ${this.hash}`,` Limit : ${N}`,` Retry After : ${l}ms`,` Sublimit : ${w?`${w}ms`:"None"}`,` Scope : ${D}`].join(`
90
- `)),w){let q=!u(this,lA);q&&(v(this,lA,new sd),u(this,lA).wait(),u(this,bi).shift()),u(this,Ur)?.resolve(),v(this,Ur,null),await vc(w);let K,le=new Promise(Ue=>K=Ue);v(this,Ur,{promise:le,resolve:K}),q&&(await u(this,bi).wait(),v(this,ca,!0))}return this.runRequest(t,A,n,r,i)}else{let M=await hd(this.manager,s,o,A,r,i);return M===null?this.runRequest(t,A,n,r,++i):M}}},bi=new WeakMap,lA=new WeakMap,Ur=new WeakMap,ca=new WeakMap,Oe(la,"SequentialHandler"),la),ua,po,mg=(po=class extends qM{constructor(A={}){super();V(this,"agent",null);V(this,"cdn");V(this,"globalRemaining");V(this,"globalDelay",null);V(this,"globalReset",-1);V(this,"hashes",new Rc);V(this,"handlers",new Rc);P(this,ua,null);V(this,"hashTimer");V(this,"handlerTimer");V(this,"options");this.cdn=new Pq(A.cdn??Sc.cdn,A.mediaProxy??Sc.mediaProxy),this.options={...Sc,...A},this.globalRemaining=Math.max(1,this.options.globalRequestsPerSecond),this.agent=A.agent??null,this.setupSweepers()}setupSweepers(){let A=Oe(n=>{if(n>144e5)throw new Error("Cannot set an interval greater than 4 hours")},"validateMaxInterval");this.options.hashSweepInterval!==0&&this.options.hashSweepInterval!==Number.POSITIVE_INFINITY&&(A(this.options.hashSweepInterval),this.hashTimer=setInterval(()=>{let n=new Rc,r=Date.now();this.hashes.sweep((i,o)=>{if(i.lastAccess===-1)return!1;let s=Math.floor(r-i.lastAccess)>this.options.hashLifetime;return s&&(n.set(o,i),this.emit("restDebug",`Hash ${i.value} for ${o} swept due to lifetime being exceeded`)),s}),this.emit("hashSweep",n)},this.options.hashSweepInterval),this.hashTimer.unref?.()),this.options.handlerSweepInterval!==0&&this.options.handlerSweepInterval!==Number.POSITIVE_INFINITY&&(A(this.options.handlerSweepInterval),this.handlerTimer=setInterval(()=>{let n=new Rc;this.handlers.sweep((r,i)=>{let{inactive:o}=r;return o&&(n.set(i,r),this.emit("restDebug",`Handler ${r.id} for ${i} swept due to being inactive`)),o}),this.emit("handlerSweep",n)},this.options.handlerSweepInterval),this.handlerTimer.unref?.())}async get(A,n={}){return this.request({...n,fullRoute:A,method:"GET"})}async delete(A,n={}){return this.request({...n,fullRoute:A,method:"DELETE"})}async post(A,n={}){return this.request({...n,fullRoute:A,method:"POST"})}async put(A,n={}){return this.request({...n,fullRoute:A,method:"PUT"})}async patch(A,n={}){return this.request({...n,fullRoute:A,method:"PATCH"})}async request(A){let n=await this.queueRequest(A);return ld(n)}setAgent(A){return this.agent=A,this}setToken(A){return v(this,ua,A),this}async queueRequest(A){let n=po.generateRouteData(A.fullRoute,A.method),r=this.hashes.get(`${A.method}:${n.bucketRoute}`)??{value:`Global(${A.method}:${n.bucketRoute})`,lastAccess:-1},i=this.handlers.get(`${r.value}:${n.majorParameter}`)??this.createHandler(r.value,n.majorParameter),{url:o,fetchOptions:s}=await this.resolveRequest(A);return i.queueRequest(n,o,s,{body:A.body,files:A.files,auth:A.auth!==!1,signal:A.signal})}createHandler(A,n){let r=n===sF?new qq(this,A,n):new Wq(this,A,n);return this.handlers.set(r.id,r),r}async resolveRequest(A){let{options:n}=this,r="";if(A.query){let h=A.query.toString();h!==""&&(r=`?${h}`)}let i={...this.options.headers,"User-Agent":`${Nq} ${n.userAgentAppendix}`.trim()};if(A.auth!==!1){if(!u(this,ua))throw new Error("Expected token to be set for this request, but none was present");i.Authorization=`${A.authPrefix??this.options.authPrefix} ${u(this,ua)}`}A.reason?.length&&(i["X-Audit-Log-Reason"]=encodeURIComponent(A.reason));let o=`${n.api}${A.versioned===!1?"":`/v${n.version}`}${A.fullRoute}${r}`,s,a={};if(A.files?.length){let h=new FormData;for(let[d,C]of A.files.entries()){let y=C.key??`files[${d}]`;if(mF(C.data)){let D=C.contentType;if(!D){let[g]=(0,bF.filetypeinfo)(C.data);g&&(D=Tq[g.mime]??g.mime??"application/octet-stream")}h.append(y,new Blob([C.data],{type:D}),C.name)}else h.append(y,new Blob([`${C.data}`],{type:C.contentType}),C.name)}if(A.body!=null)if(A.appendToFormData)for(let[d,C]of Object.entries(A.body))h.append(d,C);else h.append("payload_json",JSON.stringify(A.body));s=h}else A.body!=null&&(A.passThroughBody?s=A.body:(s=JSON.stringify(A.body),a={"Content-Type":"application/json"}));let l=A.method.toUpperCase(),I={body:["GET","HEAD"].includes(l)?null:s,headers:{...A.headers,...a,...i},method:l,dispatcher:A.dispatcher??this.agent??void 0};return{url:o,fetchOptions:I}}clearHashSweeper(){clearInterval(this.hashTimer)}clearHandlerSweeper(){clearInterval(this.handlerTimer)}static generateRouteData(A,n){if(A.startsWith("/interactions/")&&A.endsWith("/callback"))return{majorParameter:sF,bucketRoute:"/interactions/:id/:token/callback",original:A};let r=/(?:^\/webhooks\/(\d{17,19}\/[^/?]+))|(?:^\/(?:channels|guilds|webhooks)\/(\d{17,19}))/.exec(A),i=r?.[2]??r?.[1]??"global",o=A.replaceAll(/\d{17,19}/g,":id").replace(/\/reactions\/(.*)/,"/reactions/:reaction").replace(/\/webhooks\/:id\/[^/?]+/,"/webhooks/:id/:token"),s="";if(n==="DELETE"&&o==="/channels/:id/messages/:id"){let a=/\d{17,19}$/.exec(A)[0],l=LM.timestampFrom(a);Date.now()-l>1e3*60*60*24*14&&(s+="/Delete Old Message")}return{majorParameter:i,bucketRoute:o+s,original:A}}},ua=new WeakMap,Oe(po,"REST"),po);globalThis.FormData??=uF.FormData;globalThis.Blob??=lF.Blob;hF(gh()?fetch:dF);var DF=ur(require("fs/promises"));var pg=(A=>(A[A.GUILD_INSTALL=0]="GUILD_INSTALL",A[A.USER_INSTALL=1]="USER_INSTALL",A))(pg||{}),yg=(n=>(n[n.SERVER_CHANNEL=0]="SERVER_CHANNEL",n[n.BOT_DM=1]="BOT_DM",n[n.GROUP_DM=2]="GROUP_DM",n))(yg||{});var wg=(h=>(h[h.SUB_COMMAND=1]="SUB_COMMAND",h[h.SUB_COMMAND_GROUP=2]="SUB_COMMAND_GROUP",h[h.STRING=3]="STRING",h[h.INTEGER=4]="INTEGER",h[h.BOOLEAN=5]="BOOLEAN",h[h.USER=6]="USER",h[h.CHANNEL=7]="CHANNEL",h[h.ROLE=8]="ROLE",h[h.MENTIONABLE=9]="MENTIONABLE",h[h.NUMBER=10]="NUMBER",h[h.ATTACHMENT=11]="ATTACHMENT",h))(wg||{}),bg=(l=>(l[l.Text=0]="Text",l[l.Voice=2]="Voice",l[l.Category=4]="Category",l[l.Announcement=5]="Announcement",l[l.ThreadPublic=10]="ThreadPublic",l[l.ThreadPublicAnnouncement=11]="ThreadPublicAnnouncement",l[l.ThreadPrivate=12]="ThreadPrivate",l[l.Forum=15]="Forum",l[l.Media=16]="Media",l))(bg||{});var Id=require("discord.js"),Nr=class{static permissionsToBitfield(t){if(!t||t.length===0)return;if(!Array.isArray(t))throw new Error("Invalid default_permission_string : not an array");let A=0n;for(let n of t){let r=Id.PermissionFlagsBits[n];if(!r){console.warn(`Unknow permission in default_member_permissions: ${n}`);continue}A|=r}return A.toString()}static bitfieldToPermissions(t){if(!t)return[];let A=BigInt(t),n=[];for(let[r,i]of Object.entries(Id.PermissionFlagsBits))(A&i)===i&&n.push(r);return n}};var Lc=class{constructor(t,A){this.clientId=t,this.token=A,this.rest=new mg({version:"10"}).setToken(A)}async getBotName(){try{return(await this.rest.get(cA.currentApplication())).name}catch(t){return console.error("Cannot fetch bot name:",t),"Unknown Bot"}}async printInteraction(t){console.table(t.map(A=>({Nom:A.name,Type:A.type===1?"Slash":A.type===2?"User Context Menu":"Message Context Menu",Description:"description"in A?A.description:"N/A",Permissions:Nr.bitfieldToPermissions(A.default_member_permissions).join(", "),ID:A.id?A.command_scope==="global"?A.id:Object.entries(A.id).filter(([n,r])=>r!==null).map(([n,r])=>`${r}`).join(", ")||"N/A":"N/A",GuildID:A.id?A.command_scope==="global"?"Global":Object.keys(A.id).join(", "):"N/A"})))}async listFromFile(t,A){let n=A?`(guild ${A})`:"(global)";console.log(`Listing Local Handlers (${this.folderPath}) ${n}`);try{let r=await In.listJsonFiles(Zt.createPathFolder(this.folderPath));if(!r||r.length===0)return console.log("No files found"),[];let i=[];for(let[o,s]of r.entries()){if(s.includes("example"))continue;let a=await this.readInteraction(Zt.createPathFile(this.folderPath,s));if(!a)continue;if(t===1)if(a.id){if(a.command_scope!=="global"){if(A&&a.id[A])a.id={[A]:a.id[A]};else if(a.id&&a.command_scope==="guild"){let I={};for(let h of Object.keys(a.id||{}))a.id[h]&&(I[h]=a.id[h]);a.id=Object.keys(I).length>0?I:{}}}}else continue;if(t===2&&a.id){if(a.command_scope==="global")continue;if(A&&a.id[A])continue;if(a.id&&a.command_scope==="guild"){let I={};for(let h of Object.keys(a.id||{}))a.id[h]||(I[h]=null);a.id=I}}if(A&&a.id&&!Object.keys(a.id)?.includes(A))continue;let l={...a,filename:s};i.push(l)}return console.log(`${i.length} local ${this.folderPath}(s) found
90
+ `)),w){let q=!u(this,lA);q&&(v(this,lA,new sd),u(this,lA).wait(),u(this,bi).shift()),u(this,Ur)?.resolve(),v(this,Ur,null),await vc(w);let K,le=new Promise(Ue=>K=Ue);v(this,Ur,{promise:le,resolve:K}),q&&(await u(this,bi).wait(),v(this,ca,!0))}return this.runRequest(t,A,n,r,i)}else{let M=await hd(this.manager,s,o,A,r,i);return M===null?this.runRequest(t,A,n,r,++i):M}}},bi=new WeakMap,lA=new WeakMap,Ur=new WeakMap,ca=new WeakMap,Oe(la,"SequentialHandler"),la),ua,po,mg=(po=class extends qM{constructor(A={}){super();V(this,"agent",null);V(this,"cdn");V(this,"globalRemaining");V(this,"globalDelay",null);V(this,"globalReset",-1);V(this,"hashes",new Rc);V(this,"handlers",new Rc);P(this,ua,null);V(this,"hashTimer");V(this,"handlerTimer");V(this,"options");this.cdn=new Pq(A.cdn??Sc.cdn,A.mediaProxy??Sc.mediaProxy),this.options={...Sc,...A},this.globalRemaining=Math.max(1,this.options.globalRequestsPerSecond),this.agent=A.agent??null,this.setupSweepers()}setupSweepers(){let A=Oe(n=>{if(n>144e5)throw new Error("Cannot set an interval greater than 4 hours")},"validateMaxInterval");this.options.hashSweepInterval!==0&&this.options.hashSweepInterval!==Number.POSITIVE_INFINITY&&(A(this.options.hashSweepInterval),this.hashTimer=setInterval(()=>{let n=new Rc,r=Date.now();this.hashes.sweep((i,o)=>{if(i.lastAccess===-1)return!1;let s=Math.floor(r-i.lastAccess)>this.options.hashLifetime;return s&&(n.set(o,i),this.emit("restDebug",`Hash ${i.value} for ${o} swept due to lifetime being exceeded`)),s}),this.emit("hashSweep",n)},this.options.hashSweepInterval),this.hashTimer.unref?.()),this.options.handlerSweepInterval!==0&&this.options.handlerSweepInterval!==Number.POSITIVE_INFINITY&&(A(this.options.handlerSweepInterval),this.handlerTimer=setInterval(()=>{let n=new Rc;this.handlers.sweep((r,i)=>{let{inactive:o}=r;return o&&(n.set(i,r),this.emit("restDebug",`Handler ${r.id} for ${i} swept due to being inactive`)),o}),this.emit("handlerSweep",n)},this.options.handlerSweepInterval),this.handlerTimer.unref?.())}async get(A,n={}){return this.request({...n,fullRoute:A,method:"GET"})}async delete(A,n={}){return this.request({...n,fullRoute:A,method:"DELETE"})}async post(A,n={}){return this.request({...n,fullRoute:A,method:"POST"})}async put(A,n={}){return this.request({...n,fullRoute:A,method:"PUT"})}async patch(A,n={}){return this.request({...n,fullRoute:A,method:"PATCH"})}async request(A){let n=await this.queueRequest(A);return ld(n)}setAgent(A){return this.agent=A,this}setToken(A){return v(this,ua,A),this}async queueRequest(A){let n=po.generateRouteData(A.fullRoute,A.method),r=this.hashes.get(`${A.method}:${n.bucketRoute}`)??{value:`Global(${A.method}:${n.bucketRoute})`,lastAccess:-1},i=this.handlers.get(`${r.value}:${n.majorParameter}`)??this.createHandler(r.value,n.majorParameter),{url:o,fetchOptions:s}=await this.resolveRequest(A);return i.queueRequest(n,o,s,{body:A.body,files:A.files,auth:A.auth!==!1,signal:A.signal})}createHandler(A,n){let r=n===sF?new qq(this,A,n):new Wq(this,A,n);return this.handlers.set(r.id,r),r}async resolveRequest(A){let{options:n}=this,r="";if(A.query){let h=A.query.toString();h!==""&&(r=`?${h}`)}let i={...this.options.headers,"User-Agent":`${Nq} ${n.userAgentAppendix}`.trim()};if(A.auth!==!1){if(!u(this,ua))throw new Error("Expected token to be set for this request, but none was present");i.Authorization=`${A.authPrefix??this.options.authPrefix} ${u(this,ua)}`}A.reason?.length&&(i["X-Audit-Log-Reason"]=encodeURIComponent(A.reason));let o=`${n.api}${A.versioned===!1?"":`/v${n.version}`}${A.fullRoute}${r}`,s,a={};if(A.files?.length){let h=new FormData;for(let[d,C]of A.files.entries()){let y=C.key??`files[${d}]`;if(mF(C.data)){let D=C.contentType;if(!D){let[g]=(0,bF.filetypeinfo)(C.data);g&&(D=Tq[g.mime]??g.mime??"application/octet-stream")}h.append(y,new Blob([C.data],{type:D}),C.name)}else h.append(y,new Blob([`${C.data}`],{type:C.contentType}),C.name)}if(A.body!=null)if(A.appendToFormData)for(let[d,C]of Object.entries(A.body))h.append(d,C);else h.append("payload_json",JSON.stringify(A.body));s=h}else A.body!=null&&(A.passThroughBody?s=A.body:(s=JSON.stringify(A.body),a={"Content-Type":"application/json"}));let l=A.method.toUpperCase(),I={body:["GET","HEAD"].includes(l)?null:s,headers:{...A.headers,...a,...i},method:l,dispatcher:A.dispatcher??this.agent??void 0};return{url:o,fetchOptions:I}}clearHashSweeper(){clearInterval(this.hashTimer)}clearHandlerSweeper(){clearInterval(this.handlerTimer)}static generateRouteData(A,n){if(A.startsWith("/interactions/")&&A.endsWith("/callback"))return{majorParameter:sF,bucketRoute:"/interactions/:id/:token/callback",original:A};let r=/(?:^\/webhooks\/(\d{17,19}\/[^/?]+))|(?:^\/(?:channels|guilds|webhooks)\/(\d{17,19}))/.exec(A),i=r?.[2]??r?.[1]??"global",o=A.replaceAll(/\d{17,19}/g,":id").replace(/\/reactions\/(.*)/,"/reactions/:reaction").replace(/\/webhooks\/:id\/[^/?]+/,"/webhooks/:id/:token"),s="";if(n==="DELETE"&&o==="/channels/:id/messages/:id"){let a=/\d{17,19}$/.exec(A)[0],l=LM.timestampFrom(a);Date.now()-l>1e3*60*60*24*14&&(s+="/Delete Old Message")}return{majorParameter:i,bucketRoute:o+s,original:A}}},ua=new WeakMap,Oe(po,"REST"),po);globalThis.FormData??=uF.FormData;globalThis.Blob??=lF.Blob;hF(gh()?fetch:dF);var DF=ur(require("fs/promises"));var pg=(A=>(A[A.GUILD_INSTALL=0]="GUILD_INSTALL",A[A.USER_INSTALL=1]="USER_INSTALL",A))(pg||{}),yg=(n=>(n[n.SERVER_CHANNEL=0]="SERVER_CHANNEL",n[n.BOT_DM=1]="BOT_DM",n[n.GROUP_DM=2]="GROUP_DM",n))(yg||{});var wg=(h=>(h[h.SUB_COMMAND=1]="SUB_COMMAND",h[h.SUB_COMMAND_GROUP=2]="SUB_COMMAND_GROUP",h[h.STRING=3]="STRING",h[h.INTEGER=4]="INTEGER",h[h.BOOLEAN=5]="BOOLEAN",h[h.USER=6]="USER",h[h.CHANNEL=7]="CHANNEL",h[h.ROLE=8]="ROLE",h[h.MENTIONABLE=9]="MENTIONABLE",h[h.NUMBER=10]="NUMBER",h[h.ATTACHMENT=11]="ATTACHMENT",h))(wg||{}),bg=(l=>(l[l.Text=0]="Text",l[l.Voice=2]="Voice",l[l.Category=4]="Category",l[l.Announcement=5]="Announcement",l[l.ThreadPublic=10]="ThreadPublic",l[l.ThreadPublicAnnouncement=11]="ThreadPublicAnnouncement",l[l.ThreadPrivate=12]="ThreadPrivate",l[l.Forum=15]="Forum",l[l.Media=16]="Media",l))(bg||{});var Id=require("discord.js"),Nr=class{static permissionsToBitfield(t){if(!t||t.length===0)return;if(!Array.isArray(t))throw new Error("Invalid default_permission_string : not an array");let A=0n;for(let n of t){let r=Id.PermissionFlagsBits[n];if(!r){console.warn(`Unknow permission in default_member_permissions: ${n}`);continue}A|=r}return A.toString()}static bitfieldToPermissions(t){if(!t)return[];let A=BigInt(t),n=[];for(let[r,i]of Object.entries(Id.PermissionFlagsBits))(A&i)===i&&n.push(r);return n}};var Lc=class{constructor(t,A){this.clientId=t,this.token=A,this.rest=new mg({version:"10"}).setToken(A)}async getBotName(){try{return(await this.rest.get(cA.currentApplication())).name}catch(t){return console.error("Cannot fetch bot name:",t),"Unknown Bot"}}async printInteraction(t){console.table(t.map(A=>({Nom:A.name,Type:A.type===1?"Slash":A.type===2?"User Context Menu":"Message Context Menu",Description:"description"in A?A.description:"N/A",Permissions:Nr.bitfieldToPermissions(A.default_member_permissions).join(", "),ID:A.id?A.command_scope==="global"?A.id:Object.entries(A.id).filter(([n,r])=>r!==null).map(([n,r])=>`${r}`).join(", ")||"N/A":"N/A",GuildID:A.id?A.command_scope==="global"?"Global":Object.keys(A.id).join(", "):"N/A"})))}async listFromFile(t,A){let n=A?`(guild ${A})`:"(global)";console.log(`Listing Local Handlers (${this.folderPath}) ${n}`);try{let r=await In.listJsonFiles(Zt.createPathFolder(this.folderPath));if(!r||r.length===0)return console.log("No files found"),[];let i=[];for(let[o,s]of r.entries()){if(s.includes("example"))continue;let a=await this.readInteraction(Zt.createPathFile(this.folderPath,s));if(!a)continue;if(t===1)if(a.id){if(a.command_scope!=="global"){if(A&&a.id[A])a.id={[A]:a.id[A]};else if(a.id&&a.command_scope==="guild"){let I={};for(let h of Object.keys(a.id||{}))a.id[h]&&(I[h]=a.id[h]);a.id=Object.keys(I).length>0?I:{}}}}else continue;if(t===2&&a.id){if(a.command_scope==="global")continue;if(A&&a.id[A])continue;if(a.id&&a.command_scope==="guild"){if(Object.values(a.id||{}).every(h=>h!=null))continue;a.id=Object.fromEntries(Object.entries(a.id||{}).filter(([h,d])=>d==null))}}if(A&&a.id&&!Object.keys(a.id)?.includes(A))continue;let l={...a,filename:s};i.push(l)}return console.log(`${i.length} local ${this.folderPath}(s) found
91
91
  `),await this.printInteraction(i),i}catch(r){return gt.error(`${r.message}`),[]}}async fetchCommands(t,A,n,r=!0){let i=A==="global"?"global":`guild ${n}`;console.log(`Listing Deployed Handlers ${this.folderPath} on Discord (${i})`);try{let a=(await this.rest.get(t)).filter(l=>this.commandType.includes(l.type)).map((l,I)=>({name:l.name,description:"description"in l?l.description:"N/A",default_member_permissions:l.default_member_permissions,default_member_permissions_string:Nr.bitfieldToPermissions(l.default_member_permissions),dm_permission:l.dm_permission,contexts:l.contexts,integration_types:l.integration_types,...l.guild_id?{command_scope:A,id:{[l.guild_id]:l.id},type:l.type}:{command_scope:A,id:l.id,type:l.type}}));return r&&(console.log(`${a.length} ${this.folderPath}(s) found
92
92
  `),await this.printInteraction(a)),a}catch(o){let s=A==="global"?`Error: ${o.message}`:`Guild error ${A}: ${o.message}`;return gt.error(s),[]}}async list(t=!0){return this.fetchCommands(cA.applicationCommands(this.clientId),"global",void 0,t)}async listGuild(t,A=!0){return this.fetchCommands(cA.applicationGuildCommands(this.clientId,t),"guild",t,A)}async listAllGuilds(t){if(console.log(`\u{1F4E1} Getting all guilds...
93
93
  `),console.log(`\u{1F4CB} ${t.length} guild(s) found
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spatulox/discord-interaction-manager",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "author": "Spatulox",
5
5
  "description": "discord-interaction-manager is a lightweight CLI tool to manage Discord bot interactions (slash commands, context menus) in under 30 seconds. Deploy, update, delete, and generate interaction files with an interactive terminal interface.",
6
6
  "bin": {