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 @@
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",