aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2021-09-06 21:06:22 +0000
committerGitHub <noreply@github.com>2021-09-06 21:06:22 +0000
commit487f208565894f332ca58c13e1b208c3beb9c8c6 (patch)
treeb3209e94cc63658b5430bc1949b80140cc27efe4
parent4f03cb71b30978b277ff292dbddeba182117a7cb (diff)
downloadskyblock-api-487f208565894f332ca58c13e1b208c3beb9c8c6.tar.gz
skyblock-api-487f208565894f332ca58c13e1b208c3beb9c8c6.tar.bz2
skyblock-api-487f208565894f332ca58c13e1b208c3beb9c8c6.zip
Bump node-fetch from 2.6.1 to 3.0.0 (#116)
* Bump node-fetch from 2.6.1 to 3.0.0 Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 3.0.0. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v3.0.0) --- updated-dependencies: - dependency-name: node-fetch dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix issues with node fetch 3.0 * change module to esnext instead of commonjs * fix imports and tests * fix package-lock.json Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mat <github@matdoes.dev> Co-authored-by: mat <27899617+mat-1@users.noreply.github.com>
-rw-r--r--.github/workflows/test.yml2
-rw-r--r--build/cleaners/player.js23
-rw-r--r--build/cleaners/rank.js18
-rw-r--r--build/cleaners/skyblock/bank.js9
-rw-r--r--build/cleaners/skyblock/collections.js19
-rw-r--r--build/cleaners/skyblock/fairysouls.js13
-rw-r--r--build/cleaners/skyblock/inventory.js64
-rw-r--r--build/cleaners/skyblock/itemId.js9
-rw-r--r--build/cleaners/skyblock/member.js73
-rw-r--r--build/cleaners/skyblock/minions.js42
-rw-r--r--build/cleaners/skyblock/objectives.js8
-rw-r--r--build/cleaners/skyblock/profile.js54
-rw-r--r--build/cleaners/skyblock/profiles.js17
-rw-r--r--build/cleaners/skyblock/skills.js12
-rw-r--r--build/cleaners/skyblock/slayers.js19
-rw-r--r--build/cleaners/skyblock/stats.js23
-rw-r--r--build/cleaners/skyblock/zones.js8
-rw-r--r--build/cleaners/socialmedia.js11
-rw-r--r--build/constants.js110
-rw-r--r--build/database.js202
-rw-r--r--build/discord.js24
-rw-r--r--build/hypixel.js101
-rw-r--r--build/hypixelApi.js45
-rw-r--r--build/hypixelCached.js204
-rw-r--r--build/index.js74
-rw-r--r--build/mojang.js50
-rw-r--r--build/util.js29
-rw-r--r--package-lock.json2287
-rw-r--r--package.json16
-rw-r--r--src/cleaners/player.ts12
-rw-r--r--src/cleaners/rank.ts4
-rw-r--r--src/cleaners/skyblock/collections.ts2
-rw-r--r--src/cleaners/skyblock/member.ts34
-rw-r--r--src/cleaners/skyblock/minions.ts4
-rw-r--r--src/cleaners/skyblock/profile.ts10
-rw-r--r--src/cleaners/skyblock/profiles.ts4
-rw-r--r--src/cleaners/skyblock/skills.ts2
-rw-r--r--src/constants.ts19
-rw-r--r--src/database.ts23
-rw-r--r--src/discord.ts4
-rw-r--r--src/hypixel.ts28
-rw-r--r--src/hypixelApi.ts8
-rw-r--r--src/hypixelCached.ts12
-rw-r--r--src/index.ts10
-rw-r--r--src/mojang.ts16
-rw-r--r--test/test.js44
-rw-r--r--tsconfig.json7
47 files changed, 2852 insertions, 957 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index d797ab9..ed1fc94 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,7 +9,7 @@ jobs:
uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
- node-version: '14.15.0'
+ node-version: '16.0.0'
- run: npm install
- name: Run tests
diff --git a/build/cleaners/player.js b/build/cleaners/player.js
index 42c76b8..214be1f 100644
--- a/build/cleaners/player.js
+++ b/build/cleaners/player.js
@@ -1,22 +1,17 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanPlayerResponse = void 0;
-const profiles_1 = require("./skyblock/profiles");
-const socialmedia_1 = require("./socialmedia");
-const rank_1 = require("./rank");
-const util_1 = require("../util");
-async function cleanPlayerResponse(data) {
- var _a, _b;
+import { cleanPlayerSkyblockProfiles } from './skyblock/profiles.js';
+import { cleanSocialMedia } from './socialmedia.js';
+import { cleanRank } from './rank.js';
+import { undashUuid } from '../util.js';
+export async function cleanPlayerResponse(data) {
// Cleans up a 'player' api response
if (!data)
return null; // bruh
return {
- uuid: util_1.undashUuid(data.uuid),
+ uuid: undashUuid(data.uuid),
username: data.displayname,
- rank: rank_1.cleanRank(data),
- socials: socialmedia_1.cleanSocialMedia(data),
+ rank: cleanRank(data),
+ socials: cleanSocialMedia(data),
// first_join: data.firstLogin / 1000,
- profiles: profiles_1.cleanPlayerSkyblockProfiles((_b = (_a = data.stats) === null || _a === void 0 ? void 0 : _a.SkyBlock) === null || _b === void 0 ? void 0 : _b.profiles)
+ profiles: cleanPlayerSkyblockProfiles(data.stats?.SkyBlock?.profiles)
};
}
-exports.cleanPlayerResponse = cleanPlayerResponse;
diff --git a/build/cleaners/rank.js b/build/cleaners/rank.js
index 19e4938..1d80d2c 100644
--- a/build/cleaners/rank.js
+++ b/build/cleaners/rank.js
@@ -1,7 +1,4 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanRank = void 0;
-const util_1 = require("../util");
+import { colorCodeFromName, minecraftColorCodes } from '../util.js';
const rankColors = {
'NONE': '7',
'VIP': 'a',
@@ -16,15 +13,14 @@ const rankColors = {
'ADMIN': 'c'
};
/** Response cleaning (reformatting to be nicer) */
-function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusColor, rank, prefix }) {
- var _a;
+export function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusColor, rank, prefix }) {
let name;
let color;
let colored;
let bracketColor;
if (prefix) { // derive values from prefix
colored = prefix;
- color = util_1.minecraftColorCodes[colored.match(/§./)[0][1]];
+ color = minecraftColorCodes[colored.match(/§./)[0][1]];
name = colored.replace(/§./g, '').replace(/[\[\]]/g, '');
}
else {
@@ -33,7 +29,8 @@ function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusCo
else if (rank && rank !== 'NORMAL')
name = rank;
else
- name = (_a = newPackageRank === null || newPackageRank === void 0 ? void 0 : newPackageRank.replace('_PLUS', '+')) !== null && _a !== void 0 ? _a : packageRank === null || packageRank === void 0 ? void 0 : packageRank.replace('_PLUS', '+');
+ name = newPackageRank?.replace('_PLUS', '+')
+ ?? packageRank?.replace('_PLUS', '+');
switch (name) {
// MVP++ is called Superstar for some reason
case 'SUPERSTAR':
@@ -54,8 +51,8 @@ function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusCo
name = 'NONE';
break;
}
- const plusColor = rankPlusColor ? util_1.colorCodeFromName(rankPlusColor) : null;
- color = util_1.minecraftColorCodes[rankColors[name]];
+ const plusColor = rankPlusColor ? colorCodeFromName(rankPlusColor) : null;
+ color = minecraftColorCodes[rankColors[name]];
let rankColorPrefix = rankColors[name] ? '§' + rankColors[name] : '';
// the text is white, but only in the prefix
if (name === 'YOUTUBE')
@@ -82,4 +79,3 @@ function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusCo
colored
};
}
-exports.cleanRank = cleanRank;
diff --git a/build/cleaners/skyblock/bank.js b/build/cleaners/skyblock/bank.js
index 9836685..fb08af5 100644
--- a/build/cleaners/skyblock/bank.js
+++ b/build/cleaners/skyblock/bank.js
@@ -1,13 +1,8 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanBank = void 0;
-function cleanBank(data) {
- var _a, _b;
+export function cleanBank(data) {
return {
- balance: (_b = (_a = data === null || data === void 0 ? void 0 : data.banking) === null || _a === void 0 ? void 0 : _a.balance) !== null && _b !== void 0 ? _b : 0,
+ balance: data?.banking?.balance ?? 0,
// TODO: make transactions good
// history: data?.banking?.transactions ?? []
history: []
};
}
-exports.cleanBank = cleanBank;
diff --git a/build/cleaners/skyblock/collections.js b/build/cleaners/skyblock/collections.js
index 0bb4cb5..4a5b34e 100644
--- a/build/cleaners/skyblock/collections.js
+++ b/build/cleaners/skyblock/collections.js
@@ -1,7 +1,4 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanCollections = void 0;
-const itemId_1 = require("./itemId");
+import { cleanItemId } from './itemId.js';
const COLLECTIONS = {
'farming': [
'wheat',
@@ -83,15 +80,14 @@ function getCategory(collectionName) {
return categoryName;
}
}
-function cleanCollections(data) {
- var _a, _b, _c;
+export function cleanCollections(data) {
// collection tiers show up like this: [ GRAVEL_3, GOLD_INGOT_2, MELON_-1, LOG_2:1_7, RAW_FISH:3_-1]
// these tiers are the same for all players in a coop
- const playerCollectionTiersRaw = (_a = data === null || data === void 0 ? void 0 : data.unlocked_coll_tiers) !== null && _a !== void 0 ? _a : [];
+ const playerCollectionTiersRaw = data?.unlocked_coll_tiers ?? [];
const playerCollectionTiers = {};
for (const collectionTierNameValueRaw of playerCollectionTiersRaw) {
const [collectionTierNameRaw, collectionTierValueRaw] = collectionTierNameValueRaw.split(/_(?=-?\d+$)/);
- const collectionName = itemId_1.cleanItemId(collectionTierNameRaw);
+ const collectionName = cleanItemId(collectionTierNameRaw);
// ensure it's at least 0
const collectionValue = Math.max(parseInt(collectionTierValueRaw), 0);
// if the collection hasn't been checked yet, or the new value is higher than the old, replace it
@@ -100,13 +96,13 @@ function cleanCollections(data) {
}
// collection names show up like this: { LOG: 49789, LOG:2: 26219, MUSHROOM_COLLECTION: 2923}
// these values are different for each player in a coop
- const playerCollectionXpsRaw = (_b = data === null || data === void 0 ? void 0 : data.collection) !== null && _b !== void 0 ? _b : {};
+ const playerCollectionXpsRaw = data?.collection ?? {};
const playerCollections = [];
for (const collectionNameRaw in playerCollectionXpsRaw) {
const collectionXp = playerCollectionXpsRaw[collectionNameRaw];
- const collectionName = itemId_1.cleanItemId(collectionNameRaw);
+ const collectionName = cleanItemId(collectionNameRaw);
const collectionLevel = playerCollectionTiers[collectionName];
- const collectionCategory = (_c = getCategory(collectionName)) !== null && _c !== void 0 ? _c : 'unknown';
+ const collectionCategory = getCategory(collectionName) ?? 'unknown';
// in some very weird cases the collection level will be undefined, we should ignore these collections
if (collectionLevel !== undefined)
playerCollections.push({
@@ -118,4 +114,3 @@ function cleanCollections(data) {
}
return playerCollections;
}
-exports.cleanCollections = cleanCollections;
diff --git a/build/cleaners/skyblock/fairysouls.js b/build/cleaners/skyblock/fairysouls.js
index 1c6cef6..8ec8078 100644
--- a/build/cleaners/skyblock/fairysouls.js
+++ b/build/cleaners/skyblock/fairysouls.js
@@ -1,12 +1,7 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanFairySouls = void 0;
-function cleanFairySouls(data) {
- var _a, _b, _c;
+export function cleanFairySouls(data) {
return {
- total: (_a = data === null || data === void 0 ? void 0 : data.fairy_souls_collected) !== null && _a !== void 0 ? _a : 0,
- unexchanged: (_b = data === null || data === void 0 ? void 0 : data.fairy_souls) !== null && _b !== void 0 ? _b : 0,
- exchanges: (_c = data === null || data === void 0 ? void 0 : data.fairy_exchanges) !== null && _c !== void 0 ? _c : 0,
+ total: data?.fairy_souls_collected ?? 0,
+ unexchanged: data?.fairy_souls ?? 0,
+ exchanges: data?.fairy_exchanges ?? 0,
};
}
-exports.cleanFairySouls = cleanFairySouls;
diff --git a/build/cleaners/skyblock/inventory.js b/build/cleaners/skyblock/inventory.js
index 098b8d4..714a302 100644
--- a/build/cleaners/skyblock/inventory.js
+++ b/build/cleaners/skyblock/inventory.js
@@ -1,32 +1,9 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanInventories = exports.INVENTORIES = exports.cleanInventory = void 0;
// maybe todo?: create a fast replacement for prismarine-nbt
-const nbt = __importStar(require("prismarine-nbt"));
+import * as nbt from 'prismarine-nbt';
function base64decode(base64) {
return Buffer.from(base64, 'base64');
}
function cleanItem(rawItem) {
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
// if the item doesn't have an id, it isn't an item
if (rawItem.id === undefined)
return null;
@@ -34,13 +11,13 @@ function cleanItem(rawItem) {
const itemCount = rawItem.Count;
const damageValue = rawItem.Damage;
const itemTag = rawItem.tag;
- const extraAttributes = (_a = itemTag === null || itemTag === void 0 ? void 0 : itemTag.ExtraAttributes) !== null && _a !== void 0 ? _a : {};
+ const extraAttributes = itemTag?.ExtraAttributes ?? {};
let headId;
if (vanillaId === 397) {
- const headDataBase64 = (_e = (_d = (_c = (_b = itemTag === null || itemTag === void 0 ? void 0 : itemTag.SkullOwner) === null || _b === void 0 ? void 0 : _b.Properties) === null || _c === void 0 ? void 0 : _c.textures) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.Value;
+ const headDataBase64 = itemTag?.SkullOwner?.Properties?.textures?.[0]?.Value;
if (headDataBase64) {
const headData = JSON.parse(base64decode(headDataBase64).toString());
- const headDataUrl = (_g = (_f = headData === null || headData === void 0 ? void 0 : headData.textures) === null || _f === void 0 ? void 0 : _f.SKIN) === null || _g === void 0 ? void 0 : _g.url;
+ const headDataUrl = headData?.textures?.SKIN?.url;
if (headDataUrl) {
const splitUrl = headDataUrl.split('/');
headId = splitUrl[splitUrl.length - 1];
@@ -48,26 +25,26 @@ function cleanItem(rawItem) {
}
}
return {
- id: (_h = extraAttributes === null || extraAttributes === void 0 ? void 0 : extraAttributes.id) !== null && _h !== void 0 ? _h : null,
- count: itemCount !== null && itemCount !== void 0 ? itemCount : 1,
+ id: extraAttributes?.id ?? null,
+ count: itemCount ?? 1,
vanillaId: damageValue ? `${vanillaId}:${damageValue}` : vanillaId.toString(),
display: {
- name: (_k = (_j = itemTag === null || itemTag === void 0 ? void 0 : itemTag.display) === null || _j === void 0 ? void 0 : _j.Name) !== null && _k !== void 0 ? _k : 'null',
- lore: (_m = (_l = itemTag === null || itemTag === void 0 ? void 0 : itemTag.display) === null || _l === void 0 ? void 0 : _l.Lore) !== null && _m !== void 0 ? _m : [],
+ name: itemTag?.display?.Name ?? 'null',
+ lore: itemTag?.display?.Lore ?? [],
// if it has an ench value in the tag, then it should have an enchant glint effect
- glint: ((_o = itemTag === null || itemTag === void 0 ? void 0 : itemTag.ench) !== null && _o !== void 0 ? _o : []).length > 0
+ glint: (itemTag?.ench ?? []).length > 0
},
- reforge: extraAttributes === null || extraAttributes === void 0 ? void 0 : extraAttributes.modifier,
- enchantments: extraAttributes === null || extraAttributes === void 0 ? void 0 : extraAttributes.enchantments,
- anvil_uses: extraAttributes === null || extraAttributes === void 0 ? void 0 : extraAttributes.anvil_uses,
- timestamp: extraAttributes === null || extraAttributes === void 0 ? void 0 : extraAttributes.timestamp,
+ reforge: extraAttributes?.modifier,
+ enchantments: extraAttributes?.enchantments,
+ anvil_uses: extraAttributes?.anvil_uses,
+ timestamp: extraAttributes?.timestamp,
head_texture: headId,
};
}
function cleanItems(rawItems) {
return rawItems.map(cleanItem);
}
-function cleanInventory(encodedNbt) {
+export function cleanInventory(encodedNbt) {
return new Promise(resolve => {
const base64Data = base64decode(encodedNbt);
nbt.parse(base64Data, false, (err, value) => {
@@ -77,8 +54,7 @@ function cleanInventory(encodedNbt) {
});
});
}
-exports.cleanInventory = cleanInventory;
-exports.INVENTORIES = {
+export const INVENTORIES = {
armor: 'inv_armor',
inventory: 'inv_contents',
ender_chest: 'ender_chest_contents',
@@ -89,12 +65,11 @@ exports.INVENTORIES = {
trick_or_treat_bag: 'candy_inventory_contents',
wardrobe: 'wardrobe_contents'
};
-async function cleanInventories(data) {
- var _a;
+export async function cleanInventories(data) {
const cleanInventories = {};
- for (const cleanInventoryName in exports.INVENTORIES) {
- const hypixelInventoryName = exports.INVENTORIES[cleanInventoryName];
- const encodedInventoryContents = (_a = data[hypixelInventoryName]) === null || _a === void 0 ? void 0 : _a.data;
+ for (const cleanInventoryName in INVENTORIES) {
+ const hypixelInventoryName = INVENTORIES[cleanInventoryName];
+ const encodedInventoryContents = data[hypixelInventoryName]?.data;
let inventoryContents;
if (encodedInventoryContents) {
inventoryContents = await cleanInventory(encodedInventoryContents);
@@ -106,4 +81,3 @@ async function cleanInventories(data) {
}
return cleanInventories;
}
-exports.cleanInventories = cleanInventories;
diff --git a/build/cleaners/skyblock/itemId.js b/build/cleaners/skyblock/itemId.js
index 7bf5402..ea94771 100644
--- a/build/cleaners/skyblock/itemId.js
+++ b/build/cleaners/skyblock/itemId.js
@@ -1,6 +1,3 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanItemId = void 0;
// change weird item names to be more consistent with vanilla
const ITEMS = {
'log': 'oak_log',
@@ -55,8 +52,6 @@ const ITEMS = {
'enchanted_glistering_melon': 'enchanted_glistering_melon_slice'
};
/** Clean an item with a weird name (log_2:1) and make it have a better name (dark_oak_log) */
-function cleanItemId(itemId) {
- var _a;
- return (_a = ITEMS[itemId.toLowerCase()]) !== null && _a !== void 0 ? _a : itemId.toLowerCase();
+export function cleanItemId(itemId) {
+ return ITEMS[itemId.toLowerCase()] ?? itemId.toLowerCase();
}
-exports.cleanItemId = cleanItemId;
diff --git a/build/cleaners/skyblock/member.js b/build/cleaners/skyblock/member.js
index cc66488..2242828 100644
--- a/build/cleaners/skyblock/member.js
+++ b/build/cleaners/skyblock/member.js
@@ -1,37 +1,15 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSkyBlockProfileMemberResponse = exports.cleanSkyBlockProfileMemberResponseBasic = void 0;
-const collections_1 = require("./collections");
-const inventory_1 = require("./inventory");
-const fairysouls_1 = require("./fairysouls");
-const objectives_1 = require("./objectives");
-const stats_1 = require("./stats");
-const minions_1 = require("./minions");
-const slayers_1 = require("./slayers");
-const zones_1 = require("./zones");
-const skills_1 = require("./skills");
-const cached = __importStar(require("../../hypixelCached"));
-const constants = __importStar(require("../../constants"));
-async function cleanSkyBlockProfileMemberResponseBasic(member) {
+import { cleanCollections } from './collections.js';
+import { cleanInventories } from './inventory.js';
+import { cleanFairySouls } from './fairysouls.js';
+import { cleanObjectives } from './objectives.js';
+import { cleanProfileStats } from './stats.js';
+import { cleanMinions } from './minions.js';
+import { cleanSlayers } from './slayers.js';
+import { cleanVisitedZones } from './zones.js';
+import { cleanSkills } from './skills.js';
+import * as cached from '../../hypixelCached.js';
+import * as constants from '../../constants.js';
+export async function cleanSkyBlockProfileMemberResponseBasic(member) {
const player = await cached.fetchPlayer(member.uuid);
if (!player)
return null;
@@ -43,18 +21,16 @@ async function cleanSkyBlockProfileMemberResponseBasic(member) {
rank: player.rank
};
}
-exports.cleanSkyBlockProfileMemberResponseBasic = cleanSkyBlockProfileMemberResponseBasic;
/** Cleans up a member (from skyblock/profile) */
-async function cleanSkyBlockProfileMemberResponse(member, included = undefined) {
- var _a;
+export async function cleanSkyBlockProfileMemberResponse(member, included = undefined) {
// profiles.members[]
const inventoriesIncluded = included === undefined || included.includes('inventories');
const player = await cached.fetchPlayer(member.uuid);
if (!player)
return null;
- const fairySouls = fairysouls_1.cleanFairySouls(member);
+ const fairySouls = cleanFairySouls(member);
const { max_fairy_souls: maxFairySouls } = await constants.fetchConstantValues();
- if (fairySouls.total > (maxFairySouls !== null && maxFairySouls !== void 0 ? maxFairySouls : 0))
+ if (fairySouls.total > (maxFairySouls ?? 0))
await constants.setConstantValues({ max_fairy_souls: fairySouls.total });
return {
uuid: member.uuid,
@@ -63,17 +39,16 @@ async function cleanSkyBlockProfileMemberResponse(member, included = undefined)
first_join: member.first_join / 1000,
rank: player.rank,
purse: member.coin_purse,
- stats: stats_1.cleanProfileStats(member),
+ stats: cleanProfileStats(member),
// this is used for leaderboards
- rawHypixelStats: (_a = member.stats) !== null && _a !== void 0 ? _a : {},
- minions: await minions_1.cleanMinions(member),
+ rawHypixelStats: member.stats ?? {},
+ minions: await cleanMinions(member),
fairy_souls: fairySouls,
- inventories: inventoriesIncluded ? await inventory_1.cleanInventories(member) : undefined,
- objectives: objectives_1.cleanObjectives(member),
- skills: await skills_1.cleanSkills(member),
- visited_zones: zones_1.cleanVisitedZones(member),
- collections: collections_1.cleanCollections(member),
- slayers: slayers_1.cleanSlayers(member)
+ inventories: inventoriesIncluded ? await cleanInventories(member) : undefined,
+ objectives: cleanObjectives(member),
+ skills: await cleanSkills(member),
+ visited_zones: cleanVisitedZones(member),
+ collections: cleanCollections(member),
+ slayers: cleanSlayers(member)
};
}
-exports.cleanSkyBlockProfileMemberResponse = cleanSkyBlockProfileMemberResponse;
diff --git a/build/cleaners/skyblock/minions.js b/build/cleaners/skyblock/minions.js
index d2bfc41..5c0bd9a 100644
--- a/build/cleaners/skyblock/minions.js
+++ b/build/cleaners/skyblock/minions.js
@@ -1,36 +1,13 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.countUniqueMinions = exports.combineMinionArrays = exports.cleanMinions = void 0;
-const hypixel_1 = require("../../hypixel");
-const constants = __importStar(require("../../constants"));
+import { maxMinion } from '../../hypixel.js';
+import * as constants from '../../constants.js';
/**
* Clean the minions provided by Hypixel
* @param minionsRaw The minion data provided by the Hypixel API
*/
-async function cleanMinions(member) {
- var _a;
+export async function cleanMinions(member) {
const minions = [];
const processedMinionNames = new Set();
- for (const minionRaw of (_a = member === null || member === void 0 ? void 0 : member.crafted_generators) !== null && _a !== void 0 ? _a : []) {
+ for (const minionRaw of member?.crafted_generators ?? []) {
// do some regex magic to get the minion name and level
// examples of potential minion names: CLAY_11, PIG_1, MAGMA_CUBE_4
const minionName = minionRaw.split(/_\d/)[0].toLowerCase();
@@ -40,7 +17,7 @@ async function cleanMinions(member) {
// if the minion doesnt already exist in the minions array, then create it
matchingMinion = {
name: minionName,
- levels: new Array(hypixel_1.maxMinion).fill(false)
+ levels: new Array(maxMinion).fill(false)
};
minions.push(matchingMinion);
}
@@ -63,18 +40,17 @@ async function cleanMinions(member) {
processedMinionNames.add(minionName);
minions.push({
name: minionName,
- levels: new Array(hypixel_1.maxMinion).fill(false)
+ levels: new Array(maxMinion).fill(false)
});
}
}
return minions.sort((a, b) => a.name > b.name ? 1 : (a.name < b.name ? -1 : 0));
}
-exports.cleanMinions = cleanMinions;
/**
* Combine multiple arrays of minions into one, useful when getting the minions for members
* @param minions An array of arrays of minions
*/
-function combineMinionArrays(minions) {
+export function combineMinionArrays(minions) {
const resultMinions = [];
for (const memberMinions of minions) {
for (const minion of memberMinions) {
@@ -99,8 +75,7 @@ function combineMinionArrays(minions) {
}
return resultMinions;
}
-exports.combineMinionArrays = combineMinionArrays;
-function countUniqueMinions(minions) {
+export function countUniqueMinions(minions) {
let uniqueMinions = 0;
for (const minion of minions) {
// find the number of times `true` is in the list and add it to uniqueMinions
@@ -108,4 +83,3 @@ function countUniqueMinions(minions) {
}
return uniqueMinions;
}
-exports.countUniqueMinions = countUniqueMinions;
diff --git a/build/cleaners/skyblock/objectives.js b/build/cleaners/skyblock/objectives.js
index d45307c..52e92db 100644
--- a/build/cleaners/skyblock/objectives.js
+++ b/build/cleaners/skyblock/objectives.js
@@ -1,8 +1,5 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanObjectives = void 0;
-function cleanObjectives(data) {
- const rawObjectives = (data === null || data === void 0 ? void 0 : data.objectives) || {};
+export function cleanObjectives(data) {
+ const rawObjectives = data?.objectives || {};
const objectives = [];
for (const rawObjectiveName in rawObjectives) {
const rawObjectiveValue = rawObjectives[rawObjectiveName];
@@ -13,4 +10,3 @@ function cleanObjectives(data) {
}
return objectives;
}
-exports.cleanObjectives = cleanObjectives;
diff --git a/build/cleaners/skyblock/profile.js b/build/cleaners/skyblock/profile.js
index 6460c3b..42e26b3 100644
--- a/build/cleaners/skyblock/profile.js
+++ b/build/cleaners/skyblock/profile.js
@@ -1,38 +1,16 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSkyblockProfileResponse = exports.cleanSkyblockProfileResponseLighter = void 0;
-const member_1 = require("./member");
-const minions_1 = require("./minions");
-const bank_1 = require("./bank");
-const constants = __importStar(require("../../constants"));
+import { cleanSkyBlockProfileMemberResponse, cleanSkyBlockProfileMemberResponseBasic } from './member.js';
+import { combineMinionArrays, countUniqueMinions } from './minions.js';
+import * as constants from '../../constants.js';
+import { cleanBank } from './bank.js';
/** Return a `CleanProfile` instead of a `CleanFullProfile`, useful when we need to get members but don't want to waste much ram */
-async function cleanSkyblockProfileResponseLighter(data) {
+export async function cleanSkyblockProfileResponseLighter(data) {
// We use Promise.all so it can fetch all the usernames at once instead of waiting for the previous promise to complete
const promises = [];
for (const memberUUID in data.members) {
const memberRaw = data.members[memberUUID];
memberRaw.uuid = memberUUID;
// we pass an empty array to make it not check stats
- promises.push(member_1.cleanSkyBlockProfileMemberResponseBasic(memberRaw));
+ promises.push(cleanSkyBlockProfileMemberResponseBasic(memberRaw));
}
const cleanedMembers = (await Promise.all(promises)).filter(m => m);
return {
@@ -41,11 +19,10 @@ async function cleanSkyblockProfileResponseLighter(data) {
members: cleanedMembers,
};
}
-exports.cleanSkyblockProfileResponseLighter = cleanSkyblockProfileResponseLighter;
/**
* This function is somewhat costly and shouldn't be called often. Use cleanSkyblockProfileResponseLighter if you don't need all the data
*/
-async function cleanSkyblockProfileResponse(data, options) {
+export async function cleanSkyblockProfileResponse(data, options) {
// We use Promise.all so it can fetch all the users at once instead of waiting for the previous promise to complete
const promises = [];
if (!data)
@@ -53,13 +30,13 @@ async function cleanSkyblockProfileResponse(data, options) {
for (const memberUUID in data.members) {
const memberRaw = data.members[memberUUID];
memberRaw.uuid = memberUUID;
- promises.push(member_1.cleanSkyBlockProfileMemberResponse(memberRaw, [
- !(options === null || options === void 0 ? void 0 : options.basic) ? 'stats' : undefined,
- (options === null || options === void 0 ? void 0 : options.mainMemberUuid) === memberUUID ? 'inventories' : undefined
+ promises.push(cleanSkyBlockProfileMemberResponse(memberRaw, [
+ !options?.basic ? 'stats' : undefined,
+ options?.mainMemberUuid === memberUUID ? 'inventories' : undefined
]));
}
const cleanedMembers = (await Promise.all(promises)).filter(m => m !== null && m !== undefined);
- if (options === null || options === void 0 ? void 0 : options.basic) {
+ if (options?.basic) {
return {
uuid: data.profile_id,
name: data.cute_name,
@@ -70,19 +47,18 @@ async function cleanSkyblockProfileResponse(data, options) {
for (const member of cleanedMembers) {
memberMinions.push(member.minions);
}
- const minions = minions_1.combineMinionArrays(memberMinions);
+ const minions = combineMinionArrays(memberMinions);
const { max_minions: maxUniqueMinions } = await constants.fetchConstantValues();
- const uniqueMinions = minions_1.countUniqueMinions(minions);
- if (uniqueMinions > (maxUniqueMinions !== null && maxUniqueMinions !== void 0 ? maxUniqueMinions : 0))
+ const uniqueMinions = countUniqueMinions(minions);
+ if (uniqueMinions > (maxUniqueMinions ?? 0))
await constants.setConstantValues({ max_minions: uniqueMinions });
// return more detailed info
return {
uuid: data.profile_id,
name: data.cute_name,
members: cleanedMembers,
- bank: bank_1.cleanBank(data),
+ bank: cleanBank(data),
minions: minions,
minion_count: uniqueMinions
};
}
-exports.cleanSkyblockProfileResponse = cleanSkyblockProfileResponse;
diff --git a/build/cleaners/skyblock/profiles.js b/build/cleaners/skyblock/profiles.js
index b916209..a85b1f3 100644
--- a/build/cleaners/skyblock/profiles.js
+++ b/build/cleaners/skyblock/profiles.js
@@ -1,10 +1,7 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSkyblockProfilesResponse = exports.cleanPlayerSkyblockProfiles = void 0;
-const profile_1 = require("./profile");
-function cleanPlayerSkyblockProfiles(rawProfiles) {
+import { cleanSkyblockProfileResponse } from './profile.js';
+export function cleanPlayerSkyblockProfiles(rawProfiles) {
let profiles = [];
- for (const profile of Object.values(rawProfiles !== null && rawProfiles !== void 0 ? rawProfiles : {})) {
+ for (const profile of Object.values(rawProfiles ?? {})) {
profiles.push({
uuid: profile.profile_id,
name: profile.cute_name
@@ -12,15 +9,13 @@ function cleanPlayerSkyblockProfiles(rawProfiles) {
}
return profiles;
}
-exports.cleanPlayerSkyblockProfiles = cleanPlayerSkyblockProfiles;
/** Convert an array of raw profiles into clean profiles */
-async function cleanSkyblockProfilesResponse(data) {
+export async function cleanSkyblockProfilesResponse(data) {
const promises = [];
- for (const profile of data !== null && data !== void 0 ? data : []) {
+ for (const profile of data ?? []) {
// let cleanedProfile = await cleanSkyblockProfileResponseLighter(profile)
- promises.push(profile_1.cleanSkyblockProfileResponse(profile));
+ promises.push(cleanSkyblockProfileResponse(profile));
}
const cleanedProfiles = (await Promise.all(promises)).filter(p => p);
return cleanedProfiles;
}
-exports.cleanSkyblockProfilesResponse = cleanSkyblockProfilesResponse;
diff --git a/build/cleaners/skyblock/skills.js b/build/cleaners/skyblock/skills.js
index 2518d60..e9b19f8 100644
--- a/build/cleaners/skyblock/skills.js
+++ b/build/cleaners/skyblock/skills.js
@@ -1,6 +1,3 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSkills = exports.levelForSkillXp = void 0;
// the highest level you can have in each skill
// numbers taken from https://hypixel-skyblock.fandom.com/wiki/Skills
const skillsMaxLevel = {
@@ -113,21 +110,19 @@ const skillsDefaultMaxLevel = 50;
* @param xp The xp we're finding the level for
* @param easierLevel Whether it should use the alternate leveling xp table (used for cosmetic skills and dungeoneering)
*/
-function levelForSkillXp(xp, maxLevel) {
+export function levelForSkillXp(xp, maxLevel) {
const xpTable = (maxLevel <= 25 ? skillXpTableEasier : skillXpTable).slice(0, maxLevel);
const skillLevel = [...xpTable].reverse().findIndex(levelXp => xp >= levelXp);
return skillLevel === -1 ? 0 : xpTable.length - skillLevel;
}
-exports.levelForSkillXp = levelForSkillXp;
-async function cleanSkills(data) {
- var _a;
+export async function cleanSkills(data) {
const skills = [];
for (const item in data) {
if (item.startsWith('experience_skill_')) {
const skillName = item.substr('experience_skill_'.length);
// the amount of total xp you have in this skill
const skillXp = data[item];
- const skillMaxLevel = (_a = skillsMaxLevel[skillName]) !== null && _a !== void 0 ? _a : skillsDefaultMaxLevel;
+ const skillMaxLevel = skillsMaxLevel[skillName] ?? skillsDefaultMaxLevel;
const xpTable = (skillMaxLevel <= 25 ? skillXpTableEasier : skillXpTable).slice(0, skillMaxLevel);
// the level you're at for this skill
const skillLevel = levelForSkillXp(skillXp, skillMaxLevel);
@@ -149,4 +144,3 @@ async function cleanSkills(data) {
}
return skills;
}
-exports.cleanSkills = cleanSkills;
diff --git a/build/cleaners/skyblock/slayers.js b/build/cleaners/skyblock/slayers.js
index 8575d43..75894f7 100644
--- a/build/cleaners/skyblock/slayers.js
+++ b/build/cleaners/skyblock/slayers.js
@@ -1,30 +1,26 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSlayers = exports.slayerLevels = void 0;
-exports.slayerLevels = 5;
+export const slayerLevels = 5;
const SLAYER_NAMES = {
spider: 'tarantula',
zombie: 'revenant',
wolf: 'sven'
};
-function cleanSlayers(data) {
- var _a, _b;
+export function cleanSlayers(data) {
const slayers = [];
- const slayersDataRaw = data === null || data === void 0 ? void 0 : data.slayer_bosses;
+ const slayersDataRaw = data?.slayer_bosses;
let totalXp = 0;
let totalKills = 0;
for (const slayerNameRaw in slayersDataRaw) {
const slayerDataRaw = slayersDataRaw[slayerNameRaw];
// convert name provided by api (spider) to the real name (tarantula)
const slayerName = SLAYER_NAMES[slayerNameRaw];
- const slayerXp = (_a = slayerDataRaw.xp) !== null && _a !== void 0 ? _a : 0;
+ const slayerXp = slayerDataRaw.xp ?? 0;
let slayerKills = 0;
const slayerTiers = [];
for (const slayerDataKey in slayerDataRaw) {
// if a key starts with boss_kills_tier_ (boss_kills_tier_1), get the last number
if (slayerDataKey.startsWith('boss_kills_tier_')) {
const slayerTierRaw = parseInt(slayerDataKey.substr('boss_kills_tier_'.length));
- const slayerTierKills = (_b = slayerDataRaw[slayerDataKey]) !== null && _b !== void 0 ? _b : 0;
+ const slayerTierKills = slayerDataRaw[slayerDataKey] ?? 0;
// add 1 since hypixel is using 0 indexed tiers
const slayerTier = slayerTierRaw + 1;
slayerTiers.push({
@@ -37,7 +33,7 @@ function cleanSlayers(data) {
}
}
// if the slayer tier length is less than the max, add more empty ones
- while (slayerTiers.length < exports.slayerLevels)
+ while (slayerTiers.length < slayerLevels)
slayerTiers.push({
tier: slayerTiers.length + 1,
kills: 0
@@ -46,7 +42,7 @@ function cleanSlayers(data) {
name: slayerName,
raw_name: slayerNameRaw,
tiers: slayerTiers,
- xp: slayerXp !== null && slayerXp !== void 0 ? slayerXp : 0,
+ xp: slayerXp ?? 0,
kills: slayerKills
};
slayers.push(slayer);
@@ -62,4 +58,3 @@ function cleanSlayers(data) {
bosses: slayers
};
}
-exports.cleanSlayers = cleanSlayers;
diff --git a/build/cleaners/skyblock/stats.js b/build/cleaners/skyblock/stats.js
index 1f72201..361f1ba 100644
--- a/build/cleaners/skyblock/stats.js
+++ b/build/cleaners/skyblock/stats.js
@@ -1,6 +1,3 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanProfileStats = exports.getStatUnit = exports.statUnits = exports.categorizeStat = void 0;
const statCategories = {
'deaths': ['deaths_', 'deaths'],
'kills': ['kills_', 'kills'],
@@ -13,7 +10,7 @@ const statCategories = {
'slayer': ['slayer_'],
'misc': null // everything else goes here
};
-function categorizeStat(statNameRaw) {
+export function categorizeStat(statNameRaw) {
// 'deaths_void'
for (const statCategory in statCategories) {
// 'deaths'
@@ -56,15 +53,14 @@ function categorizeStat(statNameRaw) {
name: statNameRaw
};
}
-exports.categorizeStat = categorizeStat;
-exports.statUnits = {
+export const statUnits = {
time: ['_best_time', '_best_time_2'],
date: ['first_join'],
coins: ['purse'],
leaderboards: ['leaderboards_count', 'top_1_leaderboards_count']
};
-function getStatUnit(name) {
- for (const [unitName, statMatchers] of Object.entries(exports.statUnits)) {
+export function getStatUnit(name) {
+ for (const [unitName, statMatchers] of Object.entries(statUnits)) {
for (const statMatch of statMatchers) {
let trailingEnd = statMatch[0] === '_';
let trailingStart = statMatch.substr(-1) === '_';
@@ -76,23 +72,20 @@ function getStatUnit(name) {
}
return null;
}
-exports.getStatUnit = getStatUnit;
-function cleanProfileStats(data) {
- var _a, _b;
+export function cleanProfileStats(data) {
// TODO: add type for statsRaw (probably in hypixelApi.ts since its coming from there)
const stats = [];
- const rawStats = (_a = data === null || data === void 0 ? void 0 : data.stats) !== null && _a !== void 0 ? _a : {};
+ const rawStats = data?.stats ?? {};
for (const statNameRaw in rawStats) {
const statValue = rawStats[statNameRaw];
let { category: statCategory, name: statName } = categorizeStat(statNameRaw);
stats.push({
- categorizedName: statName !== null && statName !== void 0 ? statName : 'total',
+ categorizedName: statName ?? 'total',
value: statValue,
rawName: statNameRaw,
category: statCategory,
- unit: (_b = getStatUnit(statNameRaw)) !== null && _b !== void 0 ? _b : null
+ unit: getStatUnit(statNameRaw) ?? null
});
}
return stats;
}
-exports.cleanProfileStats = cleanProfileStats;
diff --git a/build/cleaners/skyblock/zones.js b/build/cleaners/skyblock/zones.js
index fb79441..ef7015e 100644
--- a/build/cleaners/skyblock/zones.js
+++ b/build/cleaners/skyblock/zones.js
@@ -1,8 +1,5 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanVisitedZones = void 0;
-function cleanVisitedZones(data) {
- const rawZones = (data === null || data === void 0 ? void 0 : data.visited_zones) || [];
+export function cleanVisitedZones(data) {
+ const rawZones = data?.visited_zones || [];
// TODO: store all the zones that exist in SkyBlock, add add those to the array with visited being false
const zones = [];
for (const rawZoneName of rawZones) {
@@ -13,4 +10,3 @@ function cleanVisitedZones(data) {
}
return zones;
}
-exports.cleanVisitedZones = cleanVisitedZones;
diff --git a/build/cleaners/socialmedia.js b/build/cleaners/socialmedia.js
index 4883cc4..c901725 100644
--- a/build/cleaners/socialmedia.js
+++ b/build/cleaners/socialmedia.js
@@ -1,11 +1,6 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.cleanSocialMedia = void 0;
-function cleanSocialMedia(data) {
- var _a, _b, _c, _d;
+export function cleanSocialMedia(data) {
return {
- discord: ((_b = (_a = data === null || data === void 0 ? void 0 : data.socialMedia) === null || _a === void 0 ? void 0 : _a.links) === null || _b === void 0 ? void 0 : _b.DISCORD) || null,
- forums: ((_d = (_c = data === null || data === void 0 ? void 0 : data.socialMedia) === null || _c === void 0 ? void 0 : _c.links) === null || _d === void 0 ? void 0 : _d.HYPIXEL) || null
+ discord: data?.socialMedia?.links?.DISCORD || null,
+ forums: data?.socialMedia?.links?.HYPIXEL || null
};
}
-exports.cleanSocialMedia = cleanSocialMedia;
diff --git a/build/constants.js b/build/constants.js
index 414a6c5..7dcb210 100644
--- a/build/constants.js
+++ b/build/constants.js
@@ -1,46 +1,21 @@
-"use strict";
/**
* Fetch and edit constants from the skyblock-constants repo
*/
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.setConstantValues = exports.fetchConstantValues = exports.addMinions = exports.fetchSkillXpEasier = exports.fetchSkillXp = exports.fetchMinions = exports.addSlayers = exports.fetchSlayers = exports.addZones = exports.fetchZones = exports.addSkills = exports.fetchSkills = exports.addCollections = exports.fetchCollections = exports.addStats = exports.fetchStats = exports.addJSONConstants = exports.fetchJSONConstant = void 0;
// we have to do this so we can mock the function from the tests properly
-const constants = __importStar(require("./constants"));
-const node_cache_1 = __importDefault(require("node-cache"));
-const queue_promise_1 = __importDefault(require("queue-promise"));
-const node_fetch_1 = __importDefault(require("node-fetch"));
-const https_1 = require("https");
-const _1 = require(".");
-const httpsAgent = new https_1.Agent({
+import * as constants from './constants.js';
+import NodeCache from 'node-cache';
+import { debug } from './index.js';
+import Queue from 'queue-promise';
+import fetch from 'node-fetch';
+import { Agent } from 'https';
+const httpsAgent = new Agent({
keepAlive: true
});
const githubApiBase = 'https://api.github.com';
const owner = 'skyblockstats';
const repo = 'skyblock-constants';
// we use a queue for editing so it always utilizes the cache if possible, and to avoid hitting the github rateimit
-const queue = new queue_promise_1.default({
+const queue = new Queue({
concurrent: 1,
interval: 10
});
@@ -53,9 +28,9 @@ const queue = new queue_promise_1.default({
*/
async function fetchGithubApi(method, route, headers, json) {
try {
- if (_1.debug)
+ if (debug)
console.debug('fetching github api', method, route);
- const data = await node_fetch_1.default(githubApiBase + route, {
+ const data = await fetch(githubApiBase + route, {
agent: () => httpsAgent,
body: json ? JSON.stringify(json) : undefined,
method,
@@ -63,7 +38,7 @@ async function fetchGithubApi(method, route, headers, json) {
'Authorization': `token ${process.env.github_token}`
}, headers),
});
- if (_1.debug)
+ if (debug)
console.debug('fetched github api', method, route);
return data;
}
@@ -74,7 +49,7 @@ async function fetchGithubApi(method, route, headers, json) {
}
}
// cache files for an hour
-const fileCache = new node_cache_1.default({
+const fileCache = new NodeCache({
stdTTL: 60 * 60,
checkperiod: 60,
useClones: false,
@@ -122,7 +97,7 @@ async function editFile(file, message, newContent) {
sha: data.content.sha
});
}
-async function fetchJSONConstant(filename) {
+export let fetchJSONConstant = async function fetchJSONConstant(filename) {
const file = await fetchFile(filename);
try {
return JSON.parse(file.content);
@@ -131,10 +106,9 @@ async function fetchJSONConstant(filename) {
// probably invalid json, return an empty array
return [];
}
-}
-exports.fetchJSONConstant = fetchJSONConstant;
+};
/** Add stats to skyblock-constants. This has caching so it's fine to call many times */
-async function addJSONConstants(filename, addingValues, unit = 'stat') {
+export let addJSONConstants = async function addJSONConstants(filename, addingValues, unit = 'stat') {
if (addingValues.length === 0)
return; // no stats provided, just return
let file = await fetchFile(filename);
@@ -166,81 +140,65 @@ async function addJSONConstants(filename, addingValues, unit = 'stat') {
file = await fetchFile(filename);
await editFile(file, commitMessage, JSON.stringify(updatedStats, null, 2));
}
-}
-exports.addJSONConstants = addJSONConstants;
+};
/** Fetch all the known SkyBlock stats as an array of strings */
-async function fetchStats() {
+export async function fetchStats() {
return await constants.fetchJSONConstant('stats.json');
}
-exports.fetchStats = fetchStats;
/** Add stats to skyblock-constants. This has caching so it's fine to call many times */
-async function addStats(addingStats) {
+export async function addStats(addingStats) {
await constants.addJSONConstants('stats.json', addingStats, 'stat');
}
-exports.addStats = addStats;
/** Fetch all the known SkyBlock collections as an array of strings */
-async function fetchCollections() {
+export async function fetchCollections() {
return await constants.fetchJSONConstant('collections.json');
}
-exports.fetchCollections = fetchCollections;
/** Add collections to skyblock-constants. This has caching so it's fine to call many times */
-async function addCollections(addingCollections) {
+export async function addCollections(addingCollections) {
await constants.addJSONConstants('collections.json', addingCollections, 'collection');
}
-exports.addCollections = addCollections;
/** Fetch all the known SkyBlock collections as an array of strings */
-async function fetchSkills() {
+export async function fetchSkills() {
return await constants.fetchJSONConstant('skills.json');
}
-exports.fetchSkills = fetchSkills;
/** Add skills to skyblock-constants. This has caching so it's fine to call many times */
-async function addSkills(addingSkills) {
+export async function addSkills(addingSkills) {
await constants.addJSONConstants('skills.json', addingSkills, 'skill');
}
-exports.addSkills = addSkills;
/** Fetch all the known SkyBlock collections as an array of strings */
-async function fetchZones() {
+export async function fetchZones() {
return await constants.fetchJSONConstant('zones.json');
}
-exports.fetchZones = fetchZones;
/** Add skills to skyblock-constants. This has caching so it's fine to call many times */
-async function addZones(addingZones) {
+export async function addZones(addingZones) {
await constants.addJSONConstants('zones.json', addingZones, 'zone');
}
-exports.addZones = addZones;
/** Fetch all the known SkyBlock slayer names as an array of strings */
-async function fetchSlayers() {
+export async function fetchSlayers() {
return await constants.fetchJSONConstant('slayers.json');
}
-exports.fetchSlayers = fetchSlayers;
/** Add skills to skyblock-constants. This has caching so it's fine to call many times */
-async function addSlayers(addingSlayers) {
+export async function addSlayers(addingSlayers) {
await constants.addJSONConstants('slayers.json', addingSlayers, 'slayer');
}
-exports.addSlayers = addSlayers;
/** Fetch all the known SkyBlock slayer names as an array of strings */
-async function fetchMinions() {
+export async function fetchMinions() {
return await constants.fetchJSONConstant('minions.json');
}
-exports.fetchMinions = fetchMinions;
-async function fetchSkillXp() {
+export async function fetchSkillXp() {
return await constants.fetchJSONConstant('manual/skill_xp.json');
}
-exports.fetchSkillXp = fetchSkillXp;
-async function fetchSkillXpEasier() {
+export async function fetchSkillXpEasier() {
return await constants.fetchJSONConstant('manual/skill_xp_easier.json');
}
-exports.fetchSkillXpEasier = fetchSkillXpEasier;
/** Add skills to skyblock-constants. This has caching so it's fine to call many times */
-async function addMinions(addingMinions) {
+export async function addMinions(addingMinions) {
await constants.addJSONConstants('minions.json', addingMinions, 'minion');
}
-exports.addMinions = addMinions;
-async function fetchConstantValues() {
+export async function fetchConstantValues() {
return await constants.fetchJSONConstant('values.json');
}
-exports.fetchConstantValues = fetchConstantValues;
-async function setConstantValues(newValues) {
+export async function setConstantValues(newValues) {
let file = await fetchFile('values.json');
if (!file.path)
return;
@@ -263,4 +221,6 @@ async function setConstantValues(newValues) {
}
catch { }
}
-exports.setConstantValues = setConstantValues;
+// this is necessary for mocking in the tests because es6
+export function mockAddJSONConstants($value) { addJSONConstants = $value; }
+export function mockFetchJSONConstant($value) { fetchJSONConstant = $value; }
diff --git a/build/database.js b/build/database.js
index a12fc9e..b55a4ae 100644
--- a/build/database.js
+++ b/build/database.js
@@ -1,54 +1,29 @@
-"use strict";
/**
* Store data about members for leaderboards
*/
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.updateAccount = exports.fetchAccountFromDiscord = exports.fetchAccount = exports.fetchSession = exports.createSession = exports.finishedCachingRawLeaderboards = exports.queueUpdateDatabaseProfile = exports.queueUpdateDatabaseMember = exports.leaderboardUpdateProfileQueue = exports.leaderboardUpdateMemberQueue = exports.updateDatabaseProfile = exports.updateDatabaseMember = exports.fetchMemberLeaderboardSpots = exports.fetchLeaderboard = exports.fetchProfileLeaderboard = exports.fetchMemberLeaderboard = exports.fetchAllMemberLeaderboardAttributes = exports.fetchSlayerLeaderboards = exports.fetchAllLeaderboardsCategorized = exports.cachedRawLeaderboards = void 0;
-const stats_1 = require("./cleaners/skyblock/stats");
-const slayers_1 = require("./cleaners/skyblock/slayers");
-const mongodb_1 = require("mongodb");
-const cached = __importStar(require("./hypixelCached"));
-const constants = __importStar(require("./constants"));
-const util_1 = require("./util");
-const node_cache_1 = __importDefault(require("node-cache"));
-const uuid_1 = require("uuid");
-const queue_promise_1 = __importDefault(require("queue-promise"));
-const _1 = require(".");
+import { categorizeStat, getStatUnit } from './cleaners/skyblock/stats.js';
+import { slayerLevels } from './cleaners/skyblock/slayers.js';
+import { MongoClient } from 'mongodb';
+import * as cached from './hypixelCached.js';
+import * as constants from './constants.js';
+import { shuffle, sleep } from './util.js';
+import NodeCache from 'node-cache';
+import { v4 as uuid4 } from 'uuid';
+import Queue from 'queue-promise';
+import { debug } from './index.js';
// don't update the user for 3 minutes
-const recentlyUpdated = new node_cache_1.default({
+const recentlyUpdated = new NodeCache({
stdTTL: 60 * 3,
checkperiod: 60,
useClones: false,
});
// don't add stuff to the queue within the same 5 minutes
-const recentlyQueued = new node_cache_1.default({
+const recentlyQueued = new NodeCache({
stdTTL: 60 * 5,
checkperiod: 60,
useClones: false,
});
-exports.cachedRawLeaderboards = new Map();
+export const cachedRawLeaderboards = new Map();
const leaderboardMax = 100;
const reversedLeaderboards = [
'first_join',
@@ -71,7 +46,7 @@ async function connect() {
return console.warn('Warning: db_uri was not found in .env. Features that utilize the database such as leaderboards won\'t work.');
if (!process.env.db_name)
return console.warn('Warning: db_name was not found in .env. Features that utilize the database such as leaderboards won\'t work.');
- client = await mongodb_1.MongoClient.connect(process.env.db_uri, { useNewUrlParser: true, useUnifiedTopology: true });
+ client = await MongoClient.connect(process.env.db_uri);
database = client.db(process.env.db_name);
memberLeaderboardsCollection = database.collection('member-leaderboards');
profileLeaderboardsCollection = database.collection('profile-leaderboards');
@@ -132,12 +107,12 @@ function getProfileLeaderboardAttributes(profile) {
unique_minions: profile.minion_count
};
}
-async function fetchAllLeaderboardsCategorized() {
+export async function fetchAllLeaderboardsCategorized() {
const memberLeaderboardAttributes = await fetchAllMemberLeaderboardAttributes();
const profileLeaderboardAttributes = await fetchAllProfileLeaderboardAttributes();
const categorizedLeaderboards = {};
for (const leaderboard of [...memberLeaderboardAttributes, ...profileLeaderboardAttributes]) {
- const { category } = stats_1.categorizeStat(leaderboard);
+ const { category } = categorizeStat(leaderboard);
if (category) {
if (!categorizedLeaderboards[category])
categorizedLeaderboards[category] = [];
@@ -150,9 +125,8 @@ async function fetchAllLeaderboardsCategorized() {
categorizedLeaderboards.misc = misc;
return categorizedLeaderboards;
}
-exports.fetchAllLeaderboardsCategorized = fetchAllLeaderboardsCategorized;
/** Fetch the raw names for the slayer leaderboards */
-async function fetchSlayerLeaderboards() {
+export async function fetchSlayerLeaderboards() {
const rawSlayerNames = await constants.fetchSlayers();
let leaderboardNames = [
'slayer_total_xp',
@@ -162,15 +136,14 @@ async function fetchSlayerLeaderboards() {
for (const slayerNameRaw of rawSlayerNames) {
leaderboardNames.push(`slayer_${slayerNameRaw}_total_xp`);
leaderboardNames.push(`slayer_${slayerNameRaw}_total_kills`);
- for (let slayerTier = 1; slayerTier <= slayers_1.slayerLevels; slayerTier++) {
+ for (let slayerTier = 1; slayerTier <= slayerLevels; slayerTier++) {
leaderboardNames.push(`slayer_${slayerNameRaw}_${slayerTier}_kills`);
}
}
return leaderboardNames;
}
-exports.fetchSlayerLeaderboards = fetchSlayerLeaderboards;
/** Fetch the names of all the leaderboards that rank members */
-async function fetchAllMemberLeaderboardAttributes() {
+export async function fetchAllMemberLeaderboardAttributes() {
return [
// we use the raw stat names rather than the clean stats in case hypixel adds a new stat and it takes a while for us to clean it
...await constants.fetchStats(),
@@ -188,7 +161,6 @@ async function fetchAllMemberLeaderboardAttributes() {
'top_1_leaderboards_count'
];
}
-exports.fetchAllMemberLeaderboardAttributes = fetchAllMemberLeaderboardAttributes;
/** Fetch the names of all the leaderboards that rank profiles */
async function fetchAllProfileLeaderboardAttributes() {
return [
@@ -211,14 +183,14 @@ const fetchingRawLeaderboardNames = new Set();
async function fetchMemberLeaderboardRaw(name) {
if (!client)
throw Error('Client isn\'t initialized yet');
- if (exports.cachedRawLeaderboards.has(name))
- return exports.cachedRawLeaderboards.get(name);
+ if (cachedRawLeaderboards.has(name))
+ return cachedRawLeaderboards.get(name);
// if it's currently being fetched, check every 100ms until it's in cachedRawLeaderboards
if (fetchingRawLeaderboardNames.has(name)) {
while (true) {
- await util_1.sleep(100);
- if (exports.cachedRawLeaderboards.has(name))
- return exports.cachedRawLeaderboards.get(name);
+ await sleep(100);
+ if (cachedRawLeaderboards.has(name))
+ return cachedRawLeaderboards.get(name);
}
}
// typescript forces us to make a new variable and set it this way because it gives an error otherwise
@@ -240,18 +212,18 @@ async function fetchMemberLeaderboardRaw(name) {
};
});
fetchingRawLeaderboardNames.delete(name);
- exports.cachedRawLeaderboards.set(name, leaderboardRaw);
+ cachedRawLeaderboards.set(name, leaderboardRaw);
return leaderboardRaw;
}
async function fetchProfileLeaderboardRaw(name) {
- if (exports.cachedRawLeaderboards.has(name))
- return exports.cachedRawLeaderboards.get(name);
+ if (cachedRawLeaderboards.has(name))
+ return cachedRawLeaderboards.get(name);
// if it's currently being fetched, check every 100ms until it's in cachedRawLeaderboards
if (fetchingRawLeaderboardNames.has(name)) {
while (true) {
- await util_1.sleep(100);
- if (exports.cachedRawLeaderboards.has(name))
- return exports.cachedRawLeaderboards.get(name);
+ await sleep(100);
+ if (cachedRawLeaderboards.has(name))
+ return cachedRawLeaderboards.get(name);
}
}
// typescript forces us to make a new variable and set it this way because it gives an error otherwise
@@ -273,12 +245,11 @@ async function fetchProfileLeaderboardRaw(name) {
};
});
fetchingRawLeaderboardNames.delete(name);
- exports.cachedRawLeaderboards.set(name, leaderboardRaw);
+ cachedRawLeaderboards.set(name, leaderboardRaw);
return leaderboardRaw;
}
/** Fetch a leaderboard that ranks members, as opposed to profiles */
-async function fetchMemberLeaderboard(name) {
- var _a;
+export async function fetchMemberLeaderboard(name) {
const leaderboardRaw = await fetchMemberLeaderboardRaw(name);
const fetchLeaderboardPlayer = async (i) => {
const player = await cached.fetchBasicPlayer(i.uuid);
@@ -295,14 +266,12 @@ async function fetchMemberLeaderboard(name) {
const leaderboard = await Promise.all(promises);
return {
name: name,
- unit: (_a = stats_1.getStatUnit(name)) !== null && _a !== void 0 ? _a : null,
+ unit: getStatUnit(name) ?? null,
list: leaderboard
};
}
-exports.fetchMemberLeaderboard = fetchMemberLeaderboard;
/** Fetch a leaderboard that ranks profiles, as opposed to members */
-async function fetchProfileLeaderboard(name) {
- var _a;
+export async function fetchProfileLeaderboard(name) {
const leaderboardRaw = await fetchProfileLeaderboardRaw(name);
const fetchLeaderboardProfile = async (i) => {
const players = [];
@@ -324,13 +293,12 @@ async function fetchProfileLeaderboard(name) {
const leaderboard = await Promise.all(promises);
return {
name: name,
- unit: (_a = stats_1.getStatUnit(name)) !== null && _a !== void 0 ? _a : null,
+ unit: getStatUnit(name) ?? null,
list: leaderboard
};
}
-exports.fetchProfileLeaderboard = fetchProfileLeaderboard;
/** Fetch a leaderboard */
-async function fetchLeaderboard(name) {
+export async function fetchLeaderboard(name) {
const profileLeaderboards = await fetchAllProfileLeaderboardAttributes();
let leaderboard;
if (profileLeaderboards.includes(name)) {
@@ -343,10 +311,8 @@ async function fetchLeaderboard(name) {
leaderboard.info = leaderboardInfos[name];
return leaderboard;
}
-exports.fetchLeaderboard = fetchLeaderboard;
/** Get the leaderboard positions a member is on. This may take a while depending on whether stuff is cached */
-async function fetchMemberLeaderboardSpots(player, profile) {
- var _a;
+export async function fetchMemberLeaderboardSpots(player, profile) {
const fullProfile = await cached.fetchProfile(player, profile);
if (!fullProfile)
return null;
@@ -364,14 +330,12 @@ async function fetchMemberLeaderboardSpots(player, profile) {
name: leaderboardName,
positionIndex: leaderboardPositionIndex,
value: applicableAttributes[leaderboardName],
- unit: (_a = stats_1.getStatUnit(leaderboardName)) !== null && _a !== void 0 ? _a : null
+ unit: getStatUnit(leaderboardName) ?? null
});
}
return memberLeaderboardSpots;
}
-exports.fetchMemberLeaderboardSpots = fetchMemberLeaderboardSpots;
async function getLeaderboardRequirement(name, leaderboardType) {
- var _a, _b, _c, _d;
let leaderboard;
if (leaderboardType === 'member')
leaderboard = await fetchMemberLeaderboardRaw(name);
@@ -379,8 +343,8 @@ async function getLeaderboardRequirement(name, leaderboardType) {
leaderboard = await fetchProfileLeaderboardRaw(name);
// if there's more than 100 items, return the 100th. if there's less, return null
return {
- top_100: (_b = (_a = leaderboard[leaderboardMax - 1]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null,
- top_1: (_d = (_c = leaderboard[1]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : null
+ top_100: leaderboard[leaderboardMax - 1]?.value ?? null,
+ top_1: leaderboard[1]?.value ?? null
};
}
/** Get the attributes for the member, but only ones that would put them on the top 100 for leaderboards */
@@ -438,17 +402,17 @@ async function getApplicableProfileLeaderboardAttributes(profile) {
return applicableAttributes;
}
/** Update the member's leaderboard data on the server if applicable */
-async function updateDatabaseMember(member, profile) {
+export async function updateDatabaseMember(member, profile) {
if (!client)
return; // the db client hasn't been initialized
- if (_1.debug)
+ if (debug)
console.debug('updateDatabaseMember', member.username);
// the member's been updated too recently, just return
if (recentlyUpdated.get(profile.uuid + member.uuid))
return;
// store the member in recentlyUpdated so it cant update for 3 more minutes
recentlyUpdated.set(profile.uuid + member.uuid, true);
- if (_1.debug)
+ if (debug)
console.debug('adding member to leaderboards', member.username);
if (member.rawHypixelStats)
await constants.addStats(Object.keys(member.rawHypixelStats));
@@ -456,10 +420,10 @@ async function updateDatabaseMember(member, profile) {
await constants.addSkills(member.skills.map(skill => skill.name));
await constants.addZones(member.visited_zones.map(zone => zone.name));
await constants.addSlayers(member.slayers.bosses.map(s => s.raw_name));
- if (_1.debug)
+ if (debug)
console.debug('done constants..');
const leaderboardAttributes = await getApplicableMemberLeaderboardAttributes(member);
- if (_1.debug)
+ if (debug)
console.debug('done getApplicableMemberLeaderboardAttributes..', leaderboardAttributes, member.username, profile.name);
await memberLeaderboardsCollection.updateOne({
uuid: member.uuid,
@@ -483,30 +447,29 @@ async function updateDatabaseMember(member, profile) {
}])
.sort((a, b) => leaderboardReverse ? a.value - b.value : b.value - a.value)
.slice(0, 100);
- exports.cachedRawLeaderboards.set(attributeName, newRawLeaderboard);
+ cachedRawLeaderboards.set(attributeName, newRawLeaderboard);
}
- if (_1.debug)
+ if (debug)
console.debug('added member to leaderboards', member.username, leaderboardAttributes);
}
-exports.updateDatabaseMember = updateDatabaseMember;
/**
* Update the profiles's leaderboard data on the server if applicable.
* This will not also update the members, you have to call updateDatabaseMember separately for that
*/
-async function updateDatabaseProfile(profile) {
+export async function updateDatabaseProfile(profile) {
if (!client)
return; // the db client hasn't been initialized
- if (_1.debug)
+ if (debug)
console.debug('updateDatabaseProfile', profile.name);
// the profile's been updated too recently, just return
if (recentlyUpdated.get(profile.uuid + 'profile'))
return;
// store the profile in recentlyUpdated so it cant update for 3 more minutes
recentlyUpdated.set(profile.uuid + 'profile', true);
- if (_1.debug)
+ if (debug)
console.debug('adding profile to leaderboards', profile.name);
const leaderboardAttributes = await getApplicableProfileLeaderboardAttributes(profile);
- if (_1.debug)
+ if (debug)
console.debug('done getApplicableProfileLeaderboardAttributes..', leaderboardAttributes, profile.name);
await profileLeaderboardsCollection.updateOne({
uuid: profile.uuid
@@ -531,47 +494,44 @@ async function updateDatabaseProfile(profile) {
}])
.sort((a, b) => leaderboardReverse ? a.value - b.value : b.value - a.value)
.slice(0, 100);
- exports.cachedRawLeaderboards.set(attributeName, newRawLeaderboard);
+ cachedRawLeaderboards.set(attributeName, newRawLeaderboard);
}
- if (_1.debug)
+ if (debug)
console.debug('added profile to leaderboards', profile.name, leaderboardAttributes);
}
-exports.updateDatabaseProfile = updateDatabaseProfile;
-exports.leaderboardUpdateMemberQueue = new queue_promise_1.default({
+export const leaderboardUpdateMemberQueue = new Queue({
concurrent: 1,
interval: 50
});
-exports.leaderboardUpdateProfileQueue = new queue_promise_1.default({
+export const leaderboardUpdateProfileQueue = new Queue({
concurrent: 1,
interval: 500
});
/** Queue an update for the member's leaderboard data on the server if applicable */
-function queueUpdateDatabaseMember(member, profile) {
+export function queueUpdateDatabaseMember(member, profile) {
if (recentlyQueued.get(profile.uuid + member.uuid))
return;
else
recentlyQueued.set(profile.uuid + member.uuid, true);
- exports.leaderboardUpdateMemberQueue.enqueue(async () => await updateDatabaseMember(member, profile));
+ leaderboardUpdateMemberQueue.enqueue(async () => await updateDatabaseMember(member, profile));
}
-exports.queueUpdateDatabaseMember = queueUpdateDatabaseMember;
/** Queue an update for the profile's leaderboard data on the server if applicable */
-function queueUpdateDatabaseProfile(profile) {
+export function queueUpdateDatabaseProfile(profile) {
if (recentlyQueued.get(profile.uuid + 'profile'))
return;
else
recentlyQueued.set(profile.uuid + 'profile', true);
- exports.leaderboardUpdateProfileQueue.enqueue(async () => await updateDatabaseProfile(profile));
+ leaderboardUpdateProfileQueue.enqueue(async () => await updateDatabaseProfile(profile));
}
-exports.queueUpdateDatabaseProfile = queueUpdateDatabaseProfile;
/**
* Remove leaderboard attributes for members that wouldn't actually be on the leaderboard. This saves a lot of storage space
*/
async function removeBadMemberLeaderboardAttributes() {
const leaderboards = await fetchAllMemberLeaderboardAttributes();
// shuffle so if the application is restarting many times itll still be useful
- for (const leaderboard of util_1.shuffle(leaderboards)) {
+ for (const leaderboard of shuffle(leaderboards)) {
// wait 10 seconds so it doesnt use as much ram
- await util_1.sleep(10 * 1000);
+ await sleep(10 * 1000);
const unsetValue = {};
unsetValue[leaderboard] = '';
const filter = {};
@@ -588,19 +548,19 @@ async function removeBadMemberLeaderboardAttributes() {
await memberLeaderboardsCollection.deleteMany({ stats: {} });
await profileLeaderboardsCollection.deleteMany({ stats: {} });
}
-exports.finishedCachingRawLeaderboards = false;
+export let finishedCachingRawLeaderboards = false;
/** Fetch all the leaderboards, used for caching. Don't call this often! */
async function fetchAllLeaderboards(fast) {
const leaderboards = await fetchAllMemberLeaderboardAttributes();
- if (_1.debug)
+ if (debug)
console.debug('Caching raw leaderboards!');
- for (const leaderboard of util_1.shuffle(leaderboards))
+ for (const leaderboard of shuffle(leaderboards))
await fetchMemberLeaderboardRaw(leaderboard);
- exports.finishedCachingRawLeaderboards = true;
+ finishedCachingRawLeaderboards = true;
}
-async function createSession(refreshToken, userData) {
- const sessionId = uuid_1.v4();
- await (sessionsCollection === null || sessionsCollection === void 0 ? void 0 : sessionsCollection.insertOne({
+export async function createSession(refreshToken, userData) {
+ const sessionId = uuid4();
+ await sessionsCollection?.insertOne({
_id: sessionId,
refresh_token: refreshToken,
discord_user: {
@@ -608,29 +568,25 @@ async function createSession(refreshToken, userData) {
name: userData.username + '#' + userData.discriminator
},
lastUpdated: new Date()
- }));
+ });
return sessionId;
}
-exports.createSession = createSession;
-async function fetchSession(sessionId) {
- return await (sessionsCollection === null || sessionsCollection === void 0 ? void 0 : sessionsCollection.findOne({ _id: sessionId }));
+export async function fetchSession(sessionId) {
+ return await sessionsCollection?.findOne({ _id: sessionId });
}
-exports.fetchSession = fetchSession;
-async function fetchAccount(minecraftUuid) {
- return await (accountsCollection === null || accountsCollection === void 0 ? void 0 : accountsCollection.findOne({ minecraftUuid }));
+export async function fetchAccount(minecraftUuid) {
+ return await accountsCollection?.findOne({ minecraftUuid });
}
-exports.fetchAccount = fetchAccount;
-async function fetchAccountFromDiscord(discordId) {
- return await (accountsCollection === null || accountsCollection === void 0 ? void 0 : accountsCollection.findOne({ discordId }));
+export async function fetchAccountFromDiscord(discordId) {
+ return await accountsCollection?.findOne({ discordId });
}
-exports.fetchAccountFromDiscord = fetchAccountFromDiscord;
-async function updateAccount(discordId, schema) {
- await (accountsCollection === null || accountsCollection === void 0 ? void 0 : accountsCollection.updateOne({
+export async function updateAccount(discordId, schema) {
+ await accountsCollection?.updateOne({
discordId
- }, { $set: schema }, { upsert: true }));
+ }, { $set: schema }, { upsert: true });
}
-exports.updateAccount = updateAccount;
// make sure it's not in a test
+console.log('global.isTest', globalThis.isTest);
if (!globalThis.isTest) {
connect().then(() => {
// when it connects, cache the leaderboards and remove bad members
diff --git a/build/discord.js b/build/discord.js
index ba9f3eb..ca910b2 100644
--- a/build/discord.js
+++ b/build/discord.js
@@ -1,16 +1,10 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.getUser = exports.exchangeCode = void 0;
-const node_fetch_1 = __importDefault(require("node-fetch"));
-const https_1 = require("https");
+import fetch from 'node-fetch';
+import { Agent } from 'https';
const DISCORD_CLIENT_ID = '656634948148527107';
-const httpsAgent = new https_1.Agent({
+const httpsAgent = new Agent({
keepAlive: true
});
-async function exchangeCode(redirectUri, code) {
+export async function exchangeCode(redirectUri, code) {
const API_ENDPOINT = 'https://discord.com/api/v6';
const CLIENT_SECRET = process.env.discord_client_secret;
if (!CLIENT_SECRET) {
@@ -25,7 +19,7 @@ async function exchangeCode(redirectUri, code) {
'redirect_uri': redirectUri,
'scope': 'identify'
};
- const fetchResponse = await node_fetch_1.default(API_ENDPOINT + '/oauth2/token', {
+ const fetchResponse = await fetch(API_ENDPOINT + '/oauth2/token', {
method: 'POST',
agent: () => httpsAgent,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
@@ -33,13 +27,11 @@ async function exchangeCode(redirectUri, code) {
});
return await fetchResponse.json();
}
-exports.exchangeCode = exchangeCode;
-async function getUser(accessToken) {
+export async function getUser(accessToken) {
const API_ENDPOINT = 'https://discord.com/api/v6';
- const response = await node_fetch_1.default(API_ENDPOINT + '/users/@me', {
+ const response = await fetch(API_ENDPOINT + '/users/@me', {
headers: { 'Authorization': 'Bearer ' + accessToken },
agent: () => httpsAgent,
});
- return response.json();
+ return await response.json();
}
-exports.getUser = getUser;
diff --git a/build/hypixel.js b/build/hypixel.js
index 414139e..6a1a916 100644
--- a/build/hypixel.js
+++ b/build/hypixel.js
@@ -1,58 +1,35 @@
-"use strict";
/**
* Fetch the clean Hypixel API
*/
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.fetchMemberProfilesUncached = exports.fetchBasicProfileFromUuidUncached = exports.fetchMemberProfileUncached = exports.fetchMemberProfile = exports.fetchUser = exports.sendCleanApiRequest = exports.maxMinion = exports.saveInterval = void 0;
-const profile_1 = require("./cleaners/skyblock/profile");
-const database_1 = require("./database");
-const hypixelApi_1 = require("./hypixelApi");
-const profiles_1 = require("./cleaners/skyblock/profiles");
-const player_1 = require("./cleaners/player");
-const cached = __importStar(require("./hypixelCached"));
-const _1 = require(".");
+import { cleanSkyblockProfileResponse } from './cleaners/skyblock/profile.js';
+import { fetchAccount, queueUpdateDatabaseMember, queueUpdateDatabaseProfile } from './database.js';
+import { chooseApiKey, sendApiRequest } from './hypixelApi.js';
+import { cleanSkyblockProfilesResponse } from './cleaners/skyblock/profiles.js';
+import { cleanPlayerResponse } from './cleaners/player.js';
+import * as cached from './hypixelCached.js';
+import { debug } from './index.js';
// the interval at which the "last_save" parameter updates in the hypixel api, this is 3 minutes
-exports.saveInterval = 60 * 3 * 1000;
+export const saveInterval = 60 * 3 * 1000;
// the highest level a minion can be
-exports.maxMinion = 11;
+export const maxMinion = 11;
/** Sends an API request to Hypixel and cleans it up. */
-async function sendCleanApiRequest({ path, args }, included, options) {
- const key = await hypixelApi_1.chooseApiKey();
- const rawResponse = await hypixelApi_1.sendApiRequest({ path, key, args });
+export async function sendCleanApiRequest({ path, args }, included, options) {
+ const key = await chooseApiKey();
+ const rawResponse = await sendApiRequest({ path, key, args });
if (rawResponse.throttled) {
// if it's throttled, wait a second and try again
await new Promise(resolve => setTimeout(resolve, 1000));
return await sendCleanApiRequest({ path, args }, included, options);
}
// clean the response
- return await cleanResponse({ path, data: rawResponse }, options !== null && options !== void 0 ? options : {});
+ return await cleanResponse({ path, data: rawResponse }, options ?? {});
}
-exports.sendCleanApiRequest = sendCleanApiRequest;
async function cleanResponse({ path, data }, options) {
// Cleans up an api response
switch (path) {
- case 'player': return await player_1.cleanPlayerResponse(data.player);
- case 'skyblock/profile': return await profile_1.cleanSkyblockProfileResponse(data.profile, options);
- case 'skyblock/profiles': return await profiles_1.cleanSkyblockProfilesResponse(data.profiles);
+ case 'player': return await cleanPlayerResponse(data.player);
+ case 'skyblock/profile': return await cleanSkyblockProfileResponse(data.profile, options);
+ case 'skyblock/profiles': return await cleanSkyblockProfilesResponse(data.profiles);
}
}
/**
@@ -61,21 +38,20 @@ async function cleanResponse({ path, data }, options) {
* @param included lets you choose what is returned, so there's less processing required on the backend
* used inclusions: player, profiles
*/
-async function fetchUser({ user, uuid, username }, included = ['player'], customization) {
- var _a, _b;
+export async function fetchUser({ user, uuid, username }, included = ['player'], customization) {
if (!uuid) {
// If the uuid isn't provided, get it
if (!username && !user)
return null;
- uuid = await cached.uuidFromUser((user !== null && user !== void 0 ? user : username));
+ uuid = await cached.uuidFromUser((user ?? username));
}
if (!uuid) {
// the user doesn't exist.
- if (_1.debug)
+ if (debug)
console.debug('error:', user, 'doesnt exist');
return null;
}
- const websiteAccountPromise = customization ? database_1.fetchAccount(uuid) : null;
+ const websiteAccountPromise = customization ? fetchAccount(uuid) : null;
const includePlayers = included.includes('player');
const includeProfiles = included.includes('profiles');
let profilesData;
@@ -85,7 +61,7 @@ async function fetchUser({ user, uuid, username }, included = ['player'], custom
playerData = await cached.fetchPlayer(uuid);
// if not including profiles, include lightweight profiles just in case
if (!includeProfiles)
- basicProfilesData = playerData === null || playerData === void 0 ? void 0 : playerData.profiles;
+ basicProfilesData = playerData?.profiles;
if (playerData)
delete playerData.profiles;
}
@@ -95,7 +71,7 @@ async function fetchUser({ user, uuid, username }, included = ['player'], custom
let lastOnline = 0;
if (includeProfiles) {
for (const profile of profilesData) {
- const member = (_a = profile.members) === null || _a === void 0 ? void 0 : _a.find(member => member.uuid === uuid);
+ const member = profile.members?.find(member => member.uuid === uuid);
if (member && member.last_save > lastOnline) {
lastOnline = member.last_save;
activeProfile = profile;
@@ -107,13 +83,12 @@ async function fetchUser({ user, uuid, username }, included = ['player'], custom
websiteAccount = await websiteAccountPromise;
return {
player: playerData,
- profiles: profilesData !== null && profilesData !== void 0 ? profilesData : basicProfilesData,
- activeProfile: includeProfiles ? (_b = activeProfile) === null || _b === void 0 ? void 0 : _b.uuid : undefined,
- online: includeProfiles ? lastOnline > (Date.now() - exports.saveInterval) : undefined,
- customization: websiteAccount === null || websiteAccount === void 0 ? void 0 : websiteAccount.customization
+ profiles: profilesData ?? basicProfilesData,
+ activeProfile: includeProfiles ? activeProfile?.uuid : undefined,
+ online: includeProfiles ? lastOnline > (Date.now() - saveInterval) : undefined,
+ customization: websiteAccount?.customization
};
}
-exports.fetchUser = fetchUser;
/**
* Fetch a CleanMemberProfile from a user and string
* This is safe to use many times as the results are cached!
@@ -121,12 +96,12 @@ exports.fetchUser = fetchUser;
* @param profile A profile name or profile uuid
* @param customization Whether stuff like the user's custom background will be returned
*/
-async function fetchMemberProfile(user, profile, customization) {
+export async function fetchMemberProfile(user, profile, customization) {
const playerUuid = await cached.uuidFromUser(user);
if (!playerUuid)
return null;
// we don't await the promise immediately so it can load while we do other stuff
- const websiteAccountPromise = customization ? database_1.fetchAccount(playerUuid) : null;
+ const websiteAccountPromise = customization ? fetchAccount(playerUuid) : null;
const profileUuid = await cached.fetchProfileUuid(user, profile);
// if the profile or player doesn't have an id, just return
if (!profileUuid)
@@ -164,41 +139,38 @@ async function fetchMemberProfile(user, profile, customization) {
...player
},
profile: cleanProfile,
- customization: websiteAccount === null || websiteAccount === void 0 ? void 0 : websiteAccount.customization
+ customization: websiteAccount?.customization
};
}
-exports.fetchMemberProfile = fetchMemberProfile;
/**
* Fetches the Hypixel API to get a CleanFullProfile. This doesn't do any caching and you should use hypixelCached.fetchProfile instead
* @param playerUuid The UUID of the Minecraft player
* @param profileUuid The UUID of the Hypixel SkyBlock profile
*/
-async function fetchMemberProfileUncached(playerUuid, profileUuid) {
+export async function fetchMemberProfileUncached(playerUuid, profileUuid) {
const profile = await sendCleanApiRequest({
path: 'skyblock/profile',
args: { profile: profileUuid }
}, undefined, { mainMemberUuid: playerUuid });
// queue updating the leaderboard positions for the member, eventually
for (const member of profile.members)
- database_1.queueUpdateDatabaseMember(member, profile);
- database_1.queueUpdateDatabaseProfile(profile);
+ queueUpdateDatabaseMember(member, profile);
+ queueUpdateDatabaseProfile(profile);
return profile;
}
-exports.fetchMemberProfileUncached = fetchMemberProfileUncached;
/**
* Fetches the Hypixel API to get a CleanProfile from its id. This doesn't do any caching and you should use hypixelCached.fetchBasicProfileFromUuid instead
* @param playerUuid The UUID of the Minecraft player
* @param profileUuid The UUID of the Hypixel SkyBlock profile
*/
-async function fetchBasicProfileFromUuidUncached(profileUuid) {
+export async function fetchBasicProfileFromUuidUncached(profileUuid) {
const profile = await sendCleanApiRequest({
path: 'skyblock/profile',
args: { profile: profileUuid }
}, undefined, { basic: true });
return profile;
}
-exports.fetchBasicProfileFromUuidUncached = fetchBasicProfileFromUuidUncached;
-async function fetchMemberProfilesUncached(playerUuid) {
+export async function fetchMemberProfilesUncached(playerUuid) {
const profiles = await sendCleanApiRequest({
path: 'skyblock/profiles',
args: {
@@ -210,10 +182,9 @@ async function fetchMemberProfilesUncached(playerUuid) {
});
for (const profile of profiles) {
for (const member of profile.members) {
- database_1.queueUpdateDatabaseMember(member, profile);
+ queueUpdateDatabaseMember(member, profile);
}
- database_1.queueUpdateDatabaseProfile(profile);
+ queueUpdateDatabaseProfile(profile);
}
return profiles;
}
-exports.fetchMemberProfilesUncached = fetchMemberProfilesUncached;
diff --git a/build/hypixelApi.js b/build/hypixelApi.js
index a35dd64..da1be16 100644
--- a/build/hypixelApi.js
+++ b/build/hypixelApi.js
@@ -1,33 +1,26 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-var _a, _b, _c;
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.sendApiRequest = exports.getKeyUsage = exports.chooseApiKey = void 0;
/**
* Fetch the raw Hypixel API
*/
-const node_fetch_1 = __importDefault(require("node-fetch"));
-const util_1 = require("./util");
-const https_1 = require("https");
+import fetch from 'node-fetch';
+import { jsonToQuery, shuffle } from './util.js';
+import { Agent } from 'https';
if (!process.env.hypixel_keys)
// if there's no hypixel keys in env, run dotenv
- require('dotenv').config();
+ (await import('dotenv')).config();
// We need to create an agent to prevent memory leaks and to only do dns lookups once
-const httpsAgent = new https_1.Agent({
+const httpsAgent = new Agent({
keepAlive: true
});
/** This array should only ever contain one item because using multiple hypixel api keys isn't allowed :) */
-const apiKeys = (_c = (_b = (_a = process.env) === null || _a === void 0 ? void 0 : _a.hypixel_keys) === null || _b === void 0 ? void 0 : _b.split(' ')) !== null && _c !== void 0 ? _c : [];
+const apiKeys = process.env?.hypixel_keys?.split(' ') ?? [];
const apiKeyUsage = {};
const baseHypixelAPI = 'https://api.hypixel.net';
/** Choose the best current API key */
-function chooseApiKey() {
+export function chooseApiKey() {
// find the api key with the lowest amount of uses
let bestKeyUsage = null;
let bestKey = null;
- for (let key of util_1.shuffle(apiKeys.slice())) {
+ for (let key of shuffle(apiKeys.slice())) {
const keyUsage = apiKeyUsage[key];
// if the key has never been used before, use it
if (!keyUsage)
@@ -43,8 +36,7 @@ function chooseApiKey() {
}
return bestKey;
}
-exports.chooseApiKey = chooseApiKey;
-function getKeyUsage() {
+export function getKeyUsage() {
let keyLimit = 0;
let keyUsage = 0;
for (let key of Object.values(apiKeyUsage)) {
@@ -56,20 +48,18 @@ function getKeyUsage() {
usage: keyUsage
};
}
-exports.getKeyUsage = getKeyUsage;
/** Send an HTTP request to the Hypixel API */
-async function sendApiRequest({ path, key, args }) {
+export let sendApiRequest = async function sendApiRequest({ path, key, args }) {
// Send a raw http request to api.hypixel.net, and return the parsed json
- var _a, _b, _c;
if (key)
// If there's an api key, add it to the arguments
args.key = key;
// Construct a url from the base api url, path, and arguments
- const fetchUrl = baseHypixelAPI + '/' + path + '?' + util_1.jsonToQuery(args);
+ const fetchUrl = baseHypixelAPI + '/' + path + '?' + jsonToQuery(args);
let fetchResponse;
let fetchJsonParsed;
try {
- fetchResponse = await node_fetch_1.default(fetchUrl, { agent: () => httpsAgent });
+ fetchResponse = await fetch(fetchUrl, { agent: () => httpsAgent });
fetchJsonParsed = await fetchResponse.json();
}
catch {
@@ -85,9 +75,9 @@ async function sendApiRequest({ path, key, args }) {
if (fetchResponse.headers.get('ratelimit-limit'))
// remember how many uses it has
apiKeyUsage[key] = {
- remaining: parseInt((_a = fetchResponse.headers.get('ratelimit-remaining')) !== null && _a !== void 0 ? _a : '0'),
- limit: parseInt((_b = fetchResponse.headers.get('ratelimit-limit')) !== null && _b !== void 0 ? _b : '0'),
- reset: Date.now() + parseInt((_c = fetchResponse.headers.get('ratelimit-reset')) !== null && _c !== void 0 ? _c : '0') * 1000
+ remaining: parseInt(fetchResponse.headers.get('ratelimit-remaining') ?? '0'),
+ limit: parseInt(fetchResponse.headers.get('ratelimit-limit') ?? '0'),
+ reset: Date.now() + parseInt(fetchResponse.headers.get('ratelimit-reset') ?? '0') * 1000
};
if (fetchJsonParsed.throttle) {
if (apiKeyUsage[key])
@@ -97,5 +87,6 @@ async function sendApiRequest({ path, key, args }) {
return await sendApiRequest({ path, key, args });
}
return fetchJsonParsed;
-}
-exports.sendApiRequest = sendApiRequest;
+};
+// this is necessary for mocking in the tests because es6
+export function mockSendApiRequest($value) { sendApiRequest = $value; }
diff --git a/build/hypixelCached.js b/build/hypixelCached.js
index b03361f..69bcc62 100644
--- a/build/hypixelCached.js
+++ b/build/hypixelCached.js
@@ -1,72 +1,47 @@
-"use strict";
/**
* Fetch the clean and cached Hypixel API
*/
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.fetchProfileName = exports.fetchBasicProfileFromUuid = exports.fetchProfile = exports.fetchProfileUuid = exports.fetchSkyblockProfiles = exports.fetchBasicPlayer = exports.fetchPlayer = exports.usernameFromUser = exports.uuidFromUser = exports.profileNameCache = exports.profilesCache = exports.profileCache = exports.basicPlayerCache = exports.playerCache = exports.basicProfilesCache = exports.usernameCache = void 0;
-const node_cache_1 = __importDefault(require("node-cache"));
-const lru_cache_1 = __importDefault(require("lru-cache"));
-const mojang = __importStar(require("./mojang"));
-const hypixel = __importStar(require("./hypixel"));
-const util_1 = require("./util");
-const _1 = require(".");
+import { isUuid, undashUuid } from './util.js';
+import * as hypixel from './hypixel.js';
+import * as mojang from './mojang.js';
+import NodeCache from 'node-cache';
+import { debug } from './index.js';
+import LRUCache from 'lru-cache';
// cache usernames for 30 minutes
/** uuid: username */
-exports.usernameCache = new node_cache_1.default({
+export const usernameCache = new NodeCache({
// stdTTL: 60 * 60 * 4,
stdTTL: 60 * 30,
checkperiod: 60,
useClones: false,
});
-exports.usernameCache.setMaxListeners(50);
-exports.basicProfilesCache = new node_cache_1.default({
+usernameCache.setMaxListeners(50);
+export const basicProfilesCache = new NodeCache({
stdTTL: 60 * 10,
checkperiod: 60,
useClones: true,
});
-exports.playerCache = new node_cache_1.default({
+export const playerCache = new NodeCache({
stdTTL: 60,
checkperiod: 10,
useClones: true,
});
// cache "basic players" (players without profiles) for 20 minutes
-exports.basicPlayerCache = new lru_cache_1.default({
+export const basicPlayerCache = new LRUCache({
max: 10000,
maxAge: 60 * 20 * 1000,
});
-exports.profileCache = new node_cache_1.default({
+export const profileCache = new NodeCache({
stdTTL: 30,
checkperiod: 10,
useClones: true,
});
-exports.profilesCache = new node_cache_1.default({
+export const profilesCache = new NodeCache({
stdTTL: 60 * 3,
checkperiod: 10,
useClones: false,
});
-exports.profileNameCache = new node_cache_1.default({
+export const profileNameCache = new NodeCache({
stdTTL: 60 * 60,
checkperiod: 60,
useClones: false,
@@ -86,77 +61,74 @@ function waitForCacheSet(cache, key, value) {
* Fetch the uuid from a user
* @param user A user can be either a uuid or a username
*/
-async function uuidFromUser(user) {
+export async function uuidFromUser(user) {
// if the user is 32 characters long, it has to be a uuid
- if (util_1.isUuid(user))
- return util_1.undashUuid(user);
- if (exports.usernameCache.has(util_1.undashUuid(user))) {
+ if (isUuid(user))
+ return undashUuid(user);
+ if (usernameCache.has(undashUuid(user))) {
// check if the uuid is a key
- const username = exports.usernameCache.get(util_1.undashUuid(user));
+ const username = usernameCache.get(undashUuid(user));
// sometimes the username will be null, return that
if (username === null)
return undefined;
// if it has .then, then that means its a waitForCacheSet promise. This is done to prevent requests made while it is already requesting
if (username.then) {
const { key: uuid, value: _username } = await username;
- exports.usernameCache.set(uuid, _username);
+ usernameCache.set(uuid, _username);
return uuid;
}
else
- return util_1.undashUuid(user);
+ return undashUuid(user);
}
// check if the username is a value
- const uuidToUsername = exports.usernameCache.mget(exports.usernameCache.keys());
+ const uuidToUsername = usernameCache.mget(usernameCache.keys());
for (const [uuid, username] of Object.entries(uuidToUsername)) {
if (username && username.toLowerCase && user.toLowerCase() === username.toLowerCase())
return uuid;
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: uuidFromUser', user);
- const undashedUser = util_1.undashUuid(user);
+ const undashedUser = undashUuid(user);
// set it as waitForCacheSet (a promise) in case uuidFromUser gets called while its fetching mojang
- exports.usernameCache.set(undashedUser, waitForCacheSet(exports.usernameCache, user, user));
+ usernameCache.set(undashedUser, waitForCacheSet(usernameCache, user, user));
// not cached, actually fetch mojang api now
let { uuid, username } = await mojang.profileFromUser(user);
if (!uuid) {
- exports.usernameCache.set(user, null);
+ usernameCache.set(user, null);
return;
}
// remove dashes from the uuid so its more normal
- uuid = util_1.undashUuid(uuid);
- exports.usernameCache.del(undashedUser);
- exports.usernameCache.set(uuid, username);
+ uuid = undashUuid(uuid);
+ usernameCache.del(undashedUser);
+ usernameCache.set(uuid, username);
return uuid;
}
-exports.uuidFromUser = uuidFromUser;
/**
* Fetch the username from a user
* @param user A user can be either a uuid or a username
*/
-async function usernameFromUser(user) {
- var _a;
- if (exports.usernameCache.has(util_1.undashUuid(user))) {
- if (_1.debug)
+export async function usernameFromUser(user) {
+ if (usernameCache.has(undashUuid(user))) {
+ if (debug)
console.debug('Cache hit! usernameFromUser', user);
- return (_a = exports.usernameCache.get(util_1.undashUuid(user))) !== null && _a !== void 0 ? _a : null;
+ return usernameCache.get(undashUuid(user)) ?? null;
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: usernameFromUser', user);
let { uuid, username } = await mojang.profileFromUser(user);
if (!uuid)
return null;
- uuid = util_1.undashUuid(uuid);
- exports.usernameCache.set(uuid, username);
+ uuid = undashUuid(uuid);
+ usernameCache.set(uuid, username);
return username;
}
-exports.usernameFromUser = usernameFromUser;
let fetchingPlayers = new Set();
-async function fetchPlayer(user) {
+export async function fetchPlayer(user) {
const playerUuid = await uuidFromUser(user);
if (!playerUuid)
return null;
- if (exports.playerCache.has(playerUuid))
- return exports.playerCache.get(playerUuid);
+ if (playerCache.has(playerUuid))
+ return playerCache.get(playerUuid);
// if it's already in the process of fetching, check every 100ms until it's not fetching the player anymore and fetch it again, since it'll be cached now
if (fetchingPlayers.has(playerUuid)) {
while (fetchingPlayers.has(playerUuid)) {
@@ -173,21 +145,20 @@ async function fetchPlayer(user) {
if (!cleanPlayer)
return null;
// clone in case it gets modified somehow later
- exports.playerCache.set(playerUuid, cleanPlayer);
- exports.usernameCache.set(playerUuid, cleanPlayer.username);
+ playerCache.set(playerUuid, cleanPlayer);
+ usernameCache.set(playerUuid, cleanPlayer.username);
const cleanBasicPlayer = Object.assign({}, cleanPlayer);
delete cleanBasicPlayer.profiles;
- exports.basicPlayerCache.set(playerUuid, cleanBasicPlayer);
+ basicPlayerCache.set(playerUuid, cleanBasicPlayer);
return cleanPlayer;
}
-exports.fetchPlayer = fetchPlayer;
/** Fetch a player without their profiles. This is heavily cached. */
-async function fetchBasicPlayer(user) {
+export async function fetchBasicPlayer(user) {
const playerUuid = await uuidFromUser(user);
if (!playerUuid)
return null;
- if (exports.basicPlayerCache.has(playerUuid))
- return exports.basicPlayerCache.get(playerUuid);
+ if (basicPlayerCache.has(playerUuid))
+ return basicPlayerCache.get(playerUuid);
const player = await fetchPlayer(playerUuid);
if (!player) {
console.debug('no player? this should never happen, perhaps the uuid is invalid or the player hasn\'t played hypixel', playerUuid);
@@ -196,15 +167,13 @@ async function fetchBasicPlayer(user) {
delete player.profiles;
return player;
}
-exports.fetchBasicPlayer = fetchBasicPlayer;
-async function fetchSkyblockProfiles(playerUuid) {
- var _a;
- if (exports.profilesCache.has(playerUuid)) {
- if (_1.debug)
+export async function fetchSkyblockProfiles(playerUuid) {
+ if (profilesCache.has(playerUuid)) {
+ if (debug)
console.debug('Cache hit! fetchSkyblockProfiles', playerUuid);
- return exports.profilesCache.get(playerUuid);
+ return profilesCache.get(playerUuid);
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: fetchSkyblockProfiles', playerUuid);
const profiles = await hypixel.fetchMemberProfilesUncached(playerUuid);
const basicProfiles = [];
@@ -213,7 +182,7 @@ async function fetchSkyblockProfiles(playerUuid) {
const basicProfile = {
name: profile.name,
uuid: profile.uuid,
- members: (_a = profile.members) === null || _a === void 0 ? void 0 : _a.map(m => {
+ members: profile.members?.map(m => {
return {
uuid: m.uuid,
username: m.username,
@@ -226,21 +195,20 @@ async function fetchSkyblockProfiles(playerUuid) {
basicProfiles.push(basicProfile);
}
// cache the profiles
- exports.profilesCache.set(playerUuid, basicProfiles);
+ profilesCache.set(playerUuid, basicProfiles);
return basicProfiles;
}
-exports.fetchSkyblockProfiles = fetchSkyblockProfiles;
/** Fetch an array of `BasicProfile`s */
async function fetchBasicProfiles(user) {
const playerUuid = await uuidFromUser(user);
if (!playerUuid)
return null; // invalid player, just return
- if (exports.basicProfilesCache.has(playerUuid)) {
- if (_1.debug)
+ if (basicProfilesCache.has(playerUuid)) {
+ if (debug)
console.debug('Cache hit! fetchBasicProfiles', playerUuid);
- return exports.basicProfilesCache.get(playerUuid);
+ return basicProfilesCache.get(playerUuid);
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: fetchBasicProfiles', user);
const player = await fetchPlayer(playerUuid);
if (!player) {
@@ -248,12 +216,12 @@ async function fetchBasicProfiles(user) {
return [];
}
const profiles = player.profiles;
- exports.basicProfilesCache.set(playerUuid, profiles);
+ basicProfilesCache.set(playerUuid, profiles);
if (!profiles)
return null;
// cache the profile names and uuids to profileNameCache because we can
for (const profile of profiles)
- exports.profileNameCache.set(`${playerUuid}.${profile.uuid}`, profile.name);
+ profileNameCache.set(`${playerUuid}.${profile.uuid}`, profile.name);
return profiles;
}
/**
@@ -261,48 +229,46 @@ async function fetchBasicProfiles(user) {
* @param user A username or uuid
* @param profile A profile name or profile uuid
*/
-async function fetchProfileUuid(user, profile) {
- var _a;
+export async function fetchProfileUuid(user, profile) {
// if a profile wasn't provided, return
if (!profile) {
- if (_1.debug)
+ if (debug)
console.debug('no profile provided?', user, profile);
return null;
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: fetchProfileUuid', user, profile);
const profiles = await fetchBasicProfiles(user);
if (!profiles)
return null; // user probably doesnt exist
- const profileUuid = util_1.undashUuid(profile);
+ const profileUuid = undashUuid(profile);
for (const p of profiles) {
- if (((_a = p.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === profileUuid.toLowerCase())
- return util_1.undashUuid(p.uuid);
- else if (util_1.undashUuid(p.uuid) === util_1.undashUuid(profileUuid))
- return util_1.undashUuid(p.uuid);
+ if (p.name?.toLowerCase() === profileUuid.toLowerCase())
+ return undashUuid(p.uuid);
+ else if (undashUuid(p.uuid) === undashUuid(profileUuid))
+ return undashUuid(p.uuid);
}
return null;
}
-exports.fetchProfileUuid = fetchProfileUuid;
/**
* Fetch an entire profile from the user and profile data
* @param user A username or uuid
* @param profile A profile name or profile uuid
*/
-async function fetchProfile(user, profile) {
+export async function fetchProfile(user, profile) {
const playerUuid = await uuidFromUser(user);
if (!playerUuid)
return null;
const profileUuid = await fetchProfileUuid(playerUuid, profile);
if (!profileUuid)
return null;
- if (exports.profileCache.has(profileUuid)) {
+ if (profileCache.has(profileUuid)) {
// we have the profile cached, return it :)
- if (_1.debug)
+ if (debug)
console.debug('Cache hit! fetchProfile', profileUuid);
- return exports.profileCache.get(profileUuid);
+ return profileCache.get(profileUuid);
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: fetchProfile', user, profile);
const profileName = await fetchProfileName(user, profile);
if (!profileName)
@@ -310,20 +276,19 @@ async function fetchProfile(user, profile) {
const cleanProfile = await hypixel.fetchMemberProfileUncached(playerUuid, profileUuid);
// we know the name from fetchProfileName, so set it here
cleanProfile.name = profileName;
- exports.profileCache.set(profileUuid, cleanProfile);
+ profileCache.set(profileUuid, cleanProfile);
return cleanProfile;
}
-exports.fetchProfile = fetchProfile;
/**
* Fetch a CleanProfile from the uuid
* @param profileUuid A profile name or profile uuid
*/
-async function fetchBasicProfileFromUuid(profileUuid) {
- if (exports.profileCache.has(profileUuid)) {
+export async function fetchBasicProfileFromUuid(profileUuid) {
+ if (profileCache.has(profileUuid)) {
// we have the profile cached, return it :)
- if (_1.debug)
+ if (debug)
console.debug('Cache hit! fetchBasicProfileFromUuid', profileUuid);
- const profile = exports.profileCache.get(profileUuid);
+ const profile = profileCache.get(profileUuid);
if (!profile)
return undefined;
return {
@@ -341,14 +306,12 @@ async function fetchBasicProfileFromUuid(profileUuid) {
// TODO: cache this
return await hypixel.fetchBasicProfileFromUuidUncached(profileUuid);
}
-exports.fetchBasicProfileFromUuid = fetchBasicProfileFromUuid;
/**
* Fetch the name of a profile from the user and profile uuid
* @param user A player uuid or username
* @param profile A profile uuid or name
*/
-async function fetchProfileName(user, profile) {
- var _a, _b;
+export async function fetchProfileName(user, profile) {
// we're fetching the profile and player uuid again in case we were given a name, but it's cached so it's not much of a problem
const profileUuid = await fetchProfileUuid(user, profile);
if (!profileUuid)
@@ -356,13 +319,13 @@ async function fetchProfileName(user, profile) {
const playerUuid = await uuidFromUser(user);
if (!playerUuid)
return null;
- if (exports.profileNameCache.has(`${playerUuid}.${profileUuid}`)) {
+ if (profileNameCache.has(`${playerUuid}.${profileUuid}`)) {
// Return the profile name if it's cached
- if (_1.debug)
+ if (debug)
console.debug('Cache hit! fetchProfileName', profileUuid);
- return (_a = exports.profileNameCache.get(`${playerUuid}.${profileUuid}`)) !== null && _a !== void 0 ? _a : null;
+ return profileNameCache.get(`${playerUuid}.${profileUuid}`) ?? null;
}
- if (_1.debug)
+ if (debug)
console.debug('Cache miss: fetchProfileName', user, profile);
const basicProfiles = await fetchBasicProfiles(playerUuid);
if (!basicProfiles)
@@ -370,8 +333,7 @@ async function fetchProfileName(user, profile) {
let profileName = null;
for (const basicProfile of basicProfiles)
if (basicProfile.uuid === playerUuid)
- profileName = (_b = basicProfile.name) !== null && _b !== void 0 ? _b : null;
- exports.profileNameCache.set(`${playerUuid}.${profileUuid}`, profileName);
+ profileName = basicProfile.name ?? null;
+ profileNameCache.set(`${playerUuid}.${profileUuid}`, profileName);
return profileName;
}
-exports.fetchProfileName = fetchProfileName;
diff --git a/build/index.js b/build/index.js
index 8bb2040..8521a1c 100644
--- a/build/index.js
+++ b/build/index.js
@@ -1,51 +1,25 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.debug = void 0;
-const database_1 = require("./database");
-const hypixel_1 = require("./hypixel");
-const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
-const constants = __importStar(require("./constants"));
-const discord = __importStar(require("./discord"));
-const express_1 = __importDefault(require("express"));
-const app = express_1.default();
-exports.debug = false;
+import { createSession, fetchAccountFromDiscord, fetchAllLeaderboardsCategorized, fetchLeaderboard, fetchMemberLeaderboardSpots, fetchSession, finishedCachingRawLeaderboards, leaderboardUpdateMemberQueue, leaderboardUpdateProfileQueue, updateAccount } from './database.js';
+import { fetchMemberProfile, fetchUser } from './hypixel.js';
+import rateLimit from 'express-rate-limit';
+import * as constants from './constants.js';
+import * as discord from './discord.js';
+import express from 'express';
+const app = express();
+export const debug = false;
const mainSiteUrl = 'https://skyblock.matdoes.dev';
// 200 requests over 5 minutes
-const limiter = express_rate_limit_1.default({
+const limiter = rateLimit({
windowMs: 60 * 1000 * 5,
max: 200,
skip: (req) => {
return req.headers.key === process.env.key;
},
keyGenerator: (req) => {
- var _a;
- return ((_a = req.headers['cf-connecting-ip']) !== null && _a !== void 0 ? _a : req.ip).toString();
+ return (req.headers['cf-connecting-ip'] ?? req.ip).toString();
}
});
app.use(limiter);
-app.use(express_1.default.json());
+app.use(express.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
@@ -56,15 +30,15 @@ app.get('/', async (req, res) => {
res.json({
ok: true,
uptimeHours: (currentTime - startTime) / 1000 / 60 / 60,
- finishedCachingRawLeaderboards: database_1.finishedCachingRawLeaderboards,
- leaderboardUpdateMemberQueueSize: database_1.leaderboardUpdateMemberQueue.size,
- leaderboardUpdateProfileQueueSize: database_1.leaderboardUpdateProfileQueue.size,
+ finishedCachingRawLeaderboards,
+ leaderboardUpdateMemberQueueSize: leaderboardUpdateMemberQueue.size,
+ leaderboardUpdateProfileQueueSize: leaderboardUpdateProfileQueue.size,
// key: getKeyUsage()
});
});
app.get('/player/:user', async (req, res) => {
try {
- const user = await hypixel_1.fetchUser({ user: req.params.user }, [req.query.basic === 'true' ? undefined : 'profiles', 'player'], req.query.customization === 'true');
+ const user = await fetchUser({ user: req.params.user }, [req.query.basic === 'true' ? undefined : 'profiles', 'player'], req.query.customization === 'true');
if (user)
res.json(user);
else
@@ -77,7 +51,7 @@ app.get('/player/:user', async (req, res) => {
});
app.get('/discord/:id', async (req, res) => {
try {
- res.json(await database_1.fetchAccountFromDiscord(req.params.id));
+ res.json(await fetchAccountFromDiscord(req.params.id));
}
catch (err) {
console.error(err);
@@ -86,7 +60,7 @@ app.get('/discord/:id', async (req, res) => {
});
app.get('/player/:user/:profile', async (req, res) => {
try {
- const profile = await hypixel_1.fetchMemberProfile(req.params.user, req.params.profile, req.query.customization === 'true');
+ const profile = await fetchMemberProfile(req.params.user, req.params.profile, req.query.customization === 'true');
if (profile)
res.json(profile);
else
@@ -99,7 +73,7 @@ app.get('/player/:user/:profile', async (req, res) => {
});
app.get('/player/:user/:profile/leaderboards', async (req, res) => {
try {
- res.json(await database_1.fetchMemberLeaderboardSpots(req.params.user, req.params.profile));
+ res.json(await fetchMemberLeaderboardSpots(req.params.user, req.params.profile));
}
catch (err) {
console.error(err);
@@ -108,7 +82,7 @@ app.get('/player/:user/:profile/leaderboards', async (req, res) => {
});
app.get('/leaderboard/:name', async (req, res) => {
try {
- res.json(await database_1.fetchLeaderboard(req.params.name));
+ res.json(await fetchLeaderboard(req.params.name));
}
catch (err) {
console.error(err);
@@ -117,7 +91,7 @@ app.get('/leaderboard/:name', async (req, res) => {
});
app.get('/leaderboards', async (req, res) => {
try {
- res.json(await database_1.fetchAllLeaderboardsCategorized());
+ res.json(await fetchAllLeaderboardsCategorized());
}
catch (err) {
console.error(err);
@@ -146,7 +120,7 @@ app.post('/accounts/createsession', async (req, res) => {
// access token is invalid :(
return res.json({ ok: false });
const userData = await discord.getUser(accessToken);
- const sessionId = await database_1.createSession(refreshToken, userData);
+ const sessionId = await createSession(refreshToken, userData);
res.json({ ok: true, session_id: sessionId });
}
catch (err) {
@@ -156,10 +130,10 @@ app.post('/accounts/createsession', async (req, res) => {
app.post('/accounts/session', async (req, res) => {
try {
const { uuid } = req.body;
- const session = await database_1.fetchSession(uuid);
+ const session = await fetchSession(uuid);
if (!session)
return res.json({ ok: false });
- const account = await database_1.fetchAccountFromDiscord(session.discord_user.id);
+ const account = await fetchAccountFromDiscord(session.discord_user.id);
res.json({ session, account });
}
catch (err) {
@@ -172,7 +146,7 @@ app.post('/accounts/update', async (req, res) => {
if (req.headers.key !== process.env.key)
return console.log('bad key!');
try {
- await database_1.updateAccount(req.body.discordId, req.body);
+ await updateAccount(req.body.discordId, req.body);
res.json({ ok: true });
}
catch (err) {
diff --git a/build/mojang.js b/build/mojang.js
index 2d2f694..7682839 100644
--- a/build/mojang.js
+++ b/build/mojang.js
@@ -1,28 +1,22 @@
-"use strict";
/**
* Fetch the Mojang username API through api.ashcon.app
*/
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.profileFromUser = exports.profileFromUsernameAlternative = exports.profileFromUsername = exports.profileFromUuid = void 0;
-const node_fetch_1 = __importDefault(require("node-fetch"));
-const https_1 = require("https");
-const util_1 = require("./util");
+import { isUuid, undashUuid } from './util.js';
+import fetch from 'node-fetch';
+import { Agent } from 'https';
// We need to create an agent to prevent memory leaks
-const httpsAgent = new https_1.Agent({
+const httpsAgent = new Agent({
keepAlive: true
});
/**
* Get mojang api data from the session server
*/
-async function profileFromUuid(uuid) {
+export let profileFromUuid = async function profileFromUuid(uuid) {
let fetchResponse;
try {
- fetchResponse = await node_fetch_1.default(
+ fetchResponse = await fetch(
// using mojang directly is faster than ashcon lol, also mojang removed the ratelimits from here
- `https://sessionserver.mojang.com/session/minecraft/profile/${util_1.undashUuid(uuid)}`, { agent: () => httpsAgent });
+ `https://sessionserver.mojang.com/session/minecraft/profile/${undashUuid(uuid)}`, { agent: () => httpsAgent });
}
catch {
// if there's an error, wait a second and try again
@@ -48,13 +42,12 @@ async function profileFromUuid(uuid) {
uuid: data.id,
username: data.name
};
-}
-exports.profileFromUuid = profileFromUuid;
-async function profileFromUsername(username) {
+};
+export let profileFromUsername = async function profileFromUsername(username) {
// since we don't care about anything other than the uuid, we can use /uuid/ instead of /user/
let fetchResponse;
try {
- fetchResponse = await node_fetch_1.default(`https://api.mojang.com/users/profiles/minecraft/${username}`, { agent: () => httpsAgent });
+ fetchResponse = await fetch(`https://api.mojang.com/users/profiles/minecraft/${username}`, { agent: () => httpsAgent });
}
catch {
// if there's an error, wait a second and try again
@@ -67,7 +60,7 @@ async function profileFromUsername(username) {
data = JSON.parse(rawData);
}
catch { }
- if (!(data === null || data === void 0 ? void 0 : data.id)) {
+ if (!data?.id) {
// return { uuid: null, username: null }
return await profileFromUsernameAlternative(username);
}
@@ -75,12 +68,11 @@ async function profileFromUsername(username) {
uuid: data.id,
username: data.name
};
-}
-exports.profileFromUsername = profileFromUsername;
-async function profileFromUsernameAlternative(username) {
+};
+export async function profileFromUsernameAlternative(username) {
let fetchResponse;
try {
- fetchResponse = await node_fetch_1.default(`https://api.ashcon.app/mojang/v2/user/${username}`, { agent: () => httpsAgent });
+ fetchResponse = await fetch(`https://api.ashcon.app/mojang/v2/user/${username}`, { agent: () => httpsAgent });
}
catch {
// if there's an error, wait a second and try again
@@ -97,16 +89,18 @@ async function profileFromUsernameAlternative(username) {
if (!data.uuid)
return { uuid: null, username: null };
return {
- uuid: util_1.undashUuid(data.uuid),
+ uuid: undashUuid(data.uuid),
username: data.username
};
}
-exports.profileFromUsernameAlternative = profileFromUsernameAlternative;
-async function profileFromUser(user) {
- if (util_1.isUuid(user)) {
+export let profileFromUser = async function profileFromUser(user) {
+ if (isUuid(user)) {
return await profileFromUuid(user);
}
else
return await profileFromUsername(user);
-}
-exports.profileFromUser = profileFromUser;
+};
+// this is necessary for mocking in the tests because es6
+export function mockProfileFromUuid($value) { profileFromUuid = $value; }
+export function mockProfileFromUsername($value) { profileFromUsername = $value; }
+export function mockProfileFromUser($value) { profileFromUser = $value; }
diff --git a/build/util.js b/build/util.js
index c0bbd42..e78e390 100644
--- a/build/util.js
+++ b/build/util.js
@@ -1,26 +1,20 @@
-"use strict";
/**
* Random utility functions that are not related to Hypixel
*/
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.isUuid = exports.sleep = exports.colorCodeFromName = exports.minecraftColorCodes = exports.shuffle = exports.jsonToQuery = exports.undashUuid = void 0;
-function undashUuid(uuid) {
+export function undashUuid(uuid) {
return uuid.replace(/-/g, '').toLowerCase();
}
-exports.undashUuid = undashUuid;
-function jsonToQuery(data) {
+export function jsonToQuery(data) {
return Object.entries(data || {}).map(e => e.join('=')).join('&');
}
-exports.jsonToQuery = jsonToQuery;
-function shuffle(a) {
+export function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
-exports.shuffle = shuffle;
-exports.minecraftColorCodes = {
+export const minecraftColorCodes = {
'0': '#000000',
'1': '#0000be',
'2': '#00be00',
@@ -59,21 +53,18 @@ exports.minecraftColorCodes = {
* For example: blue -> 9
* @param colorName The name of the color (blue, red, aqua, etc)
*/
-function colorCodeFromName(colorName) {
- const hexColor = exports.minecraftColorCodes[colorName.toLowerCase()];
- for (const key in exports.minecraftColorCodes) {
- const value = exports.minecraftColorCodes[key];
+export function colorCodeFromName(colorName) {
+ const hexColor = minecraftColorCodes[colorName.toLowerCase()];
+ for (const key in minecraftColorCodes) {
+ const value = minecraftColorCodes[key];
if (key.length === 1 && value === hexColor)
return key;
}
}
-exports.colorCodeFromName = colorCodeFromName;
-async function sleep(ms) {
+export async function sleep(ms) {
await new Promise(resolve => setTimeout(resolve, ms));
}
-exports.sleep = sleep;
/** Returns whether a string is a UUID4 (Minecraft uuid) */
-function isUuid(string) {
+export function isUuid(string) {
return undashUuid(string).length === 32;
}
-exports.isUuid = isUuid;
diff --git a/package-lock.json b/package-lock.json
index aa8d221..4837ce7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,2236 @@
{
"name": "skyblock-api",
"version": "1.0.0",
- "lockfileVersion": 1,
+ "lockfileVersion": 2,
"requires": true,
+ "packages": {
+ "": {
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "express": "^4.17.1",
+ "express-rate-limit": "^5.3.0",
+ "lru-cache": "^6.0.0",
+ "mongodb": "^4.1.1",
+ "node-cache": "^5.1.2",
+ "node-fetch": "^3.0.0",
+ "prismarine-nbt": "^1.6.0",
+ "queue-promise": "^2.2.1",
+ "uuid": "^8.3.2"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.13",
+ "@types/express-rate-limit": "^5.1.3",
+ "@types/lru-cache": "^5.1.1",
+ "@types/mocha": "^9.0.0",
+ "@types/mongodb": "^4.0.7",
+ "@types/node": "^16.7.10",
+ "dotenv": "^10.0.0",
+ "mocha": "^9.1.1",
+ "ts-node": "^10.2.1",
+ "typescript": "^4.4.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@cspotcode/source-map-consumer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+ "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
+ "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-consumer": "0.8.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+ "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+ "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+ "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
+ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+ "dev": true
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz",
+ "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==",
+ "dev": true,
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.13",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
+ "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
+ "dev": true,
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.18",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-rate-limit": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/@types/express-rate-limit/-/express-rate-limit-5.1.3.tgz",
+ "integrity": "sha512-H+TYy3K53uPU2TqPGFYaiWc2xJV6+bIFkDd/Ma2/h67Pa6ARk9kWE0p/K9OH1Okm0et9Sfm66fmXoAxsH2PHXg==",
+ "dev": true,
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.23.tgz",
+ "integrity": "sha512-WYqTtTPTJn9kXMdnAH5HPPb7ctXvBpP4PfuOb8MV4OHPQWHhDZixGlhgR159lJPpKm23WOdoCkt2//cCEaOJkw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
+ "node_modules/@types/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==",
+ "dev": true
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
+ "dev": true
+ },
+ "node_modules/@types/mocha": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz",
+ "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==",
+ "dev": true
+ },
+ "node_modules/@types/mongodb": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-4.0.7.tgz",
+ "integrity": "sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==",
+ "deprecated": "mongodb provides its own types. @types/mongodb is no longer needed.",
+ "dev": true,
+ "dependencies": {
+ "mongodb": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "16.7.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz",
+ "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA=="
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.6",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
+ "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==",
+ "dev": true
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+ "dev": true
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.13.10",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
+ "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/webidl-conversions": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
+ "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
+ "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/webidl-conversions": "*"
+ }
+ },
+ "node_modules/@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "dev": true
+ },
+ "node_modules/accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dependencies": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
+ "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
+ "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "dependencies": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "node_modules/bson": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.1.tgz",
+ "integrity": "sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA==",
+ "dependencies": {
+ "buffer": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
+ "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/denque": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
+ "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "node_modules/diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
+ "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "dependencies": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express-rate-limit": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz",
+ "integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew=="
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.2.tgz",
+ "integrity": "sha512-hunJbvy/6OLjCD0uuhLdp0mMPzP/yd2ssd1t2FCJsaA7wkWhpbp9xfuNVpv7Ll4jFhzp6T4LAupSiV9uOeg0VQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "dependencies": {
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.x"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "node_modules/lodash.reduce": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
+ "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs="
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "optional": true
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.45.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
+ "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.28",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
+ "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
+ "dependencies": {
+ "mime-db": "1.45.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz",
+ "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==",
+ "dev": true,
+ "dependencies": {
+ "@ungap/promise-all-settled": "1.1.2",
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.2",
+ "debug": "4.3.1",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.1.7",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "3.0.4",
+ "ms": "2.1.3",
+ "nanoid": "3.1.23",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "which": "2.0.2",
+ "wide-align": "1.1.3",
+ "workerpool": "6.1.5",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/mocha/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mocha/node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "node_modules/mongodb": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.1.1.tgz",
+ "integrity": "sha512-fbACrWEyvr6yl0sSiCGV0sqEiBwTtDJ8iSojmkDjAfw9JnOZSAkUyv9seFSPYhPPKwxp1PDtyjvBNfMDz0WBLQ==",
+ "dependencies": {
+ "bson": "^4.5.1",
+ "denque": "^1.5.0",
+ "mongodb-connection-string-url": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12.9.0"
+ },
+ "optionalDependencies": {
+ "saslprep": "^1.0.0"
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.0.0.tgz",
+ "integrity": "sha512-M0I1vyLoq5+HQTuPSJWbt+hIXsMCfE8sS1fS5mvP9R2DOMoi2ZD32yWqgBIITyu0dFu4qtS50erxKjvUeBiyog==",
+ "dependencies": {
+ "@types/whatwg-url": "^8.2.1",
+ "whatwg-url": "^9.1.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/nanoid": {
+ "version": "3.1.23",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
+ "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
+ "dev": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-cache": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
+ "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
+ "dependencies": {
+ "clone": "2.x"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0.tgz",
+ "integrity": "sha512-bKMI+C7/T/SPU1lKnbQbwxptpCrG9ashG+VkytmXCPZyuM9jB6VU+hY0oi4lC8LxTtAeWdckNCTa3nrGsAdA3Q==",
+ "dependencies": {
+ "data-uri-to-buffer": "^3.0.1",
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prismarine-nbt": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-1.6.0.tgz",
+ "integrity": "sha512-h0ECvIjjwjMOtsmHxHc8hNY7kzktnKqKXmOHF0AkmH7OjkcHNAFsWRiZNvfc76rOhNonRutHvTVAlh/eLtK0oA==",
+ "dependencies": {
+ "protodef": "^1.9.0"
+ }
+ },
+ "node_modules/protodef": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/protodef/-/protodef-1.14.0.tgz",
+ "integrity": "sha512-rL1WRlBC8LbAgBTa401eHMqnkX6zy1pHgS4kTSJVJ8rwP/AgVuWijGE3S3XHRkRjB/+4U1jMTqRdmtGdIqVOKQ==",
+ "dependencies": {
+ "lodash.get": "^4.4.2",
+ "lodash.reduce": "^4.6.0",
+ "protodef-validator": "^1.3.0",
+ "readable-stream": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/protodef-validator": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/protodef-validator/-/protodef-validator-1.3.1.tgz",
+ "integrity": "sha512-lZ5FWKZYR9xOjpMw1+EfZRfCjzNRQWPq+Dk+jki47Sikl2EeWEPnTfnJERwnU/EwFq6us+0zqHHzSsmLeYX+Lg==",
+ "dependencies": {
+ "ajv": "^6.5.4"
+ },
+ "bin": {
+ "protodef-validator": "cli.js"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+ "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "dependencies": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/queue-promise": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/queue-promise/-/queue-promise-2.2.1.tgz",
+ "integrity": "sha512-C3eyRwLF9m6dPV4MtqMVFX+Xmc7keZ9Ievm3jJ/wWM5t3uVbFnGsJXwpYzZ4LaIEcX9bss/mdaKzyrO6xheRuA==",
+ "engines": {
+ "node": ">=8.12.0"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "dependencies": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/saslprep": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+ "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+ "optional": true,
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
+ "optional": true,
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+ "dependencies": {
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz",
+ "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "0.6.1",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
+ "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.0.tgz",
+ "integrity": "sha512-wO9r1YnYe7kFBLHyyVEhV1H8VRWoNiNnuP+v/HUUmSTaRF8F93Kmd3JMrETx0f11GXxRek6OcL2QtjFIdc5WYw==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+ "engines": {
+ "node": ">=10.4"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz",
+ "integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==",
+ "dependencies": {
+ "tr46": "^2.1.0",
+ "webidl-conversions": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz",
+ "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
"dependencies": {
"@cspotcode/source-map-consumer": {
"version": "0.8.0",
@@ -126,15 +2354,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz",
"integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA=="
},
- "@types/node-fetch": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-3.0.3.tgz",
- "integrity": "sha512-HhggYPH5N+AQe/OmN6fmhKmRRt2XuNJow+R3pQwJxOOF9GuwM7O2mheyGeIrs5MOIeNjDEdgdoyHBOrFeJBR3g==",
- "dev": true,
- "requires": {
- "node-fetch": "*"
- }
- },
"@types/qs": {
"version": "6.9.6",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
@@ -481,6 +2700,11 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
+ "data-uri-to-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
+ "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og=="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -612,6 +2836,14 @@
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
+ "fetch-blob": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.2.tgz",
+ "integrity": "sha512-hunJbvy/6OLjCD0uuhLdp0mMPzP/yd2ssd1t2FCJsaA7wkWhpbp9xfuNVpv7Ll4jFhzp6T4LAupSiV9uOeg0VQ==",
+ "requires": {
+ "web-streams-polyfill": "^3.0.3"
+ }
+ },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1028,9 +3260,13 @@
}
},
"node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0.tgz",
+ "integrity": "sha512-bKMI+C7/T/SPU1lKnbQbwxptpCrG9ashG+VkytmXCPZyuM9jB6VU+hY0oi4lC8LxTtAeWdckNCTa3nrGsAdA3Q==",
+ "requires": {
+ "data-uri-to-buffer": "^3.0.1",
+ "fetch-blob": "^3.1.2"
+ }
},
"normalize-path": {
"version": "3.0.0",
@@ -1287,16 +3523,6 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -1312,6 +3538,16 @@
}
}
},
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -1434,6 +3670,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
+ "web-streams-polyfill": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.0.tgz",
+ "integrity": "sha512-wO9r1YnYe7kFBLHyyVEhV1H8VRWoNiNnuP+v/HUUmSTaRF8F93Kmd3JMrETx0f11GXxRek6OcL2QtjFIdc5WYw=="
+ },
"webidl-conversions": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
diff --git a/package.json b/package.json
index ec6faf6..3870277 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"start": "npm i --only=prod; node build/index.js"
},
"engines": {
- "node" : ">=16.0.0"
+ "node": ">=16.0.0"
},
"repository": {
"type": "git",
@@ -33,22 +33,22 @@
"lru-cache": "^6.0.0",
"mongodb": "^4.1.1",
"node-cache": "^5.1.2",
- "node-fetch": "^2.6.1",
+ "node-fetch": "^3.0.0",
"prismarine-nbt": "^1.6.0",
- "uuid": "^8.3.2",
- "queue-promise": "^2.2.1"
+ "queue-promise": "^2.2.1",
+ "uuid": "^8.3.2"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/express-rate-limit": "^5.1.3",
+ "@types/lru-cache": "^5.1.1",
"@types/mocha": "^9.0.0",
- "@types/node": "^16.7.10",
"@types/mongodb": "^4.0.7",
- "@types/lru-cache": "^5.1.1",
- "@types/node-fetch": "^3.0.3",
+ "@types/node": "^16.7.10",
"dotenv": "^10.0.0",
"mocha": "^9.1.1",
"ts-node": "^10.2.1",
"typescript": "^4.4.2"
- }
+ },
+ "type": "module"
}
diff --git a/src/cleaners/player.ts b/src/cleaners/player.ts
index b2dfc77..802cdd5 100644
--- a/src/cleaners/player.ts
+++ b/src/cleaners/player.ts
@@ -1,9 +1,9 @@
-import { cleanPlayerSkyblockProfiles } from './skyblock/profiles'
-import { cleanSocialMedia, CleanSocialMedia } from './socialmedia'
-import { CleanBasicProfile } from './skyblock/profile'
-import { cleanRank, CleanRank } from './rank'
-import { HypixelPlayer } from '../hypixelApi'
-import { undashUuid } from '../util'
+import { cleanPlayerSkyblockProfiles } from './skyblock/profiles.js'
+import { cleanSocialMedia, CleanSocialMedia } from './socialmedia.js'
+import { CleanBasicProfile } from './skyblock/profile.js'
+import { cleanRank, CleanRank } from './rank.js'
+import { HypixelPlayer } from '../hypixelApi.js'
+import { undashUuid } from '../util.js'
export interface CleanBasicPlayer {
uuid: string
diff --git a/src/cleaners/rank.ts b/src/cleaners/rank.ts
index 4892bf2..417c8f1 100644
--- a/src/cleaners/rank.ts
+++ b/src/cleaners/rank.ts
@@ -1,5 +1,5 @@
-import { colorCodeFromName, minecraftColorCodes } from '../util'
-import { HypixelPlayer } from '../hypixelApi'
+import { colorCodeFromName, minecraftColorCodes } from '../util.js'
+import { HypixelPlayer } from '../hypixelApi.js'
const rankColors: { [ name: string ]: string } = {
'NONE': '7',
diff --git a/src/cleaners/skyblock/collections.ts b/src/cleaners/skyblock/collections.ts
index 99fdc27..635bfce 100644
--- a/src/cleaners/skyblock/collections.ts
+++ b/src/cleaners/skyblock/collections.ts
@@ -1,4 +1,4 @@
-import { cleanItemId, hypixelItemNames } from "./itemId"
+import { cleanItemId, hypixelItemNames } from './itemId.js'
const COLLECTIONS = {
'farming': [
diff --git a/src/cleaners/skyblock/member.ts b/src/cleaners/skyblock/member.ts
index cee1864..a9a12b8 100644
--- a/src/cleaners/skyblock/member.ts
+++ b/src/cleaners/skyblock/member.ts
@@ -1,20 +1,20 @@
-import { cleanCollections, Collection } from './collections'
-import { cleanInventories, Inventories } from './inventory'
-import { cleanFairySouls, FairySouls } from './fairysouls'
-import { cleanObjectives, Objective } from './objectives'
-import { CleanFullProfileBasicMembers } from './profile'
-import { cleanProfileStats, StatItem } from './stats'
-import { CleanMinion, cleanMinions } from './minions'
-import { AccountCustomization } from '../../database'
-import { cleanSlayers, SlayerData } from './slayers'
-import { cleanVisitedZones, Zone } from './zones'
-import { cleanSkills, Skill } from './skills'
-import * as cached from '../../hypixelCached'
-import * as constants from '../../constants'
-import { Included } from '../../hypixel'
-import { CleanPlayer } from '../player'
-import { CleanRank } from '../rank'
-import { Bank } from './bank'
+import { cleanCollections, Collection } from './collections.js'
+import { cleanInventories, Inventories } from './inventory.js'
+import { cleanFairySouls, FairySouls } from './fairysouls.js'
+import { cleanObjectives, Objective } from './objectives.js'
+import { CleanFullProfileBasicMembers } from './profile.js'
+import { cleanProfileStats, StatItem } from './stats.js'
+import { CleanMinion, cleanMinions } from './minions.js'
+import { cleanSlayers, SlayerData } from './slayers.js'
+import { AccountCustomization } from '../../database.js'
+import { cleanVisitedZones, Zone } from './zones.js'
+import { cleanSkills, Skill } from './skills.js'
+import * as cached from '../../hypixelCached.js'
+import * as constants from '../../constants.js'
+import { Included } from '../../hypixel.js'
+import { CleanPlayer } from '../player.js'
+import { CleanRank } from '../rank.js'
+import { Bank } from './bank.js'
export interface CleanBasicMember {
uuid: string
diff --git a/src/cleaners/skyblock/minions.ts b/src/cleaners/skyblock/minions.ts
index d045a7e..2e51896 100644
--- a/src/cleaners/skyblock/minions.ts
+++ b/src/cleaners/skyblock/minions.ts
@@ -1,5 +1,5 @@
-import { maxMinion } from '../../hypixel'
-import * as constants from '../../constants'
+import { maxMinion } from '../../hypixel.js'
+import * as constants from '../../constants.js'
export interface CleanMinion {
name: string,
diff --git a/src/cleaners/skyblock/profile.ts b/src/cleaners/skyblock/profile.ts
index e4d2a94..34c895a 100644
--- a/src/cleaners/skyblock/profile.ts
+++ b/src/cleaners/skyblock/profile.ts
@@ -1,8 +1,8 @@
-import { CleanBasicMember, CleanMember, cleanSkyBlockProfileMemberResponse, cleanSkyBlockProfileMemberResponseBasic } from './member'
-import { CleanMinion, combineMinionArrays, countUniqueMinions } from './minions'
-import { ApiOptions } from '../../hypixel'
-import { Bank, cleanBank } from './bank'
-import * as constants from '../../constants'
+import { CleanBasicMember, CleanMember, cleanSkyBlockProfileMemberResponse, cleanSkyBlockProfileMemberResponseBasic } from './member.js'
+import { CleanMinion, combineMinionArrays, countUniqueMinions } from './minions.js'
+import * as constants from '../../constants.js'
+import { ApiOptions } from '../../hypixel.js'
+import { Bank, cleanBank } from './bank.js'
export interface CleanProfile extends CleanBasicProfile {
members?: CleanBasicMember[]
diff --git a/src/cleaners/skyblock/profiles.ts b/src/cleaners/skyblock/profiles.ts
index a068dae..ec026de 100644
--- a/src/cleaners/skyblock/profiles.ts
+++ b/src/cleaners/skyblock/profiles.ts
@@ -1,10 +1,10 @@
-import { HypixelPlayerStatsSkyBlockProfiles } from '../../hypixelApi'
+import { HypixelPlayerStatsSkyBlockProfiles } from '../../hypixelApi.js'
import {
CleanBasicProfile,
CleanFullProfile,
CleanProfile,
cleanSkyblockProfileResponse
-} from './profile'
+} from './profile.js'
export function cleanPlayerSkyblockProfiles(rawProfiles: HypixelPlayerStatsSkyBlockProfiles): CleanBasicProfile[] {
let profiles: CleanBasicProfile[] = []
diff --git a/src/cleaners/skyblock/skills.ts b/src/cleaners/skyblock/skills.ts
index 7aa4e2c..886c59c 100644
--- a/src/cleaners/skyblock/skills.ts
+++ b/src/cleaners/skyblock/skills.ts
@@ -1,4 +1,4 @@
-import { fetchSkillXp, fetchSkillXpEasier } from '../../constants'
+import { fetchSkillXp, fetchSkillXpEasier } from '../../constants.js'
export interface Skill {
name: string
diff --git a/src/constants.ts b/src/constants.ts
index dcb9acf..13fc21d 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -3,14 +3,14 @@
*/
// we have to do this so we can mock the function from the tests properly
-import * as constants from './constants'
+import * as constants from './constants.js'
import * as nodeFetch from 'node-fetch'
import NodeCache from 'node-cache'
+import { debug } from './index.js'
import Queue from 'queue-promise'
import fetch from 'node-fetch'
import { Agent } from 'https'
-import { debug } from '.'
const httpsAgent = new Agent({
keepAlive: true
@@ -87,7 +87,7 @@ function fetchFile(path: string): Promise<GithubFile> {
'Accept': 'application/vnd.github.v3+json',
},
)
- const data = await r.json()
+ const data = await r.json() as any
const file = {
path: data.path,
@@ -118,7 +118,7 @@ async function editFile(file: GithubFile, message: string, newContent: string):
branch: 'main'
}
)
- const data = await r.json()
+ const data = await r.json() as any
fileCache.set(file.path, {
path: data.content.path,
content: newContent,
@@ -126,7 +126,7 @@ async function editFile(file: GithubFile, message: string, newContent: string):
})
}
-export async function fetchJSONConstant(filename: string): Promise<any> {
+export let fetchJSONConstant = async function fetchJSONConstant(filename: string): Promise<any> {
const file = await fetchFile(filename)
try {
return JSON.parse(file.content)
@@ -137,7 +137,7 @@ export async function fetchJSONConstant(filename: string): Promise<any> {
}
/** Add stats to skyblock-constants. This has caching so it's fine to call many times */
-export async function addJSONConstants(filename: string, addingValues: string[], unit: string='stat'): Promise<void> {
+export let addJSONConstants = async function addJSONConstants(filename: string, addingValues: string[], unit: string='stat'): Promise<void> {
if (addingValues.length === 0) return // no stats provided, just return
let file: GithubFile = await fetchFile(filename)
@@ -269,4 +269,9 @@ export async function setConstantValues(newValues: constantValues) {
try {
await editFile(file, commitMessage, JSON.stringify(updatedStats, null, 2))
} catch {}
-} \ No newline at end of file
+}
+
+
+// this is necessary for mocking in the tests because es6
+export function mockAddJSONConstants($value) { addJSONConstants = $value }
+export function mockFetchJSONConstant($value) { fetchJSONConstant = $value }
diff --git a/src/database.ts b/src/database.ts
index 0e16d48..5cd10db 100644
--- a/src/database.ts
+++ b/src/database.ts
@@ -2,20 +2,20 @@
* Store data about members for leaderboards
*/
-import { categorizeStat, getStatUnit } from './cleaners/skyblock/stats'
-import { CleanFullProfile } from './cleaners/skyblock/profile'
-import { slayerLevels } from './cleaners/skyblock/slayers'
-import { CleanMember } from './cleaners/skyblock/member'
+import { categorizeStat, getStatUnit } from './cleaners/skyblock/stats.js'
+import { CleanFullProfile } from './cleaners/skyblock/profile.js'
+import { slayerLevels } from './cleaners/skyblock/slayers.js'
+import { CleanMember } from './cleaners/skyblock/member.js'
import { Collection, Db, MongoClient } from 'mongodb'
-import { CleanPlayer } from './cleaners/player'
-import * as cached from './hypixelCached'
-import * as constants from './constants'
-import { shuffle, sleep } from './util'
-import * as discord from './discord'
+import { CleanPlayer } from './cleaners/player.js'
+import * as cached from './hypixelCached.js'
+import * as constants from './constants.js'
+import { shuffle, sleep } from './util.js'
+import * as discord from './discord.js'
import NodeCache from 'node-cache'
import { v4 as uuid4 } from 'uuid'
import Queue from 'queue-promise'
-import { debug } from '.'
+import { debug } from './index.js'
// don't update the user for 3 minutes
const recentlyUpdated = new NodeCache({
@@ -121,7 +121,7 @@ async function connect(): Promise<void> {
return console.warn('Warning: db_uri was not found in .env. Features that utilize the database such as leaderboards won\'t work.')
if (!process.env.db_name)
return console.warn('Warning: db_name was not found in .env. Features that utilize the database such as leaderboards won\'t work.')
- client = await MongoClient.connect(process.env.db_uri, { useNewUrlParser: true, useUnifiedTopology: true })
+ client = await MongoClient.connect(process.env.db_uri)
database = client.db(process.env.db_name)
memberLeaderboardsCollection = database.collection('member-leaderboards')
profileLeaderboardsCollection = database.collection('profile-leaderboards')
@@ -803,6 +803,7 @@ export async function updateAccount(discordId: string, schema: AccountSchema) {
}
// make sure it's not in a test
+console.log('global.isTest', globalThis.isTest)
if (!globalThis.isTest) {
connect().then(() => {
// when it connects, cache the leaderboards and remove bad members
diff --git a/src/discord.ts b/src/discord.ts
index fac5438..067b899 100644
--- a/src/discord.ts
+++ b/src/discord.ts
@@ -50,7 +50,7 @@ export async function exchangeCode(redirectUri: string, code: string): Promise<T
body: new URLSearchParams(data).toString()
}
)
- return await fetchResponse.json()
+ return await fetchResponse.json() as TokenResponse | null
}
@@ -63,5 +63,5 @@ export async function getUser(accessToken: string): Promise<DiscordUser> {
agent: () => httpsAgent,
}
)
- return response.json()
+ return await response.json() as DiscordUser
}
diff --git a/src/hypixel.ts b/src/hypixel.ts
index d6f9661..8811624 100644
--- a/src/hypixel.ts
+++ b/src/hypixel.ts
@@ -2,14 +2,26 @@
* Fetch the clean Hypixel API
*/
-import { cleanSkyblockProfileResponse, CleanProfile, CleanBasicProfile, CleanFullProfile, CleanFullProfileBasicMembers } from './cleaners/skyblock/profile'
-import { AccountCustomization, AccountSchema, fetchAccount, queueUpdateDatabaseMember, queueUpdateDatabaseProfile } from './database'
-import { CleanBasicMember, CleanMemberProfile } from './cleaners/skyblock/member'
-import { chooseApiKey, HypixelResponse, sendApiRequest } from './hypixelApi'
-import { cleanSkyblockProfilesResponse } from './cleaners/skyblock/profiles'
-import { CleanPlayer, cleanPlayerResponse } from './cleaners/player'
-import * as cached from './hypixelCached'
-import { debug } from '.'
+import {
+ cleanSkyblockProfileResponse,
+ CleanProfile,
+ CleanBasicProfile,
+ CleanFullProfile,
+ CleanFullProfileBasicMembers
+} from './cleaners/skyblock/profile.js'
+import {
+ AccountCustomization,
+ AccountSchema,
+ fetchAccount,
+ queueUpdateDatabaseMember,
+ queueUpdateDatabaseProfile
+} from './database.js'
+import { CleanBasicMember, CleanMemberProfile } from './cleaners/skyblock/member.js'
+import { chooseApiKey, HypixelResponse, sendApiRequest } from './hypixelApi.js'
+import { cleanSkyblockProfilesResponse } from './cleaners/skyblock/profiles.js'
+import { CleanPlayer, cleanPlayerResponse } from './cleaners/player.js'
+import * as cached from './hypixelCached.js'
+import { debug } from './index.js'
export type Included = 'profiles' | 'player' | 'stats' | 'inventories' | undefined
diff --git a/src/hypixelApi.ts b/src/hypixelApi.ts
index 1b57d8f..dd5e08c 100644
--- a/src/hypixelApi.ts
+++ b/src/hypixelApi.ts
@@ -3,12 +3,12 @@
*/
import fetch from 'node-fetch'
import * as nodeFetch from 'node-fetch'
-import { jsonToQuery, shuffle } from './util'
+import { jsonToQuery, shuffle } from './util.js'
import { Agent } from 'https'
if (!process.env.hypixel_keys)
// if there's no hypixel keys in env, run dotenv
- require('dotenv').config()
+ (await import('dotenv')).config()
// We need to create an agent to prevent memory leaks and to only do dns lookups once
const httpsAgent = new Agent({
@@ -139,7 +139,7 @@ export interface HypixelPlayer {
}
/** Send an HTTP request to the Hypixel API */
-export async function sendApiRequest({ path, key, args }): Promise<HypixelResponse> {
+export let sendApiRequest = async function sendApiRequest({ path, key, args }): Promise<HypixelResponse> {
// Send a raw http request to api.hypixel.net, and return the parsed json
if (key)
@@ -188,3 +188,5 @@ export async function sendApiRequest({ path, key, args }): Promise<HypixelRespon
return fetchJsonParsed
}
+// this is necessary for mocking in the tests because es6
+export function mockSendApiRequest($value) { sendApiRequest = $value } \ No newline at end of file
diff --git a/src/hypixelCached.ts b/src/hypixelCached.ts
index 51dca5f..73e75aa 100644
--- a/src/hypixelCached.ts
+++ b/src/hypixelCached.ts
@@ -2,14 +2,14 @@
* Fetch the clean and cached Hypixel API
*/
+import { CleanProfile, CleanFullProfile, CleanBasicProfile } from './cleaners/skyblock/profile.js'
+import { CleanPlayer } from './cleaners/player.js'
+import { isUuid, undashUuid } from './util.js'
+import * as hypixel from './hypixel.js'
+import * as mojang from './mojang.js'
import NodeCache from 'node-cache'
+import { debug } from './index.js'
import LRUCache from 'lru-cache'
-import * as mojang from './mojang'
-import * as hypixel from './hypixel'
-import { CleanPlayer } from './cleaners/player'
-import { isUuid, undashUuid } from './util'
-import { CleanProfile, CleanFullProfile, CleanBasicProfile } from './cleaners/skyblock/profile'
-import { debug } from '.'
// cache usernames for 30 minutes
/** uuid: username */
diff --git a/src/index.ts b/src/index.ts
index 647038f..1327771 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,10 +1,10 @@
-import { createSession, fetchAccountFromDiscord, fetchAllLeaderboardsCategorized, fetchLeaderboard, fetchMemberLeaderboardSpots, fetchSession, finishedCachingRawLeaderboards, leaderboardUpdateMemberQueue, leaderboardUpdateProfileQueue, updateAccount } from './database'
-import { fetchMemberProfile, fetchUser } from './hypixel'
+import { createSession, fetchAccountFromDiscord, fetchAllLeaderboardsCategorized, fetchLeaderboard, fetchMemberLeaderboardSpots, fetchSession, finishedCachingRawLeaderboards, leaderboardUpdateMemberQueue, leaderboardUpdateProfileQueue, updateAccount } from './database.js'
+import { fetchMemberProfile, fetchUser } from './hypixel.js'
import rateLimit from 'express-rate-limit'
-import * as constants from './constants'
-import * as discord from './discord'
+import * as constants from './constants.js'
+import * as discord from './discord.js'
import express from 'express'
-import { getKeyUsage } from './hypixelApi'
+import { getKeyUsage } from './hypixelApi.js'
const app = express()
diff --git a/src/mojang.ts b/src/mojang.ts
index 84c8c7d..9b224d6 100644
--- a/src/mojang.ts
+++ b/src/mojang.ts
@@ -2,10 +2,10 @@
* Fetch the Mojang username API through api.ashcon.app
*/
-import fetch from 'node-fetch'
+import { isUuid, undashUuid } from './util.js'
import * as nodeFetch from 'node-fetch'
+import fetch from 'node-fetch'
import { Agent } from 'https'
-import { isUuid, undashUuid } from './util'
// We need to create an agent to prevent memory leaks
const httpsAgent = new Agent({
@@ -21,7 +21,7 @@ interface MojangApiResponse {
/**
* Get mojang api data from the session server
*/
-export async function profileFromUuid(uuid: string): Promise<MojangApiResponse> {
+export let profileFromUuid = async function profileFromUuid(uuid: string): Promise<MojangApiResponse> {
let fetchResponse: nodeFetch.Response
try {
@@ -56,7 +56,7 @@ export async function profileFromUuid(uuid: string): Promise<MojangApiResponse>
}
-export async function profileFromUsername(username: string): Promise<MojangApiResponse> {
+export let profileFromUsername = async function profileFromUsername(username: string): Promise<MojangApiResponse> {
// since we don't care about anything other than the uuid, we can use /uuid/ instead of /user/
let fetchResponse: nodeFetch.Response
@@ -118,9 +118,15 @@ export async function profileFromUsernameAlternative(username: string): Promise<
}
}
-export async function profileFromUser(user: string): Promise<MojangApiResponse> {
+export let profileFromUser = async function profileFromUser(user: string): Promise<MojangApiResponse> {
if (isUuid(user)) {
return await profileFromUuid(user)
} else
return await profileFromUsername(user)
}
+
+
+// this is necessary for mocking in the tests because es6
+export function mockProfileFromUuid($value) { profileFromUuid = $value }
+export function mockProfileFromUsername($value) { profileFromUsername = $value }
+export function mockProfileFromUser($value) { profileFromUser = $value }
diff --git a/test/test.js b/test/test.js
index bb96849..88c2ba9 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,15 +1,17 @@
globalThis.isTest = true
+console.log('set globalThis.isTest to true', globalThis.isTest)
-const { levelForSkillXp } = require('../build/cleaners/skyblock/skills')
-const hypixelCached = require('../build/hypixelCached')
-const hypixelApi = require('../build/hypixelApi')
-const constants = require('../build/constants')
-const hypixel = require('../build/hypixel')
-const mojang = require('../build/mojang')
-const util = require('../build/util')
-const assert = require('assert')
-const path = require('path')
-const fs = require('fs')
+// we use `await import` instead of `import from` so globalThis.isTest is set before importing the modules
+const { levelForSkillXp } = await import('../build/cleaners/skyblock/skills.js')
+const hypixelCached = await import('../build/hypixelCached.js')
+const hypixelApi = await import('../build/hypixelApi.js')
+const constants = await import('../build/constants.js')
+const hypixel = await import('../build/hypixel.js')
+const mojang = await import('../build/mojang.js')
+const util = await import('../build/util.js')
+const assert = await import('assert')
+const path = await import('path')
+const fs = await import('fs')
const cachedJsonData = {}
@@ -26,7 +28,7 @@ async function readJsonData(dir) {
return parsedData
}
-hypixelApi.sendApiRequest = async ({ path, key, args }) => {
+hypixelApi.mockSendApiRequest(async ({ path, key, args }) => {
requestsSent ++
switch (path) {
case 'player': {
@@ -37,32 +39,32 @@ hypixelApi.sendApiRequest = async ({ path, key, args }) => {
}
}
console.log(path, args)
-}
+})
-mojang.profileFromUuid = async (uuid) => {
+mojang.mockProfileFromUuid(async (uuid) => {
requestsSent ++
const uuidToUsername = await readJsonData('mojang')
const undashedUuid = undashUuid(uuid)
const username = uuidToUsername[undashUuid(undashedUuid)]
return { username, uuid: undashedUuid }
-}
-mojang.profileFromUsername = async (username) => {
+})
+mojang.mockProfileFromUsername(async (username) => {
requestsSent ++
const uuidToUsername = await readJsonData('mojang')
const uuid = Object.keys(uuidToUsername).find(uuid => uuidToUsername[uuid] === username)
return { username, uuid }
-}
-mojang.profileFromUser = async (user) => {
+})
+mojang.mockProfileFromUser(async (user) => {
if (util.isUuid(user))
return await mojang.profileFromUuid(user)
else
return await mojang.profileFromUsername(user)
-}
+})
-constants.addJSONConstants = async(filename, addingValues, unit) => {}
-constants.fetchJSONConstant = async(filename) => {
+constants.mockAddJSONConstants(async(filename, addingValues, unit) => {})
+constants.mockFetchJSONConstant(async(filename) => {
return await readJsonData('constants/' + filename.slice(0, filename.length - '.json'.length))
-}
+})
/** Clear all the current caches and stuff */
diff --git a/tsconfig.json b/tsconfig.json
index d54082d..927f459 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,12 @@
{
"compilerOptions": {
- "module": "commonjs",
+ "module": "ESNext",
"lib": ["esnext", "dom", "DOM.Iterable"],
- "target": "es2019",
+ "target": "ESNext",
"esModuleInterop": true,
"outDir": "build",
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "moduleResolution": "node"
},
"include": ["src"],
"exclude": ["**/node_modules"],