clashofclans.js 2.7.0-dev.a33ae73 → 2.8.0-dev.53b06d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/dist/client/Client.d.ts +20 -17
- package/dist/client/Client.js +12 -11
- package/dist/client/EventManager.js +15 -16
- package/dist/index.mjs +21 -20
- package/dist/rest/RESTManager.d.ts +1 -1
- package/dist/rest/RequestHandler.d.ts +2 -2
- package/dist/rest/RequestHandler.js +7 -12
- package/dist/rest/Throttler.d.ts +10 -12
- package/dist/rest/Throttler.js +27 -50
- package/dist/struct/ClanMember.js +1 -1
- package/dist/struct/ClanWar.js +1 -1
- package/dist/struct/ClanWarLeagueGroup.d.ts +2 -1
- package/dist/struct/ClanWarLeagueGroup.js +2 -1
- package/dist/struct/League.js +1 -1
- package/dist/struct/Player.js +11 -11
- package/dist/struct/Ranking.js +1 -1
- package/dist/struct/Unit.js +4 -5
- package/dist/struct/WarLeague.js +1 -1
- package/dist/types/lib.d.ts +8 -3
- package/dist/util/Constants.d.ts +75 -33
- package/dist/util/Constants.js +44 -35
- package/dist/util/Util.d.ts +13 -0
- package/dist/util/Util.js +30 -0
- package/dist/util/raw.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## 2.8.0 (2022-07-22)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Better Throttler with JS generator function. ([#111](https://github.com/clashperk/clashofclans.js/pull/111))
|
|
10
|
+
- Updated raw data from game files. ([#111](https://github.com/clashperk/clashofclans.js/pull/111))
|
|
11
|
+
- New method Util#parseArmyLink has been added. ([#110](https://github.com/clashperk/clashofclans.js/pull/110))
|
|
12
|
+
|
|
5
13
|
## 2.7.0 (2022-05-22)
|
|
6
14
|
|
|
7
15
|
### Features
|
|
8
16
|
|
|
9
|
-
-
|
|
17
|
+
- Some useful QOL methods have been added. ([#106](https://github.com/clashperk/clashofclans.js/pull/106))
|
|
10
18
|
|
|
11
19
|
## 2.6.1 (2022-02-03)
|
|
12
20
|
|
package/dist/client/Client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ClanSearchOptions, SearchOptions, ClientOptions, LoginOptions, OverrideOptions } from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import { Events, CWLRounds } from '../util/Constants';
|
|
4
4
|
import { RESTManager } from '../rest/RESTManager';
|
|
5
5
|
import { EventManager } from './EventManager';
|
|
6
6
|
import { EventEmitter } from 'events';
|
|
@@ -15,9 +15,9 @@ import { Clan, ClanMember, ClanWar, ClanWarLog, League, Location, Player, WarLea
|
|
|
15
15
|
*/
|
|
16
16
|
export declare class Client extends EventEmitter {
|
|
17
17
|
/** Event Manager for the client. */
|
|
18
|
-
|
|
18
|
+
events: EventManager;
|
|
19
19
|
/** REST Handler of the client. */
|
|
20
|
-
|
|
20
|
+
rest: RESTManager;
|
|
21
21
|
constructor(options?: ClientOptions);
|
|
22
22
|
/** Contains various general-purpose utility methods. */
|
|
23
23
|
get util(): typeof Util;
|
|
@@ -57,7 +57,7 @@ export declare class Client extends EventEmitter {
|
|
|
57
57
|
*/
|
|
58
58
|
getCurrentWar(clanTag: string | {
|
|
59
59
|
clanTag: string;
|
|
60
|
-
round?: keyof typeof
|
|
60
|
+
round?: keyof typeof CWLRounds;
|
|
61
61
|
}, options?: OverrideOptions): Promise<ClanWar | null>;
|
|
62
62
|
/**
|
|
63
63
|
* Get info about currently running CWL round.
|
|
@@ -72,10 +72,12 @@ export declare class Client extends EventEmitter {
|
|
|
72
72
|
*/
|
|
73
73
|
getLeagueWar(clanTag: string | {
|
|
74
74
|
clanTag: string;
|
|
75
|
-
round?: keyof typeof
|
|
75
|
+
round?: keyof typeof CWLRounds;
|
|
76
76
|
}, options?: OverrideOptions): Promise<ClanWar | null>;
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
/** Returns active wars (last 2) of the CWL group. */
|
|
78
|
+
getLeagueWars(clanTag: string, options?: OverrideOptions): Promise<ClanWar[]>;
|
|
79
|
+
/** Returns active wars (last 2 for CWL) of the clan. */
|
|
80
|
+
getWars(clanTag: string, options?: OverrideOptions): Promise<ClanWar[]>;
|
|
79
81
|
/** Get info about clan war league. */
|
|
80
82
|
getClanWarLeagueGroup(clanTag: string, options?: OverrideOptions): Promise<ClanWarLeagueGroup>;
|
|
81
83
|
/** Get info about a CWL round by WarTag. */
|
|
@@ -176,16 +178,17 @@ export declare class Client extends EventEmitter {
|
|
|
176
178
|
/** @internal */ emit<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, ...args: any[]): boolean;
|
|
177
179
|
}
|
|
178
180
|
interface ClientEvents {
|
|
179
|
-
[
|
|
180
|
-
[
|
|
181
|
-
[
|
|
182
|
-
[
|
|
183
|
-
[
|
|
184
|
-
[
|
|
185
|
-
[
|
|
186
|
-
[
|
|
187
|
-
[
|
|
188
|
-
[
|
|
181
|
+
[Events.NewSeasonStart]: [id: string];
|
|
182
|
+
[Events.MaintenanceStart]: [];
|
|
183
|
+
[Events.MaintenanceEnd]: [duration: number];
|
|
184
|
+
[Events.ClanLoopStart]: [];
|
|
185
|
+
[Events.ClanLoopEnd]: [];
|
|
186
|
+
[Events.PlayerLoopStart]: [];
|
|
187
|
+
[Events.PlayerLoopEnd]: [];
|
|
188
|
+
[Events.WarLoopStart]: [];
|
|
189
|
+
[Events.WarLoopEnd]: [];
|
|
190
|
+
[Events.Error]: [error: unknown];
|
|
191
|
+
[Events.Debug]: [path: string, status: string, message: string];
|
|
189
192
|
}
|
|
190
193
|
interface CustomEvents {
|
|
191
194
|
[key: `clan${string}`]: [oldClan: Clan, newClan: Clan];
|
package/dist/client/Client.js
CHANGED
|
@@ -116,7 +116,7 @@ class Client extends events_1.EventEmitter {
|
|
|
116
116
|
*/
|
|
117
117
|
async getLeagueWar(clanTag, options) {
|
|
118
118
|
const args = typeof clanTag === 'string' ? { clanTag } : { clanTag: clanTag.clanTag, round: clanTag.round };
|
|
119
|
-
const state = (args.round && Constants_1.
|
|
119
|
+
const state = (args.round && Constants_1.CWLRounds[args.round]) ?? 'inWar'; // eslint-disable-line
|
|
120
120
|
const data = await this.getClanWarLeagueGroup(args.clanTag, options);
|
|
121
121
|
const rounds = data.rounds.filter((round) => !round.warTags.includes('#0'));
|
|
122
122
|
if (!rounds.length)
|
|
@@ -128,23 +128,24 @@ class Client extends events_1.EventEmitter {
|
|
|
128
128
|
.flat()
|
|
129
129
|
.reverse();
|
|
130
130
|
const wars = await this.util.allSettled(warTags.map((warTag) => this.getClanWarLeagueRound({ warTag, clanTag: args.clanTag }, { ...options, ignoreRateLimit: true })));
|
|
131
|
-
if (args.round && args.round in Constants_1.
|
|
132
|
-
return wars.find((war) => war.state === state) ?? null;
|
|
131
|
+
if (args.round && args.round in Constants_1.CWLRounds) {
|
|
132
|
+
return wars.find((war) => war.clan.tag === args.clanTag && war.state === state) ?? null;
|
|
133
133
|
}
|
|
134
|
-
return wars.find((war) => war.state === state) ?? wars.at(0) ?? null;
|
|
134
|
+
return wars.find((war) => war.clan.tag === args.clanTag && war.state === state) ?? wars.at(0) ?? null;
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
/** Returns active wars (last 2) of the CWL group. */
|
|
137
|
+
async getLeagueWars(clanTag, options) {
|
|
137
138
|
const data = await this.getClanWarLeagueGroup(clanTag, options);
|
|
138
|
-
|
|
139
|
-
return data._getCurrentWars(clanTag, options);
|
|
139
|
+
return data.getCurrentWars(clanTag, options);
|
|
140
140
|
}
|
|
141
|
-
|
|
141
|
+
/** Returns active wars (last 2 for CWL) of the clan. */
|
|
142
|
+
async getWars(clanTag, options) {
|
|
142
143
|
const date = new Date().getUTCDate();
|
|
143
144
|
if (!(date >= 1 && date <= 10)) {
|
|
144
145
|
return [await this.getClanWar(clanTag, options)];
|
|
145
146
|
}
|
|
146
147
|
try {
|
|
147
|
-
return this.
|
|
148
|
+
return this.getLeagueWars(clanTag, options);
|
|
148
149
|
}
|
|
149
150
|
catch (e) {
|
|
150
151
|
if (e instanceof HTTPError_1.HTTPError && [404].includes(e.status)) {
|
|
@@ -193,12 +194,12 @@ class Client extends events_1.EventEmitter {
|
|
|
193
194
|
}
|
|
194
195
|
/** Get Legend League season Ids. */
|
|
195
196
|
async getLeagueSeasons(options) {
|
|
196
|
-
const { data } = await this.rest.getLeagueSeasons(Constants_1.
|
|
197
|
+
const { data } = await this.rest.getLeagueSeasons(Constants_1.LegendLeagueId, options);
|
|
197
198
|
return data.items.map((league) => league.id);
|
|
198
199
|
}
|
|
199
200
|
/** Get Legend League season rankings by season Id. */
|
|
200
201
|
async getSeasonRankings(seasonId, options) {
|
|
201
|
-
const { data } = await this.rest.getSeasonRankings(Constants_1.
|
|
202
|
+
const { data } = await this.rest.getSeasonRankings(Constants_1.LegendLeagueId, seasonId, options);
|
|
202
203
|
return data.items.map((entry) => new struct_1.SeasonRankedPlayer(this, entry));
|
|
203
204
|
}
|
|
204
205
|
/** Get list of Clan War Leagues. */
|
|
@@ -148,14 +148,14 @@ class EventManager {
|
|
|
148
148
|
this._inMaintenance = Boolean(false);
|
|
149
149
|
const duration = Date.now() - this._maintenanceStartTime.getTime();
|
|
150
150
|
this._maintenanceStartTime = null;
|
|
151
|
-
this.client.emit(Constants_1.
|
|
151
|
+
this.client.emit(Constants_1.Events.MaintenanceEnd, duration);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
catch (error) {
|
|
155
155
|
if (error instanceof HTTPError_1.HTTPError && error.status === 503 && !this._inMaintenance) {
|
|
156
156
|
this._inMaintenance = Boolean(true);
|
|
157
157
|
this._maintenanceStartTime = new Date();
|
|
158
|
-
this.client.emit(Constants_1.
|
|
158
|
+
this.client.emit(Constants_1.Events.MaintenanceStart);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -167,29 +167,29 @@ class EventManager {
|
|
|
167
167
|
}
|
|
168
168
|
else if (end > 0) {
|
|
169
169
|
setTimeout(() => {
|
|
170
|
-
this.client.emit(Constants_1.
|
|
170
|
+
this.client.emit(Constants_1.Events.NewSeasonStart, Util_1.Util.getSeasonId());
|
|
171
171
|
}, end + 100).unref();
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
async clanUpdateHandler() {
|
|
175
|
-
this.client.emit(Constants_1.
|
|
175
|
+
this.client.emit(Constants_1.Events.ClanLoopStart);
|
|
176
176
|
for (const tag of this._clanTags)
|
|
177
177
|
await this.runClanUpdate(tag);
|
|
178
|
-
this.client.emit(Constants_1.
|
|
178
|
+
this.client.emit(Constants_1.Events.ClanLoopEnd);
|
|
179
179
|
setTimeout(this.clanUpdateHandler.bind(this), 10000);
|
|
180
180
|
}
|
|
181
181
|
async playerUpdateHandler() {
|
|
182
|
-
this.client.emit(Constants_1.
|
|
182
|
+
this.client.emit(Constants_1.Events.PlayerLoopStart);
|
|
183
183
|
for (const tag of this._playerTags)
|
|
184
184
|
await this.runPlayerUpdate(tag);
|
|
185
|
-
this.client.emit(Constants_1.
|
|
185
|
+
this.client.emit(Constants_1.Events.PlayerLoopEnd);
|
|
186
186
|
setTimeout(this.playerUpdateHandler.bind(this), 10000);
|
|
187
187
|
}
|
|
188
188
|
async warUpdateHandler() {
|
|
189
|
-
this.client.emit(Constants_1.
|
|
189
|
+
this.client.emit(Constants_1.Events.WarLoopStart);
|
|
190
190
|
for (const tag of this._warTags)
|
|
191
191
|
await this.runWarUpdate(tag);
|
|
192
|
-
this.client.emit(Constants_1.
|
|
192
|
+
this.client.emit(Constants_1.Events.WarLoopEnd);
|
|
193
193
|
setTimeout(this.warUpdateHandler.bind(this), 10000);
|
|
194
194
|
}
|
|
195
195
|
async runClanUpdate(tag) {
|
|
@@ -208,7 +208,7 @@ class EventManager {
|
|
|
208
208
|
this.client.emit(name, cached, clan);
|
|
209
209
|
}
|
|
210
210
|
catch (error) {
|
|
211
|
-
this.client.emit(Constants_1.
|
|
211
|
+
this.client.emit(Constants_1.Events.Error, error);
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
return this._clans.set(clan.tag, clan);
|
|
@@ -229,7 +229,7 @@ class EventManager {
|
|
|
229
229
|
this.client.emit(name, cached, player);
|
|
230
230
|
}
|
|
231
231
|
catch (error) {
|
|
232
|
-
this.client.emit(Constants_1.
|
|
232
|
+
this.client.emit(Constants_1.Events.Error, error);
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
return this._players.set(player.tag, player);
|
|
@@ -237,8 +237,7 @@ class EventManager {
|
|
|
237
237
|
async runWarUpdate(tag) {
|
|
238
238
|
if (this._inMaintenance)
|
|
239
239
|
return null;
|
|
240
|
-
|
|
241
|
-
const clanWars = await this.client._getClanWars(tag).catch(() => null);
|
|
240
|
+
const clanWars = await this.client.getWars(tag).catch(() => null);
|
|
242
241
|
if (!clanWars?.length)
|
|
243
242
|
return null;
|
|
244
243
|
clanWars.forEach(async (war, index) => {
|
|
@@ -253,12 +252,12 @@ class EventManager {
|
|
|
253
252
|
this.client.emit(name, cached, war);
|
|
254
253
|
}
|
|
255
254
|
catch (error) {
|
|
256
|
-
this.client.emit(Constants_1.
|
|
255
|
+
this.client.emit(Constants_1.Events.Error, error);
|
|
257
256
|
}
|
|
258
257
|
}
|
|
259
258
|
// check for war end
|
|
260
259
|
if (index === 1 && cached.warTag !== war.warTag) {
|
|
261
|
-
const data = await this.client.getLeagueWar({ clanTag: tag, round: '
|
|
260
|
+
const data = await this.client.getLeagueWar({ clanTag: tag, round: 'PreviousRound' }).catch(() => null);
|
|
262
261
|
if (data && data.warTag === cached.warTag) {
|
|
263
262
|
for (const { name, filter } of this._events.wars) {
|
|
264
263
|
try {
|
|
@@ -267,7 +266,7 @@ class EventManager {
|
|
|
267
266
|
this.client.emit(name, cached, data);
|
|
268
267
|
}
|
|
269
268
|
catch (error) {
|
|
270
|
-
this.client.emit(Constants_1.
|
|
269
|
+
this.client.emit(Constants_1.Events.Error, error);
|
|
271
270
|
}
|
|
272
271
|
}
|
|
273
272
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import mod from "./index.js";
|
|
2
2
|
|
|
3
3
|
export default mod;
|
|
4
|
-
export const
|
|
4
|
+
export const APIBaseURL = mod.APIBaseURL;
|
|
5
5
|
export const Achievement = mod.Achievement;
|
|
6
|
-
export const BUILDER_TROOPS = mod.BUILDER_TROOPS;
|
|
7
6
|
export const Badge = mod.Badge;
|
|
8
7
|
export const BatchThrottler = mod.BatchThrottler;
|
|
9
|
-
export const
|
|
8
|
+
export const BuilderTroops = mod.BuilderTroops;
|
|
9
|
+
export const CWLRounds = mod.CWLRounds;
|
|
10
10
|
export const CacheStore = mod.CacheStore;
|
|
11
11
|
export const ChatLanguage = mod.ChatLanguage;
|
|
12
12
|
export const Clan = mod.Clan;
|
|
@@ -20,25 +20,25 @@ export const ClanWarLeagueRound = mod.ClanWarLeagueRound;
|
|
|
20
20
|
export const ClanWarLog = mod.ClanWarLog;
|
|
21
21
|
export const ClanWarMember = mod.ClanWarMember;
|
|
22
22
|
export const Client = mod.Client;
|
|
23
|
-
export const
|
|
24
|
-
export const
|
|
25
|
-
export const
|
|
26
|
-
export const
|
|
27
|
-
export const
|
|
28
|
-
export const EVENTS = mod.EVENTS;
|
|
23
|
+
export const DarkElixirSpells = mod.DarkElixirSpells;
|
|
24
|
+
export const DarkElixirTroops = mod.DarkElixirTroops;
|
|
25
|
+
export const DevSiteAPIBaseURL = mod.DevSiteAPIBaseURL;
|
|
26
|
+
export const ElixirSpells = mod.ElixirSpells;
|
|
27
|
+
export const ElixirTroops = mod.ElixirTroops;
|
|
29
28
|
export const EventManager = mod.EventManager;
|
|
30
|
-
export const
|
|
29
|
+
export const Events = mod.Events;
|
|
30
|
+
export const FriendlyWarPreparationTimes = mod.FriendlyWarPreparationTimes;
|
|
31
31
|
export const GoldPassSeason = mod.GoldPassSeason;
|
|
32
|
-
export const HEROES = mod.HEROES;
|
|
33
|
-
export const HERO_PETS = mod.HERO_PETS;
|
|
34
|
-
export const HOME_TROOPS = mod.HOME_TROOPS;
|
|
35
32
|
export const HTTPError = mod.HTTPError;
|
|
36
33
|
export const Hero = mod.Hero;
|
|
34
|
+
export const HeroPets = mod.HeroPets;
|
|
35
|
+
export const Heroes = mod.Heroes;
|
|
36
|
+
export const HomeTroops = mod.HomeTroops;
|
|
37
37
|
export const Icon = mod.Icon;
|
|
38
|
-
export const LEAGUES = mod.LEAGUES;
|
|
39
|
-
export const LEGEND_LEAGUE_ID = mod.LEGEND_LEAGUE_ID;
|
|
40
38
|
export const Label = mod.Label;
|
|
41
39
|
export const League = mod.League;
|
|
40
|
+
export const Leagues = mod.Leagues;
|
|
41
|
+
export const LegendLeagueId = mod.LegendLeagueId;
|
|
42
42
|
export const LegendStatistics = mod.LegendStatistics;
|
|
43
43
|
export const Location = mod.Location;
|
|
44
44
|
export const NotInWarError = mod.NotInWarError;
|
|
@@ -49,18 +49,19 @@ export const QueueThrottler = mod.QueueThrottler;
|
|
|
49
49
|
export const RESTManager = mod.RESTManager;
|
|
50
50
|
export const RankedClan = mod.RankedClan;
|
|
51
51
|
export const RankedPlayer = mod.RankedPlayer;
|
|
52
|
+
export const RawData = mod.RawData;
|
|
52
53
|
export const RequestHandler = mod.RequestHandler;
|
|
53
|
-
export const SIEGE_MACHINES = mod.SIEGE_MACHINES;
|
|
54
|
-
export const SPELLS = mod.SPELLS;
|
|
55
|
-
export const SUPER_TROOPS = mod.SUPER_TROOPS;
|
|
56
54
|
export const Season = mod.Season;
|
|
57
55
|
export const SeasonRankedPlayer = mod.SeasonRankedPlayer;
|
|
56
|
+
export const SiegeMachines = mod.SiegeMachines;
|
|
58
57
|
export const Spell = mod.Spell;
|
|
58
|
+
export const Spells = mod.Spells;
|
|
59
|
+
export const SuperTroops = mod.SuperTroops;
|
|
59
60
|
export const Troop = mod.Troop;
|
|
60
|
-
export const UNRANKED_LEAGUE_DATA = mod.UNRANKED_LEAGUE_DATA;
|
|
61
61
|
export const Unit = mod.Unit;
|
|
62
|
+
export const UnrankedLeagueData = mod.UnrankedLeagueData;
|
|
62
63
|
export const Util = mod.Util;
|
|
63
|
-
export const WAR_LEAGUES = mod.WAR_LEAGUES;
|
|
64
64
|
export const WarClan = mod.WarClan;
|
|
65
65
|
export const WarLeague = mod.WarLeague;
|
|
66
|
+
export const WarLeagues = mod.WarLeagues;
|
|
66
67
|
export const WarLogClan = mod.WarLogClan;
|
|
@@ -4,7 +4,7 @@ import { APIClan, APIClanList, APIClanMemberList, APIClanRankingList, APIClanVer
|
|
|
4
4
|
/** Represents a REST Manager of the client. */
|
|
5
5
|
export declare class RESTManager {
|
|
6
6
|
/** Request Handler for the RESTManager. */
|
|
7
|
-
|
|
7
|
+
handler: RequestHandler;
|
|
8
8
|
constructor(options?: RESTOptions);
|
|
9
9
|
/** Contains various general-purpose utility methods. */
|
|
10
10
|
get util(): typeof Util;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Response, RequestOptions, LoginOptions, RequestHandlerOptions } from '../types';
|
|
2
2
|
/** Represents a Request Handler. */
|
|
3
3
|
export declare class RequestHandler {
|
|
4
4
|
#private;
|
|
@@ -14,7 +14,7 @@ export declare class RequestHandler {
|
|
|
14
14
|
private readonly restRequestTimeout;
|
|
15
15
|
private readonly throttler?;
|
|
16
16
|
private readonly cached;
|
|
17
|
-
constructor(options?:
|
|
17
|
+
constructor(options?: RequestHandlerOptions);
|
|
18
18
|
private get _keys();
|
|
19
19
|
private get _key();
|
|
20
20
|
setKeys(keys: string[]): this;
|
|
@@ -30,7 +30,7 @@ class RequestHandler {
|
|
|
30
30
|
this.keys = options?.keys ?? [];
|
|
31
31
|
this.retryLimit = options?.retryLimit ?? 0;
|
|
32
32
|
this.throttler = options?.throttler ?? null;
|
|
33
|
-
this.baseURL = options?.baseURL ?? Constants_1.
|
|
33
|
+
this.baseURL = options?.baseURL ?? Constants_1.APIBaseURL;
|
|
34
34
|
this.restRequestTimeout = options?.restRequestTimeout ?? 0;
|
|
35
35
|
this.rejectIfNotValid = options?.rejectIfNotValid ?? true;
|
|
36
36
|
if (typeof options?.cache === 'object')
|
|
@@ -54,19 +54,14 @@ class RequestHandler {
|
|
|
54
54
|
return Boolean(this.email && this.password);
|
|
55
55
|
}
|
|
56
56
|
async request(path, options = {}) {
|
|
57
|
-
const cached = (await this.cached
|
|
57
|
+
const cached = this.cached ? (await this.cached.get(path)) ?? null : null;
|
|
58
58
|
if (cached && options.force !== true) {
|
|
59
59
|
return { data: cached.data, maxAge: cached.ttl - Date.now(), status: cached.status, path, ok: cached.status === 200 };
|
|
60
60
|
}
|
|
61
61
|
if (!this.throttler || options.ignoreRateLimit)
|
|
62
62
|
return this.exec(path, options);
|
|
63
63
|
await this.throttler.wait();
|
|
64
|
-
|
|
65
|
-
return await this.exec(path, options);
|
|
66
|
-
}
|
|
67
|
-
finally {
|
|
68
|
-
await this.throttler.throttle();
|
|
69
|
-
}
|
|
64
|
+
return this.exec(path, options);
|
|
70
65
|
}
|
|
71
66
|
async exec(path, options = {}, retries = 0) {
|
|
72
67
|
const res = await (0, node_fetch_1.default)(`${this.baseURL}${path}`, {
|
|
@@ -125,7 +120,7 @@ class RequestHandler {
|
|
|
125
120
|
}
|
|
126
121
|
}
|
|
127
122
|
async login() {
|
|
128
|
-
const res = await (0, node_fetch_1.default)(`${Constants_1.
|
|
123
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/login`, {
|
|
129
124
|
method: 'POST',
|
|
130
125
|
timeout: 10000,
|
|
131
126
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -140,7 +135,7 @@ class RequestHandler {
|
|
|
140
135
|
return this.getKeys(res.headers.get('set-cookie'), ip);
|
|
141
136
|
}
|
|
142
137
|
async getKeys(cookie, ip) {
|
|
143
|
-
const res = await (0, node_fetch_1.default)(`${Constants_1.
|
|
138
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/list`, {
|
|
144
139
|
method: 'POST',
|
|
145
140
|
timeout: 10000,
|
|
146
141
|
headers: { 'Content-Type': 'application/json', cookie }
|
|
@@ -182,7 +177,7 @@ class RequestHandler {
|
|
|
182
177
|
return this.keys;
|
|
183
178
|
}
|
|
184
179
|
async revokeKey(keyId, cookie) {
|
|
185
|
-
const res = await (0, node_fetch_1.default)(`${Constants_1.
|
|
180
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/revoke`, {
|
|
186
181
|
method: 'POST',
|
|
187
182
|
timeout: 10000,
|
|
188
183
|
body: JSON.stringify({ id: keyId }),
|
|
@@ -191,7 +186,7 @@ class RequestHandler {
|
|
|
191
186
|
return res.ok;
|
|
192
187
|
}
|
|
193
188
|
async createKey(cookie, ip) {
|
|
194
|
-
const res = await (0, node_fetch_1.default)(`${Constants_1.
|
|
189
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/create`, {
|
|
195
190
|
method: 'POST',
|
|
196
191
|
timeout: 10000,
|
|
197
192
|
headers: { 'Content-Type': 'application/json', cookie },
|
package/dist/rest/Throttler.d.ts
CHANGED
|
@@ -6,26 +6,24 @@
|
|
|
6
6
|
* ```
|
|
7
7
|
*/
|
|
8
8
|
export declare class QueueThrottler {
|
|
9
|
-
private lastRun?;
|
|
10
9
|
private readonly sleepTime;
|
|
11
|
-
private readonly
|
|
10
|
+
private readonly generator;
|
|
12
11
|
constructor(sleepTime?: number);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
wait(): Promise<void>;
|
|
16
|
-
private shift;
|
|
12
|
+
private init;
|
|
13
|
+
wait(): Promise<IteratorResult<undefined, void>>;
|
|
17
14
|
}
|
|
18
15
|
/**
|
|
19
16
|
* Represents a throttler that allows x requests per second before sleeping until the next second.
|
|
20
17
|
* ```js
|
|
21
|
-
* const throttler = new BatchThrottler(
|
|
22
|
-
* //
|
|
18
|
+
* const throttler = new BatchThrottler(15);
|
|
19
|
+
* // 15 requests every second.
|
|
23
20
|
* ```
|
|
24
21
|
*/
|
|
25
22
|
export declare class BatchThrottler {
|
|
26
|
-
#private;
|
|
27
23
|
private readonly rateLimit;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
private readonly sleepTime;
|
|
25
|
+
private readonly generator;
|
|
26
|
+
constructor(rateLimit?: number, sleepTime?: number);
|
|
27
|
+
private init;
|
|
28
|
+
wait(): Promise<IteratorResult<undefined, void>>;
|
|
31
29
|
}
|
package/dist/rest/Throttler.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
-
};
|
|
7
|
-
var _BatchThrottler_taskLogs;
|
|
8
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
3
|
exports.BatchThrottler = exports.QueueThrottler = void 0;
|
|
10
4
|
const Util_1 = require("../util/Util");
|
|
@@ -17,70 +11,53 @@ const Util_1 = require("../util/Util");
|
|
|
17
11
|
*/
|
|
18
12
|
class QueueThrottler {
|
|
19
13
|
constructor(sleepTime = 100) {
|
|
20
|
-
this.
|
|
14
|
+
this.generator = this.init();
|
|
21
15
|
this.sleepTime = sleepTime;
|
|
22
16
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const difference = Date.now() - this.lastRun;
|
|
17
|
+
async *init() {
|
|
18
|
+
let lastRan = 0;
|
|
19
|
+
// eslint-disable-next-line
|
|
20
|
+
while (true) {
|
|
21
|
+
const difference = Date.now() - lastRan;
|
|
29
22
|
const needToSleep = this.sleepTime - difference;
|
|
30
23
|
if (needToSleep > 0)
|
|
31
24
|
await Util_1.Util.delay(needToSleep);
|
|
25
|
+
lastRan = Date.now();
|
|
26
|
+
yield;
|
|
32
27
|
}
|
|
33
|
-
this.lastRun = Date.now();
|
|
34
|
-
return this.shift();
|
|
35
|
-
}
|
|
36
|
-
wait() {
|
|
37
|
-
const next = this.promises.length ? this.promises[this.promises.length - 1].promise : Promise.resolve();
|
|
38
|
-
let resolve;
|
|
39
|
-
const promise = new Promise((res) => {
|
|
40
|
-
resolve = res;
|
|
41
|
-
});
|
|
42
|
-
this.promises.push({ resolve: resolve, promise });
|
|
43
|
-
return next;
|
|
44
28
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (typeof deferred !== 'undefined')
|
|
48
|
-
deferred.resolve();
|
|
29
|
+
async wait() {
|
|
30
|
+
return this.generator.next();
|
|
49
31
|
}
|
|
50
32
|
}
|
|
51
33
|
exports.QueueThrottler = QueueThrottler;
|
|
52
34
|
/**
|
|
53
35
|
* Represents a throttler that allows x requests per second before sleeping until the next second.
|
|
54
36
|
* ```js
|
|
55
|
-
* const throttler = new BatchThrottler(
|
|
56
|
-
* //
|
|
37
|
+
* const throttler = new BatchThrottler(15);
|
|
38
|
+
* // 15 requests every second.
|
|
57
39
|
* ```
|
|
58
40
|
*/
|
|
59
41
|
class BatchThrottler {
|
|
60
|
-
constructor(rateLimit =
|
|
61
|
-
|
|
42
|
+
constructor(rateLimit = 15, sleepTime = 1000) {
|
|
43
|
+
this.generator = this.init();
|
|
62
44
|
this.rateLimit = rateLimit;
|
|
45
|
+
this.sleepTime = sleepTime;
|
|
63
46
|
}
|
|
64
|
-
async
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
__classPrivateFieldGet(this, _BatchThrottler_taskLogs, "f").shift();
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
47
|
+
async *init() {
|
|
48
|
+
let count = 0;
|
|
49
|
+
// eslint-disable-next-line
|
|
50
|
+
while (true) {
|
|
51
|
+
if (count++ >= this.rateLimit) {
|
|
52
|
+
if (this.sleepTime > 0)
|
|
53
|
+
await Util_1.Util.delay(this.sleepTime);
|
|
54
|
+
count = 0;
|
|
77
55
|
}
|
|
78
|
-
|
|
79
|
-
break;
|
|
80
|
-
await Util_1.Util.delay(1000);
|
|
56
|
+
yield;
|
|
81
57
|
}
|
|
82
|
-
|
|
58
|
+
}
|
|
59
|
+
async wait() {
|
|
60
|
+
return this.generator.next();
|
|
83
61
|
}
|
|
84
62
|
}
|
|
85
63
|
exports.BatchThrottler = BatchThrottler;
|
|
86
|
-
_BatchThrottler_taskLogs = new WeakMap();
|
|
@@ -12,7 +12,7 @@ class ClanMember {
|
|
|
12
12
|
this.role = data.role.replace('admin', 'elder');
|
|
13
13
|
this.expLevel = data.expLevel;
|
|
14
14
|
// eslint-disable-next-line
|
|
15
|
-
this.league = new League_1.League(data.league ?? Constants_1.
|
|
15
|
+
this.league = new League_1.League(data.league ?? Constants_1.UnrankedLeagueData);
|
|
16
16
|
this.trophies = data.trophies;
|
|
17
17
|
this.versusTrophies = data.versusTrophies ?? null;
|
|
18
18
|
this.clanRank = data.clanRank;
|
package/dist/struct/ClanWar.js
CHANGED
|
@@ -201,7 +201,7 @@ class ClanWar {
|
|
|
201
201
|
/** Whether this is a friendly war. */
|
|
202
202
|
get isFriendly() {
|
|
203
203
|
const preparationTime = this.startTime.getTime() - this.preparationStartTime.getTime();
|
|
204
|
-
return Constants_1.
|
|
204
|
+
return Constants_1.FriendlyWarPreparationTimes.includes(preparationTime);
|
|
205
205
|
}
|
|
206
206
|
/** Whether this is a CWL. */
|
|
207
207
|
get isCWL() {
|
|
@@ -62,7 +62,8 @@ export declare class ClanWarLeagueGroup {
|
|
|
62
62
|
* @param options Override options for the request.
|
|
63
63
|
*/
|
|
64
64
|
getWars(clanTag?: string, options?: OverrideOptions): Promise<ClanWar[]>;
|
|
65
|
-
|
|
65
|
+
/** Returns active wars (last 2) of the CWL group. */
|
|
66
|
+
getCurrentWars(clanTag: string, options?: OverrideOptions): Promise<ClanWar[]>;
|
|
66
67
|
/** Returns the index of the round for this specified warTag. */
|
|
67
68
|
getRoundIndex(warTag: string): number | null;
|
|
68
69
|
}
|
|
@@ -75,7 +75,8 @@ class ClanWarLeagueGroup {
|
|
|
75
75
|
.map((res) => res.value)
|
|
76
76
|
.filter((war) => (clanTag ? war.clan.tag === clanTag : true));
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
/** Returns active wars (last 2) of the CWL group. */
|
|
79
|
+
async getCurrentWars(clanTag, options) {
|
|
79
80
|
const rounds = this.rounds.filter((round) => !round.warTags.includes('#0'));
|
|
80
81
|
if (!rounds.length)
|
|
81
82
|
return [];
|
package/dist/struct/League.js
CHANGED