simply-xp 2.0.0-beta.3 → 2.0.0-beta.4

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.
package/README.md CHANGED
@@ -1,12 +1,13 @@
1
- <div class="Heading" style="text-align: center;">
1
+ <p align="center">
2
2
  <img src="https://i.ibb.co/cCKJ9FS/simplyxp.png" width="320" height="125" alt="XP Logo">
3
+ </p>
3
4
 
4
- <h2>We have levelling! - You handle the rest.</h2>
5
- <h3>Made by Abadima</h3>
6
- </div>
5
+ <h2 align="center">We have levelling! - You handle the rest.</h2>
6
+ <h3 align="center">Made by Abadima</h3>
7
7
 
8
8
  <br>
9
- <div class="badges" style="text-align: center;">
9
+
10
+ <div align="center">
10
11
 
11
12
  [![Downloads](https://img.shields.io/npm/dt/simply-xp?style=for-the-badge)](https://www.npmjs.com/package/simply-xp)
12
13
  [![Version](https://img.shields.io/npm/v/simply-xp.svg?style=for-the-badge)](https://www.npmjs.com/package/simply-xp)
package/lib/src/add.js CHANGED
@@ -20,4 +20,4 @@ async function addLevel(e,a,t,l){if(!e)throw new xplogs_1.XpFatal({function:"add
20
20
  * @link `Documentation:` https://simplyxp.js.org/docs/next/functions/addxp
21
21
  * @returns {Promise<XPResult>} - Object of user data on success.
22
22
  * @throws {XpFatal} - If parameters are not provided correctly.
23
- */async function addXP(e,a,t,l){var s;if(!("number"==typeof t||"object"==typeof xp_1.xp&&t.min&&t.max))throw new xplogs_1.XpFatal({function:"addXP()",message:"XP is not a number or object, make sure you are using the correct syntax"});if("object"==typeof t&&(t=Math.floor(Math.random()*(t.max-t.min)+t.min)),!e)throw new xplogs_1.XpFatal({function:"addXP()",message:"User ID was not provided"});if(!a)throw new xplogs_1.XpFatal({function:"addXP()",message:"Guild ID was not provided"});let o;if(s=await Database_1.Database.findOne({collection:"simply-xps",data:{user:e,guild:a}}))o=await Database_1.Database.updateOne({collection:"simply-xps",data:{user:e,guild:a}},{collection:"simply-xps",data:{user:e,guild:a,name:l||s?.name||e,level:(0,xp_1.convertFrom)(s.xp+t,"xp"),xp:s.xp+t,xp_rate:xp_1.xp.xp_rate}}).catch(e=>{throw new xplogs_1.XpFatal({function:"addXP()",message:e.stack});});else{if(!xp_1.xp.auto_create||!l)throw new xplogs_1.XpFatal({function:"addXP()",message:"User does not exist"});o=await Database_1.Database.createOne({collection:"simply-xps",data:{guild:a,user:e,name:l,level:(0,xp_1.convertFrom)(t,"xp"),xp:t,xp_rate:xp_1.xp.xp_rate}}).catch(e=>{throw new xplogs_1.XpFatal({function:"addXP()",message:e.stack});});}return l=xplogs_1.XpEvents.eventCallback,(t=s?.level&&o?.level?o.level!==s.level?o.level-s.level:0:0<o?.level?o.level:0)<0&&l?.levelDown&&"function"==typeof l.levelDown&&l.levelDown(o,await xp_1.LevelRoles.getUserRoles(e,a,{includeNext:!0})),0<t&&l?.levelUp&&"function"==typeof l.levelUp&&l.levelUp(o,await xp_1.LevelRoles.getUserRoles(e,a)),{...o,levelDifference:t};}Object.defineProperty(exports,"__esModule",{value:!0}),exports.addLevel=addLevel,exports.addXP=addXP;let Database_1=require("./classes/Database"),xplogs_1=require("./functions/xplogs"),xp_1=require("../xp");
23
+ */async function addXP(e,a,t,l){var s;if(!("number"==typeof t||"object"==typeof xp_1.xp&&t.min&&t.max))throw new xplogs_1.XpFatal({function:"addXP()",message:"XP is not a number or object, make sure you are using the correct syntax"});if("object"==typeof t&&(t=Math.floor(Math.random()*(t.max-t.min)+t.min)),!e)throw new xplogs_1.XpFatal({function:"addXP()",message:"User ID was not provided"});if(!a)throw new xplogs_1.XpFatal({function:"addXP()",message:"Guild ID was not provided"});let o;if(s=await Database_1.Database.findOne({collection:"simply-xps",data:{user:e,guild:a}}))o=await Database_1.Database.updateOne({collection:"simply-xps",data:{user:e,guild:a}},{collection:"simply-xps",data:{user:e,guild:a,name:l||s?.name||e,level:(0,xp_1.convertFrom)(s.xp+t,"xp"),xp:s.xp+t,xp_rate:xp_1.xp.xp_rate}}).catch(e=>{throw new xplogs_1.XpFatal({function:"addXP()",message:e.stack});});else{if(!xp_1.xp.auto_create||!l)throw new xplogs_1.XpFatal({function:"addXP()",message:"User does not exist"});o=await Database_1.Database.createOne({collection:"simply-xps",data:{guild:a,user:e,name:l,level:(0,xp_1.convertFrom)(t,"xp"),xp:t,xp_rate:xp_1.xp.xp_rate}}).catch(e=>{throw new xplogs_1.XpFatal({function:"addXP()",message:e.stack});});}return l=xplogs_1.XpEvents.eventCallback,(t=s?.level&&o?.level?o.level!==s.level?o.level-s.level:0:0<o?.level?o.level:0)<0&&l?.levelDown&&"function"==typeof l.levelDown&&await l.levelDown(o,await xp_1.LevelRoles.getUserRoles(e,a,{includeNext:!0})),0<t&&l?.levelUp&&"function"==typeof l.levelUp&&await l.levelUp(o,await xp_1.LevelRoles.getUserRoles(e,a)),{...o,levelDifference:t};}Object.defineProperty(exports,"__esModule",{value:!0}),exports.addLevel=addLevel,exports.addXP=addXP;let Database_1=require("./classes/Database"),xplogs_1=require("./functions/xplogs"),xp_1=require("../xp");
@@ -139,6 +139,7 @@ export declare function rankCard(guild: {
139
139
  name: string;
140
140
  }>;
141
141
  /**
142
+ * Draw a rounded rectangle with optional fill and stroke, can be used for clipping as well
142
143
  * @private
143
144
  */
144
145
  export declare function RoundedBox(ctx: SKRSContext2D, x: number, y: number, width: number, height: number, radius: number, options?: {
package/lib/src/cards.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * @returns {Promise<{attachment: Buffer, description: string, name: string}>}
11
11
  * @throws {XpFatal} - If parameters are not provided correctly or if the user is not found in the database
12
12
  */
13
- async function compareCard(e,a,l,t={},o={}){var r,n,i,s,f,d;
13
+ async function compareCard(e,l,a,t={},o={}){var r,n,i,s,f,d,c,p,g,x,h;
14
14
  /**
15
15
  * Generate a simple leaderboard card
16
16
  * @async
@@ -21,7 +21,7 @@ async function compareCard(e,a,l,t={},o={}){var r,n,i,s,f,d;
21
21
  * @link `Documentation` https://simplyxp.js.org/docs/next/functions/leaderboard
22
22
  * @returns {Promise<{attachment: Buffer, description: string, name: string}>}
23
23
  * @throws {XpFatal} - If parameters are not provided correctly
24
- */if(!e?.id||!e?.name)throw new xplogs_1.XpFatal({function:"compareCard()",message:"Please provide a guild"});if(!(a?.id&&a?.username&&l?.id&&l?.username))throw new xplogs_1.XpFatal({function:"compareCard()",message:"Please provide two valid users!"});if(!a?.avatarURL.endsWith(".png")&&!a.avatarURL.endsWith(".jpg")&&!a.avatarURL.endsWith(".webp"))throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 1] Avatar image must be a png, jpg, or webp"});await(0,xp_1.registerFont)(t?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-ExtraBold.woff2"),"Baloo"),t?.fallbackFont&&await(0,xp_1.registerFont)(t.fallbackFont,"FallbackFont"),o?.level||(o.level="Level"),o?.versus||(o.versus="vs"),s=await(0,canvas_1.loadImage)(t?.background||"https://i.ibb.co/WnfXZjc/clouds.jpg").catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"Unable to load background image, is it valid and reachable?"});}),r=await(0,canvas_1.loadImage)(a.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 1] Unable to load user's AvatarURL, is it valid and reachable?"});}),n=await(0,canvas_1.loadImage)(l.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 2] Unable to load user's AvatarURL, is it valid and reachable?"});});let c=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:a.id}});if(!c){if(!xp_1.xp.auto_create||!l?.username)throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 1] User not found in database"});c=await(0,xp_1.create)(a.id,e.id,a.username);}let p=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:l.id}});if(!p){if(!xp_1.xp.auto_create||!l?.username)throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 2] User not found in database"});p=await(0,xp_1.create)(l.id,e.id,l.username);}return RoundedBox(i=(e=(0,canvas_1.createCanvas)(1080,400)).getContext("2d"),0,0,e.width,e.height,25),i.clip(),i.fillStyle=t?.light?"#ffffff":"#000000",i.fill(),i.globalAlpha=.6,i.drawImage(s,-5,0,1090,400),i.restore(),i.globalAlpha=1,s=t?.color||t?.light?"rgba(0,0,0,0.5)":"rgba(255,255,255,0.5)",t=t?.centerBarBg||t?.light?"rgba(0,0,0,0.4)":"rgba(255,255,255,0.4)",f=o.level+(" "+shortener(c.level,!0)),d=o.level+(" "+shortener(p.level,!0)),i.save(),i.textAlign="center",i.lineWidth=6,i.strokeStyle="#000000",i.font="40px Baloo, FallbackFont",i.strokeText(`${a.username} ${o.versus} `+l.username,540,60),i.fillStyle="#ffffff",i.fillText(`${a.username} ${o.versus} `+l.username,540,60),i.restore(),i.save(),i.beginPath(),i.arc(160,200,105,0,2*Math.PI,!0),i.closePath(),i.strokeStyle=s,i.lineWidth=5,i.stroke(),i.beginPath(),i.arc(160,200,100,0,2*Math.PI,!0),i.closePath(),i.clip(),i.fillStyle=s,i.fill(),i.drawImage(r,50,90,220,220),i.restore(),i.save(),i.beginPath(),i.arc(920,200,105,0,2*Math.PI,!0),i.closePath(),i.strokeStyle=s,i.lineWidth=5,i.stroke(),i.beginPath(),i.arc(920,200,100,0,2*Math.PI,!0),i.closePath(),i.clip(),i.fillStyle=s,i.fill(),i.drawImage(n,810,90,220,220),i.restore(),i.save(),i.textAlign="center",i.font="25px Baloo, FallbackFont",i.lineWidth=5,i.strokeStyle="#000000",i.fillStyle="#ffffff",i.strokeText(f,160,350),i.fillText(f,160,350),i.strokeText(d,920,350),i.fillText(d,920,350),i.restore(),i.save(),RoundedBox(i,265,330,540,25,10),i.clip(),i.fillStyle=t,i.fill(),i.textAlign="center",i.font="22px Baloo, FallbackFont",i.lineWidth=4,i.strokeStyle="rgba(0,0,0,0.7)",i.fillStyle="#ffffff",a=(c.xp>p.xp?"+":"-")+Math.abs(c.level-p.level),i.strokeText(a,540,350),i.fillText(a,540,350),i.restore(),xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:e.toBuffer("image/png"),description:"Simply-XP Comparison Card",name:"compareCard.png"};}async function leaderboardCard(a,e={},l,t={}){var o,r,n,i,s,f;
24
+ */if(!e?.id||!e?.name)throw new xplogs_1.XpFatal({function:"compareCard()",message:"Please provide a guild"});if(!(l?.id&&l?.username&&a?.id&&a?.username))throw new xplogs_1.XpFatal({function:"compareCard()",message:"Please provide two valid users!"});await(0,xp_1.registerFont)(t?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-Regular.woff2"),"Baloo"),t?.fallbackFont&&await(0,xp_1.registerFont)(t.fallbackFont,"FallbackFont"),o?.level||(o.level="Level"),o?.versus||(o.versus="vs"),h=await(0,canvas_1.loadImage)(t?.background||"https://i.ibb.co/WnfXZjc/clouds.jpg").catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"Unable to load background image, is it valid and reachable?"});}),p=await(0,canvas_1.loadImage)(l.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 1] Unable to load user's AvatarURL, is it valid and reachable?"});}),x=await(0,canvas_1.loadImage)(a.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 2] Unable to load user's AvatarURL, is it valid and reachable?"});});let b=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:l.id}});if(!b){if(!xp_1.xp.auto_create||!a?.username)throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 1] User not found in database"});b=await(0,xp_1.create)(l.id,e.id,l.username);}let u=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:a.id}});if(!u){if(!xp_1.xp.auto_create||!a?.username)throw new xplogs_1.XpFatal({function:"compareCard()",message:"[USER 2] User not found in database"});u=await(0,xp_1.create)(a.id,e.id,a.username);}return RoundedBox(n=(r=(0,canvas_1.createCanvas)(1080,400)).getContext("2d"),0,0,r.width,r.height,25),n.clip(),n.fillStyle=t?.light?"#ffffff":"#000000",n.fill(),n.globalAlpha=.6,n.drawImage(h,-5,0,1090,400),n.restore(),n.globalAlpha=1,h=t?.color||(t?.light?"rgba(0,0,0,0.5)":"rgba(255,255,255,0.5)"),i=t?.centerBar||(t?.light?"rgba(0,0,0,0.55)":"rgba(255,255,255,0.65)"),s=t?.centerBarBg||(t?.light?"rgba(0,0,0,0.2)":"rgba(255,255,255,0.2)"),f="rgba(0,0,0,0.5)",d="#ffffff",g=o.level+(" "+shortener(b.level,!0)),c=o.level+(" "+shortener(u.level,!0)),n.save(),n.textAlign="center",n.font="32px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle=f,n.strokeText(l.username,160,50,280),n.fillStyle=d,n.fillText(l.username,160,50,280),n.restore(),n.save(),n.beginPath(),n.arc(160,195,100,0,2*Math.PI),n.closePath(),n.clip(),n.fillStyle=h,n.fill(),n.drawImage(p,50,85,220,220),n.restore(),n.save(),n.beginPath(),n.arc(160,195,105,0,2*Math.PI),n.closePath(),n.strokeStyle=h,n.lineWidth=5,n.stroke(),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle=f,n.strokeText(g,160,342),n.fillStyle=d,n.fillText(g,160,342),n.restore(),n.save(),n.textAlign="center",n.font="18px Baloo, FallbackFont",n.fillStyle=t?.light?"rgba(0,0,0,0.55)":"rgba(255,255,255,0.55)",n.fillText(shortener(b.xp)+" XP",160,366),n.restore(),n.save(),n.textAlign="center",n.font="32px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle=f,n.strokeText(a.username,920,50,280),n.fillStyle=d,n.fillText(a.username,920,50,280),n.restore(),n.save(),n.beginPath(),n.arc(920,195,100,0,2*Math.PI),n.closePath(),n.clip(),n.fillStyle=h,n.fill(),n.drawImage(x,810,85,220,220),n.restore(),n.save(),n.beginPath(),n.arc(920,195,105,0,2*Math.PI),n.closePath(),n.strokeStyle=h,n.lineWidth=5,n.stroke(),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle=f,n.strokeText(c,920,342),n.fillStyle=d,n.fillText(c,920,342),n.restore(),n.save(),n.textAlign="center",n.font="18px Baloo, FallbackFont",n.fillStyle=t?.light?"rgba(0,0,0,0.55)":"rgba(255,255,255,0.55)",n.fillText(shortener(u.xp)+" XP",920,366),n.restore(),n.save(),n.textAlign="center",n.font="64px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle=f,n.strokeText(o.versus,540,208),n.fillStyle="#ffffff",n.fillText(o.versus,540,208),n.restore(),g=0<(p=b.xp+u.xp)?Math.round(b.xp/p*500):Math.round(250),n.save(),RoundedBox(n,290,350,500,22,8,{clip:!0,fill:{color:s}}),n.restore(),0<g&&(n.save(),RoundedBox(n,290,350,g,22,8,{clip:!0,fill:{color:i}}),n.restore()),h=0<(x=b.level-u.level)?"+"+x:x<0?""+x:"=",n.save(),n.textAlign="center",n.font="16px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=4,n.strokeStyle=f,n.strokeText(h,540,365),n.fillStyle=d,n.fillText(h,540,365),n.restore(),xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:r.toBuffer("image/webp"),description:(`${l.username} (Lvl ${b.level}) vs ${a.username} (Lvl ${u.level}) in `+e.name).slice(0,200),name:"compareCard.webp"};}async function leaderboardCard(l,e={},a,t={}){var o,r,n,i,s,f;
25
25
  /**
26
26
  * Generate a simple user rank card
27
27
  * @async
@@ -32,4 +32,4 @@ async function compareCard(e,a,l,t={},o={}){var r,n,i,s,f,d;
32
32
  * @link `Documentation` https://simplyxp.js.org/docs/next/functions/rankCard
33
33
  * @returns {Promise<{attachment: Buffer, description: string, name: string}>}
34
34
  * @throws {XpFatal} - If parameters are not provided correctly
35
- */if(!a||a.length<1)throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"There must be at least 1 user in the data array"});let d=void 0,c=void 0,p,g=(e?.artworkImage&&(d=await(0,canvas_1.loadImage)(e.artworkImage).catch(()=>{throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"Unable to load artwork image, is it valid?"});})),e?.backgroundImage&&(c=await(0,canvas_1.loadImage)(e.backgroundImage).catch(()=>{throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"Unable to load background image, is it valid?"});})),await(0,xp_1.registerFont)(e?.primaryFont||(0,path_1.join)(__dirname,"fonts","Baloo2-ExtraBold.woff2"),"Baloo"),e?.secondaryFont&&await(0,xp_1.registerFont)(e.secondaryFont,"SecondaryFont"),e?.fallbackFont&&await(0,xp_1.registerFont)(e.fallbackFont,"FallbackFont"),t.level||(t.level="LEVEL"),t.members||(t.members="Members"),a=a.slice(0,8),o=e?.secondaryFont?"SecondaryFont, FallbackFont":"Baloo, FallbackFont",p=e?.light?{artworkColors:e?.artworkColors||["#997fe1","#616bff"],backgroundColor:"#FFFFFF",borderColors:e?.borderColors||["#e0d440","#fffa6b"],evenColor:e?.rowColors?.[0]||"#f0f0f0",oddColor:e?.rowColors?.[1]||"#dcdcdc",primaryTextColor:"#000000",secondaryTextColor:"rgba(0,0,0,0.5)"}:{artworkColors:e?.artworkColors||["#6B46D4","#2e3cff"],backgroundColor:"#141414",borderColors:e?.borderColors||["#e0d440","#fffa6b"],evenColor:e?.rowColors?.[0]||"#1e1e1e",oddColor:e?.rowColors?.[1]||"#282828",primaryTextColor:"#ffffff",secondaryTextColor:"rgba(255,255,255,0.5)"},RoundedBox(n=(r=(0,canvas_1.createCanvas)(1350,1080)).getContext("2d"),0,0,r.width,r.height,20,{clip:!0}),(i=n.createLinearGradient(0,0,r.width,0)).addColorStop(.4,p.artworkColors[0]),i.addColorStop(1,p.artworkColors[1]),n.fillStyle=i,n.fillRect(0,0,r.width,220),d&&(n.fillStyle="#000000",n.fillRect(0,0,r.width,220),n.globalAlpha=.5,n.drawImage(d,0,0,r.width,220),n.globalAlpha=1),n.fillStyle=e.backgroundColor||p.backgroundColor,n.fillRect(0,220,r.width,1080),c&&(n.globalAlpha=.9,n.drawImage(c,0,220,r.width,1080),n.globalAlpha=1),l&&l?.imageURL&&l?.name&&(i=await(0,canvas_1.loadImage)(l.imageURL),n.save(),n.beginPath(),n.arc(150,110,90,0,2*Math.PI,!0),n.closePath(),n.clip(),n.drawImage(i,60,20,180,180),n.restore(),(i=n.createLinearGradient(0,0,0,220)).addColorStop(0,p.borderColors[0]),i.addColorStop(1,p.borderColors[1]),n.strokeStyle=i,n.lineWidth=8,n.beginPath(),n.arc(150,110,90,0,2*Math.PI,!0),n.stroke(),n.fillStyle=p.primaryTextColor,n.font="60px Baloo, FallbackFont",l?.memberCount?(n.fillText(l.name,270,110),n.fillStyle=p.secondaryTextColor,n.font="40px Baloo, FallbackFont",n.fillText(l.memberCount+" "+t.members,270,160)):n.fillText(l.name,270,130)),p.evenColor);s=e?.rowOpacity&&!isNaN(e?.rowOpacity)?e.rowOpacity:c?.5:1;for(let e=0;e<a.length;e++)f=300+90*e,n.globalAlpha=s,n.save(),1===a.length?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g}}):0===e?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g},roundCorners:{top:!0,bottom:!1}}):e===a.length-1?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g},roundCorners:{top:!1,bottom:!0}}):RoundedBox(n,30,f,1290,90,0,{fill:{color:g}}),n.restore(),n.globalAlpha=1,n.textAlign="left",n.font="30px "+o,n.fillStyle=p.secondaryTextColor,n.fillText(e+1+".",60,55+f),n.textAlign="left",n.font="40px "+o,n.fillStyle=p.primaryTextColor,n.fillText(a[e]?.name||a[e]?.user||"???",120,60+f),n.textAlign="right",n.font="30px "+o,n.fillStyle=p.primaryTextColor,n.fillText(shortener(a[e]?.level)||"???",1270,55+f),n.fillStyle=p.secondaryTextColor,n.fillText(t.level,1270-n.measureText(shortener(a[e]?.level)||"???").width-15,55+f),g=g===p.evenColor?p.oddColor:p.evenColor;return xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:r.toBuffer("image/png"),description:"Simply-XP Leaderboard Card",name:"leaderboard.png"};}async function rankCard(e,a,l={},t={}){var o,r,n,i,s,f,d,c,p,g,x,h;if(!e)throw new xplogs_1.XpFatal({function:"rankCard()",message:"No Guild Provided"});if(!a)throw new xplogs_1.XpFatal({function:"rankCard()",message:"No User Provided"});if(t?.level||(t.level="Level"),t?.next_level||(t.next_level="Next Level"),t?.xp||(t.xp="XP"),xplogs_1.XpLog.debug("rankCard()",`${l?.legacy?"LEGACY":"MODERN"} ENABLED`),!a||!a.id||!a.username)throw new xplogs_1.XpFatal({function:"rankCard()",message:"Invalid User Provided, user must contain id, username, and avatarURL."});await(0,xp_1.registerFont)(l?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-ExtraBold.woff2"),"Baloo"),l?.fallbackFont&&await(0,xp_1.registerFont)(l.fallbackFont,"FallbackFont"),i=await(0,canvas_1.loadImage)(l?.background||(l?.legacy?"https://i.ibb.co/dck2Tnt/rank-card.webp":"https://i.ibb.co/WnfXZjc/clouds.jpg")).catch(()=>{throw new xplogs_1.XpFatal({function:"rankCard()",message:"Unable to load background image, is it valid and reachable?"});}),o=await(0,canvas_1.loadImage)(a.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"rankCard()",message:"Unable to load user's AvatarURL, is it valid and reachable??"});});let b=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:a.id}});if(!b){if(!xp_1.xp.auto_create)throw new xplogs_1.XpFatal({function:"rankCard()",message:"User not found in database"});b=await(0,xp_1.create)(a.id,e.id,a.username);}return r=await xp_1.Database.find("simply-xps",e.id),b.position=1+r.sort((e,a)=>a.xp-e.xp).findIndex(e=>e.user===a.id)||1,(n=(r=(0,canvas_1.createCanvas)(1080,400)).getContext("2d")).save(),RoundedBox(n,0,0,r.width,r.height,25),n.clip(),n.fillStyle=l?.light?"#ffffff":"#000000",n.fill(),n.globalAlpha=l?.legacy?.8:.6,n.drawImage(i,-5,0,1090,400),n.restore(),i=l?.color||(l?.legacy?"#9900ff":l?.light?"rgba(0,0,0,0.5)":"rgba(255,255,255,0.5)"),s=l?.lvlbar||"#ffffff",f=l?.lvlbarBg||l?.legacy?"#FFFFFF":l?.light?"rgba(0,0,0,0.2)":"rgba(255,255,255,0.2)",d=shortener(b.xp)+(" "+t.xp),c=t.level+(" "+shortener(b.level)),p="{current} / {needed}",g=(0,xp_1.convertFrom)(b.level+1),x=(0,xp_1.convertFrom)(b.level),x=100*(b.xp-x)/(g-x)*(l?.legacy?660:530)/100,h="326815959358898189"===b.user?"#ade6d8":1===b.position?"#ADD8E6":2===b.position?"#C0C0C0":3===b.position?"#CD7F32":"#ffffff",l?.legacy?(n.save(),n.globalAlpha=.4,n.fillStyle=l?.light?"#ffffff":"#000000",n.fillRect(40,0,240,r.height),n.restore(),n.save(),RoundedBox(n,70,30,180,180,50,{clip:!0,fill:{color:i}}),RoundedBox(n,75,35,170,170,50,{clip:!0}),n.drawImage(o,70,30,180,180),n.restore(),n.save(),RoundedBox(n,70,320,180,50,20,{clip:!0}),n.fillStyle=i,n.fillRect(70,320,180,50),n.fillStyle="#ffffff",dynamicFont(n,d,160,355,160,32),n.restore(),n.save(),RoundedBox(n,70,240,180,50,20,{clip:!0}),n.fillStyle=i,n.fillRect(70,240,180,50),n.fillStyle="#ffffff",n.textAlign="center",dynamicFont(n,c,160,275,160,32),n.restore(),n.save(),n.textAlign="left",n.font="39px Baloo, FallbackFont",n.fillStyle="#ffffff",n.lineWidth=4,n.strokeStyle="#000000",n.strokeText(a.username,395,80),n.fillText(a.username,395,80),n.restore(),n.save(),n.textAlign="right",n.font="55px Baloo, FallbackFont",n.fillStyle="#ffffff",n.lineWidth=4,n.strokeStyle="#000000",n.strokeText("#"+b.position,r.width-55,80),n.fillText("#"+b.position,r.width-55,80),n.restore(),n.save(),RoundedBox(n,390,305,660,70,20,{clip:!0}),n.globalAlpha=.2,n.fillStyle="#ffffff",n.fillRect(390,305,660,70),n.globalAlpha=1,dynamicFont(n,e.name,720,355,700,45),n.restore(),n.save(),RoundedBox(n,390,145,660,50,20,{clip:!0}),n.globalAlpha=.2,n.fillStyle=f,n.fillRect(390,145,660,50),n.restore(),n.save(),RoundedBox(n,390,145,x,50,20,{clip:!0}),n.globalAlpha=.5,n.fillStyle=s,n.fillRect(390,145,x,50),n.restore(),n.save(),n.textAlign="left",n.font="30px Baloo, FallbackFont",n.fillStyle="#ffffff",n.globalAlpha=.8,n.fillText(`${t.next_level}: ${shortener(g)} `+t.xp,390,230),n.restore(),n.textAlign="center",n.font="30px Baloo, FallbackFont",n.fillStyle="#474747",n.globalAlpha=1,d=p.replace(/{needed}/g,shortener(g)).replace(/{current}/g,shortener(b.xp)),n.fillText(d,730,180)):(n.save(),n.textAlign="center",n.font="40px Baloo, FallbackFont",n.lineWidth=4,n.strokeStyle="#000000",n.strokeText(a.username,540,80),n.fillStyle="#ffffff",n.fillText(a.username,540,80),n.restore(),n.save(),n.beginPath(),n.arc(160,200,105,0,2*Math.PI),n.strokeStyle=i,n.lineWidth=5,n.stroke(),n.beginPath(),n.arc(160,200,100,0,2*Math.PI),n.clip(),n.fillStyle=i,n.fill(),n.drawImage(o,50,90,220,220),n.restore(),n.save(),n.beginPath(),n.arc(230,130,30,0,2*Math.PI),n.strokeStyle=i,n.lineWidth=5,n.stroke(),n.beginPath(),n.arc(230,130,30,0,2*Math.PI),n.fillStyle=h,n.fill(),n.clip(),n.fillStyle="#000000",dynamicFont(n,shortener(b.position,!0),230,138,45,30),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",n.lineWidth=3,n.strokeStyle=(l?.light,"#000000"),n.strokeText(c,160,350),n.fillStyle="#ffffff",n.fillText(c,160,350),n.restore(),n.save(),RoundedBox(n,265,330,540,25,10,{clip:!0,fill:{color:f}}),RoundedBox(n,270,335,x,15,5,{clip:!0,fill:{color:s}}),n.restore(),n.save(),n.textAlign="center",n.font="22px Baloo, FallbackFont",n.fillStyle=l?.light?"rgba(0,0,0,0.6)":"rgba(255,255,255,0.6)",n.fillText(p.replace(/{needed}/g,shortener(g)).replace(/{current}/g,shortener(b.xp)),540,320),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",e=t.level+" "+shortener(b.level+1),n.lineWidth=3,n.strokeStyle=(l?.light,"#000000"),n.strokeText(e,920,350),n.fillStyle="#ffffff",n.fillText(e,920,350),n.restore()),xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:r.toBuffer("image/png"),description:"Simply-XP Rank Card",name:"rank.png"};}function RoundedBox(e,a,l,t,o,r,n){var i=n?.roundCorners||{top:!0,bottom:!0};e.beginPath(),e.moveTo(a+(i.top?r:0),l),e.lineTo(a+t-(i.top?r:0),l),i.top&&e.quadraticCurveTo(a+t,l,a+t,l+r),e.lineTo(a+t,l+o-(i.bottom?r:0)),i.bottom&&e.quadraticCurveTo(a+t,l+o,a+t-r,l+o),e.lineTo(a+(i.bottom?r:0),l+o),i.bottom&&e.quadraticCurveTo(a,l+o,a,l+o-r),e.lineTo(a,l+(i.top?r:0)),i.top&&e.quadraticCurveTo(a,l,a+r,l),e.closePath(),n?.fill&&(n?.clip&&e.clip(),n.fill?.color&&(e.fillStyle=n.fill.color),n.fill?.alpha&&(e.globalAlpha=n.fill.alpha),e.fillRect(a,l,t,o)),n?.stroke&&(n.stroke?.color&&(e.strokeStyle=n.stroke.color),n.stroke?.width&&(e.lineWidth=n.stroke.width),e.stroke()),n?.clip&&e.clip();}function shortener(e,a){let l="",t=0;if(!e||0===e)return"0";if(e>Number.MAX_SAFE_INTEGER)return"∞";for(;1e3<=e&&t<8;)e/=1e3,t++;switch(t){case 0:l="";break;case 1:l="K";break;case 2:l="M";break;case 3:l="B";break;case 4:l="T";break;case 5:l="Qa";break;case 6:l="Qi";break;default:l="S+";}return""+e.toFixed(0===t||a?0:2)+l;}function dynamicFont(e,a,l,t,o,r){let n=r;for(;0<n&&(e.font=n+"px Baloo, FallbackFont",!(e.measureText(a).width<o));)n--;e.textAlign="center",e.fillText(a,l,t);}Object.defineProperty(exports,"__esModule",{value:!0}),exports.compareCard=compareCard,exports.leaderboardCard=leaderboardCard,exports.rankCard=rankCard,exports.RoundedBox=RoundedBox;let xp_1=require("../xp"),canvas_1=require("@napi-rs/canvas"),xplogs_1=require("./functions/xplogs"),path_1=require("path");
35
+ */if(!l||l.length<1)throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"There must be at least 1 user in the data array"});let d=void 0,c=void 0,p,g=(e?.artworkImage&&(d=await(0,canvas_1.loadImage)(e.artworkImage).catch(()=>{throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"Unable to load artwork image, is it valid?"});})),e?.backgroundImage&&(c=await(0,canvas_1.loadImage)(e.backgroundImage).catch(()=>{throw new xplogs_1.XpFatal({function:"leaderboardCard()",message:"Unable to load background image, is it valid?"});})),await(0,xp_1.registerFont)(e?.primaryFont||(0,path_1.join)(__dirname,"fonts","Baloo2-Regular.woff2"),"Baloo"),e?.secondaryFont&&await(0,xp_1.registerFont)(e.secondaryFont,"SecondaryFont"),e?.fallbackFont&&await(0,xp_1.registerFont)(e.fallbackFont,"FallbackFont"),t.level||(t.level="LEVEL"),t.members||(t.members="Members"),l=l.slice(0,8),o=e?.secondaryFont?"SecondaryFont, FallbackFont":"Baloo, FallbackFont",p=e?.light?{artworkColors:e?.artworkColors||["#997fe1","#616bff"],backgroundColor:"#FFFFFF",borderColors:e?.borderColors||["#e0d440","#fffa6b"],evenColor:e?.rowColors?.[0]||"#f0f0f0",oddColor:e?.rowColors?.[1]||"#dcdcdc",primaryTextColor:"#000000",secondaryTextColor:"rgba(0,0,0,0.5)"}:{artworkColors:e?.artworkColors||["#6B46D4","#2e3cff"],backgroundColor:"#141414",borderColors:e?.borderColors||["#e0d440","#fffa6b"],evenColor:e?.rowColors?.[0]||"#1e1e1e",oddColor:e?.rowColors?.[1]||"#282828",primaryTextColor:"#ffffff",secondaryTextColor:"rgba(255,255,255,0.5)"},RoundedBox(n=(r=(0,canvas_1.createCanvas)(1350,1080)).getContext("2d"),0,0,r.width,r.height,20,{clip:!0}),(i=n.createLinearGradient(0,0,r.width,0)).addColorStop(.4,p.artworkColors[0]),i.addColorStop(1,p.artworkColors[1]),n.fillStyle=i,n.fillRect(0,0,r.width,220),d&&(n.fillStyle="#000000",n.fillRect(0,0,r.width,220),n.globalAlpha=.5,n.drawImage(d,0,0,r.width,220),n.globalAlpha=1),n.fillStyle=e.backgroundColor||p.backgroundColor,n.fillRect(0,220,r.width,1080),c&&(n.globalAlpha=.9,n.drawImage(c,0,220,r.width,1080),n.globalAlpha=1),a&&a?.imageURL&&a?.name&&(i=await(0,canvas_1.loadImage)(a.imageURL),n.save(),n.beginPath(),n.arc(150,110,90,0,2*Math.PI,!0),n.closePath(),n.clip(),n.drawImage(i,60,20,180,180),n.restore(),(i=n.createLinearGradient(0,0,0,220)).addColorStop(0,p.borderColors[0]),i.addColorStop(1,p.borderColors[1]),n.strokeStyle=i,n.lineWidth=8,n.beginPath(),n.arc(150,110,90,0,2*Math.PI,!0),n.stroke(),n.fillStyle=p.primaryTextColor,n.font="60px Baloo, FallbackFont",a?.memberCount?(n.fillText(a.name,270,110),n.fillStyle=p.secondaryTextColor,n.font="40px Baloo, FallbackFont",n.fillText(a.memberCount+" "+t.members,270,160)):n.fillText(a.name,270,130)),p.evenColor);s=e?.rowOpacity&&!isNaN(e?.rowOpacity)?e.rowOpacity:c?.5:1;for(let e=0;e<l.length;e++)f=300+90*e,n.globalAlpha=s,n.save(),1===l.length?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g}}):0===e?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g},roundCorners:{top:!0,bottom:!1}}):e===l.length-1?RoundedBox(n,30,f,1290,90,20,{clip:!0,fill:{color:g},roundCorners:{top:!1,bottom:!0}}):RoundedBox(n,30,f,1290,90,0,{fill:{color:g}}),n.restore(),n.globalAlpha=1,n.textAlign="left",n.font="30px "+o,n.fillStyle=p.secondaryTextColor,n.fillText(e+1+".",60,55+f),n.textAlign="left",n.font="40px "+o,n.fillStyle=p.primaryTextColor,n.fillText(l[e]?.name||l[e]?.user||"???",120,60+f),n.textAlign="right",n.font="30px "+o,n.fillStyle=p.primaryTextColor,n.fillText(shortener(l[e]?.level)||"???",1270,55+f),n.fillStyle=p.secondaryTextColor,n.fillText(t.level,1270-n.measureText(shortener(l[e]?.level)||"???").width-15,55+f),g=g===p.evenColor?p.oddColor:p.evenColor;return xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:r.toBuffer("image/webp"),description:(a?.name?a.name+" leaderboard":"Leaderboard")+(` — Top ${l.length} user`+(1!==l.length?"s":"")).slice(0,200),name:"leaderboard.webp"};}async function rankCard(e,l,a={},t={}){var o,r,n,i,s,f,d,c,p,g,x,h;if(!e)throw new xplogs_1.XpFatal({function:"rankCard()",message:"No Guild Provided"});if(!l)throw new xplogs_1.XpFatal({function:"rankCard()",message:"No User Provided"});if(t?.level||(t.level="Level"),t?.next_level||(t.next_level="Next Level"),t?.xp||(t.xp="XP"),xplogs_1.XpLog.debug("rankCard()",`${a?.legacy?"LEGACY":"MODERN"} ENABLED`),!l||!l.id||!l.username)throw new xplogs_1.XpFatal({function:"rankCard()",message:"Invalid User Provided, user must contain id, username, and avatarURL."});await(0,xp_1.registerFont)(a?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-Regular.woff2"),"Baloo"),a?.fallbackFont&&await(0,xp_1.registerFont)(a.fallbackFont,"FallbackFont"),i=await(0,canvas_1.loadImage)(a?.background||(a?.legacy?"https://i.ibb.co/dck2Tnt/rank-card.webp":"https://i.ibb.co/WnfXZjc/clouds.jpg")).catch(()=>{throw new xplogs_1.XpFatal({function:"rankCard()",message:"Unable to load background image, is it valid and reachable?"});}),o=await(0,canvas_1.loadImage)(l.avatarURL).catch(()=>{throw new xplogs_1.XpFatal({function:"rankCard()",message:"Unable to load user's AvatarURL, is it valid and reachable??"});});let b=await xp_1.Database.findOne({collection:"simply-xps",data:{guild:e.id,user:l.id}});if(!b){if(!xp_1.xp.auto_create)throw new xplogs_1.XpFatal({function:"rankCard()",message:"User not found in database"});b=await(0,xp_1.create)(l.id,e.id,l.username);}return r=await xp_1.Database.find("simply-xps",e.id),b.position=1+r.filter(e=>e.xp>b.xp).length||1,(n=(r=(0,canvas_1.createCanvas)(1080,400)).getContext("2d")).save(),RoundedBox(n,0,0,r.width,r.height,25),n.clip(),n.fillStyle=a?.light?"#ffffff":"#000000",n.fill(),n.globalAlpha=a?.legacy?.8:.6,n.drawImage(i,-5,0,1090,400),n.restore(),i=a?.color||(a?.legacy?"#9900ff":a?.light?"rgba(0,0,0,0.5)":"rgba(255,255,255,0.5)"),s=a?.lvlbar||"#ffffff",f=a?.lvlbarBg||a?.legacy?"#FFFFFF":a?.light?"rgba(0,0,0,0.2)":"rgba(255,255,255,0.2)",d=shortener(b.xp)+(" "+t.xp),c=t.level+(" "+shortener(b.level)),p="{current} / {needed}",g=(0,xp_1.convertFrom)(b.level+1),x=(0,xp_1.convertFrom)(b.level),x=100*(b.xp-x)/(g-x)*(a?.legacy?660:530)/100,h="326815959358898189"===b.user?"#ade6d8":1===b.position?"#ADD8E6":2===b.position?"#C0C0C0":3===b.position?"#CD7F32":"#ffffff",a?.legacy?(n.save(),n.globalAlpha=.4,n.fillStyle=a?.light?"#ffffff":"#000000",n.fillRect(40,0,240,r.height),n.restore(),n.save(),RoundedBox(n,70,30,180,180,50,{clip:!0,fill:{color:i}}),RoundedBox(n,75,35,170,170,50,{clip:!0}),n.drawImage(o,70,30,180,180),n.restore(),n.save(),RoundedBox(n,70,320,180,50,20,{clip:!0}),n.fillStyle=i,n.fillRect(70,320,180,50),n.fillStyle="#ffffff",dynamicFont(n,d,160,355,160,32),n.restore(),n.save(),RoundedBox(n,70,240,180,50,20,{clip:!0}),n.fillStyle=i,n.fillRect(70,240,180,50),n.fillStyle="#ffffff",n.textAlign="center",dynamicFont(n,c,160,275,160,32),n.restore(),n.save(),n.textAlign="left",n.font="39px Baloo, FallbackFont",n.fillStyle="#ffffff",n.lineJoin="round",n.lineWidth=5,n.strokeStyle="rgba(0,0,0,0.35)",n.strokeText(l.username,395,80),n.fillText(l.username,395,80),n.restore(),n.save(),n.textAlign="right",n.font="55px Baloo, FallbackFont",n.fillStyle="#ffffff",n.lineJoin="round",n.lineWidth=7,n.strokeStyle="rgba(0,0,0,0.35)",n.strokeText("#"+b.position,r.width-55,80),n.fillText("#"+b.position,r.width-55,80),n.restore(),n.save(),RoundedBox(n,390,305,660,70,20,{clip:!0}),n.globalAlpha=.2,n.fillStyle="#ffffff",n.fillRect(390,305,660,70),n.globalAlpha=1,dynamicFont(n,e.name,720,355,700,45),n.restore(),n.save(),RoundedBox(n,390,145,660,50,20,{clip:!0}),n.globalAlpha=.2,n.fillStyle=f,n.fillRect(390,145,660,50),n.restore(),n.save(),RoundedBox(n,390,145,x,50,20,{clip:!0}),n.globalAlpha=.5,n.fillStyle=s,n.fillRect(390,145,x,50),n.restore(),n.save(),n.textAlign="left",n.font="30px Baloo, FallbackFont",n.fillStyle="#ffffff",n.globalAlpha=.8,n.fillText(`${t.next_level}: ${shortener(g)} `+t.xp,390,230),n.restore(),n.textAlign="center",n.font="30px Baloo, FallbackFont",n.fillStyle="#474747",n.globalAlpha=1,d=p.replace(/{needed}/g,shortener(g)).replace(/{current}/g,shortener(b.xp)),n.fillText(d,730,180)):(n.save(),n.textAlign="center",n.font="40px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=7,n.strokeStyle="rgba(0,0,0,0.35)",n.strokeText(l.username,540,80),n.fillStyle="#ffffff",n.fillText(l.username,540,80),n.restore(),n.save(),n.beginPath(),n.arc(160,200,100,0,2*Math.PI),n.closePath(),n.clip(),n.fillStyle=i,n.fill(),n.drawImage(o,50,90,220,220),n.restore(),n.save(),n.beginPath(),n.arc(160,200,105,0,2*Math.PI),n.closePath(),n.strokeStyle=i,n.lineWidth=5,n.stroke(),n.restore(),n.save(),n.beginPath(),n.arc(230,130,28,0,2*Math.PI),n.closePath(),n.clip(),n.fillStyle=h,n.fill(),n.fillStyle="#000000",dynamicFont(n,shortener(b.position,!0),230,138,45,30),n.restore(),n.save(),n.beginPath(),n.arc(230,130,30,0,2*Math.PI),n.closePath(),n.strokeStyle=i,n.lineWidth=5,n.stroke(),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",n.lineJoin="round",n.lineWidth=5,n.strokeStyle="rgba(0,0,0,0.35)",n.strokeText(c,160,350),n.fillStyle="#ffffff",n.fillText(c,160,350),n.restore(),n.save(),RoundedBox(n,265,330,540,25,10,{clip:!0,fill:{color:f}}),RoundedBox(n,270,335,x,15,5,{clip:!0,fill:{color:s}}),n.restore(),n.save(),n.textAlign="center",n.font="22px Baloo, FallbackFont",n.fillStyle=a?.light?"rgba(0,0,0,0.6)":"rgba(255,255,255,0.6)",n.fillText(p.replace(/{needed}/g,shortener(g)).replace(/{current}/g,shortener(b.xp)),540,320),n.restore(),n.save(),n.textAlign="center",n.font="25px Baloo, FallbackFont",d=t.level+" "+shortener(b.level+1),n.lineJoin="round",n.lineWidth=5,n.strokeStyle="rgba(0,0,0,0.35)",n.strokeText(d,920,350),n.fillStyle="#ffffff",n.fillText(d,920,350),n.restore()),xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:r.toBuffer("image/webp"),description:(`${l.username}'s rank card — Lvl ${b.level} | ${shortener(b.xp)} XP | #${b.position} in `+e.name).slice(0,200),name:"rank.webp"};}function RoundedBox(e,l,a,t,o,r,n){var i=n?.roundCorners||{top:!0,bottom:!0};e.beginPath(),e.moveTo(l+(i.top?r:0),a),e.lineTo(l+t-(i.top?r:0),a),i.top&&e.quadraticCurveTo(l+t,a,l+t,a+r),e.lineTo(l+t,a+o-(i.bottom?r:0)),i.bottom&&e.quadraticCurveTo(l+t,a+o,l+t-r,a+o),e.lineTo(l+(i.bottom?r:0),a+o),i.bottom&&e.quadraticCurveTo(l,a+o,l,a+o-r),e.lineTo(l,a+(i.top?r:0)),i.top&&e.quadraticCurveTo(l,a,l+r,a),e.closePath(),n?.fill&&(n?.clip&&e.clip(),n.fill?.color&&(e.fillStyle=n.fill.color),n.fill?.alpha&&(e.globalAlpha=n.fill.alpha),e.fillRect(l,a,t,o)),n?.stroke&&(n.stroke?.color&&(e.strokeStyle=n.stroke.color),n.stroke?.width&&(e.lineWidth=n.stroke.width),e.stroke()),n?.clip&&e.clip();}function shortener(e,l){let a="",t=0;if(!e||0===e)return"0";if(e>Number.MAX_SAFE_INTEGER)return"∞";for(;1e3<=e&&t<8;)e/=1e3,t++;switch(t){case 0:a="";break;case 1:a="K";break;case 2:a="M";break;case 3:a="B";break;case 4:a="T";break;case 5:a="Qa";break;case 6:a="Qi";break;default:a="S+";}return""+e.toFixed(0===t||l?0:2)+a;}function dynamicFont(e,l,a,t,o,r){let n=r;for(;0<n&&(e.font=n+"px Baloo, FallbackFont",!(e.measureText(l).width<o));)n--;e.textAlign="center",e.fillText(l,a,t);}Object.defineProperty(exports,"__esModule",{value:!0}),exports.compareCard=compareCard,exports.leaderboardCard=leaderboardCard,exports.rankCard=rankCard,exports.RoundedBox=RoundedBox;let xp_1=require("../xp"),canvas_1=require("@napi-rs/canvas"),xplogs_1=require("./functions/xplogs"),path_1=require("path");
package/lib/src/charts.js CHANGED
@@ -7,4 +7,4 @@
7
7
  * @returns {Promise<{attachment: Buffer, description: string, name: string}>} Chart attachment
8
8
  * @throws {XpFatal} If invalid parameters are provided, or if there are not enough users to create a chart
9
9
  */
10
- async function charts(F,n={}){var e,t,a,o,l,r,i,h,c;if(!F)throw new xplogs_1.XpFatal({function:"charts()",message:"No Guild ID Provided"});if(!n)throw new xplogs_1.XpFatal({function:"charts()",message:"No Options Provided"});n.theme&&["blue","dark","discord","green","light","orange","pink","red","space","yellow"].includes(n.theme)||(xplogs_1.XpLog.warn("charts()","Invalid theme provided, defaulting to discord"),n.theme="discord"),n.type&&["bar","doughnut","pie"].includes(n.type)||(xplogs_1.XpLog.warn("charts()","Invalid type provided, defaulting to bar chart"),n.type="bar");let s;if((e=await(0,xp_1.leaderboard)(F,Math.min(Math.max(n?.limit||10,2),10)).catch(F=>{throw new xplogs_1.XpFatal({function:"charts()",message:F.message});})).length<2)throw new xplogs_1.XpFatal({function:"charts()",message:"Not enough users to create a chart"});switch(await(0,xp_1.registerFont)(n?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-ExtraBold.woff2"),"Baloo"),n.fallbackFont&&await(0,xp_1.registerFont)(n.fallbackFont,"FallbackFont"),n.theme){case"blue":s={background:"#1e1e3c",barColor:"#747fff",pieColors:["#5A6BFF","#52FFF2","#6FB6FF","#30EDC2","#3F8CFF","#1BB8A3","#8CD9FF","#2F53FF","#0098FF","#A9F5FF"],textColor:"#FFFFFF"};break;case"dark":s={background:"#1e1e1e",barColor:"#747474",pieColors:["#FF7A7A","#39FF9D","#4C8BF5","#FFE066","#2BD9FF","#FF5EDB","#C47BFF","#6ED0FF","#FFA53A","#FFCC66"],textColor:"#FFFFFF"};break;case"discord":s={background:"#36393f",barColor:"#5865F2",pieColors:["#5865F2","#57F287","#FEE75C","#EB459E","#ED4245","#FFFFFF","#000000","#FAA61A","#C04DF9","#00AAFF"],textColor:"#FFFFFF"};break;case"green":s={background:"#1e321e",barColor:"#74ff7f",pieColors:["#66FFB2","#4DFFDF","#A8FF66","#32FF9C","#7CFFA3","#3AD7C9","#00D47A","#59FFC2","#1ED1A6","#7AFFCE"],textColor:"#FFFFFF"};break;case"light":s={background:"#f2f2f2",barColor:"#1c1c1c",pieColors:["#FF7A7A","#6ED0FF","#FFCC66","#C47BFF","#2BD9FF","#FFA53A","#FF5EDB","#39FF9D","#FFE066","#4C8BF5"],textColor:"#000000"};break;case"orange":s={background:"#321e1e",barColor:"#ff9f74",pieColors:["#FF8A4C","#FF6E35","#FFD28C","#FF7A45","#FFAA66","#FFC999","#FF9A5E","#FFB76B","#FF8F52","#FFD28C"],textColor:"#FFFFFF"};break;case"pink":s={background:"#3c1e3c",barColor:"#ff74ff",pieColors:["#FF8BFF","#FF6BD1","#A87CFF","#FFB6FF","#7DF7FF","#8FA6FF","#5FA8FF","#CE5CFF","#FF4FA3","#DFA0FF"],textColor:"#FFFFFF"};break;case"red":s={background:"#321e1e",barColor:"#ff7474",pieColors:["#FF6B6B","#FFD166","#FF4F5C","#FFB266","#FF7A85","#FFC099","#FF6F91","#FF8F4D","#FF9A7A","#FFA8B0"],textColor:"#FFFFFF"};break;case"space":s={background:"#001F3F",barColor:"#192E5B",pieColors:["#192E5B","#264FA3","#337FEA","#2C5FC7","#1F3F7F","#3D8FFF","#4D9FFF","#5DAFFF","#6DBFFF","#7DCFFF"],textColor:"#FFFFFF"};break;case"yellow":s={background:"#32321e",barColor:"#ffff74",pieColors:["#FFEF99","#FFE266","#FFB84D","#FFF6C2","#FFD966","#e6ff77ff","#FFCC33","#E6A82E","#D4A741","#FFE8AA"],textColor:"#FFFFFF"};}let d=(0,canvas_1.createCanvas)(920,600),f=d.getContext("2d"),p=Math.max(...e.map(F=>F.level));if((0,cards_1.RoundedBox)(f,0,0,d.width,d.height,25,{clip:!0}),f.fillStyle=s.background,f.fillRect(0,0,d.width,d.height),"space"===n.theme){(F=f.createRadialGradient(d.width/2,d.height/2,1,d.width/2,d.height/2,Math.max(d.width,d.height))).addColorStop(0,"#000000"),F.addColorStop(1,"#001F3F"),f.fillStyle=F,f.fillRect(0,0,d.width,d.height),(F=f.createRadialGradient(150,150,10,150,150,100)).addColorStop(0,"#F2F2F2"),F.addColorStop(.8,"#D3D3D3"),F.addColorStop(1,"#001F3F"),f.fillStyle=F,f.beginPath(),f.arc(150,150,100,0,2*Math.PI),f.fill(),t=["#6B6B6B","#AA8F00","#473E83","#456579"];for(let F=0;F<t.length;F++)a=Math.random()*d.width,o=Math.random()*d.height,l=50*Math.random()+30,f.beginPath(),f.arc(a,o,l,0,2*Math.PI),f.fillStyle=t[F]||"#FFFFFF",f.fill();f.filter="blur(5px)",f.drawImage(d,0,0),f.filter="none";for(let F=0;F<100;F++)r=Math.random()*d.width,i=Math.random()*d.height,h=2*Math.random(),f.beginPath(),f.arc(r,i,h,0,2*Math.PI),f.fillStyle="#FFFFFF",f.fill();}let C=d.width-40,g=d.height-40;switch(n.type){case"bar":{c=f.measureText(p.toString()).width,C=d.width-c-100,g=d.height-140;let r=C/e.length-20,i=c+60,h=d.height-70;e.map((F,e)=>{var t,a=(F.level===1/0?1:F.level/p)*g,e=i+e*(20+r),o=h-a,a=(f.save(),(0,cards_1.RoundedBox)(f,e,o,r,a,10,{clip:!0,fill:{color:s.barColor}}),f.restore(),e+r/2),e=(f.fillStyle=s.textColor,f.font="22px Baloo, FallbackFont",F.level.toString()),l=f.measureText(e).width,o=o-10,e=(f.fillText(e,a-l/2,o),F?.name||F.user),l=f.measureText(e).width,o=(f.font=Math.min(Math.floor(r/l*16),18)+"px Baloo, FallbackFont",l=f.measureText(e).width,30+h);"space"===n.theme&&(t=a-(F=l+20)/2,f.fillStyle="rgba(0, 0, 0, 0.5)",f.fillRect(t,o-18,F,25)),f.fillStyle=s.textColor,f.fillText(e,a-l/2,o);});}break;case"doughnut":{let t=e.reduce((F,e)=>F+e.level,0),a=Math.min(C,g)/3,o=.6*a,l=-Math.PI/2,r=d.width/2,i=d.height/2;e.map((F,e)=>{F=l+2*Math.PI*(F.level/t),f.fillStyle=s.pieColors[e%s.pieColors.length]||"#FFFFFF",f.beginPath(),f.moveTo(r+a*Math.cos(l),i+a*Math.sin(l)),f.arc(r,i,a,l,F),f.lineTo(r+o*Math.cos(F),i+o*Math.sin(F)),f.arc(r,i,o,F,l,!0),f.closePath(),f.fill(),l=F;});}break;case"pie":{let t=e.reduce((F,e)=>F+e.level,0),a=Math.min(C,g)/3,o=-Math.PI/2,l=d.width/2,r=d.height/2;e.map((F,e)=>{F=o+2*Math.PI*(F.level/t),f.fillStyle=s.pieColors[e%s.pieColors.length]||"#FFFFFF",f.beginPath(),f.moveTo(l,r),f.arc(l,r,a,o,F),f.closePath(),f.fill(),o=F;});}break;default:throw new xplogs_1.XpFatal({function:"charts()",message:"Invalid chart type provided"});}if(["doughnut","pie"].includes(n.type)){let a=d.height-20-20*e.length;f.fillStyle="rgba(0,0,0,0.25)",f.fillRect(15,a-5,200,20*e.length+5),f.font="12px Baloo, FallbackFont",e.map((F,e)=>{var t=s.pieColors[e%s.pieColors.length],e=a+20*e;f.fillStyle=t||"#FFFFFF",f.fillRect(20,e,15,15),f.fillStyle=s.textColor,f.fillText(F?.name||F.user,40,11.5+e);});}return xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:d.toBuffer("image/png"),description:"Chart",name:"chart.png"};}Object.defineProperty(exports,"__esModule",{value:!0}),exports.charts=charts;let xp_1=require("../xp"),xplogs_1=require("./functions/xplogs"),canvas_1=require("@napi-rs/canvas"),cards_1=require("./cards"),path_1=require("path");
10
+ async function charts(F,n={}){var e,t,a,o,l,r,i,h,c;if(!F)throw new xplogs_1.XpFatal({function:"charts()",message:"No Guild ID Provided"});if(!n)throw new xplogs_1.XpFatal({function:"charts()",message:"No Options Provided"});n.theme&&["blue","dark","discord","green","light","orange","pink","red","space","yellow"].includes(n.theme)||(xplogs_1.XpLog.warn("charts()","Invalid theme provided, defaulting to discord"),n.theme="discord"),n.type&&["bar","doughnut","pie"].includes(n.type)||(xplogs_1.XpLog.warn("charts()","Invalid type provided, defaulting to bar chart"),n.type="bar");let s;if((e=await(0,xp_1.leaderboard)(F,Math.min(Math.max(n?.limit||10,2),10)).catch(F=>{throw new xplogs_1.XpFatal({function:"charts()",message:F.message});})).length<2)throw new xplogs_1.XpFatal({function:"charts()",message:"Not enough users to create a chart"});switch(await(0,xp_1.registerFont)(n?.font||(0,path_1.join)(__dirname,"fonts","Baloo2-Regular.woff2"),"Baloo"),n.fallbackFont&&await(0,xp_1.registerFont)(n.fallbackFont,"FallbackFont"),n.theme){case"blue":s={background:"#1e1e3c",barColor:"#747fff",pieColors:["#5A6BFF","#52FFF2","#6FB6FF","#30EDC2","#3F8CFF","#1BB8A3","#8CD9FF","#2F53FF","#0098FF","#A9F5FF"],textColor:"#FFFFFF"};break;case"dark":s={background:"#1e1e1e",barColor:"#747474",pieColors:["#FF7A7A","#39FF9D","#4C8BF5","#FFE066","#2BD9FF","#FF5EDB","#C47BFF","#6ED0FF","#FFA53A","#FFCC66"],textColor:"#FFFFFF"};break;case"discord":s={background:"#36393f",barColor:"#5865F2",pieColors:["#5865F2","#57F287","#FEE75C","#EB459E","#ED4245","#FFFFFF","#000000","#FAA61A","#C04DF9","#00AAFF"],textColor:"#FFFFFF"};break;case"green":s={background:"#1e321e",barColor:"#74ff7f",pieColors:["#66FFB2","#4DFFDF","#A8FF66","#32FF9C","#7CFFA3","#3AD7C9","#00D47A","#59FFC2","#1ED1A6","#7AFFCE"],textColor:"#FFFFFF"};break;case"light":s={background:"#f2f2f2",barColor:"#1c1c1c",pieColors:["#FF7A7A","#6ED0FF","#FFCC66","#C47BFF","#2BD9FF","#FFA53A","#FF5EDB","#39FF9D","#FFE066","#4C8BF5"],textColor:"#000000"};break;case"orange":s={background:"#321e1e",barColor:"#ff9f74",pieColors:["#FF8A4C","#FF6E35","#FFD28C","#FF7A45","#FFAA66","#FFC999","#FF9A5E","#FFB76B","#FF8F52","#FFD28C"],textColor:"#FFFFFF"};break;case"pink":s={background:"#3c1e3c",barColor:"#ff74ff",pieColors:["#FF8BFF","#FF6BD1","#A87CFF","#FFB6FF","#7DF7FF","#8FA6FF","#5FA8FF","#CE5CFF","#FF4FA3","#DFA0FF"],textColor:"#FFFFFF"};break;case"red":s={background:"#321e1e",barColor:"#ff7474",pieColors:["#FF6B6B","#FFD166","#FF4F5C","#FFB266","#FF7A85","#FFC099","#FF6F91","#FF8F4D","#FF9A7A","#FFA8B0"],textColor:"#FFFFFF"};break;case"space":s={background:"#001F3F",barColor:"#192E5B",pieColors:["#192E5B","#264FA3","#337FEA","#2C5FC7","#1F3F7F","#3D8FFF","#4D9FFF","#5DAFFF","#6DBFFF","#7DCFFF"],textColor:"#FFFFFF"};break;case"yellow":s={background:"#32321e",barColor:"#ffff74",pieColors:["#FFEF99","#FFE266","#FFB84D","#FFF6C2","#FFD966","#e6ff77ff","#FFCC33","#E6A82E","#D4A741","#FFE8AA"],textColor:"#FFFFFF"};}let d=(0,canvas_1.createCanvas)(920,600),p=d.getContext("2d"),f=Math.max(...e.map(F=>F.level));if((0,cards_1.RoundedBox)(p,0,0,d.width,d.height,25,{clip:!0}),p.fillStyle=s.background,p.fillRect(0,0,d.width,d.height),"space"===n.theme){(F=p.createRadialGradient(d.width/2,d.height/2,1,d.width/2,d.height/2,Math.max(d.width,d.height))).addColorStop(0,"#000000"),F.addColorStop(1,"#001F3F"),p.fillStyle=F,p.fillRect(0,0,d.width,d.height),(F=p.createRadialGradient(150,150,10,150,150,100)).addColorStop(0,"#F2F2F2"),F.addColorStop(.8,"#D3D3D3"),F.addColorStop(1,"#001F3F"),p.fillStyle=F,p.beginPath(),p.arc(150,150,100,0,2*Math.PI),p.fill(),t=["#6B6B6B","#AA8F00","#473E83","#456579"];for(let F=0;F<t.length;F++)a=Math.random()*d.width,o=Math.random()*d.height,l=50*Math.random()+30,p.beginPath(),p.arc(a,o,l,0,2*Math.PI),p.fillStyle=t[F]||"#FFFFFF",p.fill();p.filter="blur(5px)",p.drawImage(d,0,0),p.filter="none";for(let F=0;F<100;F++)r=Math.random()*d.width,i=Math.random()*d.height,h=2*Math.random(),p.beginPath(),p.arc(r,i,h,0,2*Math.PI),p.fillStyle="#FFFFFF",p.fill();}let C=d.width-40,g=d.height-40;switch(n.type){case"bar":{c=p.measureText(f.toString()).width,C=d.width-c-100,g=d.height-140;let r=C/e.length-20,i=c+60,h=d.height-70;e.map((F,e)=>{var t,a=(F.level===1/0?1:F.level/f)*g,e=i+e*(20+r),o=h-a,a=(p.save(),(0,cards_1.RoundedBox)(p,e,o,r,a,10,{clip:!0,fill:{color:s.barColor}}),p.restore(),e+r/2),e=(p.fillStyle=s.textColor,p.font="22px Baloo, FallbackFont",F.level.toString()),l=p.measureText(e).width,o=o-10,e=(p.fillText(e,a-l/2,o),F?.name||F.user),l=p.measureText(e).width,o=(p.font=Math.min(Math.floor(r/l*16),18)+"px Baloo, FallbackFont",l=p.measureText(e).width,30+h);"space"===n.theme&&(t=a-(F=l+20)/2,p.fillStyle="rgba(0, 0, 0, 0.5)",p.fillRect(t,o-18,F,25)),p.fillStyle=s.textColor,p.fillText(e,a-l/2,o);});}break;case"doughnut":{let t=e.reduce((F,e)=>F+e.level,0),a=Math.min(C,g)/3,o=.6*a,l=-Math.PI/2,r=d.width/2,i=d.height/2;e.map((F,e)=>{F=l+2*Math.PI*(F.level/t),p.fillStyle=s.pieColors[e%s.pieColors.length]||"#FFFFFF",p.beginPath(),p.moveTo(r+a*Math.cos(l),i+a*Math.sin(l)),p.arc(r,i,a,l,F),p.lineTo(r+o*Math.cos(F),i+o*Math.sin(F)),p.arc(r,i,o,F,l,!0),p.closePath(),p.fill(),l=F;});}break;case"pie":{let t=e.reduce((F,e)=>F+e.level,0),a=Math.min(C,g)/3,o=-Math.PI/2,l=d.width/2,r=d.height/2;e.map((F,e)=>{F=o+2*Math.PI*(F.level/t),p.fillStyle=s.pieColors[e%s.pieColors.length]||"#FFFFFF",p.beginPath(),p.moveTo(l,r),p.arc(l,r,a,o,F),p.closePath(),p.fill(),o=F;});}break;default:throw new xplogs_1.XpFatal({function:"charts()",message:"Invalid chart type provided"});}if(["doughnut","pie"].includes(n.type)){let a=d.height-20-20*e.length;p.fillStyle="rgba(0,0,0,0.25)",p.fillRect(15,a-5,200,20*e.length+5),p.font="12px Baloo, FallbackFont",e.map((F,e)=>{var t=s.pieColors[e%s.pieColors.length],e=a+20*e;p.fillStyle=t||"#FFFFFF",p.fillRect(20,e,15,15),p.fillStyle=s.textColor,p.fillText(F?.name||F.user,40,11.5+e);});}return xp_1.xp.auto_clean&&(0,xp_1.clean)(),{attachment:d.toBuffer("image/webp"),description:`${n.type.charAt(0).toUpperCase()+n.type.slice(1)} chart — Top ${e.length} users (${n.theme} theme)`.slice(0,200),name:"chart.webp"};}Object.defineProperty(exports,"__esModule",{value:!0}),exports.charts=charts;let xp_1=require("../xp"),xplogs_1=require("./functions/xplogs"),canvas_1=require("@napi-rs/canvas"),cards_1=require("./cards"),path_1=require("path");
@@ -13,7 +13,7 @@ function handleError(e,a){throw new xplogs_1.XpFatal({function:"Database."+a,mes
13
13
  * @returns {Collection} The collection.
14
14
  * @throws {XpFatal} Throws an error if there is no database connection, or database type is invalid.
15
15
  */
16
- static getCollection(e){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"getCollection()",message:"No database connection"});if("mongodb"!==xp_1.xp.dbType)throw new xplogs_1.XpFatal({function:"getCollection()",message:"MongoDB has to be your database type to use this function."});return xp_1.xp.database.db().collection(e);}
16
+ static getCollection(e){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"getCollection()",message:"No database connection"});if("mongodb"!==xp_1.xp.dbType)throw new xplogs_1.XpFatal({function:"getCollection()",message:"MongoDB has to be your database type to use this function."});return xp_1.xp.database.db(xp_1.xp.dbName).collection(e);}
17
17
  /**
18
18
  * Creates one document in the database.
19
19
  *
@@ -58,14 +58,14 @@ function handleError(e,a){throw new xplogs_1.XpFatal({function:"Database."+a,mes
58
58
  * @link `Documentation:` https://simplyxp.js.org/docs/next/Classes/database#dbfind
59
59
  * @returns {Promise<UserResult[] | LevelRoleResult[]>} An array of found documents.
60
60
  * @throws {XpFatal} Throws an error if there is no database connection.
61
- */static async find(e,a){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"find()",message:"No database connection"});switch(xp_1.xp.dbType){case"mongodb":return xp_1.xp.database.db().collection(e).find({guild:a}).toArray().catch(e=>handleError(e,"find()"));case"sqlite":return"simply-xps"===e?xp_1.xp.database.prepare("SELECT * FROM \"simply-xps\" WHERE guild = ?").all(a).map(e=>parseFlags(e)):xp_1.xp.database.prepare("SELECT * FROM \"simply-xp-levelroles\" WHERE gid = ?").all(a).map(e=>(e.levelrole&&"string"==typeof e.levelrole&&(e.levelrole=JSON.parse(e.levelrole)),e));}}
61
+ */static async find(e,a){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"find()",message:"No database connection"});switch(xp_1.xp.dbType){case"mongodb":return xp_1.xp.database.db(xp_1.xp.dbName).collection(e).find({guild:a}).toArray().catch(e=>handleError(e,"find()"));case"sqlite":return"simply-xps"===e?xp_1.xp.database.prepare("SELECT * FROM \"simply-xps\" WHERE guild = ?").all(a).map(e=>parseFlags(e)):xp_1.xp.database.prepare("SELECT * FROM \"simply-xp-levelroles\" WHERE gid = ?").all(a).map(e=>(e.levelrole&&"string"==typeof e.levelrole&&(e.levelrole=JSON.parse(e.levelrole)),e));}}
62
62
  /**
63
63
  * Finds all documents in a collection.
64
64
  * @param {"simply-xps" | "simply-xp-levelroles"} collection - The collection to search for all documents.
65
65
  * @link `Documentation:` https://simplyxp.js.org/docs/next/Classes/database#dbfindall
66
66
  * @returns {Promise<UserResult[] | LevelRoleResult[]>} An array of found documents.
67
67
  * @throws {XpFatal} Throws an error if there is no database connection.
68
- */static async findAll(e){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"findAll()",message:"No database connection"});switch(xp_1.xp.dbType){case"mongodb":return xp_1.xp.database.db().collection(e).find().toArray().catch(e=>handleError(e,"findAll()"));case"sqlite":return"simply-xps"===e?xp_1.xp.database.prepare("SELECT * FROM \"simply-xps\"").all().map(e=>parseFlags(e)):xp_1.xp.database.prepare("SELECT * FROM \"simply-xp-levelroles\"").all();}}
68
+ */static async findAll(e){if(!xp_1.xp.database)throw new xplogs_1.XpFatal({function:"findAll()",message:"No database connection"});switch(xp_1.xp.dbType){case"mongodb":return xp_1.xp.database.db(xp_1.xp.dbName).collection(e).find().toArray().catch(e=>handleError(e,"findAll()"));case"sqlite":return"simply-xps"===e?xp_1.xp.database.prepare("SELECT * FROM \"simply-xps\"").all().map(e=>parseFlags(e)):xp_1.xp.database.prepare("SELECT * FROM \"simply-xp-levelroles\"").all();}}
69
69
  /**
70
70
  * Updates one document in the database.
71
71
  *
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0;let xp_1=require("../../xp"),xplogs_1=require("../functions/xplogs");class LevelRoles{
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0;let xplogs_1=require("../functions/xplogs"),xp_1=require("../../xp");class LevelRoles{
2
2
  /**
3
3
  * Add a role to the role setup
4
4
  * @async
@@ -8,7 +8,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
8
8
  * @returns {Promise<boolean>} - True if successful
9
9
  * @throws {XpFatal} If an invalid type is provided or value is not provided.
10
10
  */
