diff --git a/client/src/components/Summoner/Live/LiveTeam.vue b/client/src/components/Summoner/Live/LiveTeam.vue index f2c09ac..51d38e3 100644 --- a/client/src/components/Summoner/Live/LiveTeam.vue +++ b/client/src/components/Summoner/Live/LiveTeam.vue @@ -37,8 +37,20 @@
+ class="relative w-12 h-12 ml-2 bg-center bg-cover border-2 rounded-full bg-blue-1000" + > +
+
+
+
p.teamId === this.teamColor) : [] + if (!this.current || !this.current.participants) { + return [] + } + return this.current.participants.filter(p => p.teamId === this.teamColor).sort(this.sortTeamByRole) }, displayStartTime() { if (this.current.gameStartTime === 0) { @@ -19,7 +23,10 @@ export const liveGame = { return this.$options.filters.secToTime(this.gameLength, true) }, enemyTeam() { - return this.current && this.current.participants ? this.current.participants.filter(p => p.teamId !== this.teamColor) : [] + if (!this.current || !this.current.participants) { + return [] + } + return this.current.participants.filter(p => p.teamId !== this.teamColor).sort(this.sortTeamByRole) }, gamemode() { if (this.current.participants) { @@ -62,5 +69,6 @@ export const liveGame = { this.gameLength = (new Date() - new Date(this.gameStartTime)) / 1000 }, + sortTeamByRole } } diff --git a/server/app/Services/RoleIdentificationService.js b/server/app/Services/RoleIdentificationService.js new file mode 100644 index 0000000..ef7fd99 --- /dev/null +++ b/server/app/Services/RoleIdentificationService.js @@ -0,0 +1,195 @@ +'use strict' + +const got = require('got') +const Redis = use('Redis') + +class RoleIdentificationService { + _getPermutations (array) { + const result = [] + + for (let i = 0; i < array.length; i++) { + const rest = this._getPermutations(array.slice(0, i).concat(array.slice(i + 1))) + + if (!rest.length) { + result.push([array[i]]) + } else { + for (let j = 0; j < rest.length; j++) { + result.push([array[i]].concat(rest[j])) + } + } + } + return result + } + + _calculateMetric (championPositions, bestPositions) { + return Object.entries(bestPositions).reduce((agg, [position, champion]) => { + return agg + (championPositions[champion][position] || 0) + }, 0) / Object.keys(bestPositions).length + } + + _getPositions (championPositions, composition, top, jungle, middle, adc, support) { + // Set the initial guess to be the champion in the composition, order doesn't matter + let bestPositions = { + 'TOP': composition[0], + 'JUNGLE': composition[1], + 'MIDDLE': composition[2], + 'BOTTOM': composition[3], + 'UTILITY': composition[4], + } + + let bestMetric = this._calculateMetric(championPositions, bestPositions) + let secondBestMetric = -Infinity + let secondBestPositions = null + + // Figure out which champions and positions we need to fill + const knownChampions = [top, jungle, middle, adc, support].filter(Boolean) + const unknownChampions = composition.filter(champ => !knownChampions.includes(champ)) + const unknownPositions = Object.entries({ + 'TOP': top, 'JUNGLE': jungle, 'MIDDLE': middle, 'BOTTOM': adc, 'UTILITY': support, + }) + .filter(pos => !pos[1]) + .map(pos => pos[0]) + + const testComposition = { + 'TOP': top, + 'JUNGLE': jungle, + 'MIDDLE': middle, + 'BOTTOM': adc, + 'UTILITY': support, + } + + // Iterate over the positions we need to fill and record how well each composition "performs" + for (const champs of this._getPermutations(unknownChampions)) { + for (let [i, position] of unknownPositions.entries()) { + testComposition[position] = champs[i] + } + + const metric = this._calculateMetric(championPositions, testComposition) + + if (metric > bestMetric) { + secondBestMetric = bestMetric + secondBestPositions = bestPositions + bestMetric = metric + bestPositions = { ...testComposition } + } + + if (bestMetric > metric && metric > secondBestMetric) { + secondBestMetric = metric + secondBestPositions = { ...testComposition } + } + } + + const bestPlayPercents = {} + for (const [position, champion] of Object.entries(bestPositions)) { + bestPlayPercents[champion] = championPositions[champion][position] + } + + let secondBestPlayPercents = null + if (secondBestPositions !== null) { + secondBestPlayPercents = {} + for (const [position, champion] of Object.entries(secondBestPositions)) { + secondBestPlayPercents[champion] = championPositions[champion][position] + } + } + + if (JSON.stringify(secondBestPositions) === JSON.stringify(bestPositions)) { + secondBestPositions = null + secondBestPlayPercents = null + secondBestMetric = -Infinity + } + + return { bestPositions, bestMetric, secondBestPositions } + } + + /** + * Get the CDN data of the champion playrates by role + */ + async pullData () { + const url = 'http://cdn.merakianalytics.com/riot/lol/resources/latest/en-US/championrates.json' + + // Check if cached + const requestCached = await Redis.get(url) + if (requestCached) { + return JSON.parse(requestCached) + } + + const data = {} + const response = await got(url, { responseType: 'json' }) + + for (const [championId, roles] of Object.entries(response.body.data)) { + const playRates = {} + + for (const [position, rates] of Object.entries(roles)) { + playRates[position.toUpperCase()] = rates['playRate'] + } + + for (const position of ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'UTILITY']) { + if (playRates[position] === undefined) { + playRates[position] = 0 + } + } + + data[championId] = playRates + } + + // Cache result + await Redis.set(url, JSON.stringify(data), 'EX', 36000) + + return data + } + + /** + * Get roles for the 5 players of a team + * @param championPositions + * @param composition + */ + getRoles (championPositions, composition) { + const identified = {} + let positions = {} + let secondaryPositions = null + let secondaryMetric = -Infinity + + while (Object.keys(identified).length < composition.length - 1) { + let { bestPositions, bestMetric: metric, secondBestPositions: sbp } = + this._getPositions(championPositions, composition, + identified.TOP, identified.JUNGLE, identified.MIDDLE, identified.ADC, identified.SUPPORT + ) + + positions = bestPositions + + if (sbp !== null) { + let _metric = this._calculateMetric(championPositions, { ...sbp }) + + if (secondaryPositions === null) { + secondaryPositions = sbp + secondaryMetric = _metric + } else if (metric > _metric && _metric > secondaryMetric) { + secondaryMetric = _metric + secondaryPositions = sbp + } + } + + // Done! Grab the results. + const positionsWithMetric = {} + for (const [position, champion] of Object.entries(positions)) { + if (Object.keys(identified).includes(position)) { + continue + } + positionsWithMetric[position] = { + champion, + metric: championPositions[champion][position], + } + } + const bestPosition = Object.keys(positionsWithMetric).reduce((posA, posB) => { + return positionsWithMetric[posA].metric > positionsWithMetric[posB].metric ? posA : posB + }) + + const best = [bestPosition, positionsWithMetric[bestPosition].champion] + identified[best[0]] = best[1] + } + + return positions + } +} + +module.exports = new RoleIdentificationService() diff --git a/server/app/Transformers/LiveMatchTransformer.js b/server/app/Transformers/LiveMatchTransformer.js index 8c175f0..c515d0e 100644 --- a/server/app/Transformers/LiveMatchTransformer.js +++ b/server/app/Transformers/LiveMatchTransformer.js @@ -1,6 +1,7 @@ 'use strict' const MatchTransformer = use('App/Transformers/MatchTransformer') +const RoleIdentificationService = use('App/Services/RoleIdentificationService') const SummonerService = use('App/Services/SummonerService') /** @@ -9,7 +10,7 @@ const SummonerService = use('App/Services/SummonerService') * @class LiveMatchTransformer */ class LiveMatchTransformer extends MatchTransformer { - async _getPlayerDatq(participant, region) { + async _getPlayerRank(participant, region) { const account = await SummonerService.getAccount(participant.summonerName, region) if (account) { participant.level = account.summonerLevel @@ -29,12 +30,35 @@ class LiveMatchTransformer extends MatchTransformer { async transform(match, { region }) { await super.getContext() - // Perks - for (const participant of match.participants) { - participant.runes = participant.perks ? super.getPerksImages(participant.perks.perkIds[0], participant.perks.perkSubStyle) : {} + // Roles + const blueTeam = [] // 100 + const redTeam = [] // 200 + let blueRoles = [] + let redRoles = [] + if (this.championRoles) { + match.participants.map(p => { + p.teamId === 100 ? blueTeam.push(p.championId) : redTeam.push(p.championId) + }) + blueRoles = RoleIdentificationService.getRoles(this.championRoles, blueTeam) + redRoles = RoleIdentificationService.getRoles(this.championRoles, redTeam) } - const requestsParticipants = match.participants.map(p => this._getPlayerDatq(p, region)) + for (const participant of match.participants) { + // Perks + participant.runes = participant.perks ? super.getPerksImages(participant.perks.perkIds[0], participant.perks.perkSubStyle) : {} + + // Roles + if (this.championRoles) { + const roles = participant.teamId === 100 ? blueRoles : redRoles + participant.role = Object.entries(roles).find(([, champion]) => participant.championId === champion)[0] + if (participant.role === 'UTILITY') { + participant.role = 'SUPPORT' + } + } + } + + // Ranks + const requestsParticipants = match.participants.map(p => this._getPlayerRank(p, region)) match.participants = await Promise.all(requestsParticipants) return match diff --git a/server/app/Transformers/MatchTransformer.js b/server/app/Transformers/MatchTransformer.js index ff00ec5..907d162 100644 --- a/server/app/Transformers/MatchTransformer.js +++ b/server/app/Transformers/MatchTransformer.js @@ -2,6 +2,7 @@ const Jax = use('App/Services/Jax') const Helpers = use('App/helpers') +const RoleIdentificationService = use('App/Services/RoleIdentificationService') /** * MatchTransformer class @@ -18,12 +19,14 @@ class MatchTransformer { const perks = await Jax.CDragon.perks() const perkstyles = await Jax.CDragon.perkstyles() const summonerSpells = await Jax.CDragon.summonerSpells() + const championRoles = await RoleIdentificationService.pullData().catch(() => {}) this.champions = champions this.items = items this.perks = perks this.perkstyles = perkstyles.styles this.summonerSpells = summonerSpells + this.championRoles = championRoles this.sortTeamByRole = Helpers.sortTeamByRole // League of Legends seasons timestamps diff --git a/server/package-lock.json b/server/package-lock.json index 5b380a8..06dd0da 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -196,16 +196,53 @@ } }, "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" }, "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", "requires": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", + "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.0.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", + "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==" + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" } }, "accepts": { @@ -726,18 +763,23 @@ } } }, + "cacheable-lookup": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz", + "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==" + }, "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", + "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "responselike": "^2.0.0" }, "dependencies": { "get-stream": { @@ -747,11 +789,6 @@ "requires": { "pump": "^3.0.0" } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" } } }, @@ -1115,17 +1152,24 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + } } }, "defer-to-connect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz", - "integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", + "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==" }, "define-properties": { "version": "1.1.3", @@ -1188,11 +1232,6 @@ "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1720,21 +1759,32 @@ } }, "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/got/-/got-11.3.0.tgz", + "integrity": "sha512-yi/kiZY2tNMtt5IfbfX8UL3hAZWb2gZruxYZ72AY28pU5p0TZjZdl0uRsuaFbnC0JopdUi3I+Mh1F3dPQ9Dh0Q==", "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@sindresorhus/is": "^2.1.1", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "get-stream": "^5.1.0", + "http2-wrapper": "^1.0.0-beta.4.5", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "dependencies": { + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + } } }, "graceful-fs": { @@ -1840,9 +1890,9 @@ "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==" }, "http-cache-semantics": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", - "integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { "version": "1.7.3", @@ -1866,6 +1916,15 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "1.0.0-beta.4.6", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.4.6.tgz", + "integrity": "sha512-9oB4BiGDTI1FmIBlOF9OJ5hwJvcBEmPCqk/hy314Uhy2uq5TjekUZM8w8SPLLlUEM+mxNhXdPAXfrJN2Zbb/GQ==", + "requires": { + "quick-lru": "^5.0.0", + "resolve-alpn": "^1.0.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2147,9 +2206,9 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-schema": { "version": "0.2.3", @@ -2222,11 +2281,11 @@ } }, "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz", + "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==", "requires": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "kind-of": { @@ -2516,9 +2575,9 @@ } }, "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "lru-cache": { "version": "4.1.5", @@ -2958,9 +3017,9 @@ } }, "normalize-url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz", - "integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, "oauth-sign": { "version": "0.9.0", @@ -3118,9 +3177,9 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" }, "p-limit": { "version": "1.3.0", @@ -3259,11 +3318,6 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -3773,6 +3827,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz", "integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==" }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, "radio-symbol": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/radio-symbol/-/radio-symbol-2.0.0.tgz", @@ -4068,6 +4127,11 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==" + }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", @@ -4088,11 +4152,11 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", "requires": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" } }, "ret": { @@ -4790,11 +4854,6 @@ "kind-of": "^3.0.2" } }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -5006,14 +5065,6 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - } - }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/server/package.json b/server/package.json index 1535835..abeb4b7 100644 --- a/server/package.json +++ b/server/package.json @@ -27,7 +27,7 @@ "@adonisjs/lucid": "^6.1.3", "@adonisjs/redis": "^2.0.7", "bee-queue": "^1.2.3", - "got": "^9.6.0", + "got": "^11.3.0", "lucid-mongo": "^3.1.6", "mongodb-core": "^3.2.7", "request": "^2.88.2",