UNPKG

@snazzah/emoji-sync

Version:

Sync Discord emojis with your app

9 lines (8 loc) 11 kB
var C=n=>{throw TypeError(n)};var M=(n,e,t)=>e.has(n)||C("Cannot "+t);var a=(n,e,t)=>(M(n,e,"read from private field"),t?t.call(n):e.get(n)),m=(n,e,t)=>e.has(n)?C("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),b=(n,e,t,i)=>(M(n,e,"write to private field"),i?i.call(n,t):e.set(n,t),t),c=(n,e,t)=>(M(n,e,"access private method"),t);import{extname as H,parse as lt}from"node:path";var p,$,_,y=class{constructor(){m(this,$);m(this,p,[])}get locked(){return a(this,p).length>0}acquire(e){let t=this.locked,i=new Promise(r=>{if(e)return a(this,p).unshift(r);a(this,p).push(r)});return t||c(this,$,_).call(this),i}static wait(e){return new Promise(t=>{setTimeout(t,e)})}};p=new WeakMap,$=new WeakSet,_=function(){let e=a(this,p).shift();if(!e)return;let t=!1;e(()=>{t||(t=!0,c(this,$,_).call(this))})};var D=class n extends Error{constructor(e,t,i){super(`${t.status} ${t.statusText||"Unknown error"} on ${e.method} ${e.path}`),this.req=e,this.res=t,this.code=t.status,this.stack="",i?this.stack=this.name+": "+this.message+` `+i:Error.captureStackTrace(this,n)}get headers(){return this.res.headers}get name(){return this.constructor.name}};var O=class n extends Error{constructor(e,t,i,r){super(),this.req=e,this.res=t,this.response=i,this.code=t.status;let s=i?.message||"Unknown error";if(i?.errors)s+=` `+this.flattenErrors(i.errors).join(` `);else if(i){let l=this.flattenErrors(i);l.length>0&&(s+=` `+l.join(` `))}this.message=s,r?this.stack=this.name+": "+this.message+` `+r:(this.stack="",Error.captureStackTrace(this,n))}get name(){return`${this.constructor.name} [${this.code}]`}flattenErrors(e,t=""){let i=[];for(let r in e)if(!(!(r in e)||r==="message"||r==="code")){if(r==="_errors"){i=i.concat(e._errors.map(s=>`${t?`${t}: `:""}${s.message}`));continue}e[r]._errors?i=i.concat(e[r]._errors.map(s=>`${t+r}: ${s.message}`)):Array.isArray(e[r])?i=i.concat(e[r].map(s=>`${t+r}: ${s}`)):typeof e[r]=="object"&&(i=i.concat(this.flattenErrors(e[r],t+r+".")))}return i}};async function K(n){return n.headers.get("content-type")==="application/json"?await n.json():null}function rt(n){switch(n){case"user":return"User";case"global":return"Global";case"shared":return"Shared";default:return"Unexpected"}}var o,w,x,q,f,j,N,W,P=class{constructor(e,t,i){m(this,f);this.limit=1;this.remaining=1;this.reset=0;m(this,o);m(this,w);m(this,x);m(this,q,new y);b(this,o,e),b(this,w,t),b(this,x,i)}get id(){return`${a(this,w)}:${a(this,x)}`}get inactive(){return!this.limited&&!a(this,o).limited&&!a(this,q).locked}get limited(){return this.remaining<=0&&Date.now()<this.reset}async add(e,t){let i=await a(this,q).acquire(t);try{return await c(this,f,j).call(this,e)}finally{i()}}};o=new WeakMap,w=new WeakMap,x=new WeakMap,q=new WeakMap,f=new WeakSet,j=async function(e,t=0){let i={};for(Error.captureStackTrace(i),i.stack.startsWith(`Error `)&&(i.stack=i.stack.substring(6));this.limited||a(this,o).limited;){if(a(this,o).limited){let u=a(this,o).globalReset-Date.now();a(this,o).globalTimeout||c(this,f,W).call(this,u),await a(this,o).globalTimeout;continue}let h=this.reset-Date.now();await y.wait(h)}a(this,o).globalReset<Date.now()&&(a(this,o).globalReset=Date.now()+1e3,a(this,o).globalBlock=!1);let r,s=Date.now();try{r=await e.send(),s=Date.now()-s}catch(h){if(t>=a(this,o).options.retryLimit)throw h.name==="AbortError"?new Error(`Request timed out (>${a(this,o).options.requestTimeout}ms) on ${e.method} ${e.path}`):h;return c(this,f,j).call(this,e,++t)}a(this,o).manager?.listenerCount("rawREST")&&a(this,o).manager.emit("rawREST",{auth:e.options.auth??!1,body:e.options.body,files:e.options.files,latency:s,url:e.url,method:e.method,request:e,response:r});let l=c(this,f,N).call(this,e,r,s);if(a(this,o).manager?.emit("debug",`${e.method} ${e.route} (${this.id}) ${r.status}: ${s}ms | ${this.remaining}/${this.limit} left | Reset ${this.reset} (${this.reset-Date.now()}ms left)`),r.status>=200&&r.status<300)return K(r);if(r.status>=400&&r.status<500){let h=await K(r);if(r.status===429){let u=h.retry_after?h.retry_after*1e3:l;return a(this,o).manager?.emit("debug",`${rt(r.headers.get("x-ratelimit-scope"))} 429. Retrying in ${u}ms (${this.id})`),u&&await y.wait(u),c(this,f,j).call(this,e,t)}throw new O(e,r,h,i.stack)}if(r.status>=500&&r.status<600){if(t>=a(this,o).options.retryLimit)throw new D(e,r,i.stack);return c(this,f,j).call(this,e,++t)}return null},N=function(e,t,i){let r=t.headers.get("x-ratelimit-bucket"),s=t.headers.get("x-ratelimit-limit"),l=t.headers.get("x-ratelimit-remaining"),h=t.headers.get("x-ratelimit-reset-after")||t.headers.get("retry-after"),u=Date.now();if(r)if(a(this,w)!==r)a(this,o).hashes.set(e.id,{value:r,lastAccess:u}),a(this,o).manager?.emit("debug",`Updated bucket hash (${a(this,w)}) to ${r}`);else{let F=a(this,o).hashes.get(e.id);F&&(F.lastAccess=u)}s&&(this.limit=+s),this.remaining=l?+l:1;let d=0;if(h&&(d=+h*1e3+a(this,o).options.ratelimiterOffset),d>0)return t.headers.get("x-ratelimit-global")?(a(this,o).globalReset=u+d,a(this,o).globalBlock=!0):this.reset=u+d,d;let g=t.headers.has("date")?Date.parse(t.headers.get("date")):u,T=u-g+i;this.reset=Math.max(+(t.headers.get("x-ratelimit-reset")||0)*1e3+T,u)+a(this,o).options.ratelimiterOffset},W=function(e){a(this,o).globalTimeout=y.wait(e).then(()=>{a(this,o).globalTimeout=void 0})};import it from"node:path";import{readdir as st,lstat as nt}from"node:fs/promises";async function I(n,e=!1){let t=await st(n),i=[];for(let r of t){let s=it.join(n,r),l=await nt(s);l.isDirectory()&&e?i.push(...await I(s)):l.isFile()&&i.push(s)}return i}function G(n){return at(n)+14200704e5}function at(n){return Math.floor(Math.floor(Number(BigInt(n)/4194304n)))}function z(n){return`<${n.animated?"a":""}:${n.name}:${n.id}>`}function S(n,e){let t=("Buffer"in globalThis&&n instanceof Buffer?n:Buffer.from(n)).toString("base64");return`data:${e};base64,${t}`}function U(n){switch((n.startsWith(".")?n.slice(1):n).toLowerCase()){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"gif":return"image/gif";case"webp":return"image/webp";default:return null}}var V="0.1.2",jt=10,J="https://discord.com/api/v10",xt="https://cdn.discordapp.com";var ot=`DiscordBot (https://github.com/Snazzah/emoji-sync, ${V})`,R,X,Z,A=class{constructor(e,t,i,r){m(this,R);this.headers={"User-Agent":ot};if(this.handler=e,this.method=t,this.path=i,this.options=r,this.url=new URL(e.options.baseURL+i),typeof r.query=="object")for(let s in r.query)r.query[s]!==void 0&&this.url.searchParams.append(s,r.query[s]);if(typeof r.headers=="object")for(let s in r.headers)this.headers[s]=r.headers[s];r.reason&&(this.headers["X-Audit-Log-Reason"]=encodeURIComponent(r.reason)),this.setBody(r.body,r.files),this.majorParameter=c(this,R,X).call(this),this.route=c(this,R,Z).call(this)}get id(){return`${this.method}:${this.route}`}async send(){let e=new AbortController;return setTimeout(()=>e.abort(),this.handler.options.requestTimeout),fetch(this.url,{body:this.data,dispatcher:this.handler.options.dispatcher,headers:this.headers,method:this.method,signal:e.signal})}setBody(e,t){if(t?.length){let i=new FormData;for(let r=0;r<t.length;r++)if(t[r]){let s=t[r].file;"Buffer"in globalThis&&s instanceof Buffer&&(s=new Blob([s])),i.append(`files[${r}]`,s,t[r].name)}e&&i.append("payload_json",JSON.stringify(e)),this.data=i}else e&&(this.data=JSON.stringify(e,(i,r)=>typeof r=="bigint"?r.toString():r),this.headers["Content-Type"]="application/json");return this}};R=new WeakSet,X=function(){return/^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(this.path)?.[1]??"global"},Z=function(){let e=this.path.replace(/\/reactions\/.*/g,"/reactions/:id").replace(/\d{16,19}/g,":id").replace(/[a-zA-Z0-9]{150,300}/g,":token"),t="";if(this.method==="DELETE"&&e==="/channels/:id/messages/:id"){let i=this.path.slice(this.path.lastIndexOf("/")+1),r=G(i),s=Date.now()-r;s>=12096e5?t+=";old":s<=1e4&&(t+=";new")}return e+t};var E,B,Q,v=class{constructor(e,t={}){m(this,B);this.buckets=new Map;this.globalBlock=!1;this.globalReset=0;this.hashes=new Map;m(this,E);this.manager=e,this.options={baseURL:t.baseURL??J,ratelimiterOffset:t.ratelimiterOffset??0,requestTimeout:t.requestTimeout??15e3,retryLimit:t.retryLimit??3},t.token&&b(this,E,t.token)}get limited(){return this.globalBlock&&Date.now()<this.globalReset}async request(e,t,i={}){let r=new A(this,e,t,i);if(i.auth){if(!a(this,E))throw new Error("Missing required token");r.headers.Authorization=a(this,E)}let s=this.hashes.get(r.id)?.value??r.id;return c(this,B,Q).call(this,s,r.majorParameter).add(r)}};E=new WeakMap,B=new WeakSet,Q=function(e,t){let i=this.buckets.get(`${e}:${t}`);if(i)return i;let r=new P(this,e,t);return this.buckets.set(r.id,r),r};import{fileURLToPath as ht}from"node:url";import{readFile as Y}from"node:fs/promises";import mt from"eventemitter3";var k,L,et,tt=class extends mt{constructor(t){super();m(this,L);this.emojis=new Map;m(this,k,new Map);let i=t.token&&!t.token.startsWith("Bot ")&&!t.token.startsWith("Bearer ")?"Bot "+t.token:t.token;this.requestHandler=new v(this,{...t.rest??{},token:i})}get(t){return this.emojis.get(t)??null}getPartial(t){let i=this.emojis.get(t);return i?{id:i.id,name:i.name,animated:i.animated}:null}getMarkdown(t){let i=this.get(t);return i?z(i):null}load(t){for(let i in t)a(this,k).set(i,t[i])}async loadFromFolder(t,i){let r=await I(t,i?.recursive??!1);for(let s of r){let l=lt(s).name;a(this,k).set(l,s)}}async sync(){let i=`/applications/${await c(this,L,et).call(this)}/emojis`,r=await this.requestHandler.request("GET",i,{auth:!0});for(let s of r.items)this.emojis.set(s.name,s);for(let[s,l]of a(this,k)){if(this.emojis.has(s))continue;let h;if(l.startsWith("data:"))h=l;else if(l.startsWith("file:")){let d=ht(l),g=await Y(d),T=U(H(d));if(!T)throw new Error(`[${s}] Unknown file type for file: ${d}`);h=S(g,T)}else if(l.startsWith("https://")||l.startsWith("http://")){let d=await fetch(l);if(!d.ok)throw new Error(`[${s}] URL returned ${d.status}: ${l}`);let g=d.headers.get("content-type")||U(H(l));if(!g)throw new Error(`[${s}] URL response does not have a Content-Type and URL does not have a known extension: ${l}`);h=S(await d.arrayBuffer(),g)}else{let d=await Y(l),g=U(H(l));if(!g)throw new Error(`[${s}] Unknown file type for file: ${l}`);h=S(d,g)}this.emit("debug",`Uploading emoji ${s} from path "${l}"...`);let u=await this.requestHandler.request("POST",i,{auth:!0,body:{name:s,image:h}});this.emojis.set(u.name,u)}}loadFromDiscord(t){for(let i of t)this.emojis.set(i.name,i)}};k=new WeakMap,L=new WeakSet,et=async function(){if(this.applicationId)return this.applicationId;let t=await this.requestHandler.request("GET","/applications/@me",{auth:!0});return this.applicationId=t.id,this.applicationId};export{J as API_BASE_URL,jt as API_VERSION,xt as CDN_URL,D as DiscordHTTPError,O as DiscordRESTError,tt as EmojiManager,V as VERSION,U as extensionToMimeType,G as getCreatedAt,at as getDiscordEpoch,I as getFiles,S as toDataUri,z as toMarkdown};