feat: add identified roles in live game tab

This commit is contained in:
Valentin Kaelin 2020-06-12 17:45:16 +02:00
parent 1c9842dcab
commit 93a46d3a9e
8 changed files with 395 additions and 94 deletions

View file

@ -37,8 +37,20 @@
<div <div
:style="{backgroundImage: `url('https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-icons/${player.championId}.png')`}" :style="{backgroundImage: `url('https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-icons/${player.championId}.png')`}"
:class="borderChampion(player.summonerId)" :class="borderChampion(player.summonerId)"
class="w-12 h-12 ml-2 bg-center bg-cover border-2 rounded-full bg-blue-1000" class="relative w-12 h-12 ml-2 bg-center bg-cover border-2 rounded-full bg-blue-1000"
>
<div
v-if="player.role && player.role !== 'NONE'"
:class="borderChampion(player.summonerId)"
class="absolute border rounded-full p-2px bg-blue-1000"
style="bottom: -5px; right: -5px;"
>
<div
:style="{backgroundImage: `url(${require('@/assets/img/roles/' + player.role + '.png')})`}"
class="w-4 h-4 bg-center bg-cover"
></div> ></div>
</div>
</div>
<div class="flex flex-col ml-2"> <div class="flex flex-col ml-2">
<div <div
:style="{backgroundImage: `url(${getSummonerLink(player.spell1Id)})`}" :style="{backgroundImage: `url(${getSummonerLink(player.spell1Id)})`}"

View file

@ -23,3 +23,11 @@ export function timeDifference(previous) {
return new Date(previous).toLocaleString(undefined, dateOptions).replace(/\//g, '.') return new Date(previous).toLocaleString(undefined, dateOptions).replace(/\//g, '.')
} }
} }
/**
* Sort an array of players by role
*/
export function sortTeamByRole (a, b) {
const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT']
return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role)
}

View file

