@hokkiai/djs-level-importer 1.0.0

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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "cSpell.words": [
3
+ "tatsu","sokora","hokki","zakahacecosas","amari","lurkr"
4
+ ]
5
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,156 @@
1
+ <!-- markdownlint-disable md024 -->
2
+ <!-- preserve old changelogs here -->
3
+
4
+ # Sokora Changelog
5
+
6
+ ## 0.3.2
7
+
8
+ ## Changed
9
+
10
+ - User can't use any commands in DMs (thanks @userandaname)
11
+ - You can use /user info for people outside of the server
12
+
13
+ ## Fixed
14
+
15
+ - Top.gg reminders are fixed once more, now they should send **only** when you didn't vote
16
+ - Attempt to fix tempbans not unbanning the user due to Sokora not finding them through the cache (by fetching the ban list instead)
17
+ - "Unknown guild" error in serverboard
18
+
19
+ ## Removed
20
+
21
+ - Executor in message delete events
22
+
23
+ ## 0.3.1
24
+
25
+ ## Changed
26
+
27
+ - Made /help, /about, /changelog, /credits, /ping, /settings and /user settings ephemeral (only visible to you)
28
+ - Sokora alerts server owners if they enable but misconfigure showing a server invite in serverboard
29
+
30
+ ## Fixed
31
+
32
+ - Fixed issues with timestamps
33
+ - Fixed some moderation commands "failing" (even though they did the job)
34
+ - Fixed invites for serverboard sometimes silently failing to create or crashing /serverboard
35
+ - Fixed topgg reminders
36
+ - Some internal fixes
37
+
38
+ ## 0.3.0
39
+
40
+ ### Added
41
+
42
+ - New commands.
43
+ - Added a new `/games` category.
44
+ - Added `/games rps` to play Rock, Paper, Scissors.
45
+ - Added `/games coin` to flip a coin.
46
+ - Added a new `/math` category.
47
+ - Added `/math graph` to graphically represent a function.
48
+ - Added `/math calc` to execute a mathematical expression.
49
+ - Added `/help variables` to show help with _Dynamic (variables)_.
50
+ - Added `/ping` to view bot ping and latency.
51
+ - Dynamic (variables)
52
+ - Gave a proper name to replaceable variables (`Dynamic (variables)`), and added more options:
53
+ - - `(serverowner)` - Server owner's name
54
+ - - `(currentdate)` - Current date in the 'July 10, 2025' format
55
+ - - `(currentdate, simple)` - Current date in the '7/10/25' format
56
+ - - `(currentdate, detailed)` - Current date in the 'July 10, 2025, at 1:11 PM' format
57
+ - User settings
58
+ - Added user settings as a feature.
59
+ - Added TopGG reminders setting.
60
+ - Moderation
61
+ - Added the ability to clear messages for a single user.
62
+ - Added reason field to `/moderation unmute`.
63
+ - Added the ability to silently perform moderation actions.
64
+ - Added the ability to view all cases of a server, and to filter by case type.
65
+ - Other additions
66
+ - Added a starboard. It can be configured from `/settings starboard`.
67
+ - Added unique member count to `/about`.
68
+ - Added the ability for server owners to display an invite link to their servers from the serverboard.
69
+ - Easter eggs
70
+ - Added two new easter eggs.
71
+ - Settings
72
+ - Enable/disable specific easter eggs.
73
+ - Enable easter eggs in specific channels only.
74
+ - Give roles to users when they join.
75
+ - Now you can set different channels for join and leave messages.
76
+ - Whether to show an invite to your server or not in serverboard.
77
+ - What channel the invite should point to.
78
+ - Whether all moderation actions should be silent or not.
79
+ - What kind of moderation events should be logged.
80
+ - Settings for the new starboard feature.
81
+ - Channel to send starred messages to, emoji to be reacted, and reaction threshold.
82
+
83
+ ### Changed
84
+
85
+ - Settings were rebuilt into completely new settings panes that allow to change settings from the own embed, without using commands.
86
+
87
+ ### Fixed
88
+
89
+ - News
90
+ - Fixed not being able to delete the first new you create.
91
+ - Moderation
92
+ - Fixed the bot crashing because of too large messages being deleted.
93
+ - Fixed a `Jump to message` option being shown on deleted messages (you cannot jump to a deleted message).
94
+ - Fixed the bot showing "Application didn't respond" when unmuting someone muted by another bot.
95
+ - Fixed the bot unable to send a moderation log when a deleted / edited message is too large. It will instead upload two text files containing old and new messages.
96
+ - _Many other fixes were made, not all of them are tracked._
97
+
98
+ ### Removed
99
+
100
+ - Moderation
101
+ - Removed the ability to add notes on users.
102
+ - Settings
103
+ - Commands to change settings. Use the new embeds to change settings from there.
104
+ - Changelog
105
+ - Changelog itself won't be shown in embeds anymore (it's too long). `/changelog` will show a link to this file.
106
+
107
+ ---
108
+
109
+ ## 0.2.0
110
+
111
+ ### Added
112
+
113
+ #### Commands
114
+
115
+ - `/changelog`
116
+ - `/credits`
117
+ - `/moderation notes`
118
+
119
+ ### Changed
120
+
121
+ - The bot will remove levels when an admin changed the leveling difficulty
122
+ - Now `/leaderboard` shows 6 users per page instead of 5
123
+ - When you add the bot, it sends a message in the system channel
124
+ - Remade the message logs
125
+ - Edit logs will let you jump to the message that got edited
126
+
127
+ #### /settings
128
+
129
+ - Autocompletes with channels/users/roles (you don't have to copy IDs now :tada:)
130
+ - In the embed it will show links to channels/users/roles instead of showing IDs
131
+
132
+ #### /about
133
+
134
+ - Vote button added
135
+ - Moved credits into a different command to reduce the height of the embed
136
+
137
+ ### Fixed
138
+
139
+ #### News
140
+
141
+ - Major issue related to the database, where the guild wasn't provided to ensure that news would be unique to every server, **thank you @Golem642!!!!**
142
+ - `/news` edit's modal errored when sending
143
+
144
+ #### Moderation commands
145
+
146
+ - `/moderation clear` removed one more message than the user provided
147
+ - `/moderation unban` errored internally (it should send an error embed) when the user didn\'t have the "Ban Members" permission
148
+
149
+ ### Typos
150
+
151
+ - warn mentions in `/moderation warn` are now warning to be more consistent
152
+ - Removed old markdown remnants from `/moderation slowdown`
153
+
154
+ ## 0.1.0
155
+
156
+ ### Initial release :)
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2025 ZakaHaceCosas
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # `djs-level-importer`
2
+
3
+ An open, JavaScript-based library to import leveling data from MEE6 and other bots. Made jointly by the [Sokora](https://sokora.org) and [Hokki](https://www.hokki.app) Discord bots.
4
+
5
+ ## Usage
6
+
7
+ Instantiate the `Leveler` class (exported by this package) providing the ID of the guild you want to import data from. Then, call the `GetLeaderboard` method, passing, for example, a `0` for MEE6 (more onto this later on).
8
+
9
+ ```ts
10
+ const leveler = new Leveler({
11
+ guild: "903852579837059113", // your server's ID
12
+ });
13
+
14
+ const leveling_data = await leveler.GetLeaderboard(0);
15
+ ```
16
+
17
+ You will be given an array of objects matching either of these interfaces:
18
+
19
+ ```ts
20
+ export interface BaseUserLevels {
21
+ /** User ID. */
22
+ uid: string;
23
+ /** Current XP **in total**. */
24
+ current_xp: number;
25
+ }
26
+
27
+ export interface FullUserLevels extends BaseUserLevels {
28
+ /** Current XP **relative to the level**. */
29
+ current_lvl_xp: number;
30
+ /** Current level. */
31
+ lvl: number;
32
+ /** XP required to level up. */
33
+ next_lvl_xp: number;
34
+ }
35
+ ```
36
+
37
+ > [!IMPORTANT]
38
+ > **`BaseUserLevels`** objects are returned when importing data from **Tatsu**, and **`FullUserLevels`** are returned when importing data from **MEE6**.
39
+ >
40
+ > This is not the most intuitive, but the best thing we can do to provide you with all _possible_ data despite Tatsu not providing these extra fields that other bots provide.
41
+ >
42
+ > **Bear in mind that extensions to bot support may or may not result in breaking changes to these interfaces** (we'll try to avoid them as much as we can).
43
+
44
+ ## Bot support
45
+
46
+ As of now, MEE6 and Tatsu are supported. Most bots don't document their APIs and it's therefore difficult to add new bots, so no guarantees are made; however we do try to add new bots to this library.
47
+
48
+ **Bots are selected using integers** when calling `GetLeaderboard`. You can check int-bot associations by looking at the exported `SupportedBots` enum. Or just look at it here:
49
+
50
+ ```ts
51
+ export enum SupportedBots {
52
+ MEE6 = 0,
53
+ TATSU = 1,
54
+ }
55
+ ```
56
+
57
+ ### Per bot requirements
58
+
59
+ #### MEE6
60
+
61
+ You need to enable leaderboard visibility from your dashboard. Open the leaderboard settings in the MEE6 dashboard and enable the option `Make my server's leaderboard public`. Otherwise data cannot be imported.
62
+
63
+ #### Tatsu
64
+
65
+ You need an API key, obtained from [this link](https://dev.tatsu.gg/api/reference#authentication) and passed to the constructor via the `tatsu_api` parameter.
66
+
67
+ ```ts
68
+ new Leveler({ guild: "...", tatsu_api: "123ABC..." });
69
+ ```
70
+
71
+ <!-- #### Atlas
72
+
73
+ Nothing is required. -->
74
+
75
+ ## Credits and license
76
+
77
+ Originally made by [ZakaHaceCosas](https://zakahacecosas.github.io/) for the [Hokki](https://www.hokki.app) and [Sokora](https://sokora.org) Discord bots. Made open source under the MIT license for everyone to use, so long as our work is attributed (which'd make us really happy as reverse engineering some APIs was a true pain, to be fair).
78
+
79
+ ---
80
+
81
+ Copyright (c) 2025 ZakaHaceCosas
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
84
+
85
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
86
+
87
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/TODO.txt ADDED
@@ -0,0 +1,15 @@
1
+ [DONE] indicates the bot being supported.
2
+ >[WIP] indicates the bot being actively worked on.
3
+ *[NXT] indicates the bot is to be added. Asterisk can be:
4
+ + likely to be worked on at some point
5
+ ? wanted to implement, but viability is not fully investigated
6
+ - unlikely to be implemented, but noted here as a known and not-yet-discarded leveling bot
7
+
8
+ [DONE] MEE6
9
+ [DONE] Tatsu
10
+ >[WIP] Atlas
11
+ +[NXT] Polaris
12
+ ?[NXT] Amari
13
+ ?[NXT] Arcane
14
+ ?[NXT] Lurkr
15
+ -[NXT] CarlBot
package/bun.lock ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "djs-level-importer",
7
+ "dependencies": {
8
+ "tatsu": "latest",
9
+ },
10
+ "devDependencies": {
11
+ "@types/bun": "latest",
12
+ },
13
+ },
14
+ },
15
+ "packages": {
16
+ "@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
17
+
18
+ "@types/node": ["@types/node@16.18.126", "", {}, "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw=="],
19
+
20
+ "bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="],
21
+
22
+ "tatsu": ["tatsu@1.2.0", "", { "dependencies": { "@types/node": "^16.11.19", "typescript": "^4.5.4" } }, "sha512-7iN50ZvwVisD1e8Q4NPboOE2UzwxB+Ex9N5UZIrWvC1N2giauw68gcU+pOExjOwgLiDy83PP2i7J6mGN4AM3HQ=="],
23
+
24
+ "typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="],
25
+
26
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
27
+
28
+ "bun-types/@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
29
+ }
30
+ }
package/fknode.yaml ADDED
@@ -0,0 +1,3 @@
1
+ prettyScript: "prettier"
2
+ flagless:
3
+ flaglessPretty: true
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@hokkiai/djs-level-importer",
3
+ "version": "1.0.0",
4
+ "description": "An open, JavaScript-based library to import leveling data from MEE6 and other bots. Made jointly by the Sokora and Hokki Discord bots.",
5
+ "type": "module",
6
+ "homepage": "https://github.com/hokkiai/djs-level-importer",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "keywords": [
16
+ "discord",
17
+ "discord.js",
18
+ "levels",
19
+ "importer",
20
+ "discord leveling"
21
+ ],
22
+ "author": {
23
+ "name": "ZakaHaceCosas",
24
+ "email": "zakahacecosas@protonmail.com",
25
+ "url": "https://zakahacecosas.github.io"
26
+ },
27
+ "contributors": [
28
+ {
29
+ "name": "The Sokora Discord bot",
30
+ "url": "https://sokora.org"
31
+ },
32
+ {
33
+ "name": "The Hokki Discord bot",
34
+ "url": "https://www.hokki.app"
35
+ }
36
+ ],
37
+ "license": "MIT",
38
+ "dependencies": {
39
+ "tatsu": "latest"
40
+ },
41
+ "devDependencies": {
42
+ "@types/bun": "latest"
43
+ }
44
+ }
package/src/main.ts ADDED
@@ -0,0 +1,108 @@
1
+ import { MEE6GetLeaderboard } from "./mee6.js";
2
+ import { TATSUGetLeaderboard } from "./tatsu.js";
3
+
4
+ /** A user/guild ID. MEE6 has a slightly inconsistent way of telling you this, as far as I know. */
5
+ export type Identifier = string | { id: string };
6
+
7
+ /**
8
+ * Resolves a user/guild ID from the MEE6 (or any) API.
9
+ *
10
+ * @param {Identifier} id ID
11
+ * @returns {string} Resolved ID
12
+ */
13
+ export function GET_ID(id: Identifier): string {
14
+ if (typeof id === "string") return id;
15
+ else if (typeof id.id === "string") return id.id;
16
+ else throw new Error("Invalid Identifier specified: " + id);
17
+ }
18
+
19
+ /**
20
+ * A user's leveling information, in a common format **with minimal data**. Required for compat with lesser capable bots like Tatsu.
21
+ *
22
+ * @interface BaseUserLevels
23
+ */
24
+ export interface BaseUserLevels {
25
+ /** User ID. */
26
+ uid: string;
27
+ /** Current XP **in total**. */
28
+ current_xp: number;
29
+ }
30
+
31
+ /**
32
+ * A user's leveling information, in a common format **with levels and rank up**.
33
+ *
34
+ * @interface FullUserLevels
35
+ */
36
+ export interface FullUserLevels extends BaseUserLevels {
37
+ /** Current XP **relative to the level**. */
38
+ current_lvl_xp: number;
39
+ /** Current level. */
40
+ lvl: number;
41
+ /** XP required to level up. */
42
+ next_lvl_xp: number;
43
+ }
44
+
45
+ /** Type-guards if you're on MEE6, basically. */
46
+ export function SUPPORTS_LEVELS(a: any): a is FullUserLevels {
47
+ return a.lvl && a.lvl !== undefined && typeof a.lvl === "number";
48
+ }
49
+
50
+ /**
51
+ * Supported Discord bots
52
+ *
53
+ * ```ts
54
+ * MEE6 = 0,
55
+ * TATSU = 1
56
+ * ```
57
+ * @enum {number}
58
+ */
59
+ export enum SupportedBots {
60
+ MEE6 = 0,
61
+ TATSU = 1,
62
+ }
63
+
64
+ export class Leveler {
65
+ private guild: string;
66
+ private tatsu_api: string | null = null;
67
+
68
+ /**
69
+ * Creates an instance of a Leveler, with which you'll be able to import leveling data from supported bots.
70
+ *
71
+ * @constructor
72
+ * @param {string} guild Guild ID.
73
+ * @param {?string} tatsu_api If importing from Tatsu, you need to bring in your own API key. This is free and pretty easy to get from the Tatsu bot itself.
74
+ */
75
+ constructor(options: { guild: string; tatsu_api?: string }) {
76
+ this.guild = options.guild;
77
+ if (options.tatsu_api) this.tatsu_api = options.tatsu_api;
78
+ }
79
+
80
+ /** Gets the whole server leaderboard from MEE6. Throws if unable to get it. */
81
+ public async GetLeaderboard(
82
+ target: SupportedBots.MEE6,
83
+ ): Promise<FullUserLevels[]>;
84
+ /** Gets the whole server leaderboard from Tatsu. Throws if unable to get it. */
85
+ public async GetLeaderboard(target: SupportedBots.TATSU): Promise<BaseUserLevels[]>;
86
+ public async GetLeaderboard(target: SupportedBots): Promise<BaseUserLevels[] | FullUserLevels[]> {
87
+ if (target === SupportedBots.MEE6) {
88
+ const levels = await MEE6GetLeaderboard(this.guild);
89
+ return levels.map(u => {
90
+ return {
91
+ uid: u.id,
92
+ lvl: u.level,
93
+ current_xp: u.xp.totalXp,
94
+ current_lvl_xp: u.xp.userXp,
95
+ next_lvl_xp: u.xp.levelXp,
96
+ };
97
+ });
98
+ } else {
99
+ const levels = await TATSUGetLeaderboard(this.tatsu_api, this.guild);
100
+ return levels.rankings.map(r => {
101
+ return {
102
+ uid: r.user_id,
103
+ current_xp: r.score,
104
+ };
105
+ });
106
+ }
107
+ }
108
+ }
package/src/mee6.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { GET_ID, Identifier } from "./main.js";
2
+
3
+ interface MEE6User {
4
+ id: string;
5
+ level: number;
6
+ xp: {
7
+ userXp: number;
8
+ levelXp: number;
9
+ totalXp: number;
10
+ };
11
+ }
12
+
13
+ /**
14
+ * Get a page of the leaderboard of a guild.
15
+ * @param {Identifier} guild Guild to get the leaderboard from.
16
+ * @param {number} limit Limit of users to fetch per page. Maximum 1000.
17
+ * @param {number} page Number of pages to skip.
18
+ * @returns {Promise<MEE6User[]>} Leaderboard page.
19
+ */
20
+ async function getLeaderboardPage(
21
+ guild: Identifier,
22
+ limit: number = 1000,
23
+ page: number = 0,
24
+ ): Promise<MEE6User[]> {
25
+ const guildId = GET_ID(guild);
26
+ const response = await fetch(
27
+ `https://mee6.xyz/api/plugins/levels/leaderboard/${guildId}?limit=${limit}&page=${page}`,
28
+ { method: "GET" },
29
+ );
30
+ const j = (await response.json()) as any;
31
+ if (response.status !== 200) {
32
+ if (j.error && j.error.message) throw new Error(`${response.status}: ${j.error.message}`);
33
+ else throw new Error(`${response.status}: ${response.statusText}`);
34
+ }
35
+ return j.players.map((user: any) => {
36
+ const { id, level } = user;
37
+ const [userXp, levelXp, totalXp] = user.detailed_xp;
38
+ return {
39
+ id,
40
+ level,
41
+ xp: { userXp, levelXp, totalXp },
42
+ };
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Get the leaderboard of a guild.
48
+ * @param {Identifier} guild Guild to get the leaderboard from.
49
+ * @returns {Promise<MEE6User[]>} Leaderboard of the guild.
50
+ */
51
+ export async function MEE6GetLeaderboard(guild: Identifier): Promise<MEE6User[]> {
52
+ const leaderboard = [];
53
+ let pageNumber = 0;
54
+ while (true) {
55
+ const page = await getLeaderboardPage(guild, 1000, pageNumber);
56
+ leaderboard.push(...page);
57
+ if (page.length < 1000) break;
58
+ pageNumber += 1;
59
+ }
60
+ return leaderboard;
61
+ }
package/src/tatsu.ts ADDED
@@ -0,0 +1,19 @@
1
+ // thanks tatsu for caring to make a package
2
+ import { GuildRankings, Tatsu } from "tatsu";
3
+
4
+ /**
5
+ * Get the leaderboard of a guild.
6
+ *
7
+ * @async
8
+ * @param {(string | null)} tkn API token for Tatsu.
9
+ * @param {string} guildId Guild to get the leaderboard from.
10
+ * @returns {Promise<GuildRankings>} Leaderboard of the guild.
11
+ */
12
+ export async function TATSUGetLeaderboard(
13
+ tkn: string | null,
14
+ guildId: string,
15
+ ): Promise<GuildRankings> {
16
+ if (!tkn) throw `No Tatsu API key provided. Cannot use Tatsu API.`;
17
+ const tatsu = new Tatsu(tkn);
18
+ return await tatsu.getGuildRankings(guildId);
19
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2024",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+
7
+ "outDir": "dist",
8
+ "declaration": true,
9
+
10
+ "strict": true,
11
+ "esModuleInterop": true,
12
+ "strictNullChecks": true,
13
+ "strictBindCallApply": true,
14
+ "strictFunctionTypes": true,
15
+ "strictBuiltinIteratorReturn": true,
16
+ "strictPropertyInitialization": true,
17
+ "noImplicitAny": true,
18
+ "noImplicitOverride": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noPropertyAccessFromIndexSignature": true,
22
+ "noUncheckedIndexedAccess": true,
23
+ "noUncheckedSideEffectImports": true,
24
+ "noImplicitThis": true,
25
+ "noImplicitReturns": true,
26
+ "noFallthroughCasesInSwitch": true,
27
+ "forceConsistentCasingInFileNames": true,
28
+ "exactOptionalPropertyTypes": true,
29
+ "useUnknownInCatchVariables": true,
30
+ "allowArbitraryExtensions": true,
31
+ "skipLibCheck": true,
32
+ "lib": [
33
+ "ES2024"
34
+ ]
35
+ },
36
+ "include": [
37
+ "src/"
38
+ ],
39
+ "exclude": ["node_modules/"],
40
+ "buildOptions": {
41
+ "incremental": true
42
+ }
43
+ }