-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathaccount-blob.js
149 lines (129 loc) · 5.3 KB
/
account-blob.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const _get = require('fast-get')
const flow = require('../flow.js')
function blob (parent) {
const client = parent.client
const requests = {
account: wrap(() => client.account().get()),
achievements: wrap(() => client.account().achievements().get()),
bank: wrap(() => client.account().bank().get()),
characters: wrap(() => client.characters().all()),
'commerce.buys': wrap(() => client.commerce().transactions().current().buys().all()),
'commerce.delivery': wrap(() => client.commerce().delivery().get()),
'commerce.sells': wrap(() => client.commerce().transactions().current().sells().all()),
dungeons: wrap(() => client.account().dungeons().get()),
dyes: wrap(() => client.account().dyes().get()),
emotes: wrap(() => client.account().emotes().get()),
finishers: wrap(() => client.account().finishers().get()),
gliders: wrap(() => client.account().gliders().get()),
guilds: wrap(() => accountGuilds(client)),
'home.cats': wrap(() => client.account().home().cats().get()),
'home.nodes': wrap(() => client.account().home().nodes().get()),
'homestead.decorations': wrap(() => client.account().homestead().decorations().get()),
'homestead.glyphs': wrap(() => client.account().homestead().glyphs().get()),
jadebots: wrap(() => client.account().jadebots().get()),
legendaryarmory: wrap(() => client.account().legendaryarmory().get()),
luck: wrap(() => client.account().luck().get()),
mailcarriers: wrap(() => client.account().mailcarriers().get()),
masteries: wrap(() => client.account().masteries().get()),
'mastery.points': wrap(() => client.account().mastery().points().get()),
materials: wrap(() => client.account().materials().get()),
minis: wrap(() => client.account().minis().get()),
'mounts.skins': wrap(() => client.account().mounts().skins().get()),
'mounts.types': wrap(() => client.account().mounts().types().get()),
novelties: wrap(() => client.account().novelties().get()),
outfits: wrap(() => client.account().outfits().get()),
'pvp.games': wrap(() => client.account().pvp().games().all()),
'pvp.heroes': wrap(() => client.account().pvp().heroes().get()),
'pvp.standings': wrap(() => client.account().pvp().standings().get()),
'pvp.stats': wrap(() => client.account().pvp().stats().get()),
raids: wrap(() => client.account().raids().get()),
recipes: wrap(() => client.account().recipes().get()),
shared: wrap(() => client.account().inventory().get()),
skiffs: wrap(() => client.account().skiffs().get()),
skins: wrap(() => client.account().skins().get()),
titles: wrap(() => client.account().titles().get()),
wallet: wrap(() => client.account().wallet().get())
}
return flow.parallel(requests).then(data => {
data = unflatten(data)
data.characters = filterBetaCharacters(data.characters)
return data
})
}
// Get the guild data accessible for the account
function accountGuilds (client) {
return client.account().get().then(account => {
if (!account.guild_leader) {
return []
}
let requests = account.guild_leader.map(id => wrap(() => guildData(id)))
return flow.parallel(requests)
})
function guildData (id) {
let requests = {
data: wrap(() => client.guild().get(id)),
members: wrap(() => client.guild(id).members().get()),
ranks: wrap(() => client.guild(id).ranks().get()),
stash: wrap(() => client.guild(id).stash().get()),
teams: wrap(() => Promise.resolve(null)),
treasury: wrap(() => client.guild(id).treasury().get()),
upgrades: wrap(() => client.guild(id).upgrades().get())
}
return flow.parallel(requests)
}
}
// Filter out beta characters from the total account blob, since they are
// technically not part of the actual live account and live on a different server
function filterBetaCharacters (characters) {
/* istanbul ignore next */
if (!characters) {
return null
}
return characters.filter(x => !x.flags || !x.flags.includes('Beta'))
}
// Wrap a promise function so all errors that have to do with the API
// just result in an empty response instead of throwing an error
// This prevents API errors / changes breaking the entire infrastructure
function wrap (func) {
return () => new Promise((resolve, reject) => {
func()
.then(x => resolve(x))
.catch(err => {
let status = _get(err, 'response.status')
let text = _get(err, 'content.text')
if (status || text) {
console.warn(`API error: ${text} (${status})`)
return resolve(null)
}
reject(err)
})
})
}
// Unflatten an object with keys describing a nested structure
function unflatten (object) {
let result = {}
for (let key in object) {
_set(result, key, object[key])
}
return result
}
// Set the value of an object based on a flat key ("a.b.c")
function _set (object, key, value) {
const keyParts = key.split('.')
let walking = object
keyParts.forEach((key, index) => {
// Create the nested object if it does not exist
if (!walking[key]) {
walking[key] = {}
}
// If we reached the last part, set the value and exit out
if (index === keyParts.length - 1) {
walking[key] = value
return
}
// Set the next part of the key
walking = walking[key]
})
}
module.exports = blob
module.exports.wrap = wrap