@ -1,4 +1,5 @@
import { gameModes } from '@/data/data.js' import { gameModes } from '@/data/data.js'
import { sortTeamByRole } from '@/helpers/functions.js'
import { mapState } from 'vuex' import { mapState } from 'vuex'
export const liveGame = { export const liveGame = {
@ -10,7 +11,10 @@ export const liveGame = {
computed: { computed: {
allyTeam() { allyTeam() {
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)
}, },
displayStartTime() { displayStartTime() {
if (this.current.gameStartTime === 0) { if (this.current.gameStartTime === 0) {
@ -19,7 +23,10 @@ export const liveGame = {
return this.$options.filters.secToTime(this.gameLength, true) return this.$options.filters.secToTime(this.gameLength, true)
}, },
enemyTeam() { 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() { gamemode() {
if (this.current.participants) { if (this.current.participants) {
@ -62,5 +69,6 @@ export const liveGame = {
this.gameLength = (new Date() - new Date(this.gameStartTime)) / 1000 this.gameLength = (new Date() - new Date(this.gameStartTime)) / 1000
}, },
sortTeamByRole
} }
} }

View file

@ -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()

View file

@ -1,6 +1,7 @@
'use strict' 'use strict'
const MatchTransformer = use('App/Transformers/MatchTransformer') const MatchTransformer = use('App/Transformers/MatchTransformer')
const RoleIdentificationService = use('App/Services/RoleIdentificationService')
const SummonerService = use('App/Services/SummonerService') const SummonerService = use('App/Services/SummonerService')
/** /**
@ -9,7 +10,7 @@ const SummonerService = use('App/Services/SummonerService')
* @class LiveMatchTransformer * @class LiveMatchTransformer
*/ */
class LiveMatchTransformer extends MatchTransformer { class LiveMatchTransformer extends MatchTransformer {
async _getPlayerDatq(participant, region) { async _getPlayerRank(participant, region) {
const account = await SummonerService.getAccount(participant.summonerName, region) const account = await SummonerService.getAccount(participant.summonerName, region)
if (account) { if (account) {
participant.level = account.summonerLevel participant.level = account.summonerLevel
@ -29,12 +30,35 @@ class LiveMatchTransformer extends MatchTransformer {
async transform(match, { region }) { async transform(match, { region }) {
await super.getContext() await super.getContext()
// Perks // Roles
for (const participant of match.participants) { const blueTeam = [] // 100
participant.runes = participant.perks ? super.getPerksImages(participant.perks.perkIds[0], participant.perks.perkSubStyle) : {} 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) match.participants = await Promise.all(requestsParticipants)
return match return match

View file

@ -2,6 +2,7 @@
const Jax = use('App/Services/Jax') const Jax = use('App/Services/Jax')
const Helpers = use('App/helpers') const Helpers = use('App/helpers')
const RoleIdentificationService = use('App/Services/RoleIdentificationService')
/** /**
* MatchTransformer class * MatchTransformer class
@ -18,12 +19,14 @@ class MatchTransformer {
const perks = await Jax.CDragon.perks() const perks = await Jax.CDragon.perks()
const perkstyles = await Jax.CDragon.perkstyles() const perkstyles = await Jax.CDragon.perkstyles()
const summonerSpells = await Jax.CDragon.summonerSpells() const summonerSpells = await Jax.CDragon.summonerSpells()
const championRoles = await RoleIdentificationService.pullData().catch(() => {})
this.champions = champions this.champions = champions
this.items = items this.items = items
this.perks = perks this.perks = perks
this.perkstyles = perkstyles.styles this.perkstyles = perkstyles.styles
this.summonerSpells = summonerSpells this.summonerSpells = summonerSpells
this.championRoles = championRoles
this.sortTeamByRole = Helpers.sortTeamByRole this.sortTeamByRole = Helpers.sortTeamByRole
// League of Legends seasons timestamps // League of Legends seasons timestamps

219
server/package-lock.json generated
View file

@ -196,16 +196,53 @@
} }
}, },
"@sindresorhus/is": { "@sindresorhus/is": {
"version": "0.14.0", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz",
"integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg=="
}, },
"@szmarczak/http-timer": { "@szmarczak/http-timer": {
"version": "1.1.2", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
"integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
"requires": { "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": { "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": { "cacheable-request": {
"version": "6.1.0", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz",
"integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==",
"requires": { "requires": {
"clone-response": "^1.0.2", "clone-response": "^1.0.2",
"get-stream": "^5.1.0", "get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0", "http-cache-semantics": "^4.0.0",
"keyv": "^3.0.0", "keyv": "^4.0.0",
"lowercase-keys": "^2.0.0", "lowercase-keys": "^2.0.0",
"normalize-url": "^4.1.0", "normalize-url": "^4.1.0",
"responselike": "^1.0.2" "responselike": "^2.0.0"
}, },
"dependencies": { "dependencies": {
"get-stream": { "get-stream": {
@ -747,11 +789,6 @@
"requires": { "requires": {
"pump": "^3.0.0" "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=" "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
}, },
"decompress-response": { "decompress-response": {
"version": "3.3.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": { "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": { "defer-to-connect": {
"version": "1.0.2", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
"integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==" "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg=="
}, },
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
@ -1188,11 +1232,6 @@
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
"integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" "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": { "ecc-jsbn": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -1720,21 +1759,32 @@
} }
}, },
"got": { "got": {
"version": "9.6.0", "version": "11.3.0",
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "resolved": "https://registry.npmjs.org/got/-/got-11.3.0.tgz",
"integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "integrity": "sha512-yi/kiZY2tNMtt5IfbfX8UL3hAZWb2gZruxYZ72AY28pU5p0TZjZdl0uRsuaFbnC0JopdUi3I+Mh1F3dPQ9Dh0Q==",
"requires": { "requires": {
"@sindresorhus/is": "^0.14.0", "@sindresorhus/is": "^2.1.1",
"@szmarczak/http-timer": "^1.1.2", "@szmarczak/http-timer": "^4.0.5",
"cacheable-request": "^6.0.0", "@types/cacheable-request": "^6.0.1",
"decompress-response": "^3.3.0", "@types/responselike": "^1.0.0",
"duplexer3": "^0.1.4", "cacheable-lookup": "^5.0.3",
"get-stream": "^4.1.0", "cacheable-request": "^7.0.1",
"lowercase-keys": "^1.0.1", "decompress-response": "^6.0.0",
"mimic-response": "^1.0.1", "get-stream": "^5.1.0",
"p-cancelable": "^1.0.0", "http2-wrapper": "^1.0.0-beta.4.5",
"to-readable-stream": "^1.0.0", "lowercase-keys": "^2.0.0",
"url-parse-lax": "^3.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": { "graceful-fs": {
@ -1840,9 +1890,9 @@
"integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==" "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ=="
}, },
"http-cache-semantics": { "http-cache-semantics": {
"version": "4.0.3", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==" "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
}, },
"http-errors": { "http-errors": {
"version": "1.7.3", "version": "1.7.3",
@ -1866,6 +1916,15 @@
"sshpk": "^1.7.0" "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": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -2147,9 +2206,9 @@
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
}, },
"json-buffer": { "json-buffer": {
"version": "3.0.0", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
}, },
"json-schema": { "json-schema": {
"version": "0.2.3", "version": "0.2.3",
@ -2222,11 +2281,11 @@
} }
}, },
"keyv": { "keyv": {
"version": "3.1.0", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz",
"integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==",
"requires": { "requires": {
"json-buffer": "3.0.0" "json-buffer": "3.0.1"
} }
}, },
"kind-of": { "kind-of": {
@ -2516,9 +2575,9 @@
} }
}, },
"lowercase-keys": { "lowercase-keys": {
"version": "1.0.1", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
}, },
"lru-cache": { "lru-cache": {
"version": "4.1.5", "version": "4.1.5",
@ -2958,9 +3017,9 @@
} }
}, },
"normalize-url": { "normalize-url": {
"version": "4.3.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
"integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==" "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ=="
}, },
"oauth-sign": { "oauth-sign": {
"version": "0.9.0", "version": "0.9.0",
@ -3118,9 +3177,9 @@
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
}, },
"p-cancelable": { "p-cancelable": {
"version": "1.1.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg=="
}, },
"p-limit": { "p-limit": {
"version": "1.3.0", "version": "1.3.0",
@ -3259,11 +3318,6 @@
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" "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": { "pretty-hrtime": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "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", "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz",
"integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==" "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": { "radio-symbol": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/radio-symbol/-/radio-symbol-2.0.0.tgz", "resolved": "https://registry.npmjs.org/radio-symbol/-/radio-symbol-2.0.0.tgz",
@ -4068,6 +4127,11 @@
"path-parse": "^1.0.6" "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": { "resolve-dir": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
@ -4088,11 +4152,11 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
}, },
"responselike": { "responselike": {
"version": "1.0.2", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
"requires": { "requires": {
"lowercase-keys": "^1.0.0" "lowercase-keys": "^2.0.0"
} }
}, },
"ret": { "ret": {
@ -4790,11 +4854,6 @@
"kind-of": "^3.0.2" "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": { "to-regex": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "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", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" "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": { "use": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",

View file

@ -27,7 +27,7 @@
"@adonisjs/lucid": "^6.1.3", "@adonisjs/lucid": "^6.1.3",
"@adonisjs/redis": "^2.0.7", "@adonisjs/redis": "^2.0.7",
"bee-queue": "^1.2.3", "bee-queue": "^1.2.3",
"got": "^9.6.0", "got": "^11.3.0",
"lucid-mongo": "^3.1.6", "lucid-mongo": "^3.1.6",
"mongodb-core": "^3.2.7", "mongodb-core": "^3.2.7",
"request": "^2.88.2", "request": "^2.88.2",