clashofclans.js 2.0.0-dev.4c7acc8 → 2.0.0-dev.75d755c
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/README.md +1 -1
- package/dist/client/Client.d.ts +3 -8
- package/dist/client/Client.js +2 -2
- package/dist/client/EventManager.d.ts +12 -12
- package/dist/client/EventManager.js +39 -30
- package/dist/rest/HTTPError.d.ts +2 -2
- package/dist/rest/HTTPError.js +3 -3
- package/dist/rest/RequestHandler.d.ts +1 -1
- package/dist/rest/RequestHandler.js +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ const client = new Client({
|
|
|
44
44
|
throttler: new BatchThrottler(30)
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
client.events.addClans(['#8P2QG08P']);
|
|
47
|
+
client.events.addClans(['#8QU8J9LP', '#8P2QG08P']);
|
|
48
48
|
client.events.setClanEvent({
|
|
49
49
|
name: 'clanDescriptionChange',
|
|
50
50
|
filter: (oldClan, newClan) => {
|
package/dist/client/Client.d.ts
CHANGED
|
@@ -155,8 +155,7 @@ export declare class Client extends EventEmitter {
|
|
|
155
155
|
emit<S extends keyof CustomEvents>(event: Exclude<S, keyof ClientEvents>, ...args: CustomEvents[S]): this;
|
|
156
156
|
/** @internal */ emit<S extends string | symbol>(event: Exclude<S, keyof ClientEvents>, ...args: any[]): boolean;
|
|
157
157
|
}
|
|
158
|
-
|
|
159
|
-
export interface ClientEvents {
|
|
158
|
+
interface ClientEvents {
|
|
160
159
|
[EVENTS.NEW_SEASON_START]: [id: string];
|
|
161
160
|
[EVENTS.MAINTENANCE_START]: [];
|
|
162
161
|
[EVENTS.MAINTENANCE_END]: [duration: number];
|
|
@@ -168,13 +167,9 @@ export interface ClientEvents {
|
|
|
168
167
|
[EVENTS.WAR_LOOP_END]: [];
|
|
169
168
|
[EVENTS.ERROR]: [error: unknown];
|
|
170
169
|
}
|
|
171
|
-
|
|
172
|
-
* Custom events that can be emitted by the client.
|
|
173
|
-
*
|
|
174
|
-
* TypeScript 4.5 now can narrow values that have template string types, and also recognizes template string types as discriminants.
|
|
175
|
-
*/
|
|
176
|
-
export interface CustomEvents {
|
|
170
|
+
interface CustomEvents {
|
|
177
171
|
[key: `clan${string}`]: [oldClan: Clan, newClan: Clan];
|
|
178
172
|
[key: `war${string}`]: [oldWar: ClanWar, newWar: ClanWar];
|
|
179
173
|
[key: `player${string}`]: [oldPlayer: Player, newPlayer: Player];
|
|
180
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
|
}
|
|
@@ -153,7 +153,7 @@ class Client extends events_1.EventEmitter {
|
|
|
153
153
|
const args = typeof warTag === 'string' ? { warTag } : { warTag: warTag.warTag, clanTag: warTag.clanTag };
|
|
154
154
|
const { data, maxAge, status, path } = await this.rest.getClanWarLeagueRound(args.warTag, options);
|
|
155
155
|
if (data.state === 'notInWar') {
|
|
156
|
-
throw new HTTPError_1.HTTPError(HTTPError_1.
|
|
156
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
|
|
157
157
|
}
|
|
158
158
|
return new struct_1.ClanWar(this, data, { warTag: args.warTag, clanTag: args.clanTag, maxAge });
|
|
159
159
|
}
|
|
@@ -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
|
*
|
|
@@ -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
|
}
|
|
@@ -164,7 +171,7 @@ class EventManager {
|
|
|
164
171
|
for (const tag of this._playerTags)
|
|
165
172
|
await this.runPlayerUpdate(tag);
|
|
166
173
|
this.client.emit(Constants_1.EVENTS.PLAYER_LOOP_END);
|
|
167
|
-
setTimeout(this.playerUpdateHandler.bind(this),
|
|
174
|
+
setTimeout(this.playerUpdateHandler.bind(this), 10000);
|
|
168
175
|
}
|
|
169
176
|
async warUpdateHandler() {
|
|
170
177
|
this.client.emit(Constants_1.EVENTS.WAR_LOOP_START);
|
|
@@ -240,14 +247,16 @@ class EventManager {
|
|
|
240
247
|
// check for war end
|
|
241
248
|
if (state === 1 && cached.warTag !== war.warTag) {
|
|
242
249
|
const data = await this.client.getLeagueWar({ clanTag: tag, round: 'PREVIOUS_ROUND' }).catch(() => null);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
if (data && data.warTag === cached.warTag) {
|
|
251
|
+
for (const { name, filter } of this._events.wars) {
|
|
252
|
+
try {
|
|
253
|
+
if (!filter(cached, data))
|
|
254
|
+
continue;
|
|
255
|
+
this.client.emit(name, cached, data);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
this.client.emit(Constants_1.EVENTS.ERROR, error);
|
|
259
|
+
}
|
|
251
260
|
}
|
|
252
261
|
}
|
|
253
262
|
}
|
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
|
};
|
|
@@ -11,9 +11,9 @@ export declare class RequestHandler {
|
|
|
11
11
|
private keys;
|
|
12
12
|
private readonly baseURL;
|
|
13
13
|
private readonly retryLimit;
|
|
14
|
-
private readonly cached;
|
|
15
14
|
private readonly restRequestTimeout;
|
|
16
15
|
private readonly throttler?;
|
|
16
|
+
private readonly cached;
|
|
17
17
|
constructor(options?: ClientOptions);
|
|
18
18
|
private get _keys();
|
|
19
19
|
private get _key();
|
|
@@ -51,7 +51,7 @@ class RequestHandler {
|
|
|
51
51
|
async request(path, options = {}) {
|
|
52
52
|
const cached = (await this.cached?.get(path)) ?? null;
|
|
53
53
|
if (cached && options.force !== true)
|
|
54
|
-
return { data: cached, maxAge:
|
|
54
|
+
return { data: cached.data, maxAge: cached.ttl - Date.now(), status: 200, path };
|
|
55
55
|
if (!this.throttler || options.ignoreRateLimit)
|
|
56
56
|
return this.exec(path, options);
|
|
57
57
|
await this.throttler.wait();
|
|
@@ -79,11 +79,12 @@ 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
|
-
if (this.cached && maxAge > 0 && options.cache !== false)
|
|
86
|
-
await this.cached.set(path, data, maxAge);
|
|
85
|
+
if (this.cached && maxAge > 0 && options.cache !== false) {
|
|
86
|
+
await this.cached.set(path, { data, ttl: Date.now() + maxAge }, maxAge);
|
|
87
|
+
}
|
|
87
88
|
return { data, maxAge, status: res.status, path };
|
|
88
89
|
}
|
|
89
90
|
async init(options) {
|
package/package.json
CHANGED