clashofclans.js 2.0.0-dev.0e51540 → 2.0.0-dev.2c5b083
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 +6 -5
- package/README.md +4 -3
- package/dist/client/Client.d.ts +47 -13
- package/dist/client/Client.js +56 -32
- package/dist/client/EventManager.d.ts +13 -13
- package/dist/client/EventManager.js +72 -37
- package/dist/rest/HTTPError.d.ts +17 -1
- package/dist/rest/HTTPError.js +14 -5
- package/dist/rest/RESTManager.d.ts +49 -120
- package/dist/rest/RESTManager.js +25 -1
- package/dist/rest/RequestHandler.d.ts +14 -6
- package/dist/rest/RequestHandler.js +20 -12
- package/dist/rest/Throttler.d.ts +0 -4
- package/dist/struct/Clan.d.ts +2 -1
- package/dist/struct/Clan.js +2 -2
- package/dist/struct/ClanMember.d.ts +2 -1
- package/dist/struct/ClanMember.js +2 -2
- package/dist/struct/ClanWar.d.ts +6 -4
- package/dist/struct/ClanWar.js +17 -3
- package/dist/struct/ClanWarLeagueGroup.d.ts +5 -3
- package/dist/struct/ClanWarLeagueGroup.js +12 -10
- package/dist/struct/ClanWarLog.d.ts +2 -2
- package/dist/struct/ClanWarLog.js +2 -2
- package/dist/struct/Player.d.ts +2 -1
- package/dist/struct/Player.js +7 -5
- package/dist/struct/PlayerClan.d.ts +2 -1
- package/dist/struct/PlayerClan.js +2 -2
- package/dist/struct/Unit.d.ts +37 -4
- package/dist/struct/Unit.js +49 -9
- package/dist/types/index.d.ts +2 -4
- package/dist/util/Util.js +3 -1
- package/dist/util/raw.json +1 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
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.0.0
|
|
5
|
+
## 2.0.0 (2021-11-26)
|
|
6
6
|
|
|
7
7
|
This new version is a complete TypeScript rewrite to convert everything from plain (literal JSON) objects to class (constructor) objects and support a lot more features.
|
|
8
8
|
|
|
9
9
|
### Features
|
|
10
10
|
|
|
11
|
-
- EventManager and Custom Events ([#37](https://github.com/clashperk/clashofclans.js/issues/37)) ([5027ae6](https://github.com/clashperk/clashofclans.js/commit/5027ae663a8e07175e17384c7e5706f4a1a7afb4)) ([984451d](https://github.com/clashperk/clashofclans.js/commit/30ea3240c11866008d0dae514468c0fdbb34ffd0))
|
|
12
|
-
- Internal Caching Options ([#53](https://github.com/clashperk/clashofclans.js/issues/53))
|
|
13
|
-
- Email Password Login ([#31](https://github.com/clashperk/clashofclans.js/issues/31)) ([4153cd3](https://github.com/clashperk/clashofclans.js/commit/4153cd37ea0e1c71550b9e892105b84d5a407e23))
|
|
14
11
|
- API Date Parser and Request Retries ([#26](https://github.com/clashperk/clashofclans.js/issues/26)) ([94585f3](https://github.com/clashperk/clashofclans.js/commit/94585f3a84a7175b2d07872f9eb9e42372b95e12))
|
|
15
|
-
-
|
|
12
|
+
- EventManager and Custom Events ([#37](https://github.com/clashperk/clashofclans.js/issues/37)) ([5027ae6](https://github.com/clashperk/clashofclans.js/commit/5027ae663a8e07175e17384c7e5706f4a1a7afb4))
|
|
13
|
+
- Email Password Login ([#31](https://github.com/clashperk/clashofclans.js/issues/31)) ([4153cd3](https://github.com/clashperk/clashofclans.js/commit/4153cd37ea0e1c71550b9e892105b84d5a407e23))
|
|
16
14
|
- QueueThrottler and BatchThrottler ([#34](https://github.com/clashperk/clashofclans.js/issues/34)) ([3a8f051](https://github.com/clashperk/clashofclans.js/commit/3a8f051552e93b98f89bc7d524acdecddf242718))
|
|
15
|
+
- Override Request Options ([#36](https://github.com/clashperk/clashofclans.js/issues/36)) ([42d7fdd](https://github.com/clashperk/clashofclans.js/commit/42d7fdd36262cc46f23b731f8cffb9daea19d3b0))
|
|
16
|
+
- Internal Caching Options ([#53](https://github.com/clashperk/clashofclans.js/issues/53)) ([984451d](https://github.com/clashperk/clashofclans.js/commit/30ea3240c11866008d0dae514468c0fdbb34ffd0))
|
|
17
|
+
- Raw Data for Player Units ([#65](https://github.com/clashperk/clashofclans.js/pull/65)) ([aa1696](https://github.com/clashperk/clashofclans.js/commit/aa1696243d96d4fed0250b4282c60522a6482343))
|
package/README.md
CHANGED
|
@@ -39,12 +39,13 @@ const client = new Client();
|
|
|
39
39
|
```js
|
|
40
40
|
const { Client, BatchThrottler } = require('clashofclans.js');
|
|
41
41
|
const client = new Client({
|
|
42
|
+
cache: true,
|
|
42
43
|
retryLimit: 1,
|
|
43
|
-
restRequestTimeout:
|
|
44
|
-
throttler: new BatchThrottler(
|
|
44
|
+
restRequestTimeout: 5000,
|
|
45
|
+
throttler: new BatchThrottler(20)
|
|
45
46
|
});
|
|
46
47
|
|
|
47
|
-
client.events.addClans(['#8P2QG08P']);
|
|
48
|
+
client.events.addClans(['#8QU8J9LP', '#8P2QG08P']);
|
|
48
49
|
client.events.setClanEvent({
|
|
49
50
|
name: 'clanDescriptionChange',
|
|
50
51
|
filter: (oldClan, newClan) => {
|
package/dist/client/Client.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare class Client extends EventEmitter {
|
|
|
21
21
|
constructor(options?: ClientOptions);
|
|
22
22
|
/** Contains various general-purpose utility methods. */
|
|
23
23
|
get util(): typeof Util;
|
|
24
|
+
/** Whether the API is in maintenance break. */
|
|
25
|
+
get inMaintenance(): boolean;
|
|
24
26
|
/**
|
|
25
27
|
* Initialize the client to create keys.
|
|
26
28
|
* @example
|
|
@@ -40,14 +42,34 @@ export declare class Client extends EventEmitter {
|
|
|
40
42
|
getClanMembers(clanTag: string, options?: SearchOptions): Promise<ClanMember[]>;
|
|
41
43
|
/** Get clan war log. */
|
|
42
44
|
getClanWarLog(clanTag: string, options?: SearchOptions): Promise<ClanWarLog[]>;
|
|
43
|
-
/** Get info about currently running war (
|
|
44
|
-
getClanWar(clanTag: string, options?: OverrideOptions): Promise<ClanWar
|
|
45
|
-
/**
|
|
45
|
+
/** Get info about currently running war (normal or friendly) in the clan. */
|
|
46
|
+
getClanWar(clanTag: string, options?: OverrideOptions): Promise<ClanWar>;
|
|
47
|
+
/**
|
|
48
|
+
* Get info about currently running war in the clan.
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* await client.getCurrentWar('#8QU8J9LP');
|
|
52
|
+
* ```
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* await client.getCurrentWar({ clanTag: '#8QU8J9LP', round: 'PREVIOUS_ROUND' });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
46
58
|
getCurrentWar(clanTag: string | {
|
|
47
59
|
clanTag: string;
|
|
48
60
|
round?: keyof typeof CWL_ROUNDS;
|
|
49
61
|
}, options?: OverrideOptions): Promise<ClanWar | null>;
|
|
50
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Get info about currently running CWL round.
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* await client.getLeagueWar('#8QU8J9LP');
|
|
67
|
+
* ```
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* await client.getLeagueWar({ clanTag: '#8QU8J9LP', round: 'PREVIOUS_ROUND' });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
51
73
|
getLeagueWar(clanTag: string | {
|
|
52
74
|
clanTag: string;
|
|
53
75
|
round?: keyof typeof CWL_ROUNDS;
|
|
@@ -56,11 +78,11 @@ export declare class Client extends EventEmitter {
|
|
|
56
78
|
private _getClanWars;
|
|
57
79
|
/** Get information about clan war league. */
|
|
58
80
|
getClanWarLeagueGroup(clanTag: string, options?: OverrideOptions): Promise<ClanWarLeagueGroup>;
|
|
59
|
-
/** Get
|
|
81
|
+
/** Get info about a CWL round by WarTag. */
|
|
60
82
|
getClanWarLeagueRound(warTag: string | {
|
|
61
83
|
warTag: string;
|
|
62
84
|
clanTag?: string;
|
|
63
|
-
}, options?: OverrideOptions): Promise<ClanWar
|
|
85
|
+
}, options?: OverrideOptions): Promise<ClanWar>;
|
|
64
86
|
/** Get information about a player by tag. */
|
|
65
87
|
getPlayer(playerTag: string, options?: OverrideOptions): Promise<Player>;
|
|
66
88
|
/** Verify Player API token that can be found from the Game settings. */
|
|
@@ -79,9 +101,9 @@ export declare class Client extends EventEmitter {
|
|
|
79
101
|
getClanRanks(locationId: number | 'global', options?: SearchOptions): Promise<RankedClan[]>;
|
|
80
102
|
/** Get player rankings for a specific location. */
|
|
81
103
|
getPlayerRanks(locationId: number | 'global', options?: SearchOptions): Promise<RankedPlayer[]>;
|
|
82
|
-
/** Get clan versus rankings for a specific location */
|
|
104
|
+
/** Get clan versus rankings for a specific location. */
|
|
83
105
|
getVersusClanRanks(locationId: number | 'global', options?: SearchOptions): Promise<RankedClan[]>;
|
|
84
|
-
/** Get player versus rankings for a specific location */
|
|
106
|
+
/** Get player versus rankings for a specific location. */
|
|
85
107
|
getVersusPlayerRanks(locationId: number | 'global', options?: SearchOptions): Promise<RankedPlayer[]>;
|
|
86
108
|
/** Get list of clan labels. */
|
|
87
109
|
getClanLabels(options?: SearchOptions): Promise<Label[]>;
|
|
@@ -94,8 +116,8 @@ export declare class Client extends EventEmitter {
|
|
|
94
116
|
*
|
|
95
117
|
* **Parameters**
|
|
96
118
|
*
|
|
97
|
-
* | Name |
|
|
98
|
-
* | :--: |
|
|
119
|
+
* | Name | Type | Description |
|
|
120
|
+
* | :--: | :------: | :-------------------: |
|
|
99
121
|
* | `id` | `string` | Id of the new season. |
|
|
100
122
|
* @public
|
|
101
123
|
* @event
|
|
@@ -112,8 +134,8 @@ export declare class Client extends EventEmitter {
|
|
|
112
134
|
*
|
|
113
135
|
* **Parameters**
|
|
114
136
|
*
|
|
115
|
-
* |
|
|
116
|
-
* |
|
|
137
|
+
* | Name | Type | Description |
|
|
138
|
+
* | :--------: | :------: | :------------------------------------------------: |
|
|
117
139
|
* | `duration` | `number` | Duration of the maintenance break in milliseconds. |
|
|
118
140
|
* @public
|
|
119
141
|
* @event
|
|
@@ -121,15 +143,21 @@ export declare class Client extends EventEmitter {
|
|
|
121
143
|
private static maintenanceEnd;
|
|
122
144
|
/** @internal */
|
|
123
145
|
on<K extends keyof ClientEvents>(event: K, listeners: (...args: ClientEvents[K]) => void): this;
|
|
146
|
+
/** @internal */
|
|
147
|
+
on<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: CustomEvents[S]) => void): this;
|
|
124
148
|
/** @internal */ on<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: any[]) => void): this;
|
|
125
149
|
/** @internal */
|
|
126
150
|
once<K extends keyof ClientEvents>(event: K, listeners: (...args: ClientEvents[K]) => void): this;
|
|
151
|
+
/** @internal */
|
|
152
|
+
once<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: CustomEvents[S]) => void): this;
|
|
127
153
|
/** @internal */ once<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: any[]) => void): this;
|
|
128
154
|
/** @internal */
|
|
129
155
|
emit<K extends keyof ClientEvents>(event: K, ...args: ClientEvents[K]): boolean;
|
|
156
|
+
/** @internal */
|
|
157
|
+
emit<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, ...args: CustomEvents[S]): this;
|
|
130
158
|
/** @internal */ emit<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, ...args: any[]): boolean;
|
|
131
159
|
}
|
|
132
|
-
|
|
160
|
+
interface ClientEvents {
|
|
133
161
|
[EVENTS.NEW_SEASON_START]: [id: string];
|
|
134
162
|
[EVENTS.MAINTENANCE_START]: [];
|
|
135
163
|
[EVENTS.MAINTENANCE_END]: [duration: number];
|
|
@@ -141,3 +169,9 @@ export interface ClientEvents {
|
|
|
141
169
|
[EVENTS.WAR_LOOP_END]: [];
|
|
142
170
|
[EVENTS.ERROR]: [error: unknown];
|
|
143
171
|
}
|
|
172
|
+
interface CustomEvents {
|
|
173
|
+
[key: `clan${string}`]: [oldClan: Clan, newClan: Clan];
|
|
174
|
+
[key: `war${string}`]: [oldWar: ClanWar, newWar: ClanWar];
|
|
175
|
+
[key: `player${string}`]: [oldPlayer: Player, newPlayer: Player];
|
|
176
|
+
}
|
|
177
|
+
export {};
|
package/dist/client/Client.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Client = void 0;
|
|
4
4
|
const Constants_1 = require("../util/Constants");
|
|
5
|
+
const HTTPError_1 = require("../rest/HTTPError");
|
|
5
6
|
const RESTManager_1 = require("../rest/RESTManager");
|
|
6
7
|
const EventManager_1 = require("./EventManager");
|
|
7
|
-
const HTTPError_1 = require("../rest/HTTPError");
|
|
8
8
|
const events_1 = require("events");
|
|
9
9
|
const Util_1 = require("../util/Util");
|
|
10
10
|
const struct_1 = require("../struct");
|
|
@@ -25,6 +25,11 @@ class Client extends events_1.EventEmitter {
|
|
|
25
25
|
get util() {
|
|
26
26
|
return Util_1.Util;
|
|
27
27
|
}
|
|
28
|
+
/** Whether the API is in maintenance break. */
|
|
29
|
+
get inMaintenance() {
|
|
30
|
+
// @ts-expect-error
|
|
31
|
+
return this.events._inMaintenance;
|
|
32
|
+
}
|
|
28
33
|
/**
|
|
29
34
|
* Initialize the client to create keys.
|
|
30
35
|
* @example
|
|
@@ -62,28 +67,48 @@ class Client extends events_1.EventEmitter {
|
|
|
62
67
|
const { data } = await this.rest.getClanWarLog(clanTag, options);
|
|
63
68
|
return data.items.map((entry) => new struct_1.ClanWarLog(this, entry));
|
|
64
69
|
}
|
|
65
|
-
/** Get info about currently running war (
|
|
70
|
+
/** Get info about currently running war (normal or friendly) in the clan. */
|
|
66
71
|
async getClanWar(clanTag, options) {
|
|
67
|
-
const { data, maxAge } = await this.rest.getCurrentWar(clanTag, options);
|
|
68
|
-
if (data.state === 'notInWar')
|
|
69
|
-
|
|
72
|
+
const { data, maxAge, path, status } = await this.rest.getCurrentWar(clanTag, options);
|
|
73
|
+
if (data.state === 'notInWar') {
|
|
74
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
|
|
75
|
+
}
|
|
70
76
|
return new struct_1.ClanWar(this, data, { clanTag, maxAge });
|
|
71
77
|
}
|
|
72
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Get info about currently running war in the clan.
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* await client.getCurrentWar('#8QU8J9LP');
|
|
83
|
+
* ```
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* await client.getCurrentWar({ clanTag: '#8QU8J9LP', round: 'PREVIOUS_ROUND' });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
73
89
|
async getCurrentWar(clanTag, options) {
|
|
74
90
|
const args = typeof clanTag === 'string' ? { clanTag } : { clanTag: clanTag.clanTag, round: clanTag.round };
|
|
75
91
|
try {
|
|
76
|
-
|
|
77
|
-
return data ?? (await this.getLeagueWar({ clanTag: args.clanTag, round: args.round }));
|
|
92
|
+
return await this.getClanWar(args.clanTag, options);
|
|
78
93
|
}
|
|
79
94
|
catch (e) {
|
|
80
|
-
if (e instanceof HTTPError_1.HTTPError && e.status
|
|
81
|
-
return this.getLeagueWar({ clanTag: args.clanTag, round: args.round });
|
|
95
|
+
if (e instanceof HTTPError_1.HTTPError && [200, 403].includes(e.status)) {
|
|
96
|
+
return this.getLeagueWar({ clanTag: args.clanTag, round: args.round }, options);
|
|
82
97
|
}
|
|
98
|
+
throw e;
|
|
83
99
|
}
|
|
84
|
-
return null;
|
|
85
100
|
}
|
|
86
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Get info about currently running CWL round.
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* await client.getLeagueWar('#8QU8J9LP');
|
|
106
|
+
* ```
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* await client.getLeagueWar({ clanTag: '#8QU8J9LP', round: 'PREVIOUS_ROUND' });
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
87
112
|
async getLeagueWar(clanTag, options) {
|
|
88
113
|
const args = typeof clanTag === 'string' ? { clanTag } : { clanTag: clanTag.clanTag, round: clanTag.round };
|
|
89
114
|
const state = (args.round && Constants_1.CWL_ROUNDS[args.round]) ?? 'inWar'; // eslint-disable-line
|
|
@@ -97,32 +122,30 @@ class Client extends events_1.EventEmitter {
|
|
|
97
122
|
.map((round) => round.warTags)
|
|
98
123
|
.flat()
|
|
99
124
|
.reverse();
|
|
100
|
-
const wars = await this.util.allSettled(warTags.map((warTag) => this.getClanWarLeagueRound({ warTag, clanTag: args.clanTag }, { ignoreRateLimit: true })));
|
|
125
|
+
const wars = await this.util.allSettled(warTags.map((warTag) => this.getClanWarLeagueRound({ warTag, clanTag: args.clanTag }, { ...options, ignoreRateLimit: true })));
|
|
101
126
|
if (args.round && args.round in Constants_1.CWL_ROUNDS) {
|
|
102
|
-
return wars.find((war) => war
|
|
127
|
+
return wars.find((war) => war.state === state) ?? null;
|
|
103
128
|
}
|
|
104
129
|
return wars.find((war) => war.state === state) ?? wars.at(0) ?? null;
|
|
105
130
|
}
|
|
106
131
|
async _getCurrentLeagueWars(clanTag, options) {
|
|
107
132
|
const data = await this.getClanWarLeagueGroup(clanTag, options);
|
|
108
133
|
// @ts-expect-error
|
|
109
|
-
return data._getCurrentWars(clanTag);
|
|
134
|
+
return data._getCurrentWars(clanTag, options);
|
|
110
135
|
}
|
|
111
136
|
async _getClanWars(clanTag, options) {
|
|
112
|
-
const date = new Date().
|
|
137
|
+
const date = new Date().getUTCDate();
|
|
138
|
+
if (!(date >= 1 && date <= 10)) {
|
|
139
|
+
return [await this.getClanWar(clanTag, options)];
|
|
140
|
+
}
|
|
113
141
|
try {
|
|
114
|
-
|
|
115
|
-
if (!(date >= 1 && date <= 10))
|
|
116
|
-
return data ? [data] : [];
|
|
117
|
-
return data ? [data] : await this._getCurrentLeagueWars(clanTag);
|
|
142
|
+
return this._getCurrentLeagueWars(clanTag, options);
|
|
118
143
|
}
|
|
119
144
|
catch (e) {
|
|
120
|
-
if (
|
|
121
|
-
return [];
|
|
122
|
-
if (e instanceof HTTPError_1.HTTPError && e.status === 403) {
|
|
123
|
-
return this._getCurrentLeagueWars(clanTag);
|
|
145
|
+
if (e instanceof HTTPError_1.HTTPError && [404].includes(e.status)) {
|
|
146
|
+
return [await this.getClanWar(clanTag, options)];
|
|
124
147
|
}
|
|
125
|
-
|
|
148
|
+
throw e;
|
|
126
149
|
}
|
|
127
150
|
}
|
|
128
151
|
/** Get information about clan war league. */
|
|
@@ -130,12 +153,13 @@ class Client extends events_1.EventEmitter {
|
|
|
130
153
|
const { data } = await this.rest.getClanWarLeagueGroup(clanTag, options);
|
|
131
154
|
return new struct_1.ClanWarLeagueGroup(this, data);
|
|
132
155
|
}
|
|
133
|
-
/** Get
|
|
156
|
+
/** Get info about a CWL round by WarTag. */
|
|
134
157
|
async getClanWarLeagueRound(warTag, options) {
|
|
135
158
|
const args = typeof warTag === 'string' ? { warTag } : { warTag: warTag.warTag, clanTag: warTag.clanTag };
|
|
136
|
-
const { data, maxAge } = await this.rest.getClanWarLeagueRound(args.warTag, options);
|
|
137
|
-
if (data.state === 'notInWar')
|
|
138
|
-
|
|
159
|
+
const { data, maxAge, status, path } = await this.rest.getClanWarLeagueRound(args.warTag, options);
|
|
160
|
+
if (data.state === 'notInWar') {
|
|
161
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
|
|
162
|
+
}
|
|
139
163
|
return new struct_1.ClanWar(this, data, { warTag: args.warTag, clanTag: args.clanTag, maxAge });
|
|
140
164
|
}
|
|
141
165
|
/** Get information about a player by tag. */
|
|
@@ -145,7 +169,7 @@ class Client extends events_1.EventEmitter {
|
|
|
145
169
|
}
|
|
146
170
|
/** Verify Player API token that can be found from the Game settings. */
|
|
147
171
|
async verifyPlayerToken(playerTag, token, options) {
|
|
148
|
-
const { data } = await this.rest.
|
|
172
|
+
const { data } = await this.rest.verifyPlayerToken(playerTag, token, options);
|
|
149
173
|
return data.status === 'ok';
|
|
150
174
|
}
|
|
151
175
|
/** Get list of Leagues. */
|
|
@@ -184,12 +208,12 @@ class Client extends events_1.EventEmitter {
|
|
|
184
208
|
const { data } = await this.rest.getPlayerRanks(locationId, options);
|
|
185
209
|
return data.items.map((entry) => new struct_1.RankedPlayer(this, entry));
|
|
186
210
|
}
|
|
187
|
-
/** Get clan versus rankings for a specific location */
|
|
211
|
+
/** Get clan versus rankings for a specific location. */
|
|
188
212
|
async getVersusClanRanks(locationId, options) {
|
|
189
213
|
const { data } = await this.rest.getVersusClanRanks(locationId, options);
|
|
190
214
|
return data.items.map((entry) => new struct_1.RankedClan(entry));
|
|
191
215
|
}
|
|
192
|
-
/** Get player versus rankings for a specific location */
|
|
216
|
+
/** Get player versus rankings for a specific location. */
|
|
193
217
|
async getVersusPlayerRanks(locationId, options) {
|
|
194
218
|
const { data } = await this.rest.getVersusPlayerRanks(locationId, options);
|
|
195
219
|
return data.items.map((entry) => new struct_1.RankedPlayer(this, entry));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Clan, ClanWar, Player } from '../struct';
|
|
2
2
|
import { Client } from './Client';
|
|
3
|
-
/** Represents Event Manager of the {@link Client}
|
|
3
|
+
/** Represents Event Manager of the {@link Client}. */
|
|
4
4
|
export declare class EventManager {
|
|
5
5
|
private readonly client;
|
|
6
6
|
private readonly _clanTags;
|
|
@@ -15,18 +15,18 @@ export declare class EventManager {
|
|
|
15
15
|
constructor(client: Client);
|
|
16
16
|
/** Initialize the Event Manager to start pulling. */
|
|
17
17
|
init(): Promise<string[]>;
|
|
18
|
-
/** Add
|
|
19
|
-
addClans(
|
|
20
|
-
/** Delete
|
|
21
|
-
deleteClans(
|
|
22
|
-
/** Add
|
|
23
|
-
addPlayers(
|
|
24
|
-
/** Delete
|
|
25
|
-
deletePlayers(
|
|
26
|
-
/** Add
|
|
27
|
-
addWars(
|
|
28
|
-
/** Delete
|
|
29
|
-
deleteWars(
|
|
18
|
+
/** Add clan tags to clan events. */
|
|
19
|
+
addClans(tags: string[] | string): this;
|
|
20
|
+
/** Delete clan tags from clan events. */
|
|
21
|
+
deleteClans(tags: string[] | string): this;
|
|
22
|
+
/** Add player tags for player events. */
|
|
23
|
+
addPlayers(tags: string[] | string): this;
|
|
24
|
+
/** Delete player tags from player events. */
|
|
25
|
+
deletePlayers(tags: string[] | string): this;
|
|
26
|
+
/** Add clan tags for war events. */
|
|
27
|
+
addWars(tags: string[] | string): this;
|
|
28
|
+
/** Delete clan tags from war events. */
|
|
29
|
+
deleteWars(tags: string[] | string): this;
|
|
30
30
|
/**
|
|
31
31
|
* Set your own custom clan event.
|
|
32
32
|
*
|
|
@@ -4,7 +4,7 @@ exports.EventManager = void 0;
|
|
|
4
4
|
const HTTPError_1 = require("../rest/HTTPError");
|
|
5
5
|
const Constants_1 = require("../util/Constants");
|
|
6
6
|
const Util_1 = require("../util/Util");
|
|
7
|
-
/** Represents Event Manager of the {@link Client}
|
|
7
|
+
/** Represents Event Manager of the {@link Client}. */
|
|
8
8
|
class EventManager {
|
|
9
9
|
constructor(client) {
|
|
10
10
|
this.client = client;
|
|
@@ -31,45 +31,52 @@ class EventManager {
|
|
|
31
31
|
this.warUpdateHandler();
|
|
32
32
|
return Promise.resolve(this.client.eventNames());
|
|
33
33
|
}
|
|
34
|
-
/** Add
|
|
35
|
-
addClans(
|
|
36
|
-
for (const tag of tags) {
|
|
34
|
+
/** Add clan tags to clan events. */
|
|
35
|
+
addClans(tags) {
|
|
36
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
37
37
|
this._clanTags.add(this.client.util.parseTag(tag));
|
|
38
38
|
}
|
|
39
39
|
return this;
|
|
40
40
|
}
|
|
41
|
-
/** Delete
|
|
42
|
-
deleteClans(
|
|
43
|
-
for (const tag of tags) {
|
|
44
|
-
this.
|
|
41
|
+
/** Delete clan tags from clan events. */
|
|
42
|
+
deleteClans(tags) {
|
|
43
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
44
|
+
const key = this.client.util.parseTag(tag);
|
|
45
|
+
this._clans.delete(key);
|
|
46
|
+
this._clanTags.delete(key);
|
|
45
47
|
}
|
|
46
48
|
return this;
|
|
47
49
|
}
|
|
48
|
-
/** Add
|
|
49
|
-
addPlayers(
|
|
50
|
-
for (const tag of tags) {
|
|
50
|
+
/** Add player tags for player events. */
|
|
51
|
+
addPlayers(tags) {
|
|
52
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
51
53
|
this._playerTags.add(this.client.util.parseTag(tag));
|
|
52
54
|
}
|
|
53
55
|
return this;
|
|
54
56
|
}
|
|
55
|
-
/** Delete
|
|
56
|
-
deletePlayers(
|
|
57
|
-
for (const tag of tags) {
|
|
58
|
-
this.
|
|
57
|
+
/** Delete player tags from player events. */
|
|
58
|
+
deletePlayers(tags) {
|
|
59
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
60
|
+
const key = this.client.util.parseTag(tag);
|
|
61
|
+
this._players.delete(key);
|
|
62
|
+
this._playerTags.delete(key);
|
|
59
63
|
}
|
|
60
64
|
return this;
|
|
61
65
|
}
|
|
62
|
-
/** Add
|
|
63
|
-
addWars(
|
|
64
|
-
for (const tag of tags) {
|
|
66
|
+
/** Add clan tags for war events. */
|
|
67
|
+
addWars(tags) {
|
|
68
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
65
69
|
this._warTags.add(this.client.util.parseTag(tag));
|
|
66
70
|
}
|
|
67
71
|
return this;
|
|
68
72
|
}
|
|
69
|
-
/** Delete
|
|
70
|
-
deleteWars(
|
|
71
|
-
for (const tag of tags) {
|
|
72
|
-
this.
|
|
73
|
+
/** Delete clan tags from war events. */
|
|
74
|
+
deleteWars(tags) {
|
|
75
|
+
for (const tag of Array.isArray(tags) ? tags : [tags]) {
|
|
76
|
+
const key = this.client.util.parseTag(tag);
|
|
77
|
+
this._wars.delete(`${key}:${1}`);
|
|
78
|
+
this._wars.delete(`${key}:${2}`);
|
|
79
|
+
this._warTags.delete(key);
|
|
73
80
|
}
|
|
74
81
|
return this;
|
|
75
82
|
}
|
|
@@ -100,7 +107,11 @@ class EventManager {
|
|
|
100
107
|
* @returns
|
|
101
108
|
*/
|
|
102
109
|
setClanEvent(event) {
|
|
103
|
-
|
|
110
|
+
if (!event.name)
|
|
111
|
+
throw new Error('Event name is required.');
|
|
112
|
+
if (typeof event.filter !== 'function')
|
|
113
|
+
throw new Error('Filter function is required.');
|
|
114
|
+
this._events.clans.push(event);
|
|
104
115
|
return this;
|
|
105
116
|
}
|
|
106
117
|
/**
|
|
@@ -109,7 +120,11 @@ class EventManager {
|
|
|
109
120
|
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
110
121
|
*/
|
|
111
122
|
setWarEvent(event) {
|
|
112
|
-
|
|
123
|
+
if (!event.name)
|
|
124
|
+
throw new Error('Event name is required.');
|
|
125
|
+
if (typeof event.filter !== 'function')
|
|
126
|
+
throw new Error('Filter function is required.');
|
|
127
|
+
this._events.wars.push(event);
|
|
113
128
|
return this;
|
|
114
129
|
}
|
|
115
130
|
/**
|
|
@@ -118,7 +133,11 @@ class EventManager {
|
|
|
118
133
|
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
119
134
|
*/
|
|
120
135
|
setPlayerEvent(event) {
|
|
121
|
-
|
|
136
|
+
if (!event.name)
|
|
137
|
+
throw new Error('Event name is required.');
|
|
138
|
+
if (typeof event.filter !== 'function')
|
|
139
|
+
throw new Error('Filter function is required.');
|
|
140
|
+
this._events.players.push(event);
|
|
122
141
|
return this;
|
|
123
142
|
}
|
|
124
143
|
async maintenanceHandler() {
|
|
@@ -127,7 +146,7 @@ class EventManager {
|
|
|
127
146
|
const res = await this.client.rest.getClans({ maxMembers: Math.floor(Math.random() * 40) + 10, limit: 1 });
|
|
128
147
|
if (res.status === 200 && this._inMaintenance) {
|
|
129
148
|
this._inMaintenance = Boolean(false);
|
|
130
|
-
const duration =
|
|
149
|
+
const duration = Date.now() - this._maintenanceStartTime.getTime();
|
|
131
150
|
this._maintenanceStartTime = null;
|
|
132
151
|
this.client.emit(Constants_1.EVENTS.MAINTENANCE_END, duration);
|
|
133
152
|
}
|
|
@@ -157,21 +176,21 @@ class EventManager {
|
|
|
157
176
|
for (const tag of this._clanTags)
|
|
158
177
|
await this.runClanUpdate(tag);
|
|
159
178
|
this.client.emit(Constants_1.EVENTS.CLAN_LOOP_END);
|
|
160
|
-
setTimeout(this.clanUpdateHandler.bind(this), 10000);
|
|
179
|
+
setTimeout(this.clanUpdateHandler.bind(this), 10000).unref();
|
|
161
180
|
}
|
|
162
181
|
async playerUpdateHandler() {
|
|
163
182
|
this.client.emit(Constants_1.EVENTS.PLAYER_LOOP_START);
|
|
164
183
|
for (const tag of this._playerTags)
|
|
165
184
|
await this.runPlayerUpdate(tag);
|
|
166
185
|
this.client.emit(Constants_1.EVENTS.PLAYER_LOOP_END);
|
|
167
|
-
setTimeout(this.playerUpdateHandler.bind(this),
|
|
186
|
+
setTimeout(this.playerUpdateHandler.bind(this), 10000).unref();
|
|
168
187
|
}
|
|
169
188
|
async warUpdateHandler() {
|
|
170
189
|
this.client.emit(Constants_1.EVENTS.WAR_LOOP_START);
|
|
171
190
|
for (const tag of this._warTags)
|
|
172
191
|
await this.runWarUpdate(tag);
|
|
173
192
|
this.client.emit(Constants_1.EVENTS.WAR_LOOP_END);
|
|
174
|
-
setTimeout(this.warUpdateHandler.bind(this), 10000);
|
|
193
|
+
setTimeout(this.warUpdateHandler.bind(this), 10000).unref();
|
|
175
194
|
}
|
|
176
195
|
async runClanUpdate(tag) {
|
|
177
196
|
if (this._inMaintenance)
|
|
@@ -182,9 +201,9 @@ class EventManager {
|
|
|
182
201
|
const cached = this._clans.get(clan.tag);
|
|
183
202
|
if (!cached)
|
|
184
203
|
return this._clans.set(clan.tag, clan);
|
|
185
|
-
for (const { name,
|
|
204
|
+
for (const { name, filter } of this._events.clans) {
|
|
186
205
|
try {
|
|
187
|
-
if (!
|
|
206
|
+
if (!filter(cached, clan))
|
|
188
207
|
continue;
|
|
189
208
|
this.client.emit(name, cached, clan);
|
|
190
209
|
}
|
|
@@ -203,9 +222,9 @@ class EventManager {
|
|
|
203
222
|
const cached = this._players.get(player.tag);
|
|
204
223
|
if (!cached)
|
|
205
224
|
return this._players.set(player.tag, player);
|
|
206
|
-
for (const { name,
|
|
225
|
+
for (const { name, filter } of this._events.players) {
|
|
207
226
|
try {
|
|
208
|
-
if (!
|
|
227
|
+
if (!filter(cached, player))
|
|
209
228
|
continue;
|
|
210
229
|
this.client.emit(name, cached, player);
|
|
211
230
|
}
|
|
@@ -222,14 +241,14 @@ class EventManager {
|
|
|
222
241
|
const clanWars = await this.client._getClanWars(tag).catch(() => null);
|
|
223
242
|
if (!clanWars?.length)
|
|
224
243
|
return null;
|
|
225
|
-
clanWars.forEach((war,
|
|
226
|
-
const key =
|
|
244
|
+
clanWars.forEach(async (war, index) => {
|
|
245
|
+
const key = `${tag}:${index}`;
|
|
227
246
|
const cached = this._wars.get(key);
|
|
228
247
|
if (!cached)
|
|
229
248
|
return this._wars.set(key, war);
|
|
230
|
-
for (const { name,
|
|
249
|
+
for (const { name, filter } of this._events.wars) {
|
|
231
250
|
try {
|
|
232
|
-
if (!
|
|
251
|
+
if (!filter(cached, war))
|
|
233
252
|
continue;
|
|
234
253
|
this.client.emit(name, cached, war);
|
|
235
254
|
}
|
|
@@ -237,6 +256,22 @@ class EventManager {
|
|
|
237
256
|
this.client.emit(Constants_1.EVENTS.ERROR, error);
|
|
238
257
|
}
|
|
239
258
|
}
|
|
259
|
+
// check for war end
|
|
260
|
+
if (index === 1 && cached.warTag !== war.warTag) {
|
|
261
|
+
const data = await this.client.getLeagueWar({ clanTag: tag, round: 'PREVIOUS_ROUND' }).catch(() => null);
|
|
262
|
+
if (data && data.warTag === cached.warTag) {
|
|
263
|
+
for (const { name, filter } of this._events.wars) {
|
|
264
|
+
try {
|
|
265
|
+
if (!filter(cached, data))
|
|
266
|
+
continue;
|
|
267
|
+
this.client.emit(name, cached, data);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
this.client.emit(Constants_1.EVENTS.ERROR, error);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
240
275
|
return this._wars.set(key, war);
|
|
241
276
|
});
|
|
242
277
|
}
|
package/dist/rest/HTTPError.d.ts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
/** Represents an HTTP Error. */
|
|
2
2
|
export declare class HTTPError extends Error {
|
|
3
|
+
/** The message of this error. */
|
|
4
|
+
message: string;
|
|
5
|
+
/** The HTTP method of this request. */
|
|
3
6
|
method: string;
|
|
7
|
+
/** The reason of this error. */
|
|
4
8
|
reason: string;
|
|
9
|
+
/** The HTTP status code of this request. */
|
|
5
10
|
status: number;
|
|
11
|
+
/** The path of this request. */
|
|
6
12
|
path: string;
|
|
7
|
-
|
|
13
|
+
/** Maximum number of milliseconds the results can be cached. */
|
|
14
|
+
maxAge: number;
|
|
15
|
+
constructor(error: any, status: number, path: string, maxAge: number, method?: string);
|
|
8
16
|
}
|
|
17
|
+
export declare const NotInWarError: {
|
|
18
|
+
message: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const PrivateWarLogError: {
|
|
22
|
+
message: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
package/dist/rest/HTTPError.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HTTPError = void 0;
|
|
3
|
+
exports.PrivateWarLogError = exports.NotInWarError = exports.HTTPError = void 0;
|
|
4
4
|
const messages = {
|
|
5
5
|
500: 'Unknown error happened when handling the request.',
|
|
6
|
-
504: 'The user aborted
|
|
7
|
-
404: '
|
|
6
|
+
504: 'The user aborted this request.',
|
|
7
|
+
404: 'Requested resource was not found.',
|
|
8
8
|
400: 'Client provided incorrect parameters for the request.',
|
|
9
9
|
503: 'Service is temporarily unavailable because of maintenance.',
|
|
10
10
|
429: 'Request was throttled, because amount of requests was above the threshold defined for the used API token.',
|
|
@@ -21,13 +21,22 @@ const reasons = {
|
|
|
21
21
|
};
|
|
22
22
|
/** Represents an HTTP Error. */
|
|
23
23
|
class HTTPError extends Error {
|
|
24
|
-
constructor(error, status, path, method
|
|
24
|
+
constructor(error, status, path, maxAge, method) {
|
|
25
25
|
super();
|
|
26
26
|
this.message = error?.message ?? messages[status];
|
|
27
27
|
this.reason = error?.reason ?? reasons[status];
|
|
28
28
|
this.path = path;
|
|
29
|
-
this.method = method;
|
|
29
|
+
this.method = method ?? 'GET';
|
|
30
30
|
this.status = status;
|
|
31
|
+
this.maxAge = maxAge;
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
exports.HTTPError = HTTPError;
|
|
35
|
+
exports.NotInWarError = {
|
|
36
|
+
message: 'Clan is not in war at this moment.',
|
|
37
|
+
reason: 'notInWar'
|
|
38
|
+
};
|
|
39
|
+
exports.PrivateWarLogError = {
|
|
40
|
+
message: 'Access denied, clan war log is private.',
|
|
41
|
+
reason: 'privateWarLog'
|
|
42
|
+
};
|