11
- static async add(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Level must be a number"});var s;if(l?.roles&&Array.isArray(l?.roles)&&0!==l?.roles.length)return(s=await xp_1.db.findOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}))&&(l.roles=Array.from(new Set([...s.levelrole.roles||[],...l.roles]))),xp_1.db.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:l.roles}}},{upsert:!0}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Roles must be a non-empty array of strings"});}
11
+ static async add(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Level must be a number"});var s;if(l?.roles&&Array.isArray(l?.roles)&&0!==l?.roles.length)return(s=await xp_1.Database.findOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}))&&(l.roles=Array.from(new Set([...s.levelrole.roles||[],...l.roles]))),xp_1.Database.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:l.roles}}},{upsert:!0}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.add()",message:"Roles must be a non-empty array of strings"});}
12
12
  /**
13
13
  * Delete some or all roles from the level.
14
14
  * @async
@@ -17,7 +17,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
17
17
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/LevelRoles#levelrolesdelete
18
18
  * @returns {Promise<boolean>} - True if successful
19
19
  * @throws {XpFatal} If an invalid type is provided or value is not provided.
20
- */static async delete(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Level must be a number"});var s;if(!l?.roles||Array.isArray(l?.roles)&&0!==l?.roles.length)return!!(s=await xp_1.db.findOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}))&&(0===(s=l.roles?(s.levelrole.roles||[]).filter(e=>!l.roles.includes(e)):[]).length?xp_1.db.deleteOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}):xp_1.db.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:s}}})).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Roles must be a non-empty array of strings"});}
20
+ */static async delete(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Level must be a number"});var s;if(!l?.roles||Array.isArray(l?.roles)&&0!==l?.roles.length)return!!(s=await xp_1.Database.findOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}))&&(0===(s=l.roles?(s.levelrole.roles||[]).filter(e=>!l.roles.includes(e)):[]).length?xp_1.Database.deleteOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}}):xp_1.Database.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:s}}})).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.delete()",message:"Roles must be a non-empty array of strings"});}
21
21
  /**
22
22
  * Delete all roles in a guild's role setup
23
23
  * @async
@@ -25,7 +25,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
25
25
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/LevelRoles#levelrolesdeleteall
26
26
  * @returns {Promise<boolean>} - True if successful
27
27
  * @throws {XpFatal} If an invalid type is provided or value is not provided.
28
- */static async deleteAll(e){if(e)return xp_1.db.deleteMany({collection:"simply-xp-levelroles",data:{guild:e}}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.deleteAll()",message:"Guild ID was not provided"});}
28
+ */static async deleteAll(e){if(e)return xp_1.Database.deleteMany({collection:"simply-xp-levelroles",data:{guild:e}}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.deleteAll()",message:"Guild ID was not provided"});}
29
29
  /**
30
30
  * Fetch all roles in a guild's role setup
31
31
  * @async
@@ -33,7 +33,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
33
33
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/LevelRoles#levelrolesfetchall
34
34
  * @returns {Promise<LevelRoleResult[]>} - The level role object
35
35
  * @throws {XpFatal} If there are no roles in the guild.
36
- */static async getGuildRoles(e){if(e)return xp_1.db.find("simply-xp-levelroles",e);throw new xplogs_1.XpFatal({function:"LevelRoles.fetchAll()",message:"Guild ID was not provided"});}
36
+ */static async getGuildRoles(e){if(e)return xp_1.Database.find("simply-xp-levelroles",e);throw new xplogs_1.XpFatal({function:"LevelRoles.fetchAll()",message:"Guild ID was not provided"});}
37
37
  /**
38
38
  * Get roles for a user's level
39
39
  * @async
@@ -43,7 +43,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
43
43
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/LevelRoles#getuserroles
44
44
  * @returns {Promise<string[]>} - Array of role IDs or empty array if none
45
45
  * @throws {XpFatal} If an invalid type is provided or value is not provided.
46
- */static async getUserRoles(e,l,s={}){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.getUserRoles()",message:"User ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.getUserRoles()",message:"Guild ID was not provided"});let o=await xp_1.db.findOne({collection:"simply-xps",data:{user:e,guild:l}});if(!o?.level)return[];let t=await LevelRoles.getGuildRoles(l),{includeCurrent:a=!0,includeNext:r=!1,includePrevious:n=!1}=s;return t.reduce((e,{levelrole:{level:l,roles:s}})=>((a&&l===o.level||r&&l>o.level||n&&l<o.level)&&s?.length&&e.push(...s),e),[]);}
46
+ */static async getUserRoles(e,l,s={}){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.getUserRoles()",message:"User ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.getUserRoles()",message:"Guild ID was not provided"});let o=await xp_1.Database.findOne({collection:"simply-xps",data:{user:e,guild:l}});if(!o?.level)return[];let t=await LevelRoles.getGuildRoles(l),{includeCurrent:a=!0,includeNext:r=!1,includePrevious:n=!1}=s;return t.reduce((e,{levelrole:{level:l,roles:s}})=>((a&&l===o.level||r&&l>o.level||n&&l<o.level)&&s?.length&&e.push(...s),e),[]);}
47
47
  /**
48
48
  * Set roles for a level (overwrites existing roles)
49
49
  * @async
@@ -52,4 +52,4 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LevelRoles=void 0
52
52
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/LevelRoles#levelrolesset
53
53
  * @returns {Promise<boolean>} - True if successful
54
54
  * @throws {XpFatal} If an invalid type is provided or value is not provided.
55
- */static async set(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Level must be a number"});if(Array.isArray(l?.roles)&&0!==l?.roles.length)return xp_1.db.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:l.roles}}},{upsert:!0}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Roles must be a non-empty array of strings"});}}exports.LevelRoles=LevelRoles;
55
+ */static async set(e,l){if(!e)throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Guild ID was not provided"});if(!l)throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Options were not provided"});if(isNaN(l?.level))throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Level must be a number"});if(Array.isArray(l?.roles)&&0!==l?.roles.length)return xp_1.Database.updateOne({collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level}}},{collection:"simply-xp-levelroles",data:{guild:e,levelrole:{level:l.level,roles:l.roles}}},{upsert:!0}).then(()=>!0).catch(()=>!1);throw new xplogs_1.XpFatal({function:"LevelRoles.set()",message:"Roles must be a non-empty array of strings"});}}exports.LevelRoles=LevelRoles;
@@ -16,7 +16,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.migrate=exports.M
16
16
  * @link `Documentation:` https://simplyxp.js.org/docs/next/classes/migrate#migratefromdb
17
17
  * @returns {Promise<boolean>} - Returns true if migration is successful
18
18
  * @throws {XpFatal} - If parameters are not provided correctly
19
- */xplogs_1.XpLog.debug("migrate.discord_xp()",`FOUND ${l.length} DOCUMENTS`);try{for(a of l)await xp_1.db.findOne({collection:"simply-xps",data:{guild:a.guildID,user:a.userID}})||(await xp_1.db.createOne({collection:"simply-xps",data:{guild:a.guildID,user:a.userID,xp:a.xp,level:(0,xp_1.convertFrom)(a.xp,"xp")}}),e&&await xp_1.db.getCollection("levels").deleteOne({userID:a.userID,guildID:a.guildID}));return!0;}catch(e){return xplogs_1.XpLog.err("migrate.discord_xp()",e),!1;}}static async fromDB(e,a){if(!e)throw new xplogs_1.XpFatal({function:"migrate.database()",message:"No database type provided"});if(!a)throw new xplogs_1.XpFatal({function:"migrate.database()",message:"No database connection provided"});if(xp_1.xp.dbType===e)return xplogs_1.XpLog.info("migrate.fromDB()","Same database received, that was unnecessary!");let l;switch(e){case"mongodb":try{switch(await(0,connect_1.checkPackageVersion)("mongodb",3,7)){case"too_low":throw new xplogs_1.XpFatal({function:"migrate.fromDB()",message:"MongoDB V3 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("migrate.fromDB()","MongoDB VERSION IS NEWER THAN TESTED (V7) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("migrate.fromDB()","MongoDB is natively compatible with our package! 🎉");}l=await a.db().collection("simply-xps").find().toArray();}catch(e){return xplogs_1.XpLog.err("migrate.fromDB()",e),!1;}break;case"sqlite":try{switch(await(0,connect_1.checkPackageVersion)("better-sqlite3",7,12)){case"too_low":throw new xplogs_1.XpFatal({function:"migrate.fromDB()",message:"BETTER-SQLITE3 V7 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("migrate.fromDB()","BETTER-SQLITE3 VERSION IS NEWER THAN TESTED (V12) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("migrate.fromDB()","better-sqlite3 is natively compatible with our package! 🎉");}l=a.prepare("SELECT * FROM `simply-xps`").all();}catch(e){return xplogs_1.XpLog.err("migrate.fromDB()",e),!1;}}return xplogs_1.XpLog.debug("migrate.fromDB()",`FOUND ${l.length} RESULTS`),await Promise.all(l.map(async e=>await xp_1.db.findOne({collection:"simply-xps",data:{guild:e.guild,user:e.user}})?xp_1.db.updateOne({collection:"simply-xps",data:{guild:e.guild,user:e.user}},{collection:"simply-xps",data:{guild:e.guild,user:e.user,name:e.name,xp:e.xp,level:e.level}}):xp_1.db.createOne({collection:"simply-xps",data:{guild:e.guild,user:e.user,xp:e.xp,level:e.level}}))),!0;}
19
+ */xplogs_1.XpLog.debug("migrate.discord_xp()",`FOUND ${l.length} DOCUMENTS`);try{for(a of l)await xp_1.db.findOne({collection:"simply-xps",data:{guild:a.guildID,user:a.userID}})||(await xp_1.db.createOne({collection:"simply-xps",data:{guild:a.guildID,user:a.userID,xp:a.xp,level:(0,xp_1.convertFrom)(a.xp,"xp")}}),e&&await xp_1.db.getCollection("levels").deleteOne({userID:a.userID,guildID:a.guildID}));return!0;}catch(e){return xplogs_1.XpLog.err("migrate.discord_xp()",e),!1;}}static async fromDB(e,a){if(!e)throw new xplogs_1.XpFatal({function:"migrate.database()",message:"No database type provided"});if(!a)throw new xplogs_1.XpFatal({function:"migrate.database()",message:"No database connection provided"});if(xp_1.xp.dbType===e)return xplogs_1.XpLog.info("migrate.fromDB()","Same database received, that was unnecessary!");let l;switch(e){case"mongodb":try{switch(await(0,connect_1.checkPackageVersion)("mongodb",3,7)){case"too_low":throw new xplogs_1.XpFatal({function:"migrate.fromDB()",message:"MongoDB V3 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("migrate.fromDB()","MongoDB VERSION IS NEWER THAN TESTED (V7) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("migrate.fromDB()","MongoDB is natively compatible with our package! 🎉");}l=await a.db(xp_1.xp.dbName).collection("simply-xps").find().toArray();}catch(e){return xplogs_1.XpLog.err("migrate.fromDB()",e),!1;}break;case"sqlite":try{switch(await(0,connect_1.checkPackageVersion)("better-sqlite3",7,12)){case"too_low":throw new xplogs_1.XpFatal({function:"migrate.fromDB()",message:"BETTER-SQLITE3 V7 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("migrate.fromDB()","BETTER-SQLITE3 VERSION IS NEWER THAN TESTED (V12) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("migrate.fromDB()","better-sqlite3 is natively compatible with our package! 🎉");}l=a.prepare("SELECT * FROM `simply-xps`").all();}catch(e){return xplogs_1.XpLog.err("migrate.fromDB()",e),!1;}}return xplogs_1.XpLog.debug("migrate.fromDB()",`FOUND ${l.length} RESULTS`),await Promise.all(l.map(async e=>await xp_1.db.findOne({collection:"simply-xps",data:{guild:e.guild,user:e.user}})?xp_1.db.updateOne({collection:"simply-xps",data:{guild:e.guild,user:e.user}},{collection:"simply-xps",data:{guild:e.guild,user:e.user,name:e.name,xp:e.xp,level:e.level}}):xp_1.db.createOne({collection:"simply-xps",data:{guild:e.guild,user:e.user,xp:e.xp,level:e.level}}))),!0;}
20
20
  /**
21
21
  * Effortlessly migrate from roleSetup's schema to LevelRoles schema.
22
22
  * @async
@@ -24,7 +24,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.migrate=exports.M
24
24
  * @param {boolean} keepOld - Keep old data after migration
25
25
  * @returns {Promise<boolean>} - Returns true if migration is successful
26
26
  * @throws {XpLog.err} - If migration fails.
27
- */static async roleSetup(e=!1){var a,l,t,r=await Database_1.Database.findAll("simply-xp-levelroles");xplogs_1.XpLog.debug("migrate.roleSetup()",`FOUND ${r.length} DOCUMENTS`);try{for(a of r)if((l=a.lvlrole)&&!a.levelrole&&(t=Array.isArray(l.role)?l.role:[l.role],await Database_1.Database.createOne({collection:"simply-xp-levelroles",data:{guild:a.guild,levelrole:{level:l.lvl,roles:t}}}),!e))switch(xp_1.xp.dbType){case"mongodb":await Database_1.Database.getCollection("simply-xp-levelroles").deleteOne({guild:a.guild,lvlrole:l});break;case"sqlite":xp_1.xp.database.prepare("DELETE FROM `simply-xp-levelroles` WHERE gid = ? AND lvlrole = ?").run(a.guild,JSON.stringify(l));}return"sqlite"!==xp_1.xp.dbType||e||xp_1.xp.database.exec(`
27
+ */static async roleSetup(e=!1){var a,l,t,r=await Database_1.Database.findAll("simply-xp-levelroles");xplogs_1.XpLog.debug("migrate.roleSetup()",`FOUND ${r.length} DOCUMENTS`);try{for(a of r)if((l=a.lvlrole)&&!a.levelrole&&(t=Array.isArray(l.role)?l.role:[l.role],a.guild)&&(await Database_1.Database.createOne({collection:"simply-xp-levelroles",data:{guild:a.guild,levelrole:{level:l.lvl,roles:t}}}),!e))switch(xp_1.xp.dbType){case"mongodb":await Database_1.Database.getCollection("simply-xp-levelroles").deleteOne({guild:a.guild,lvlrole:l});break;case"sqlite":xp_1.xp.database.prepare("DELETE FROM `simply-xp-levelroles` WHERE gid = ? AND lvlrole = ?").run(a.guild,JSON.stringify(l));}return"sqlite"!==xp_1.xp.dbType||e||xp_1.xp.database.exec(`
28
28
  CREATE TABLE "simply-xp-levelroles_tmp" AS SELECT gid, levelrole, createdAt, lastUpdated FROM "simply-xp-levelroles";
29
29
  DROP TABLE "simply-xp-levelroles";
30
30
  ALTER TABLE "simply-xp-levelroles_tmp" RENAME TO "simply-xp-levelroles";
@@ -1,3 +1,5 @@
1
+ import type { Database as SQLiteDatabase } from "better-sqlite3";
2
+ import type { MongoClient } from "mongodb";
1
3
  export type ConnectionOptions = {
2
4
  auto_clean?: boolean;
3
5
  auto_create?: boolean;
@@ -17,6 +19,15 @@ export type ConnectionOptions = {
17
19
  * @throws {XpFatal} If an invalid type is provided or if the value is not provided.
18
20
  */
19
21
  export declare function connect(uri: string, options?: ConnectionOptions): Promise<boolean>;
22
+ /**
23
+ * @private
24
+ */
25
+ export declare function ensureSqliteSchemaVersion(db: SQLiteDatabase, existingDb?: boolean): number;
26
+ /**
27
+ * Ensures the MongoDB schema version is set and up to date, performs necessary migrations if required
28
+ * @private
29
+ */
30
+ export declare function ensureMongoSchemaVersion(client: MongoClient): Promise<number>;
20
31
  /**
21
32
  * Check database package versions
22
33
  * @private
@@ -8,12 +8,7 @@
8
8
  * @returns {Promise<boolean>}
9
9
  * @throws {XpFatal} If an invalid type is provided or if the value is not provided.
10
10
  */
11
- async function connect(e,t={type:void 0}){var a,{type:o,auto_create:n,auto_clean:r,notify:c,debug:s,xp_rate:p}=t;
12
- /**
13
- * Returns the package manager used
14
- * @private
15
- * @returns {Promise<"yarn" | "npm" | "pnpm">}
16
- */if(!p||"slow"!==p&&"normal"!==p&&"fast"!==p&&isNaN(p)||(xp_1.xp.xp_rate="slow"===p?.05:"normal"===p?.1:"fast"===p?.5:p),!e)throw new xplogs_1.XpFatal({function:"connect()",message:"No URI Provided"});switch(!1===c&&(xp_1.xp.notify=!1),n&&(xp_1.xp.auto_create=!0),r&&(xp_1.xp.auto_clean=!0),s&&(xp_1.xp.debug=!0),o||(t.type="mongodb",xplogs_1.XpLog.warn("connect()","Database type not provided, defaulting to MongoDB")),o){case"mongodb":switch(await checkPackageVersion("mongodb",3,7)){case"too_low":throw new xplogs_1.XpFatal({function:"connect()",message:"MONGODB V3 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("connect()","MONGODB VERSION IS NEWER THAN TESTED (V7) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("connect()","MongoDB is natively compatible with our package! 🎉");}xplogs_1.XpLog.debug("[connect()]","ATTEMPTING MONGODB CONNECTION"),a=await(await Promise.resolve().then(()=>__importStar(require("mongodb")))).MongoClient.connect(e).catch(e=>{throw new xplogs_1.XpFatal({function:"connect()",message:e.message});}),xp_1.xp.dbType="mongodb",xp_1.xp.database=a||void 0;break;case"sqlite":try{switch(await checkPackageVersion("better-sqlite3",7,12)){case"too_low":throw new xplogs_1.XpFatal({function:"connect()",message:"BETTER-SQLITE3 V7 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("connect()","BETTER-SQLITE3 VERSION IS NEWER THAN TESTED (V12) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("connect()","better-sqlite3 is natively compatible with our package! 🎉");}xp_1.xp.database=new(await Promise.resolve().then(()=>__importStar(require("better-sqlite3")))).default(e),xplogs_1.XpLog.info("[connect()]","Successfully connected to SQLite database."),xp_1.xp.dbType="sqlite",xp_1.xp.database.exec(`
11
+ async function connect(e,t={type:void 0}){var a,o,{type:n,auto_create:r,auto_clean:s,notify:l,debug:i,xp_rate:p}=t;if(!p||"slow"!==p&&"normal"!==p&&"fast"!==p&&isNaN(p)||(xp_1.xp.xp_rate="slow"===p?.05:"normal"===p?.1:"fast"===p?.5:p),!e)throw new xplogs_1.XpFatal({function:"connect()",message:"No URI Provided"});switch(!1===l&&(xp_1.xp.notify=!1),r&&(xp_1.xp.auto_create=!0),s&&(xp_1.xp.auto_clean=!0),i&&(xp_1.xp.debug=!0),n||(t.type="mongodb",xplogs_1.XpLog.warn("connect()","Database type not provided, defaulting to MongoDB")),n){case"mongodb":switch(await checkPackageVersion("mongodb",3,7)){case"too_low":throw new xplogs_1.XpFatal({function:"connect()",message:"MONGODB V3 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("connect()","MONGODB VERSION IS NEWER THAN TESTED (V7) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("connect()","MongoDB is natively compatible with our package! 🎉");}xplogs_1.XpLog.debug("[connect()]","ATTEMPTING MONGODB CONNECTION"),o=await(await Promise.resolve().then(()=>__importStar(require("mongodb")))).MongoClient.connect(e).catch(e=>{throw new xplogs_1.XpFatal({function:"connect()",message:e.message});}),xp_1.xp.dbType="mongodb",xp_1.xp.database=o||void 0,xp_1.xp.database&&await ensureMongoSchemaVersion(xp_1.xp.database);break;case"sqlite":try{switch(await checkPackageVersion("better-sqlite3",7,12)){case"too_low":throw new xplogs_1.XpFatal({function:"connect()",message:"BETTER-SQLITE3 V7 OR NEWER IS REQUIRED"});case"too_high":xplogs_1.XpLog.warn("connect()","BETTER-SQLITE3 VERSION IS NEWER THAN TESTED (V12) -- CONTINUE WITH CAUTION");break;case"ok":xplogs_1.XpLog.debug("connect()","better-sqlite3 is natively compatible with our package! 🎉");}xp_1.xp.database=new(await Promise.resolve().then(()=>__importStar(require("better-sqlite3")))).default(e),xplogs_1.XpLog.info("[connect()]","Successfully connected to SQLite database."),xp_1.xp.dbType="sqlite",a=Boolean(xp_1.xp.database.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='simply-xps'").get()),xp_1.xp.database.exec(`
17
12
  CREATE TABLE IF NOT EXISTS "simply-xps" (
18
13
  user TEXT NOT NULL,
19
14
  guild TEXT NOT NULL,
@@ -34,11 +29,12 @@ async function connect(e,t={type:void 0}){var a,{type:o,auto_create:n,auto_clean
34
29
  createdAt DATE NOT NULL DEFAULT (datetime('now')),
35
30
  lastUpdated DATE NOT NULL DEFAULT (datetime('now'))
36
31
  );
37
- `);try{xp_1.xp.database.exec(`
38
- ALTER TABLE "simply-xps" ADD COLUMN createdAt DATE NOT NULL DEFAULT (datetime('now'));
39
- ALTER TABLE "simply-xp-levelroles" ADD COLUMN createdAt DATE NOT NULL DEFAULT (datetime('now'));
40
- ALTER TABLE "simply-xp-levelroles" ADD COLUMN levelrole TEXT NOT NULL DEFAULT '{}';
41
- `);}catch{}}catch(e){if("object"==typeof e&&null!==e&&void 0!==(a=e).code&&"MODULE_NOT_FOUND"!==a.code)throw new xplogs_1.XpFatal({function:"connect()",message:a.message});}break;default:throw new xplogs_1.XpFatal({function:"connect()",message:"DATABASE TYPE NOT PROVIDED OR INVALID"});}return!!xp_1.xp.database&&(xplogs_1.XpLog.info("connect()","Connected to database!"),r&&(0,xp_1.clean)({db:!0}),await xp_1.Database.findAll("simply-xps").then(e=>{e.filter(e=>e?.xp_rate!==xp_1.xp.xp_rate).map(e=>{xp_1.Database.updateOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}},{collection:"simply-xps",data:{user:e.user,guild:e.guild,level:(0,xp_1.convertFrom)(e.xp,"xp"),xp:e.xp,xp_rate:xp_1.xp.xp_rate}});});}),xplogs_1.XpLog.debug("connect()","UPDATED ALL USERS WITH NEW XP RATE"),!0);}async function getPackageManager(){var e,t,a=(await Promise.resolve().then(()=>__importStar(require("fs")))).existsSync;for([e,t]of Object.entries({"yarn.lock":"yarn","pnpm-lock.yaml":"pnpm","pnpm-lock.json":"pnpm","package-lock.json":"npm"}))if(a(e))return xplogs_1.XpLog.debug("getPackageManager()","Using "+t.toUpperCase()),t;return xplogs_1.XpLog.debug("getPackageManager()","No lockfile found, defaulting to NPM"),"npm";}
32
+ `),ensureSqliteSchemaVersion(xp_1.xp.database,a);}catch(e){if("object"==typeof e&&null!==e&&void 0!==(o=e).code&&"MODULE_NOT_FOUND"!==o.code)throw new xplogs_1.XpFatal({function:"connect()",message:o.message});}break;default:throw new xplogs_1.XpFatal({function:"connect()",message:"DATABASE TYPE NOT PROVIDED OR INVALID"});}return!!xp_1.xp.database&&(xplogs_1.XpLog.info("connect()","Connected to database!"),s&&(0,xp_1.clean)({db:!0}),await xp_1.Database.findAll("simply-xps").then(e=>{e.filter(e=>e?.xp_rate!==xp_1.xp.xp_rate).map(e=>{xp_1.Database.updateOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}},{collection:"simply-xps",data:{user:e.user,guild:e.guild,level:(0,xp_1.convertFrom)(e.xp,"xp"),xp:e.xp,xp_rate:xp_1.xp.xp_rate}});});}),xplogs_1.XpLog.debug("connect()","UPDATED ALL USERS WITH NEW XP RATE"),!0);}function ensureSqliteSchemaVersion(e,t){var a=Boolean(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='simply-xp-meta'").get()),o=Boolean(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='simply-xps'").get()),n=Boolean(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='simply-xp-levelroles'").get()),t="boolean"==typeof t?t:o,o=sqliteNeedsV2Migration(e,o,n);if(!a){if(e.exec("CREATE TABLE IF NOT EXISTS \"simply-xp-meta\" (schemaVersion INTEGER NOT NULL)"),!t)return setSqliteSchemaVersion(e,2),2;setSqliteSchemaVersion(e,o?1:2);}let r=getSqliteSchemaVersion(e)||1;return r<2&&o&&(migrateSqliteToV2(e),setSqliteSchemaVersion(e,2),r=2),r<2&&!o&&(setSqliteSchemaVersion(e,2),r=2),r;}function getSqliteSchemaVersion(e){try{var t=e.prepare("SELECT schemaVersion FROM \"simply-xp-meta\" LIMIT 1").get();return"number"==typeof t?.schemaVersion?t.schemaVersion:0;}catch{return 0;}}function setSqliteSchemaVersion(e,t){(e.prepare("SELECT 1 FROM \"simply-xp-meta\" LIMIT 1").get()?e.prepare("UPDATE \"simply-xp-meta\" SET schemaVersion = ?"):e.prepare("INSERT INTO \"simply-xp-meta\" (schemaVersion) VALUES (?)")).run(t);}function sqliteNeedsV2Migration(e,t,a){return!(!t||e.prepare("PRAGMA table_info(\"simply-xps\")").all().some(e=>"createdAt"===e.name))||!(!a||(a=(t=e.prepare("PRAGMA table_info(\"simply-xp-levelroles\")").all()).some(e=>"createdAt"===e.name),e=t.some(e=>"levelrole"===e.name),a&&e));}function migrateSqliteToV2(e){e.prepare("PRAGMA table_info(\"simply-xps\")").all().some(e=>"createdAt"===e.name)||e.exec("ALTER TABLE \"simply-xps\" ADD COLUMN createdAt DATE NOT NULL DEFAULT (datetime('now'));");var t=e.prepare("PRAGMA table_info(\"simply-xp-levelroles\")").all(),a=t.some(e=>"levelrole"===e.name),o=t.some(e=>"lvlrole"===e.name);if(t.some(e=>"createdAt"===e.name)||e.exec("ALTER TABLE \"simply-xp-levelroles\" ADD COLUMN createdAt DATE NOT NULL DEFAULT (datetime('now'));"),!a&&o)try{e.exec("ALTER TABLE \"simply-xp-levelroles\" RENAME COLUMN lvlrole TO levelrole;");}catch{e.exec("ALTER TABLE \"simply-xp-levelroles\" ADD COLUMN levelrole TEXT NOT NULL DEFAULT '{}';");try{e.exec("UPDATE \"simply-xp-levelroles\" SET levelrole = lvlrole WHERE levelrole IS NULL OR levelrole = '{}';");}catch{}}else a||o||e.exec("ALTER TABLE \"simply-xp-levelroles\" ADD COLUMN levelrole TEXT NOT NULL DEFAULT '{}';");}async function ensureMongoSchemaVersion(e){var t=(e=e.db(xp_1.xp.dbName)).collection("simply-xp-meta"),a=await t.findOne({_id:"schema"});return a?"number"==typeof a.schemaVersion?a.schemaVersion:1:(a=await e.listCollections({name:"simply-xps"}).hasNext()?1:2,await t.updateOne({_id:"schema"},{$set:{schemaVersion:a}},{upsert:!0}),a);}
33
+ /**
34
+ * Returns the package manager used
35
+ * @private
36
+ * @returns {Promise<"yarn" | "npm" | "pnpm">}
37
+ */async function getPackageManager(){var e,t;for([e,t]of Object.entries({"yarn.lock":"yarn","pnpm-lock.yaml":"pnpm","pnpm-lock.json":"pnpm","package-lock.json":"npm"}))if((0,fs_1.existsSync)(e))return xplogs_1.XpLog.debug("getPackageManager()","Using "+t.toUpperCase()),t;return xplogs_1.XpLog.debug("getPackageManager()","No lockfile found, defaulting to NPM"),"npm";}
42
38
  /**
43
39
  * Check database package versions
44
40
  * @private
@@ -47,4 +43,4 @@ async function connect(e,t={type:void 0}){var a,{type:o,auto_create:n,auto_clean
47
43
  * @param {number} max - Maximum Major Version Number (Optional)
48
44
  * @returns {Promise<"too_low" | "ok" | "too_high">} - Version Status
49
45
  * @throws {XpFatal} If the package version is not supported
50
- */async function checkPackageVersion(e,t,a){try{var o=await Promise.resolve(e+"/package.json").then(e=>__importStar(require(e))),n=parseInt(o.version.split(".")[0],10);return n<t?"too_low":a&&a<n?"too_high":"ok";}catch(o){return xplogs_1.XpLog.info("checkPackageVersion()",`Installing ${e} [V${a||t}] | Please wait...`),(0,child_process_1.execSync)(await getPackageManager()+` add ${e}@${a||t}.x.x`),xplogs_1.XpLog.warn("checkPackageVersion()",`Installed ${e}. Please restart!`),process.exit(0);}}var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,a,o){void 0===o&&(o=a);var n=Object.getOwnPropertyDescriptor(t,a);n&&("get"in n?t.__esModule:!n.writable&&!n.configurable)||(n={enumerable:!0,get:function(){return t[a];}}),Object.defineProperty(e,o,n);}:function(e,t,a,o){e[o=void 0===o?a:o]=t[a];}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),__importStar=this&&this.__importStar||(()=>{var n=function(e){return(n=Object.getOwnPropertyNames||function(e){var t,a=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(a[a.length]=t);return a;})(e);};return function(e){var t,a,o;if(e&&e.__esModule)return e;if(t={},null!=e)for(a=n(e),o=0;o<a.length;o++)"default"!==a[o]&&__createBinding(t,e,a[o]);return __setModuleDefault(t,e),t;};})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.connect=connect,exports.checkPackageVersion=checkPackageVersion;let xp_1=require("../xp"),xplogs_1=require("./functions/xplogs"),child_process_1=require("child_process");
46
+ */async function checkPackageVersion(e,t,a){try{var o=await Promise.resolve(e+"/package.json").then(e=>__importStar(require(e))),n=parseInt(o.version.split(".")[0],10);return n<t?"too_low":a&&a<n?"too_high":"ok";}catch(o){return xplogs_1.XpLog.info("checkPackageVersion()",`Installing ${e} [V${a||t}] | Please wait...`),(0,child_process_1.execSync)(await getPackageManager()+` add ${e}@${a||t}.x.x`),xplogs_1.XpLog.warn("checkPackageVersion()",`Installed ${e}. Please restart!`),process.exit(0);}}var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,a,o){void 0===o&&(o=a);var n=Object.getOwnPropertyDescriptor(t,a);n&&("get"in n?t.__esModule:!n.writable&&!n.configurable)||(n={enumerable:!0,get:function(){return t[a];}}),Object.defineProperty(e,o,n);}:function(e,t,a,o){e[o=void 0===o?a:o]=t[a];}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),__importStar=this&&this.__importStar||(()=>{var n=function(e){return(n=Object.getOwnPropertyNames||function(e){var t,a=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(a[a.length]=t);return a;})(e);};return function(e){var t,a,o;if(e&&e.__esModule)return e;if(t={},null!=e)for(a=n(e),o=0;o<a.length;o++)"default"!==a[o]&&__createBinding(t,e,a[o]);return __setModuleDefault(t,e),t;};})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.connect=connect,exports.ensureSqliteSchemaVersion=ensureSqliteSchemaVersion,exports.ensureMongoSchemaVersion=ensureMongoSchemaVersion,exports.checkPackageVersion=checkPackageVersion;let xp_1=require("../xp"),xplogs_1=require("./functions/xplogs"),child_process_1=require("child_process"),fs_1=require("fs");
package/lib/src/create.js CHANGED
@@ -8,4 +8,4 @@
8
8
  * @returns {Promise<UserResult>}
9
9
  * @throws {XpFatal} If invalid parameters are provided
10
10
  */
11
- async function create(e,t,r){if(!e)throw new xplogs_1.XpFatal({function:"create()",message:"User ID was not provided"});if(!t)throw new xplogs_1.XpFatal({function:"create()",message:"Guild ID was not provided"});var a;if(r)return await(a=(await Promise.resolve().then(()=>__importStar(require("./classes/Database")))).Database).findOne({collection:"simply-xps",data:{user:e,guild:t}})||a.createOne({collection:"simply-xps",data:{name:r,user:e,guild:t,level:0,xp:0,xp_rate:xp_1.xp.xp_rate}});throw new xplogs_1.XpFatal({function:"create()",message:"Username was not provided"});}var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,a){void 0===a&&(a=r);var n=Object.getOwnPropertyDescriptor(t,r);n&&("get"in n?t.__esModule:!n.writable&&!n.configurable)||(n={enumerable:!0,get:function(){return t[r];}}),Object.defineProperty(e,a,n);}:function(e,t,r,a){e[a=void 0===a?r:a]=t[r];}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),__importStar=this&&this.__importStar||(()=>{var n=function(e){return(n=Object.getOwnPropertyNames||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[r.length]=t);return r;})(e);};return function(e){var t,r,a;if(e&&e.__esModule)return e;if(t={},null!=e)for(r=n(e),a=0;a<r.length;a++)"default"!==r[a]&&__createBinding(t,e,r[a]);return __setModuleDefault(t,e),t;};})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=create;let xplogs_1=require("./functions/xplogs"),xp_1=require("../xp");
11
+ async function create(e,a,t){if(!e)throw new xplogs_1.XpFatal({function:"create()",message:"User ID was not provided"});if(!a)throw new xplogs_1.XpFatal({function:"create()",message:"Guild ID was not provided"});if(t)return await Database_1.Database.findOne({collection:"simply-xps",data:{user:e,guild:a}})||Database_1.Database.createOne({collection:"simply-xps",data:{name:t,user:e,guild:a,level:0,xp:0,xp_rate:xp_1.xp.xp_rate}});throw new xplogs_1.XpFatal({function:"create()",message:"Username was not provided"});}Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=create;let Database_1=require("./classes/Database"),xplogs_1=require("./functions/xplogs"),xp_1=require("../xp");
package/lib/src/fetch.js CHANGED
@@ -8,4 +8,4 @@
8
8
  * @returns {Promise<{name: string | null, user: string, guild: string, level: number, position: number, xp: number}>}
9
9
  * @throws {XpFatal} If invalid parameters are provided, or if the user data is not found.
10
10
  */
11
- async function fetch(t,e,r){var n;if(!t)throw new xplogs_1.XpFatal({function:"create()",message:"User ID was not provided"});if(!e)throw new xplogs_1.XpFatal({function:"create()",message:"Guild ID was not provided"});(0,xp_1.clean)({db:!0});let a=(n=await(await Promise.resolve().then(()=>__importStar(require("./classes/Database")))).db.find("simply-xps",e)).find(e=>e.user===t);if(!a){if(!xp_1.xp.auto_create||!r)throw new xplogs_1.XpFatal({function:"fetch()",message:"User data not found"});a=await(await Promise.resolve().then(()=>__importStar(require("./create")))).create(e,t,r),n.push(a);}return e=n.sort((e,t)=>t.xp-e.xp).findIndex(e=>e.user===t)+1,{flags:a?.flags,guild:a.guild,user:a.user,name:a?.name,level:a.level,position:e,xp:a.xp};}var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);a&&("get"in a?t.__esModule:!a.writable&&!a.configurable)||(a={enumerable:!0,get:function(){return t[r];}}),Object.defineProperty(e,n,a);}:function(e,t,r,n){e[n=void 0===n?r:n]=t[r];}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),__importStar=this&&this.__importStar||(()=>{var a=function(e){return(a=Object.getOwnPropertyNames||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[r.length]=t);return r;})(e);};return function(e){var t,r,n;if(e&&e.__esModule)return e;if(t={},null!=e)for(r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&__createBinding(t,e,r[n]);return __setModuleDefault(t,e),t;};})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.fetch=fetch;let xplogs_1=require("./functions/xplogs"),xp_1=require("../xp");
11
+ async function fetch(a,e,t){var s;if(!a)throw new xplogs_1.XpFatal({function:"create()",message:"User ID was not provided"});if(!e)throw new xplogs_1.XpFatal({function:"create()",message:"Guild ID was not provided"});(0,xp_1.clean)({db:!0});let r=(s=await Database_1.Database.find("simply-xps",e)).find(e=>e.user===a);if(!r){if(!xp_1.xp.auto_create||!t)throw new xplogs_1.XpFatal({function:"fetch()",message:"User data not found"});r=await(0,create_1.create)(e,a,t),s.push(r);}return e=1+s.filter(e=>e.xp>r.xp).length,{flags:r?.flags,guild:r.guild,user:r.user,name:r?.name,level:r.level,position:e,xp:r.xp};}Object.defineProperty(exports,"__esModule",{value:!0}),exports.fetch=fetch;let Database_1=require("./classes/Database"),xplogs_1=require("./functions/xplogs"),xp_1=require("../xp"),create_1=require("./create");
@@ -1,5 +1,5 @@
1
- import { Database } from "better-sqlite3";
2
1
  import { Plugin } from "../../xp";
2
+ import { Database } from "better-sqlite3";
3
3
  import { MongoClient } from "mongodb";
4
4
  /**
5
5
  * Options for clean function.
@@ -16,6 +16,7 @@ type CleanOptions = {
16
16
  * @property {object} dbOptions - The database options.
17
17
  * @property {"mongodb" | "sqlite"} dbOptions.type - The database type.
18
18
  * @property {MongoClient | Database} dbOptions.database - The database connection.
19
+ * @property {string} [dbOptions.name] - MongoDB only: explicit database name. If set, overrides the default derived from the connection URI.
19
20
  * @property {boolean} debug - Whether to enable debug logs.
20
21
  * @property {boolean} notify - Enable/Disable console notifications.
21
22
  * @property {"slow" | "normal" | "fast" | number} xp_rate - The XP rate.
@@ -26,6 +27,7 @@ interface NewClientOptions {
26
27
  dbOptions: {
27
28
  type: "mongodb";
28
29
  database: MongoClient;
30
+ name?: string;
29
31
  } | {
30
32
  type: "sqlite";
31
33
  database: Database;
@@ -6,7 +6,7 @@
6
6
  * @returns {void} - Nothing.
7
7
  * @throws {XpFatal} If an error occurs.
8
8
  */
9
- function clean(e={}){e?.db&&xp_1.xp?.database&&xp_1.db.findAll("simply-xps").then(e=>{e.forEach(async e=>{0===e.level&&0===e.xp&&await xp_1.db.deleteOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}});}),xplogs_1.XpLog.debug("clean()","REMOVED ALL USERS WITHOUT XP");}),(0,canvas_1.clearAllCache)(),xplogs_1.XpLog.debug("clean()","CLEARED CANVAS CACHE");}
9
+ function clean(e={}){e?.db&&xp_1.xp?.database&&xp_1.Database.findAll("simply-xps").then(e=>{e.forEach(async e=>{0===e.level&&0===e.xp&&await xp_1.Database.deleteOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}});}),xplogs_1.XpLog.debug("clean()","REMOVED ALL USERS WITHOUT XP");}),(0,canvas_1.clearAllCache)(),xplogs_1.XpLog.debug("clean()","CLEARED CANVAS CACHE");}
10
10
  /**
11
11
  * Convert XP to level and vice versa.
12
12
  *
@@ -32,7 +32,7 @@ function clean(e={}){e?.db&&xp_1.xp?.database&&xp_1.db.findAll("simply-xps").the
32
32
  * @link `Documentation:` https://simplyxp.js.org/docs/next/Functions/registerPlugins
33
33
  * @returns {void} - Nothing.
34
34
  * @throws {XpFatal} If an invalid plugin is provided.
35
- */function registerPlugins(e){if(!Array.isArray(e))throw new xplogs_1.XpFatal({function:"registerPlugins()",message:"Plugins must be an array"});Promise.all(e.map(async t=>{try{let n=!1,o=!0;if(t?.initialize&&t?.name||(o=!1,xplogs_1.XpLog.warn("registerPlugins()",t?.name?t.name.toUpperCase()+" PLUGIN NOT INITIALIZED: No initialize function provided.":"INVALID PLUGIN PROVIDED")),Array.isArray(t?.requiredVersions)&&!t.requiredVersions.includes(xp_1.xp.version)&&(t.requiredVersions.forEach(e=>{var[t,a,p]=xp_1.xp.version.split(".").map(e=>parseInt(e));return(e=e.match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-[\w\d.-]+)?$/))?o=parseInt(e[1]||"0")===t&&!(e[2]&&parseInt(e[2])!==a||e[3]&&parseInt(e[3])!==p):n=!0;}),n&&xplogs_1.XpLog.warn("registerPlugins()",t.name.toUpperCase()+" PLUGIN FAILED VERSION CHECKS, ANYWAYS..."),!o))return xplogs_1.XpLog.warn("registerPlugins()",t.name.toUpperCase()+" PLUGIN NOT INITIALIZED: Requires: v"+t.requiredVersions.join(", v"));await t.initialize(xp_1.xp),xplogs_1.XpLog.info("registerPlugins()",t.name.toUpperCase()+" PLUGIN INITIALIZED");}catch(e){throw new xplogs_1.XpFatal({function:"registerPlugins()",message:`Failed to register plugin: ${t.name}
35
+ */function registerPlugins(e){if(!Array.isArray(e))throw new xplogs_1.XpFatal({function:"registerPlugins()",message:"Plugins must be an array"});Promise.all(e.map(async t=>{try{let n=!1,s=!0;if(t?.initialize&&t?.name||(s=!1,xplogs_1.XpLog.warn("registerPlugins()",t?.name?t.name.toUpperCase()+" PLUGIN NOT INITIALIZED: No initialize function provided.":"INVALID PLUGIN PROVIDED")),Array.isArray(t?.requiredVersions)&&!t.requiredVersions.includes(xp_1.xp.version)&&(t.requiredVersions.forEach(e=>{var[t,a,p]=xp_1.xp.version.split(".").map(e=>parseInt(e));return(e=e.match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-[\w\d.-]+)?$/))?s=parseInt(e[1]||"0")===t&&!(e[2]&&parseInt(e[2])!==a||e[3]&&parseInt(e[3])!==p):n=!0;}),n&&xplogs_1.XpLog.warn("registerPlugins()",t.name.toUpperCase()+" PLUGIN FAILED VERSION CHECKS, ANYWAYS..."),!s))return xplogs_1.XpLog.warn("registerPlugins()",t.name.toUpperCase()+" PLUGIN NOT INITIALIZED: Requires: v"+t.requiredVersions.join(", v"));await t.initialize(xp_1.xp),xplogs_1.XpLog.info("registerPlugins()",t.name.toUpperCase()+" PLUGIN INITIALIZED");}catch(e){throw new xplogs_1.XpFatal({function:"registerPlugins()",message:`Failed to register plugin: ${t.name}
36
36
  `+e});}}));}
37
37
  /**
38
38
  * Updates the options of the XP client.
@@ -40,4 +40,4 @@ function clean(e={}){e?.db&&xp_1.xp?.database&&xp_1.db.findAll("simply-xps").the
40
40
  * @link `Documentation:` https://simplyxp.js.org/docs/next/Functions/updateOptions
41
41
  * @returns {void} - Nothing.
42
42
  * @throws {XpFatal} If an invalid option is provided.
43
- */function updateOptions(e){if(!e)throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Options were not provided"});if("object"!=typeof e)throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Options must be an object"});if(e?.auto_clean&&(xp_1.xp.auto_clean=!0),e?.auto_create&&(xp_1.xp.auto_create=!0),e?.debug&&(xp_1.xp.debug=!0),e?.notify&&(xp_1.xp.notify=e.notify),e?.xp_rate&&("number"==typeof e.xp_rate||["fast","normal","slow"].includes(e.xp_rate))&&(xp_1.xp.xp_rate="slow"===e.xp_rate?.05:"normal"===e.xp_rate?.1:"fast"===e.xp_rate?.5:e.xp_rate),e.dbOptions&&"object"==typeof e.dbOptions&&e.dbOptions.type&&e.dbOptions.database){var{type:t,database:a}=e.dbOptions;if(!(t&&"mongodb"===t||"sqlite"===t))throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid database type provided"});if(xp_1.xp.dbType=t,a){xp_1.xp.database=a;let t="mongodb"===xp_1.xp.dbType?{name:"MONGODB",type:"mongodb",min:3,max:7}:{name:"BETTER-SQLITE3",type:"better-sqlite3",min:7,max:12};(0,connect_1.checkPackageVersion)(t.type,t.min,t.max).then(e=>{switch(e){case"too_low":throw new xplogs_1.XpFatal({function:"updateOptions()",message:`${t.name} V${t.min} OR NEWER IS REQUIRED`});case"too_high":xplogs_1.XpLog.warn("updateOptions()",`${t.name} VERSION IS NEWER THAN TESTED (V${t.max}) -- CONTINUE WITH CAUTION`);break;case"ok":xplogs_1.XpLog.debug("updateOptions()",t.name+" is natively compatible with our package! 🎉");}switch(xp_1.xp.dbType){case"mongodb":xp_1.xp.database.db().command({ping:1}).catch(()=>{throw xp_1.xp.database=void 0,new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid MongoDB connection"});});break;case"sqlite":try{xp_1.xp.database.prepare("SELECT 1").get();}catch(e){throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid SQLite connection"});}}});}}e?.auto_clean&&clean({db:!0}),xp_1.db.findAll("simply-xps").then(e=>{e.filter(e=>e?.xp_rate!==xp_1.xp.xp_rate).map(async e=>{await xp_1.db.updateOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}},{collection:"simply-xps",data:{user:e.user,guild:e.guild,level:convertFrom(e.xp,"xp"),xp:e.xp,xp_rate:xp_1.xp.xp_rate}});}),xplogs_1.XpLog.debug("updateOptions()","UPDATED ALL USERS WITH NEW XP RATE");});}Object.defineProperty(exports,"__esModule",{value:!0}),exports.clean=clean,exports.convertFrom=convertFrom,exports.registerFont=registerFont,exports.registerPlugins=registerPlugins,exports.updateOptions=updateOptions;let connect_1=require("../connect"),canvas_1=require("@napi-rs/canvas"),xp_1=require("../../xp"),xplogs_1=require("./xplogs");
43
+ */function updateOptions(e){if(!e)throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Options were not provided"});if("object"!=typeof e)throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Options must be an object"});if(e?.auto_clean&&(xp_1.xp.auto_clean=!0),e?.auto_create&&(xp_1.xp.auto_create=!0),e?.debug&&(xp_1.xp.debug=!0),e?.notify&&(xp_1.xp.notify=e.notify),e?.xp_rate&&("number"==typeof e.xp_rate||["fast","normal","slow"].includes(e.xp_rate))&&(xp_1.xp.xp_rate="slow"===e.xp_rate?.05:"normal"===e.xp_rate?.1:"fast"===e.xp_rate?.5:e.xp_rate),e.dbOptions&&"object"==typeof e.dbOptions&&e.dbOptions.type&&e.dbOptions.database){var{type:a,database:p}=e.dbOptions;if(!(a&&"mongodb"===a||"sqlite"===a))throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid database type provided"});if(xp_1.xp.dbType=a,p){xp_1.xp.database=p,"mongodb"===a&&(xp_1.xp.dbName=e.dbOptions.name);let t="mongodb"===xp_1.xp.dbType?{name:"MONGODB",type:"mongodb",min:3,max:7}:{name:"BETTER-SQLITE3",type:"better-sqlite3",min:7,max:12};(0,connect_1.checkPackageVersion)(t.type,t.min,t.max).then(e=>{switch(e){case"too_low":throw new xplogs_1.XpFatal({function:"updateOptions()",message:`${t.name} V${t.min} OR NEWER IS REQUIRED`});case"too_high":xplogs_1.XpLog.warn("updateOptions()",`${t.name} VERSION IS NEWER THAN TESTED (V${t.max}) -- CONTINUE WITH CAUTION`);break;case"ok":xplogs_1.XpLog.debug("updateOptions()",t.name+" is natively compatible with our package! 🎉");}switch(xp_1.xp.dbType){case"mongodb":xp_1.xp.database.db(xp_1.xp.dbName).command({ping:1}).catch(()=>{throw xp_1.xp.database=void 0,new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid MongoDB connection"});}),(0,connect_1.ensureMongoSchemaVersion)(xp_1.xp.database).catch(()=>{});break;case"sqlite":try{xp_1.xp.database.prepare("SELECT 1").get(),(0,connect_1.ensureSqliteSchemaVersion)(xp_1.xp.database);}catch(e){throw new xplogs_1.XpFatal({function:"updateOptions()",message:"Invalid SQLite connection"});}}});}}e?.auto_clean&&clean({db:!0}),xp_1.Database.findAll("simply-xps").then(e=>{e.filter(e=>e?.xp_rate!==xp_1.xp.xp_rate).map(async e=>{await xp_1.Database.updateOne({collection:"simply-xps",data:{user:e.user,guild:e.guild}},{collection:"simply-xps",data:{user:e.user,guild:e.guild,level:convertFrom(e.xp,"xp"),xp:e.xp,xp_rate:xp_1.xp.xp_rate}});}),xplogs_1.XpLog.debug("updateOptions()","UPDATED ALL USERS WITH NEW XP RATE");});}Object.defineProperty(exports,"__esModule",{value:!0}),exports.clean=clean,exports.convertFrom=convertFrom,exports.registerFont=registerFont,exports.registerPlugins=registerPlugins,exports.updateOptions=updateOptions;let connect_1=require("../connect"),canvas_1=require("@napi-rs/canvas"),xp_1=require("../../xp"),xplogs_1=require("./xplogs");
@@ -61,13 +61,13 @@ export declare class XpLog {
61
61
  static warn(xpFunction: string, message: string): void;
62
62
  }
63
63
  export type XpEventCallback = {
64
- custom: (message: string) => void;
65
- debug: (xpFunction: string, message: string) => void;
66
- error: (xpFunction: string, message: string) => void;
67
- info: (xpFunction: string, message: string) => void;
68
- levelDown: (data: UserResult, lostRoles: string[]) => void;
69
- levelUp: (data: UserResult, newRoles: string[]) => void;
70
- warn: (xpFunction: string, message: string) => void;
64
+ custom?: (message: string) => void | Promise<void>;
65
+ debug?: (xpFunction: string, message: string) => void | Promise<void>;
66
+ error?: (xpFunction: string, message: string) => void | Promise<void>;
67
+ info?: (xpFunction: string, message: string) => void | Promise<void>;
68
+ levelDown?: (data: UserResult, lostRoles: string[]) => void | Promise<void>;
69
+ levelUp?: (data: UserResult, newRoles: string[]) => void | Promise<void>;
70
+ warn?: (xpFunction: string, message: string) => void | Promise<void>;
71
71
  };
72
72
  /**
73
73
  * Event handler for XP events
package/lib/xp.d.ts CHANGED
@@ -33,10 +33,24 @@ export interface User {
33
33
  position: number;
34
34
  xp: number;
35
35
  }
36
+ /**
37
+ * Runtime configuration and metadata surface exposed through `xp`.
38
+ * @property {boolean} auto_clean - Automatically clean caches or databases after major operations.
39
+ * @property {boolean} auto_create - Allow functions to create missing users when queried.
40
+ * @property {MongoClient | Database | undefined} database - Underlying database connection reference.
41
+ * @property {string} [dbName] - MongoDB only: explicit database name. When set, used instead of the default derived from the connection URI.
42
+ * @property {"mongodb" | "sqlite"} dbType - The configured database provider.
43
+ * @property {boolean} debug - Emit debug logging via `XpLog.debug`.
44
+ * @property {boolean} notify - Enable console notifications (on by default).
45
+ * @property {string[]} registeredFonts - Fonts already registered for rendering helpers.
46
+ * @property {`${number}.${number}.${number}` | `${number}.${number}.${number}-${string}.${number}`} version - The simply-xp version string baked into the package.
47
+ * @property {number} xp_rate - Global XP rate used in XP ↔︎ level conversions.
48
+ */
36
49
  export interface XPClient {
37
50
  auto_clean: boolean;
38
51
  auto_create: boolean;
39
52
  database: MongoClient | Database | undefined;
53
+ dbName?: string;
40
54
  dbType: "mongodb" | "sqlite";
41
55
  debug: boolean;
42
56
  notify: boolean;
package/lib/xp.js CHANGED
@@ -55,6 +55,6 @@ exports.xp = {
55
55
  debug: false,
56
56
  notify: true,
57
57
  registeredFonts: [],
58
- version: "2.0.0-beta.3",
58
+ version: "2.0.0-beta.4",
59
59
  xp_rate: 0.1
60
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simply-xp",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.4",
4
4
  "description": "The easiest way to implement xp system",
5
5
  "main": "lib/xp.js",
6
6
  "scripts": {
@@ -42,17 +42,17 @@
42
42
  "url": "git+https://github.com/Abadima/simply-xp.git"
43
43
  },
44
44
  "dependencies": {
45
- "@napi-rs/canvas": "0.1.88"
45
+ "@napi-rs/canvas": "0.1.96"
46
46
  },
47
47
  "devDependencies": {
48
- "@eslint/eslintrc": "^3.3.3",
48
+ "@eslint/eslintrc": "^3.3.4",
49
49
  "@types/better-sqlite3": "^7.6.13",
50
- "@types/node": "^25.0.10",
51
- "@typescript-eslint/eslint-plugin": "^8.53.1",
52
- "@typescript-eslint/parser": "^8.53.1",
50
+ "@types/node": "^25.3.3",
51
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
52
+ "@typescript-eslint/parser": "^8.56.1",
53
53
  "better-sqlite3": "^12.6.2",
54
- "eslint": "^9.39.2",
55
- "mongodb": "^7.0.0",
54
+ "eslint": "^9.39.3",
55
+ "mongodb": "^7.1.0",
56
56
  "typescript": "^5.9.3",
57
57
  "uglify-js": "^3.19.3"
58
58
  },