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 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) => {
@@ -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
- /** Client events that can be emitted by the client. */
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 {};
@@ -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.notInWarError, status, path, maxAge);
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.notInWarError, status, path, maxAge);
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 a clan tag to clan events. */
19
- addClans(...tags: string[]): this;
20
- /** Delete a clan tag from clan events. */
21
- deleteClans(...tags: string[]): this;
22
- /** Add a player tag for player events. */
23
- addPlayers(...tags: string[]): this;
24
- /** Delete a player tag from player events. */
25
- deletePlayers(...tags: string[]): this;
26
- /** Add a clan tag for war events. */
27
- addWars(...tags: string[]): this;
28
- /** Delete a clan tag from war events. */
29
- deleteWars(...tags: string[]): this;
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 a clan tag to clan events. */
35
- addClans(...tags) {
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 a clan tag from clan events. */
42
- deleteClans(...tags) {
43
- for (const tag of tags) {
44
- this._warTags.delete(this.client.util.parseTag(tag));
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 a player tag for player events. */
49
- addPlayers(...tags) {
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 a player tag from player events. */
56
- deletePlayers(...tags) {
57
- for (const tag of tags) {
58
- this._warTags.delete(this.client.util.parseTag(tag));
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 a clan tag for war events. */
63
- addWars(...tags) {
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 a clan tag from war events. */
70
- deleteWars(...tags) {
71
- for (const tag of tags) {
72
- this._warTags.delete(this.client.util.parseTag(tag));
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), 100000);
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
- for (const { name, filter } of this._events.wars) {
244
- try {
245
- if (data && !filter(cached, data))
246
- continue;
247
- this.client.emit(name, cached, data);
248
- }
249
- catch (error) {
250
- this.client.emit(Constants_1.EVENTS.ERROR, error);
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
  }
@@ -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 notInWarError: {
19
+ export declare const NotInWarError: {
20
20
  message: string;
21
21
  reason: string;
22
22
  };
23
- export declare const privateWarLogError: {
23
+ export declare const PrivateWarLogError: {
24
24
  message: string;
25
25
  reason: string;
26
26
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.privateWarLogError = exports.notInWarError = 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
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.notInWarError = {
37
+ exports.NotInWarError = {
38
38
  message: 'Clan is not in war at this moment.',
39
39
  reason: 'notInWar'
40
40
  };
41
- exports.privateWarLogError = {
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: 0, status: 200, path };
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.privateWarLogError, res.status, path, maxAge);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "2.0.0-dev.4c7acc8",
3
+ "version": "2.0.0-dev.75d755c",
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",