Added champions items (first try)
This commit is contained in:
@@ -5,4 +5,4 @@ USER node
|
||||
COPY --chown=node:node package*.json ./
|
||||
RUN npm install
|
||||
COPY --chown=node:node . .
|
||||
CMD [ "node", "index.js" ]
|
||||
CMD [ "node", "--import=tsx", "index.js" ]
|
||||
@@ -1,105 +0,0 @@
|
||||
function sameArrays(array1, array2) {
|
||||
if(array1.length != array2.length) return false;
|
||||
for(let e of array1) {
|
||||
if(!array2.includes(e)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function championInfos(client, patch, championId) {
|
||||
const database = client.db("matches");
|
||||
const matches = database.collection(patch)
|
||||
const allMatches = matches.find()
|
||||
|
||||
let winningMatches = 0;
|
||||
let losingMatches = 0;
|
||||
let totalMatches = 0;
|
||||
const runes = [];
|
||||
for await (let match of allMatches) {
|
||||
totalMatches += 1;
|
||||
for(let participant of match.info.participants) {
|
||||
if(participant.championId != championId) continue;
|
||||
|
||||
if(participant.win)
|
||||
winningMatches += 1;
|
||||
else
|
||||
losingMatches += 1;
|
||||
|
||||
const primaryStyle = participant.perks.styles[0].style
|
||||
const secondaryStyle = participant.perks.styles[1].style
|
||||
const selections = []
|
||||
for(let style of participant.perks.styles) {
|
||||
for(let perk of style.selections) {
|
||||
selections.push(perk.perk)
|
||||
}
|
||||
}
|
||||
const gameRunes = {count:1, primaryStyle: primaryStyle, secondaryStyle: secondaryStyle, selections: selections};
|
||||
let addRunes = true;
|
||||
for(let rune of runes) {
|
||||
if(rune.primaryStyle == gameRunes.primaryStyle
|
||||
&& rune.secondaryStyle == gameRunes.secondaryStyle
|
||||
&& sameArrays(rune.selections, gameRunes.selections)) {
|
||||
rune.count++; addRunes = false; break;
|
||||
}
|
||||
}
|
||||
if(addRunes) runes.push(gameRunes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter runes to keep 3 most played
|
||||
const maxes = [0, 0, 0] // 24, 2, 1 -> 18 > 1 -> 24, 2, 2 -> 18 > 2 -> 24, 24, 2
|
||||
const maxRunes = [null, null, null]
|
||||
for(let rune of runes) {
|
||||
let maxcount = 2;
|
||||
if(rune.count <= maxes[maxcount]) continue;
|
||||
|
||||
while(maxcount > 0 && rune.count > maxes[maxcount]) {
|
||||
maxes[maxcount] = maxes[maxcount - 1];
|
||||
maxRunes[maxcount] = maxRunes[maxcount - 1];
|
||||
maxcount--;
|
||||
}
|
||||
|
||||
rune.pickrate = rune.count / (winningMatches + losingMatches)
|
||||
if(rune.count <= maxes[maxcount]) maxcount++;
|
||||
maxes[maxcount] = rune.count
|
||||
maxRunes[maxcount] = rune
|
||||
}
|
||||
|
||||
return {id: championId,
|
||||
winrate:winningMatches / (winningMatches + losingMatches),
|
||||
gameCount:(winningMatches + losingMatches),
|
||||
pickrate:(winningMatches + losingMatches)/totalMatches,
|
||||
runes: maxRunes.filter((x) => x != null)
|
||||
};
|
||||
}
|
||||
|
||||
async function makeChampionStat(client, patch, championId) {
|
||||
const championInfo = await championInfos(client, patch, championId)
|
||||
const database = client.db("champions")
|
||||
const collection = database.collection(patch)
|
||||
await collection.updateOne({id: championInfo.id}, {$set: championInfo}, { upsert: true })
|
||||
}
|
||||
|
||||
async function championList() {
|
||||
const response = await fetch("https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-summary.json");
|
||||
const list = await response.json()
|
||||
return list.slice(1)
|
||||
}
|
||||
|
||||
async function makeChampionsStats(client, patch) {
|
||||
const list = await championList()
|
||||
console.log("Generating stats for " + list.length + " champions")
|
||||
let i = 0;
|
||||
for(let champion of list) {
|
||||
console.log("Entry " + i + "/" + list.length + " ...")
|
||||
await makeChampionStat(client, patch, champion.id)
|
||||
i += 1
|
||||
}
|
||||
|
||||
const database = client.db("champions")
|
||||
const collection = database.collection(patch)
|
||||
await collection.createIndex({id:1})
|
||||
}
|
||||
|
||||
module.exports = {makeChampionsStats}
|
||||
226
match_collector/champion_stat.ts
Normal file
226
match_collector/champion_stat.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
function sameArrays(array1 : Array<any>, array2 : Array<any>) {
|
||||
if(array1.length != array2.length) return false;
|
||||
for(let e of array1) {
|
||||
if(!array2.includes(e)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
import { ItemTree, treeInit, treeMerge, treeCutBranches, treeSort } from "./item_tree";
|
||||
const itemDict = new Map()
|
||||
|
||||
async function itemList() {
|
||||
const response = await fetch("https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/items.json")
|
||||
const list = await response.json()
|
||||
return list
|
||||
}
|
||||
|
||||
type Rune = {
|
||||
count: number
|
||||
primaryStyle: number
|
||||
secondaryStyle: number
|
||||
selections: Array<number>
|
||||
pickrate?: number
|
||||
};
|
||||
type Builds = {
|
||||
tree: ItemTree
|
||||
start: Array<{data: number, count: number}>
|
||||
bootsFirst: number
|
||||
boots: Array<{data: number, count: number}>
|
||||
lateGame: Array<{data: number, count: number}>
|
||||
}
|
||||
|
||||
async function championInfos(client, patch: number, championId: number) {
|
||||
const database = client.db("matches");
|
||||
const matches = database.collection(patch)
|
||||
const allMatches = matches.find()
|
||||
|
||||
let winningMatches = 0;
|
||||
let losingMatches = 0;
|
||||
let totalMatches = 0;
|
||||
const runes : Array<Rune> = [];
|
||||
const builds : Builds = {tree:treeInit(), start: [], bootsFirst: 0, boots: [], lateGame: []}
|
||||
for await (let match of allMatches) {
|
||||
totalMatches += 1;
|
||||
let participantIndex = 0;
|
||||
for(let participant of match.info.participants) {
|
||||
participantIndex += 1
|
||||
if(participant.championId != championId) continue;
|
||||
|
||||
// Winrate
|
||||
if(participant.win)
|
||||
winningMatches += 1;
|
||||
else
|
||||
losingMatches += 1;
|
||||
|
||||
// Runes
|
||||
const primaryStyle = participant.perks.styles[0].style
|
||||
const secondaryStyle = participant.perks.styles[1].style
|
||||
const selections : Array<number> = []
|
||||
for(let style of participant.perks.styles) {
|
||||
for(let perk of style.selections) {
|
||||
selections.push(perk.perk)
|
||||
}
|
||||
}
|
||||
const gameRunes : Rune = {count:1, primaryStyle: primaryStyle, secondaryStyle: secondaryStyle, selections: selections};
|
||||
let addRunes = true;
|
||||
for(let rune of runes) {
|
||||
if(rune.primaryStyle == gameRunes.primaryStyle
|
||||
&& rune.secondaryStyle == gameRunes.secondaryStyle
|
||||
&& sameArrays(rune.selections, gameRunes.selections)) {
|
||||
rune.count++; addRunes = false; break;
|
||||
}
|
||||
}
|
||||
if(addRunes) runes.push(gameRunes)
|
||||
|
||||
// Items
|
||||
const items : Array<number> = []
|
||||
for(let frame of match.timeline.info.frames) {
|
||||
for(let event of frame.events) {
|
||||
if(event.participantId != participantIndex) continue;
|
||||
if(event.type == "ITEM_UNDO") {
|
||||
if(items.length > 0 && items[items.length - 1] == event.beforeId) {
|
||||
items.pop()
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(event.type != "ITEM_PURCHASED") continue;
|
||||
|
||||
let itemInfo = itemDict.get(event.itemId)
|
||||
|
||||
// Handle boots differently
|
||||
if(itemInfo.categories.includes("Boots")){
|
||||
if(itemInfo.to.length == 0 || event.itemId == 3006) {
|
||||
// Check for bootsFirst
|
||||
if(items.length < 2) {
|
||||
builds.bootsFirst += 1
|
||||
}
|
||||
|
||||
// Add to boots
|
||||
const already = builds.boots.find((x) => x.data == event.itemId)
|
||||
if(already == undefined) builds.boots.push({count:1, data:event.itemId})
|
||||
else already.count += 1
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if item should be included
|
||||
if(itemInfo.categories.includes("Consumable")) continue;
|
||||
if(itemInfo.categories.includes("Trinket")) continue;
|
||||
|
||||
// Ignore Cull as not-first item
|
||||
if(event.itemId == 1083 && items.length >= 1) continue;
|
||||
|
||||
// Ignore non-final items, except when first item bought
|
||||
if(itemInfo.to.length != 0 && items.length >= 1) continue;
|
||||
|
||||
items.push(event.itemId)
|
||||
}
|
||||
}
|
||||
|
||||
// Core items
|
||||
treeMerge(builds.tree, items.slice(1, 4))
|
||||
|
||||
// Start items
|
||||
const already = builds.start.find((x) => x.data == items[0])
|
||||
if(already == undefined) builds.start.push({count:1, data:items[0]})
|
||||
else already.count += 1
|
||||
|
||||
// Late game items
|
||||
for(let item of items.slice(4)) {
|
||||
const already = builds.lateGame.find((x) => x.data == item)
|
||||
if(already == undefined) builds.lateGame.push({count:1, data:item})
|
||||
else already.count += 1
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter runes to keep 3 most played
|
||||
const maxes = [0, 0, 0] // 24, 2, 1 -> 18 > 1 -> 24, 2, 2 -> 18 > 2 -> 24, 24, 2
|
||||
const maxRunes : Array<Rune | null> = [null, null, null]
|
||||
for(let rune of runes) {
|
||||
let maxcount = 2;
|
||||
if(rune.count <= maxes[maxcount]) continue;
|
||||
|
||||
while(maxcount > 0 && rune.count > maxes[maxcount]) {
|
||||
maxes[maxcount] = maxes[maxcount - 1];
|
||||
maxRunes[maxcount] = maxRunes[maxcount - 1];
|
||||
maxcount--;
|
||||
}
|
||||
|
||||
rune.pickrate = rune.count / (winningMatches + losingMatches)
|
||||
if(rune.count <= maxes[maxcount]) maxcount++;
|
||||
maxes[maxcount] = rune.count
|
||||
maxRunes[maxcount] = rune
|
||||
}
|
||||
|
||||
// Cut item tree branches to keep only 4 branches every time and with percentage threshold
|
||||
builds.tree.count = (winningMatches + losingMatches)
|
||||
treeCutBranches(builds.tree, 4, 0.05)
|
||||
treeSort(builds.tree)
|
||||
|
||||
// Cut item start, to only 4 and with percentage threshold
|
||||
while(builds.start.length > 4) {
|
||||
let leastUsedItem = builds.start.reduce((a, b) => Math.min(a.count, b.count) == a.count ? a : b, {data:undefined, count: +Infinity})
|
||||
builds.start.splice(builds.start.indexOf(leastUsedItem), 1)
|
||||
}
|
||||
let toRemove : Array<{data: number, count:number}> = []
|
||||
for(let item of builds.start) {
|
||||
if((item.count/(winningMatches + losingMatches)) < 0.05) {
|
||||
toRemove.push(item)
|
||||
}
|
||||
}
|
||||
for(let tr of toRemove) {
|
||||
builds.start.splice(builds.start.indexOf(tr), 1)
|
||||
}
|
||||
builds.start.sort((a, b) => b.count - a.count)
|
||||
builds.boots.sort((a, b) => b.count - a.count)
|
||||
builds.bootsFirst /= (winningMatches + losingMatches)
|
||||
builds.lateGame.sort((a, b) => b.count - a.count)
|
||||
|
||||
return {id: championId,
|
||||
winrate:winningMatches / (winningMatches + losingMatches),
|
||||
gameCount:(winningMatches + losingMatches),
|
||||
pickrate:(winningMatches + losingMatches)/totalMatches,
|
||||
runes: maxRunes.filter((x) => x != null),
|
||||
builds: builds
|
||||
};
|
||||
}
|
||||
|
||||
async function makeChampionStat(client, patch, championId) {
|
||||
const championInfo = await championInfos(client, patch, championId)
|
||||
const database = client.db("champions")
|
||||
const collection = database.collection(patch)
|
||||
await collection.updateOne({id: championInfo.id}, {$set: championInfo}, { upsert: true })
|
||||
}
|
||||
|
||||
async function championList() {
|
||||
const response = await fetch("https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-summary.json");
|
||||
const list = await response.json()
|
||||
return list.slice(1)
|
||||
}
|
||||
|
||||
async function makeChampionsStats(client, patch) {
|
||||
var globalItems = await itemList()
|
||||
for(let item of globalItems) {
|
||||
itemDict.set(item.id, item)
|
||||
}
|
||||
|
||||
const list = await championList()
|
||||
console.log("Generating stats for " + list.length + " champions")
|
||||
let i = 0;
|
||||
for(let champion of list) {
|
||||
console.log("Entry " + i + "/" + list.length + " (" + champion.name + ")...")
|
||||
await makeChampionStat(client, patch, champion.id)
|
||||
i += 1
|
||||
}
|
||||
|
||||
const database = client.db("champions")
|
||||
const collection = database.collection(patch)
|
||||
await collection.createIndex({id:1})
|
||||
}
|
||||
|
||||
export default {makeChampionsStats}
|
||||
@@ -2,7 +2,9 @@ const base = "https://euw1.api.riotgames.com"
|
||||
const api_key = process.env.RIOT_API_KEY
|
||||
const sleep_minutes = 3
|
||||
|
||||
var champion_stat = require("./champion_stat")
|
||||
import { MongoClient } from 'mongodb'
|
||||
|
||||
import champion_stat from "./champion_stat"
|
||||
|
||||
main()
|
||||
|
||||
@@ -15,32 +17,34 @@ async function main() {
|
||||
const alreadySeenGameList = await alreadySeenGames(client, latestPatch);
|
||||
console.log("We already have " + alreadySeenGameList.length + " matches for this patch !")
|
||||
|
||||
const challengerLeague = await fetchChallengerLeague();
|
||||
console.log("ChallengerLeague: got " + challengerLeague.entries.length + " entries");
|
||||
if(process.env.RIOT_API_KEY != null && process.env.RIOT_API_KEY != undefined && process.env.RIOT_API_KEY != "") {
|
||||
const challengerLeague = await fetchChallengerLeague();
|
||||
console.log("ChallengerLeague: got " + challengerLeague.entries.length + " entries");
|
||||
|
||||
const gameList = [];
|
||||
let i = 0;
|
||||
for(let challenger of challengerLeague.entries) {
|
||||
console.log("Entry " + i + "/" + challengerLeague.entries.length + " ...")
|
||||
const puuid = await summonerPuuid(challenger.summonerId);
|
||||
const challengerGameList = await summonerGameList(puuid, latestPatchTime);
|
||||
for(let game of challengerGameList) {
|
||||
if(!gameList.includes(game) && !alreadySeenGameList.includes(game)) {
|
||||
gameList.push(game)
|
||||
const gameList = [];
|
||||
let i = 0;
|
||||
for(let challenger of challengerLeague.entries) {
|
||||
console.log("Entry " + i + "/" + challengerLeague.entries.length + " ...")
|
||||
const puuid = await summonerPuuid(challenger.summonerId);
|
||||
const challengerGameList = await summonerGameList(puuid, latestPatchTime);
|
||||
for(let game of challengerGameList) {
|
||||
if(!gameList.includes(game) && !alreadySeenGameList.includes(game)) {
|
||||
gameList.push(game)
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
console.log("Games: got " + gameList.length + " entries");
|
||||
i = 0;
|
||||
for(let game of gameList) {
|
||||
console.log("Entry " + i + "/" + gameList.length + " ...")
|
||||
const gameMatch = await match(game)
|
||||
const gameTimeline = await matchTimeline(game)
|
||||
gameMatch.timeline = gameTimeline
|
||||
await saveMatch(client, gameMatch, latestPatch)
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
console.log("Games: got " + gameList.length + " entries");
|
||||
i = 0;
|
||||
for(let game of gameList) {
|
||||
console.log("Entry " + i + "/" + gameList.length + " ...")
|
||||
const gameMatch = await match(game)
|
||||
const gameTimeline = await matchTimeline(game)
|
||||
gameMatch.timeline = gameTimeline
|
||||
await saveMatch(client, gameMatch, latestPatch)
|
||||
i++;
|
||||
}
|
||||
|
||||
console.log("Generating stats...");
|
||||
@@ -50,17 +54,17 @@ async function main() {
|
||||
await client.close()
|
||||
}
|
||||
|
||||
async function handleRateLimit(url) {
|
||||
async function handleRateLimit(url : URL) : Promise<Response> {
|
||||
let response = await fetch(url)
|
||||
if(response.status == 429) {
|
||||
await new Promise(resolve => setTimeout(resolve, sleep_minutes * 60 * 1000))
|
||||
response = handleRateLimit(url)
|
||||
response = await handleRateLimit(url)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
function handleError(response) {
|
||||
function handleError(response : Response) {
|
||||
if(!response.ok) {
|
||||
console.log("Error during fetch(" + response.url + "): STATUS " + response.status + " (" + response.statusText + ")");
|
||||
process.exit(1);
|
||||
@@ -68,7 +72,6 @@ function handleError(response) {
|
||||
}
|
||||
|
||||
async function connectToDatabase() {
|
||||
const { MongoClient, ServerApiVersion } = require("mongodb");
|
||||
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
|
||||
const client = new MongoClient(`mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@mongo:27017`)
|
||||
await client.connect()
|
||||
@@ -87,7 +90,7 @@ async function fetchChallengerLeague() {
|
||||
const endpoint = `/lol/league/v4/challengerleagues/by-queue/${queue}`
|
||||
const url = `${base}${endpoint}?api_key=${api_key}`
|
||||
|
||||
const challengerLeagueResponse = await handleRateLimit(url);
|
||||
const challengerLeagueResponse = await handleRateLimit(new URL(url));
|
||||
|
||||
handleError(challengerLeagueResponse)
|
||||
|
||||
@@ -99,7 +102,7 @@ async function summonerPuuid(summonerId) {
|
||||
const endpoint = `/lol/summoner/v4/summoners/${summonerId}`
|
||||
const url = `${base}${endpoint}?api_key=${api_key}`
|
||||
|
||||
const puuidResponse = await handleRateLimit(url);
|
||||
const puuidResponse = await handleRateLimit(new URL(url));
|
||||
handleError(puuidResponse)
|
||||
const puuidJson = await puuidResponse.json();
|
||||
|
||||
@@ -110,7 +113,7 @@ async function summonerGameList(puuid, startTime) {
|
||||
const endpoint = `/lol/match/v5/matches/by-puuid/${puuid}/ids`;
|
||||
const url = `${base}${endpoint}?queue=420&type=ranked&startTime=${startTime}&api_key=${api_key}`
|
||||
|
||||
const gameListResponse = await handleRateLimit(url);
|
||||
const gameListResponse = await handleRateLimit(new URL(url));
|
||||
handleError(gameListResponse)
|
||||
const gameList = await gameListResponse.json();
|
||||
|
||||
@@ -122,7 +125,7 @@ async function match(matchId) {
|
||||
const endpoint = `/lol/match/v5/matches/${matchId}`
|
||||
const url = `${base}${endpoint}?api_key=${api_key}`
|
||||
|
||||
const matchResponse = await handleRateLimit(url)
|
||||
const matchResponse = await handleRateLimit(new URL(url))
|
||||
handleError(matchResponse)
|
||||
const match = await matchResponse.json();
|
||||
|
||||
@@ -134,7 +137,7 @@ async function matchTimeline(matchId) {
|
||||
const endpoint = `/lol/match/v5/matches/${matchId}/timeline`
|
||||
const url = `${base}${endpoint}?api_key=${api_key}`
|
||||
|
||||
const timelineResponse = await handleRateLimit(url)
|
||||
const timelineResponse = await handleRateLimit(new URL(url))
|
||||
handleError(timelineResponse)
|
||||
const timeline = await timelineResponse.json();
|
||||
|
||||
89
match_collector/item_tree.ts
Normal file
89
match_collector/item_tree.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
type ItemTree = {
|
||||
data: any
|
||||
count: number
|
||||
children: Array<ItemTree>
|
||||
};
|
||||
|
||||
function treeInit() : ItemTree {
|
||||
return {data:undefined, count:0, children:[]}
|
||||
}
|
||||
|
||||
|
||||
function treeNode(data : number, count : number) : ItemTree {
|
||||
return {data:data, count:count, children:[]}
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge a node with an item tree
|
||||
*/
|
||||
function nodeMerge(itemtree : ItemTree, node : ItemTree) {
|
||||
const item = node.data;
|
||||
const count = node.count;
|
||||
let next : ItemTree | null = null;
|
||||
|
||||
// Try to find an existing node in this tree level with same item
|
||||
for(let node of itemtree.children) {
|
||||
if(node.data == item) {
|
||||
node.count += 1;
|
||||
next = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not found, add item node at this level
|
||||
if(next == null) {
|
||||
next = treeNode(item, count)
|
||||
itemtree.children.push(next)
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge a full build path with an existing item tree
|
||||
*/
|
||||
function treeMerge(itemtree : ItemTree, items : Array<number>) {
|
||||
let current = itemtree;
|
||||
|
||||
for(let item of items) {
|
||||
current = nodeMerge(current, {data: item, count:1, children:[]})
|
||||
}
|
||||
}
|
||||
|
||||
function treeCutBranches(itemtree : ItemTree, thresholdCount : number, thresholdPerc : number) {
|
||||
// Remove branches that are above threshold count
|
||||
while(itemtree.children.length > thresholdCount) {
|
||||
let leastUsedBranch = itemtree.children.reduce((a, b) => Math.min(a.count, b.count) == a.count ? a : b, {data:undefined, count: +Infinity, children: []})
|
||||
itemtree.children.splice(itemtree.children.indexOf(leastUsedBranch), 1)
|
||||
}
|
||||
|
||||
// Remove branches that are of too low usage
|
||||
let toRemove : Array<ItemTree> = []
|
||||
for(let child of itemtree.children) {
|
||||
if((child.count/itemtree.count) < thresholdPerc) {
|
||||
toRemove.push(child)
|
||||
}
|
||||
}
|
||||
for(let tr of toRemove) {
|
||||
itemtree.children.splice(itemtree.children.indexOf(tr), 1)
|
||||
}
|
||||
|
||||
itemtree.children.map((x) => treeCutBranches(x, thresholdCount, thresholdPerc))
|
||||
}
|
||||
|
||||
function treeMergeTree(itemtree1: ItemTree, itemtree2: ItemTree) {
|
||||
for(let child of itemtree2.children) {
|
||||
let node = nodeMerge(itemtree1, child)
|
||||
treeMergeTree(node, child)
|
||||
}
|
||||
}
|
||||
|
||||
function treeSort(itemtree: ItemTree) {
|
||||
itemtree.children.sort((a, b) => b.count - a.count)
|
||||
|
||||
for(let item of itemtree.children) {
|
||||
treeSort(item)
|
||||
}
|
||||
}
|
||||
|
||||
export {ItemTree, treeMerge, treeInit, treeCutBranches, treeSort}
|
||||
531
match_collector/package-lock.json
generated
531
match_collector/package-lock.json
generated
@@ -1,15 +1,427 @@
|
||||
{
|
||||
"name": "stat_collector",
|
||||
"name": "match_collector",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "stat_collector",
|
||||
"name": "match_collector",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"mongodb": "^6.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.9.1",
|
||||
"tsx": "^4.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
|
||||
"integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
|
||||
"integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
|
||||
"integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
|
||||
"integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@mongodb-js/saslprep": {
|
||||
@@ -21,6 +433,16 @@
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz",
|
||||
"integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/webidl-conversions": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
|
||||
@@ -45,6 +467,74 @@
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
|
||||
"integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.23.1",
|
||||
"@esbuild/android-arm": "0.23.1",
|
||||
"@esbuild/android-arm64": "0.23.1",
|
||||
"@esbuild/android-x64": "0.23.1",
|
||||
"@esbuild/darwin-arm64": "0.23.1",
|
||||
"@esbuild/darwin-x64": "0.23.1",
|
||||
"@esbuild/freebsd-arm64": "0.23.1",
|
||||
"@esbuild/freebsd-x64": "0.23.1",
|
||||
"@esbuild/linux-arm": "0.23.1",
|
||||
"@esbuild/linux-arm64": "0.23.1",
|
||||
"@esbuild/linux-ia32": "0.23.1",
|
||||
"@esbuild/linux-loong64": "0.23.1",
|
||||
"@esbuild/linux-mips64el": "0.23.1",
|
||||
"@esbuild/linux-ppc64": "0.23.1",
|
||||
"@esbuild/linux-riscv64": "0.23.1",
|
||||
"@esbuild/linux-s390x": "0.23.1",
|
||||
"@esbuild/linux-x64": "0.23.1",
|
||||
"@esbuild/netbsd-x64": "0.23.1",
|
||||
"@esbuild/openbsd-arm64": "0.23.1",
|
||||
"@esbuild/openbsd-x64": "0.23.1",
|
||||
"@esbuild/sunos-x64": "0.23.1",
|
||||
"@esbuild/win32-arm64": "0.23.1",
|
||||
"@esbuild/win32-ia32": "0.23.1",
|
||||
"@esbuild/win32-x64": "0.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
|
||||
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
@@ -116,6 +606,16 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
@@ -137,6 +637,33 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.19.2",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz",
|
||||
"integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "~0.23.0",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
},
|
||||
"bin": {
|
||||
"tsx": "dist/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "match_collector",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"main": "index.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
@@ -11,5 +11,9 @@
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"mongodb": "^6.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.9.1",
|
||||
"tsx": "^4.19.2"
|
||||
}
|
||||
}
|
||||
|
||||
6
match_collector/tsconfig.json
Normal file
6
match_collector/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["node"]
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user