clashofclans.js 2.0.0-dev.86dfaef → 2.0.0-dev.dedb83d
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/dist/client/Client.d.ts +13 -1
- package/dist/client/Client.js +12 -11
- package/dist/client/EventManager.d.ts +1 -1
- package/dist/client/EventManager.js +29 -13
- package/dist/rest/HTTPError.d.ts +2 -2
- package/dist/rest/HTTPError.js +3 -3
- package/dist/rest/RequestHandler.js +1 -1
- package/dist/struct/ClanWarLeagueGroup.js +2 -1
- package/dist/util/Util.js +3 -1
- package/package.json +5 -5
package/dist/client/Client.d.ts
CHANGED
|
@@ -141,15 +141,21 @@ export declare class Client extends EventEmitter {
|
|
|
141
141
|
private static maintenanceEnd;
|
|
142
142
|
/** @internal */
|
|
143
143
|
on<K extends keyof ClientEvents>(event: K, listeners: (...args: ClientEvents[K]) => void): this;
|
|
144
|
+
/** @internal */
|
|
145
|
+
on<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: CustomEvents[S]) => void): this;
|
|
144
146
|
/** @internal */ on<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: any[]) => void): this;
|
|
145
147
|
/** @internal */
|
|
146
148
|
once<K extends keyof ClientEvents>(event: K, listeners: (...args: ClientEvents[K]) => void): this;
|
|
149
|
+
/** @internal */
|
|
150
|
+
once<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: CustomEvents[S]) => void): this;
|
|
147
151
|
/** @internal */ once<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, listeners: (...args: any[]) => void): this;
|
|
148
152
|
/** @internal */
|
|
149
153
|
emit<K extends keyof ClientEvents>(event: K, ...args: ClientEvents[K]): boolean;
|
|
154
|
+
/** @internal */
|
|
155
|
+
emit<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, ...args: CustomEvents[S]): this;
|
|
150
156
|
/** @internal */ emit<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, ...args: any[]): boolean;
|
|
151
157
|
}
|
|
152
|
-
|
|
158
|
+
interface ClientEvents {
|
|
153
159
|
[EVENTS.NEW_SEASON_START]: [id: string];
|
|
154
160
|
[EVENTS.MAINTENANCE_START]: [];
|
|
155
161
|
[EVENTS.MAINTENANCE_END]: [duration: number];
|
|
@@ -161,3 +167,9 @@ export interface ClientEvents {
|
|
|
161
167
|
[EVENTS.WAR_LOOP_END]: [];
|
|
162
168
|
[EVENTS.ERROR]: [error: unknown];
|
|
163
169
|
}
|
|
170
|
+
interface CustomEvents {
|
|
171
|
+
[key: `clan${string}`]: [oldClan: Clan, newClan: Clan];
|
|
172
|
+
[key: `war${string}`]: [oldWar: ClanWar, newWar: ClanWar];
|
|
173
|
+
[key: `player${string}`]: [oldPlayer: Player, newPlayer: Player];
|
|
174
|
+
}
|
|
175
|
+
export {};
|
package/dist/client/Client.js
CHANGED
|
@@ -66,7 +66,7 @@ class Client extends events_1.EventEmitter {
|
|
|
66
66
|
async getClanWar(clanTag, options) {
|
|
67
67
|
const { data, maxAge, path, status } = await this.rest.getCurrentWar(clanTag, options);
|
|
68
68
|
if (data.state === 'notInWar') {
|
|
69
|
-
throw new HTTPError_1.HTTPError(HTTPError_1.
|
|
69
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
|
|
70
70
|
}
|
|
71
71
|
return new struct_1.ClanWar(this, data, { clanTag, maxAge });
|
|
72
72
|
}
|
|
@@ -87,11 +87,11 @@ class Client extends events_1.EventEmitter {
|
|
|
87
87
|
return await this.getClanWar(args.clanTag, options);
|
|
88
88
|
}
|
|
89
89
|
catch (e) {
|
|
90
|
-
if (e instanceof HTTPError_1.HTTPError && e.status
|
|
90
|
+
if (e instanceof HTTPError_1.HTTPError && [200, 403].includes(e.status)) {
|
|
91
91
|
return this.getLeagueWar({ clanTag: args.clanTag, round: args.round });
|
|
92
92
|
}
|
|
93
|
+
throw e;
|
|
93
94
|
}
|
|
94
|
-
return null;
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* Get info about currently running CWL round.
|
|
@@ -129,17 +129,18 @@ class Client extends events_1.EventEmitter {
|
|
|
129
129
|
return data._getCurrentWars(clanTag);
|
|
130
130
|
}
|
|
131
131
|
async _getClanWars(clanTag, options) {
|
|
132
|
-
const date = new Date().
|
|
133
|
-
|
|
132
|
+
const date = new Date().getUTCDate();
|
|
133
|
+
if (!(date >= 1 && date <= 10)) {
|
|
134
134
|
return [await this.getClanWar(clanTag, options)];
|
|
135
135
|
}
|
|
136
|
+
try {
|
|
137
|
+
return this._getCurrentLeagueWars(clanTag);
|
|
138
|
+
}
|
|
136
139
|
catch (e) {
|
|
137
|
-
if (
|
|
138
|
-
return [];
|
|
139
|
-
if (e instanceof HTTPError_1.HTTPError && [200, 403].includes(e.status)) {
|
|
140
|
-
return this._getCurrentLeagueWars(clanTag);
|
|
140
|
+
if (e instanceof HTTPError_1.HTTPError && [404].includes(e.status)) {
|
|
141
|
+
return [await this.getClanWar(clanTag)];
|
|
141
142
|
}
|
|
142
|
-
|
|
143
|
+
throw e;
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
/** Get information about clan war league. */
|
|
@@ -152,7 +153,7 @@ class Client extends events_1.EventEmitter {
|
|
|
152
153
|
const args = typeof warTag === 'string' ? { warTag } : { warTag: warTag.warTag, clanTag: warTag.clanTag };
|
|
153
154
|
const { data, maxAge, status, path } = await this.rest.getClanWarLeagueRound(args.warTag, options);
|
|
154
155
|
if (data.state === 'notInWar') {
|
|
155
|
-
throw new HTTPError_1.HTTPError(HTTPError_1.
|
|
156
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
|
|
156
157
|
}
|
|
157
158
|
return new struct_1.ClanWar(this, data, { warTag: args.warTag, clanTag: args.clanTag, maxAge });
|
|
158
159
|
}
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -100,7 +100,7 @@ class EventManager {
|
|
|
100
100
|
* @returns
|
|
101
101
|
*/
|
|
102
102
|
setClanEvent(event) {
|
|
103
|
-
this._events.clans.push(
|
|
103
|
+
this._events.clans.push(event);
|
|
104
104
|
return this;
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
@@ -109,7 +109,7 @@ class EventManager {
|
|
|
109
109
|
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
110
110
|
*/
|
|
111
111
|
setWarEvent(event) {
|
|
112
|
-
this._events.wars.push(
|
|
112
|
+
this._events.wars.push(event);
|
|
113
113
|
return this;
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
@@ -118,7 +118,7 @@ class EventManager {
|
|
|
118
118
|
* In order to emit the custom event, you must have this filter function that returns a boolean.
|
|
119
119
|
*/
|
|
120
120
|
setPlayerEvent(event) {
|
|
121
|
-
this._events.players.push(
|
|
121
|
+
this._events.players.push(event);
|
|
122
122
|
return this;
|
|
123
123
|
}
|
|
124
124
|
async maintenanceHandler() {
|
|
@@ -164,7 +164,7 @@ class EventManager {
|
|
|
164
164
|
for (const tag of this._playerTags)
|
|
165
165
|
await this.runPlayerUpdate(tag);
|
|
166
166
|
this.client.emit(Constants_1.EVENTS.PLAYER_LOOP_END);
|
|
167
|
-
setTimeout(this.playerUpdateHandler.bind(this),
|
|
167
|
+
setTimeout(this.playerUpdateHandler.bind(this), 10000);
|
|
168
168
|
}
|
|
169
169
|
async warUpdateHandler() {
|
|
170
170
|
this.client.emit(Constants_1.EVENTS.WAR_LOOP_START);
|
|
@@ -182,9 +182,9 @@ class EventManager {
|
|
|
182
182
|
const cached = this._clans.get(clan.tag);
|
|
183
183
|
if (!cached)
|
|
184
184
|
return this._clans.set(clan.tag, clan);
|
|
185
|
-
for (const { name,
|
|
185
|
+
for (const { name, filter } of this._events.clans) {
|
|
186
186
|
try {
|
|
187
|
-
if (!
|
|
187
|
+
if (!filter(cached, clan))
|
|
188
188
|
continue;
|
|
189
189
|
this.client.emit(name, cached, clan);
|
|
190
190
|
}
|
|
@@ -203,9 +203,9 @@ class EventManager {
|
|
|
203
203
|
const cached = this._players.get(player.tag);
|
|
204
204
|
if (!cached)
|
|
205
205
|
return this._players.set(player.tag, player);
|
|
206
|
-
for (const { name,
|
|
206
|
+
for (const { name, filter } of this._events.players) {
|
|
207
207
|
try {
|
|
208
|
-
if (!
|
|
208
|
+
if (!filter(cached, player))
|
|
209
209
|
continue;
|
|
210
210
|
this.client.emit(name, cached, player);
|
|
211
211
|
}
|
|
@@ -222,14 +222,14 @@ class EventManager {
|
|
|
222
222
|
const clanWars = await this.client._getClanWars(tag).catch(() => null);
|
|
223
223
|
if (!clanWars?.length)
|
|
224
224
|
return null;
|
|
225
|
-
clanWars.forEach((war,
|
|
226
|
-
const key =
|
|
225
|
+
clanWars.forEach(async (war, state) => {
|
|
226
|
+
const key = `${tag}:${state}`;
|
|
227
227
|
const cached = this._wars.get(key);
|
|
228
228
|
if (!cached)
|
|
229
229
|
return this._wars.set(key, war);
|
|
230
|
-
for (const { name,
|
|
230
|
+
for (const { name, filter } of this._events.wars) {
|
|
231
231
|
try {
|
|
232
|
-
if (!
|
|
232
|
+
if (!filter(cached, war))
|
|
233
233
|
continue;
|
|
234
234
|
this.client.emit(name, cached, war);
|
|
235
235
|
}
|
|
@@ -237,6 +237,22 @@ class EventManager {
|
|
|
237
237
|
this.client.emit(Constants_1.EVENTS.ERROR, error);
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
|
+
// check for war end
|
|
241
|
+
if (state === 1 && cached.warTag !== war.warTag) {
|
|
242
|
+
const data = await this.client.getLeagueWar({ clanTag: tag, round: 'PREVIOUS_ROUND' }).catch(() => null);
|
|
243
|
+
if (data && data.warTag === cached.warTag) {
|
|
244
|
+
for (const { name, filter } of this._events.wars) {
|
|
245
|
+
try {
|
|
246
|
+
if (!filter(cached, data))
|
|
247
|
+
continue;
|
|
248
|
+
this.client.emit(name, cached, data);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
this.client.emit(Constants_1.EVENTS.ERROR, error);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
240
256
|
return this._wars.set(key, war);
|
|
241
257
|
});
|
|
242
258
|
}
|
package/dist/rest/HTTPError.d.ts
CHANGED
|
@@ -16,11 +16,11 @@ export declare class HTTPError extends Error {
|
|
|
16
16
|
maxAge: number;
|
|
17
17
|
constructor(error: any, status: number, path: string, maxAge: number, method?: string);
|
|
18
18
|
}
|
|
19
|
-
export declare const
|
|
19
|
+
export declare const NotInWarError: {
|
|
20
20
|
message: string;
|
|
21
21
|
reason: string;
|
|
22
22
|
};
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const PrivateWarLogError: {
|
|
24
24
|
message: string;
|
|
25
25
|
reason: string;
|
|
26
26
|
};
|
package/dist/rest/HTTPError.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PrivateWarLogError = exports.NotInWarError = exports.HTTPError = void 0;
|
|
4
4
|
const messages = {
|
|
5
5
|
500: 'Unknown error happened when handling the request.',
|
|
6
6
|
504: 'The user aborted this request.',
|
|
@@ -34,11 +34,11 @@ class HTTPError extends Error {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
exports.HTTPError = HTTPError;
|
|
37
|
-
exports.
|
|
37
|
+
exports.NotInWarError = {
|
|
38
38
|
message: 'Clan is not in war at this moment.',
|
|
39
39
|
reason: 'notInWar'
|
|
40
40
|
};
|
|
41
|
-
exports.
|
|
41
|
+
exports.PrivateWarLogError = {
|
|
42
42
|
message: 'Access denied, clan war log is private.',
|
|
43
43
|
reason: 'privateWarLog'
|
|
44
44
|
};
|
|
@@ -79,7 +79,7 @@ class RequestHandler {
|
|
|
79
79
|
}
|
|
80
80
|
const maxAge = Number(res?.headers.get('cache-control')?.split('=')?.[1] ?? 0) * 1000;
|
|
81
81
|
if (res?.status === 403 && !data?.message)
|
|
82
|
-
throw new HTTPError_1.HTTPError(HTTPError_1.
|
|
82
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.PrivateWarLogError, res.status, path, maxAge);
|
|
83
83
|
if (!res?.ok)
|
|
84
84
|
throw new HTTPError_1.HTTPError(data, res?.status ?? 504, path, maxAge, options.method);
|
|
85
85
|
if (this.cached && maxAge > 0 && options.cache !== false)
|
|
@@ -68,7 +68,8 @@ class ClanWarLeagueGroup {
|
|
|
68
68
|
const warTags = rounds
|
|
69
69
|
.slice(-2)
|
|
70
70
|
.map((round) => round.warTags)
|
|
71
|
-
.flat()
|
|
71
|
+
.flat()
|
|
72
|
+
.reverse();
|
|
72
73
|
const wars = await Promise.allSettled(warTags.map((warTag) => this.client.getClanWarLeagueRound({ warTag, clanTag }, { ignoreRateLimit: true })));
|
|
73
74
|
return wars
|
|
74
75
|
.filter((res) => res.status === 'fulfilled')
|
package/dist/util/Util.js
CHANGED
|
@@ -18,6 +18,8 @@ class Util extends null {
|
|
|
18
18
|
/** Get URL search params. */
|
|
19
19
|
static queryString(options = {}) {
|
|
20
20
|
const query = new URLSearchParams(options);
|
|
21
|
+
for (const key of ['cache', 'force', 'retryLimit', 'ignoreRateLimit', 'restRequestTimeout'])
|
|
22
|
+
query.delete(key);
|
|
21
23
|
return query.toString();
|
|
22
24
|
}
|
|
23
25
|
static getSeasonEnd(month, autoFix = true) {
|
|
@@ -41,7 +43,7 @@ class Util extends null {
|
|
|
41
43
|
}
|
|
42
44
|
static async allSettled(values) {
|
|
43
45
|
return (await Promise.allSettled(values))
|
|
44
|
-
.filter((res) => res.status === 'fulfilled'
|
|
46
|
+
.filter((res) => res.status === 'fulfilled')
|
|
45
47
|
.map((res) => res.value);
|
|
46
48
|
}
|
|
47
49
|
static async delay(ms) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clashofclans.js",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.dedb83d",
|
|
4
4
|
"description": "JavaScript library for interacting with the Clash of Clans API",
|
|
5
5
|
"author": "SUVAJIT <suvajit.me@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -95,15 +95,15 @@
|
|
|
95
95
|
"@types/keyv": "^3.1.3",
|
|
96
96
|
"@types/node": "^16.10.3",
|
|
97
97
|
"@types/node-fetch": "^2.5.12",
|
|
98
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
99
|
-
"@typescript-eslint/parser": "^5.
|
|
100
|
-
"eslint": "^
|
|
98
|
+
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
|
99
|
+
"@typescript-eslint/parser": "^5.4.0",
|
|
100
|
+
"eslint": "^8.3.0",
|
|
101
101
|
"eslint-config-marine": "^9.0.6",
|
|
102
102
|
"eslint-config-prettier": "^8.3.0",
|
|
103
103
|
"eslint-plugin-prettier": "^4.0.0",
|
|
104
104
|
"prettier": "^2.4.1",
|
|
105
105
|
"rimraf": "^3.0.2",
|
|
106
|
-
"typescript": "^4.
|
|
106
|
+
"typescript": "^4.5.2"
|
|
107
107
|
},
|
|
108
108
|
"engines": {
|
|
109
109
|
"node": ">=14.x"
|