aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat-1 <github@matdoes.dev>2021-02-28 07:23:42 +0000
committermat-1 <github@matdoes.dev>2021-02-28 07:23:42 +0000
commit3fb0c21c294a4ff02353e5726d5ef1c21c39cb0d (patch)
treedee9c60e13ba2876b02791cc10d8d16b3bb6cc06
parent6dadf95683a8b8574976c9d024b0b148521012f7 (diff)
downloadskyblock-api-3fb0c21c294a4ff02353e5726d5ef1c21c39cb0d.tar.gz
skyblock-api-3fb0c21c294a4ff02353e5726d5ef1c21c39cb0d.tar.bz2
skyblock-api-3fb0c21c294a4ff02353e5726d5ef1c21c39cb0d.zip
Compiled TS into JS
-rw-r--r--build/cleaners/rank.js10
-rw-r--r--build/cleaners/skyblock/profile.js7
-rw-r--r--build/constants.js42
-rw-r--r--build/database.js64
-rw-r--r--build/hypixelCached.js11
-rw-r--r--build/index.js6
-rw-r--r--package-lock.json876
7 files changed, 115 insertions, 901 deletions
diff --git a/build/cleaners/rank.js b/build/cleaners/rank.js
index 2b8fb77..a9e5f35 100644
--- a/build/cleaners/rank.js
+++ b/build/cleaners/rank.js
@@ -25,10 +25,12 @@ function cleanRank({ packageRank, newPackageRank, monthlyPackageRank, rankPlusCo
name = colored.replace(/ยง./g, '').replace(/[\[\]]/g, '');
}
else {
- name = monthlyPackageRank
- || rank
- || (newPackageRank === null || newPackageRank === void 0 ? void 0 : newPackageRank.replace('_PLUS', '+'))
- || (packageRank === null || packageRank === void 0 ? void 0 : packageRank.replace('_PLUS', '+'));
+ if (monthlyPackageRank !== 'NONE')
+ name = monthlyPackageRank;
+ else
+ name = rank
+ || (newPackageRank === null || newPackageRank === void 0 ? void 0 : newPackageRank.replace('_PLUS', '+'))
+ || (packageRank === null || packageRank === void 0 ? void 0 : packageRank.replace('_PLUS', '+'));
// MVP++ is called Superstar for some reason
if (name === 'SUPERSTAR')
name = 'MVP++';
diff --git a/build/cleaners/skyblock/profile.js b/build/cleaners/skyblock/profile.js
index fe1161e..3a6bc6f 100644
--- a/build/cleaners/skyblock/profile.js
+++ b/build/cleaners/skyblock/profile.js
@@ -26,13 +26,14 @@ exports.cleanSkyblockProfileResponseLighter = cleanSkyblockProfileResponseLighte
* 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) {
- const cleanedMembers = [];
+ // We use Promise.all so it can fetch all the users 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;
- const member = await member_1.cleanSkyBlockProfileMemberResponse(memberRaw, ['stats', (options === null || options === void 0 ? void 0 : options.mainMemberUuid) === memberUUID ? 'inventories' : undefined]);
- cleanedMembers.push(member);
+ promises.push(member_1.cleanSkyBlockProfileMemberResponse(memberRaw, ['stats', (options === null || options === void 0 ? void 0 : options.mainMemberUuid) === memberUUID ? 'inventories' : undefined]));
}
+ const cleanedMembers = await Promise.all(promises);
const memberMinions = [];
for (const member of cleanedMembers) {
memberMinions.push(member.minions);
diff --git a/build/constants.js b/build/constants.js
index 23d2b75..ff6155b 100644
--- a/build/constants.js
+++ b/build/constants.js
@@ -6,7 +6,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
-exports.addStats = exports.fetchStats = void 0;
+exports.addCollections = exports.addStats = exports.fetchCollections = exports.fetchStats = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
const https_1 = require("https");
const node_cache_1 = __importDefault(require("node-cache"));
@@ -81,6 +81,18 @@ async function fetchStats() {
}
}
exports.fetchStats = fetchStats;
+/** Fetch all the known SkyBlock collections as an array of strings */
+async function fetchCollections() {
+ const file = await fetchFile('collections.json');
+ try {
+ return JSON.parse(file.content);
+ }
+ catch {
+ // probably invalid json, return an empty array
+ return [];
+ }
+}
+exports.fetchCollections = fetchCollections;
/** Add stats to skyblock-constants. This has caching so it's fine to call many times */
async function addStats(addingStats) {
if (addingStats.length === 0)
@@ -109,3 +121,31 @@ async function addStats(addingStats) {
await editFile(file, commitMessage, JSON.stringify(updatedStats, null, 2));
}
exports.addStats = addStats;
+/** Add stats to skyblock-constants. This has caching so it's fine to call many times */
+async function addCollections(addingCollections) {
+ if (addingCollections.length === 0)
+ return; // no stats provided, just return
+ const file = await fetchFile('collections.json');
+ if (!file.path)
+ return;
+ let oldCollections;
+ try {
+ oldCollections = JSON.parse(file.content);
+ }
+ catch {
+ // invalid json, set it as an empty array
+ oldCollections = [];
+ }
+ const updatedCollections = oldCollections
+ .concat(addingCollections)
+ // remove duplicates
+ .filter((value, index, array) => array.indexOf(value) === index)
+ .sort((a, b) => a.localeCompare(b));
+ const newCollections = updatedCollections.filter(value => !oldCollections.includes(value));
+ // there's not actually any new stats, just return
+ if (newCollections.length === 0)
+ return;
+ const commitMessage = newCollections.length >= 2 ? `Add ${newCollections.length} new collections` : `Add '${newCollections[0]}'`;
+ await editFile(file, commitMessage, JSON.stringify(updatedCollections, null, 2));
+}
+exports.addCollections = addCollections;
diff --git a/build/database.js b/build/database.js
index 31c85ee..737b0a3 100644
--- a/build/database.js
+++ b/build/database.js
@@ -25,8 +25,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
-exports.updateDatabaseMember = void 0;
+exports.updateDatabaseMember = exports.fetchMemberLeaderboard = void 0;
const constants = __importStar(require("./constants"));
+const cached = __importStar(require("./hypixelCached"));
const mongodb_1 = require("mongodb");
const node_cache_1 = __importDefault(require("node-cache"));
// don't update the user for 3 minutes
@@ -57,7 +58,7 @@ function getMemberCollectionAttributes(member) {
return collectionAttributes;
}
function getMemberLeaderboardAttributes(member) {
- // if you want to add a new leaderboard for member attributes, add it here
+ // if you want to add a new leaderboard for member attributes, add it here (and getAllLeaderboardAttributes)
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
...member.rawHypixelStats,
@@ -69,6 +70,19 @@ function getMemberLeaderboardAttributes(member) {
visited_zones: member.visited_zones.length,
};
}
+/** Fetch the names of all the leaderboards */
+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(),
+ // collection leaderboards
+ ...(await constants.fetchCollections()).map(value => `collection_${value}`),
+ 'fairy_souls',
+ 'first_join',
+ 'purse',
+ 'visited_zones',
+ ];
+}
async function fetchMemberLeaderboard(name) {
if (cachedLeaderboards.has(name))
return cachedLeaderboards.get(name);
@@ -76,16 +90,28 @@ async function fetchMemberLeaderboard(name) {
const query = {};
query[`stats.${name}`] = { '$exists': true };
const sortQuery = {};
- sortQuery[`stats.${name}`] = 1;
- const leaderboard = await memberLeaderboardsCollection.find(query).sort(sortQuery).toArray();
+ sortQuery[`stats.${name}`] = -1;
+ const leaderboardRaw = await memberLeaderboardsCollection.find(query).sort(sortQuery).limit(100).toArray();
+ const fetchLeaderboardPlayer = async (item) => {
+ return {
+ player: await cached.fetchPlayer(item.uuid),
+ value: item.stats[name]
+ };
+ };
+ const promises = [];
+ for (const item of leaderboardRaw) {
+ promises.push(fetchLeaderboardPlayer(item));
+ }
+ const leaderboard = await Promise.all(promises);
cachedLeaderboards.set(name, leaderboard);
return leaderboard;
}
-async function getLeaderboardRequirement(name) {
+exports.fetchMemberLeaderboard = fetchMemberLeaderboard;
+async function getMemberLeaderboardRequirement(name) {
const leaderboard = await fetchMemberLeaderboard(name);
// if there's more than 100 items, return the 100th. if there's less, return null
- if (leaderboard.length > 100)
- return leaderboard[100].stats[name];
+ if (leaderboard.length >= 100)
+ return leaderboard[99].value;
else
return null;
}
@@ -99,6 +125,7 @@ async function updateDatabaseMember(member) {
// store the member in recentlyUpdated so it cant update for 3 more minutes
recentlyUpdated.set(member.uuid, true);
await constants.addStats(Object.keys(member.rawHypixelStats));
+ await constants.addCollections(member.collections.map(value => value.name));
const leaderboardAttributes = getMemberLeaderboardAttributes(member);
await memberLeaderboardsCollection.updateOne({
uuid: member.uuid
@@ -112,4 +139,25 @@ async function updateDatabaseMember(member) {
});
}
exports.updateDatabaseMember = updateDatabaseMember;
-connect();
+/**
+ * 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();
+ for (const leaderboard of leaderboards) {
+ // wait 10 seconds so it doesnt use as much ram
+ await new Promise(resolve => setTimeout(resolve, 10000));
+ const unsetValue = {};
+ unsetValue[leaderboard] = '';
+ const filter = {};
+ const requirement = await getMemberLeaderboardRequirement(leaderboard);
+ if (requirement !== null) {
+ filter[`stats.${leaderboard}`] = {
+ '$lt': requirement
+ };
+ await memberLeaderboardsCollection.updateMany(filter, { '$unset': unsetValue });
+ }
+ }
+}
+connect()
+ .then(removeBadMemberLeaderboardAttributes);
diff --git a/build/hypixelCached.js b/build/hypixelCached.js
index 5a970f8..67d34d9 100644
--- a/build/hypixelCached.js
+++ b/build/hypixelCached.js
@@ -81,9 +81,8 @@ async function uuidFromUser(user) {
if (usernameCache.has(util_1.undashUuid(user))) {
// check if the uuid is a key
const username = usernameCache.get(util_1.undashUuid(user));
- // if it has .then, then that means its a waitForSet promise
+ // if it has .then, then that means its a waitForSet promise. This is done to prevent requests made while it is already requesting
if (username.then) {
- console.log('pog, prevented double request');
return (await username()).key;
}
else
@@ -92,15 +91,13 @@ async function uuidFromUser(user) {
// check if the username is a value
const uuidToUsername = usernameCache.mget(usernameCache.keys());
for (const [uuid, username] of Object.entries(uuidToUsername)) {
- if (user.toLowerCase() === username.toLowerCase())
+ if (username.toLowerCase && user.toLowerCase() === username.toLowerCase())
return uuid;
}
if (_1.debug)
console.log('Cache miss: uuidFromUser', user);
// set it as waitForSet (a promise) in case uuidFromUser gets called while its fetching mojang
- console.log('setting', util_1.undashUuid(user));
usernameCache.set(util_1.undashUuid(user), waitForSet(usernameCache, user, user));
- console.log(util_1.undashUuid(user), usernameCache.has(util_1.undashUuid(user)));
// not cached, actually fetch mojang api now
let { uuid, username } = await mojang.mojangDataFromUser(user);
if (!uuid)
@@ -134,12 +131,8 @@ exports.usernameFromUser = usernameFromUser;
async function fetchPlayer(user) {
const playerUuid = await uuidFromUser(user);
if (playerCache.has(playerUuid)) {
- if (_1.debug)
- console.log('Cache hit! fetchPlayer', user);
return playerCache.get(playerUuid);
}
- if (_1.debug)
- console.log('Cache miss: uuidFromUser', user);
const cleanPlayer = await hypixel.sendCleanApiRequest({
path: 'player',
args: { uuid: playerUuid }
diff --git a/build/index.js b/build/index.js
index 3174e69..52e711c 100644
--- a/build/index.js
+++ b/build/index.js
@@ -6,8 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.debug = void 0;
const hypixel_1 = require("./hypixel");
const express_1 = __importDefault(require("express"));
+const database_1 = require("./database");
const app = express_1.default();
-exports.debug = true;
+exports.debug = false;
app.use((req, res, next) => {
if (process.env.key && req.headers.key !== process.env.key)
// if a key is set in process.env and the header doesn't match return an error
@@ -24,4 +25,7 @@ app.get('/player/:user', async (req, res) => {
app.get('/player/:user/:profile', async (req, res) => {
res.json(await hypixel_1.fetchMemberProfile(req.params.user, req.params.profile));
});
+app.get('/leaderboard/:name', async (req, res) => {
+ res.json(await database_1.fetchMemberLeaderboard(req.params.name));
+});
app.listen(8080, () => console.log('App started :)'));
diff --git a/package-lock.json b/package-lock.json
index b2561d7..b0b54fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,882 +1,8 @@
{
"name": "skyblock-api",
"version": "1.0.0",
- "lockfileVersion": 2,
+ "lockfileVersion": 1,
"requires": true,
- "packages": {
- "": {
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "express": "^4.17.1",
- "mongodb": "^3.6.4",
- "node-cache": "^5.1.2",
- "node-fetch": "^2.6.1",
- "prismarine-nbt": "^1.4.0"
- },
- "devDependencies": {
- "@types/mongodb": "^3.6.8",
- "@types/node": "^14.14.28",
- "@types/node-fetch": "^2.5.8",
- "dotenv": "^8.2.0"
- }
- },
- "node_modules/@types/bson": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz",
- "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/mongodb": {
- "version": "3.6.8",
- "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.8.tgz",
- "integrity": "sha512-8qNbL5/GFrljXc/QijcuQcUMYZ1iWNcqnJ6tneROwbfU0LsAjQ9bmq3aHi5lWXM4cyBPd2F/n9INAk/pZZttHw==",
- "dev": true,
- "dependencies": {
- "@types/bson": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/node": {
- "version": "14.14.28",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.28.tgz",
- "integrity": "sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g==",
- "dev": true
- },
- "node_modules/@types/node-fetch": {
- "version": "2.5.8",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.8.tgz",
- "integrity": "sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw==",
- "dev": true,
- "dependencies": {
- "@types/node": "*",
- "form-data": "^3.0.0"
- }
- },
- "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/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"
- }
- },
- "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/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
- "dev": true
- },
- "node_modules/bl": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
- "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
- "dependencies": {
- "readable-stream": "^2.3.5",
- "safe-buffer": "^5.1.1"
- }
- },
- "node_modules/bl/node_modules/readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/bl/node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
- },
- "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/bson": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
- "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==",
- "engines": {
- "node": ">=0.6.19"
- }
- },
- "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/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/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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/core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "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/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
- "dev": true,
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/denque": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
- "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==",
- "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/dotenv": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
- "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "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/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/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "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/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/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/form-data": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
- "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
- "dev": true,
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "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/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/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/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "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/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/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/mongodb": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz",
- "integrity": "sha512-Y+Ki9iXE9jI+n9bVtbTOOdK0B95d6wVGSucwtBkvQ+HIvVdTCfpVRp01FDC24uhC/Q2WXQ8Lpq3/zwtB5Op9Qw==",
- "dependencies": {
- "bl": "^2.2.1",
- "bson": "^1.1.4",
- "denque": "^1.4.1",
- "require_optional": "^1.0.1",
- "safe-buffer": "^5.1.2"
- },
- "engines": {
- "node": ">=4"
- },
- "optionalDependencies": {
- "saslprep": "^1.0.0"
- },
- "peerDependenciesMeta": {
- "aws4": {
- "optional": true
- },
- "bson-ext": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "mongodb-extjson": {
- "optional": true
- },
- "snappy": {
- "optional": true
- }
- }
- },
- "node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "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": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
- "engines": {
- "node": "4.x || >=6.0.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/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",