clashofclans.js 3.0.1-dev.e71b7fa → 3.0.2-dev.6c774bd

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 CHANGED
@@ -2,13 +2,14 @@
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
- ## 3.0.1 (11-01-2023)
5
+ ## 3.0.2 (15-01-2023)
6
6
 
7
7
  ### Bug Fixes
8
8
 
9
9
  - Conflict with the same name of builder base and home base troops. (#123)
10
10
  - Fix the issue with the `Client#getLeagueWar()` method.
11
11
  - Typings and documentation for clan capital.
12
+ - Fix the issue with the `Clan#clanCapital` property.
12
13
 
13
14
  ### Features
14
15
 
@@ -92,13 +92,17 @@ class Client extends node_events_1.EventEmitter {
92
92
  async getCurrentWar(clanTag, options) {
93
93
  const args = typeof clanTag === 'string' ? { clanTag } : { clanTag: clanTag.clanTag, round: clanTag.round };
94
94
  try {
95
- return await this.getClanWar(args.clanTag, options);
95
+ const data = await this.getClanWar(args.clanTag, options);
96
+ if (data.state === 'notInWar') {
97
+ return await this.getLeagueWar({ clanTag: args.clanTag, round: args.round }, options);
98
+ }
99
+ return data;
96
100
  }
97
- catch (e) {
98
- if (e instanceof HTTPError_1.HTTPError && [200, 403].includes(e.status)) {
101
+ catch (err) {
102
+ if (err instanceof HTTPError_1.HTTPError && err.status === 403) {
99
103
  return this.getLeagueWar({ clanTag: args.clanTag, round: args.round }, options);
100
104
  }
101
- throw e;
105
+ throw err;
102
106
  }
103
107
  }
104
108
  /**
@@ -1,5 +1,5 @@
1
1
  import { Clan, ClanWar, Player } from '../struct';
2
- import { ClientOptions } from '../types';
2
+ import { PollingClientOptions } from '../types';
3
3
  import { PollingEvents } from '../util/Constants';
4
4
  import { Client } from './Client';
5
5
  /**
@@ -13,13 +13,14 @@ export declare class PollingClient extends Client {
13
13
  private readonly _clanTags;
14
14
  private readonly _playerTags;
15
15
  private readonly _warTags;
16
+ private readonly _pollingInterval;
16
17
  private readonly _clans;
17
18
  private readonly _players;
18
19
  private readonly _wars;
19
20
  private readonly _pollingEvents;
20
21
  inMaintenance: boolean;
21
22
  private _maintenanceStartTime;
22
- constructor(options?: ClientOptions);
23
+ constructor(options?: PollingClientOptions);
23
24
  /** Initialize the PollingEvent Manager to start pulling the data by polling api. */
24
25
  init(): Promise<string[]>;
25
26
  /** Add clan tags to clan polling events. */
@@ -27,6 +27,10 @@ class PollingClient extends Client_1.Client {
27
27
  };
28
28
  this.inMaintenance = Boolean(false);
29
29
  this._maintenanceStartTime = null;
30
+ if (options?.pollingInterval && !isNaN(options.pollingInterval)) {
31
+ throw new Error('The property "pollingInterval" must be a type of number.');
32
+ }
33
+ this._pollingInterval = Math.max(options?.pollingInterval ?? 1000, 1000);
30
34
  }
31
35
  /** Initialize the PollingEvent Manager to start pulling the data by polling api. */
32
36
  async init() {
@@ -147,7 +151,7 @@ class PollingClient extends Client_1.Client {
147
151
  return this;
148
152
  }
149
153
  async maintenanceHandler() {
150
- setTimeout(this.maintenanceHandler.bind(this), 10000).unref();
154
+ setTimeout(this.maintenanceHandler.bind(this), this._pollingInterval).unref();
151
155
  if (!(this.listenerCount(Constants_1.PollingEvents.MaintenanceStart) && this.listenerCount(Constants_1.PollingEvents.MaintenanceEnd)))
152
156
  return;
153
157
  try {
@@ -184,21 +188,21 @@ class PollingClient extends Client_1.Client {
184
188
  for (const tag of this._clanTags)
185
189
  await this.runClanUpdate(tag);
186
190
  this.emit(Constants_1.PollingEvents.ClanLoopEnd);
187
- setTimeout(this.clanUpdateHandler.bind(this), 10000);
191
+ setTimeout(this.clanUpdateHandler.bind(this), this._pollingInterval);
188
192
  }
189
193
  async playerUpdateHandler() {
190
194
  this.emit(Constants_1.PollingEvents.PlayerLoopStart);
191
195
  for (const tag of this._playerTags)
192
196
  await this.runPlayerUpdate(tag);
193
197
  this.emit(Constants_1.PollingEvents.PlayerLoopEnd);
194
- setTimeout(this.playerUpdateHandler.bind(this), 10000);
198
+ setTimeout(this.playerUpdateHandler.bind(this), this._pollingInterval);
195
199
  }
196
200
  async warUpdateHandler() {
197
201
  this.emit(Constants_1.PollingEvents.WarLoopStart);
198
202
  for (const tag of this._warTags)
199
203
  await this.runWarUpdate(tag);
200
204
  this.emit(Constants_1.PollingEvents.WarLoopEnd);
201
- setTimeout(this.warUpdateHandler.bind(this), 10000);
205
+ setTimeout(this.warUpdateHandler.bind(this), this._pollingInterval);
202
206
  }
203
207
  async runClanUpdate(tag) {
204
208
  if (this.inMaintenance)
@@ -67,7 +67,7 @@ export declare class RESTManager extends EventEmitter {
67
67
  /** Get info about a CWL round by WarTag. */
68
68
  getClanWarLeagueRound(warTag: string, options?: OverrideOptions): Promise<import("../types").Response<APIClanWar>>;
69
69
  /** Retrieve clan's capital raid seasons. */
70
- getCapitalRaidSeasons(tag: string, options?: OverrideOptions): Promise<import("../types").Response<APICapitalRaidSeasons>>;
70
+ getCapitalRaidSeasons(tag: string, options?: SearchOptions): Promise<import("../types").Response<APICapitalRaidSeasons>>;
71
71
  /** Get info about a player by tag. */
72
72
  getPlayer(playerTag: string, options?: OverrideOptions): Promise<import("../types").Response<APIPlayer>>;
73
73
  /** Verify Player API token that can be found from the Game settings. */
@@ -145,7 +145,7 @@ class RequestHandler extends node_events_1.EventEmitter {
145
145
  for (const key of this.keys) {
146
146
  const res = await (0, node_fetch_1.default)(`${this.baseURL}/locations?limit=1`, {
147
147
  method: 'GET',
148
- timeout: 10000,
148
+ timeout: this.restRequestTimeout,
149
149
  headers: { 'Authorization': `Bearer ${key}`, 'Content-Type': 'application/json' }
150
150
  }).catch(() => null);
151
151
  if (res?.status === 403) {
@@ -158,7 +158,7 @@ class RequestHandler extends node_events_1.EventEmitter {
158
158
  async login() {
159
159
  const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/login`, {
160
160
  method: 'POST',
161
- timeout: 10000,
161
+ timeout: this.restRequestTimeout,
162
162
  headers: { 'Content-Type': 'application/json' },
163
163
  body: JSON.stringify({ email: this.email, password: this.password })
164
164
  });
@@ -173,7 +173,7 @@ class RequestHandler extends node_events_1.EventEmitter {
173
173
  async getKeys(cookie, ip) {
174
174
  const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/list`, {
175
175
  method: 'POST',
176
- timeout: 10000,
176
+ timeout: this.restRequestTimeout,
177
177
  headers: { 'Content-Type': 'application/json', cookie }
178
178
  });
179
179
  const data = await res.json();
@@ -215,7 +215,7 @@ class RequestHandler extends node_events_1.EventEmitter {
215
215
  async revokeKey(keyId, cookie) {
216
216
  const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/revoke`, {
217
217
  method: 'POST',
218
- timeout: 10000,
218
+ timeout: this.restRequestTimeout,
219
219
  body: JSON.stringify({ id: keyId }),
220
220
  headers: { 'Content-Type': 'application/json', cookie }
221
221
  });
@@ -224,7 +224,7 @@ class RequestHandler extends node_events_1.EventEmitter {
224
224
  async createKey(cookie, ip) {
225
225
  const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/create`, {
226
226
  method: 'POST',
227
- timeout: 10000,
227
+ timeout: this.restRequestTimeout,
228
228
  headers: { 'Content-Type': 'application/json', cookie },
229
229
  body: JSON.stringify({
230
230
  cidrRanges: [ip],
@@ -244,7 +244,7 @@ class RequestHandler extends node_events_1.EventEmitter {
244
244
  return props.cidrs[0].match(IP_REGEX)[0];
245
245
  }
246
246
  catch {
247
- const body = await (0, node_fetch_1.default)('https://api.ipify.org', { timeout: 10000 }).then((res) => res.text());
247
+ const body = await (0, node_fetch_1.default)('https://api.ipify.org', { timeout: this.restRequestTimeout }).then((res) => res.text());
248
248
  return body.match(IP_REGEX)?.[0] ?? null;
249
249
  }
250
250
  }
@@ -34,7 +34,8 @@ class Clan {
34
34
  this.warLeague = data.warLeague ? new WarLeague_1.WarLeague(data.warLeague) : null;
35
35
  this.memberCount = data.members;
36
36
  this.labels = data.labels.map((label) => new Label_1.Label(label));
37
- this.clanCapital = Object.keys(data.clanCapital).length > 0 ? new ClanCapital_1.ClanCapital(data.clanCapital) : null;
37
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
38
+ this.clanCapital = Object.keys(data.clanCapital ?? {}).length > 0 ? new ClanCapital_1.ClanCapital(data.clanCapital) : null;
38
39
  this.isFamilyFriendly = data.isFamilyFriendly;
39
40
  this.capitalPoints = data.clanCapitalPoints;
40
41
  this.capitalLeague = data.capitalLeague;
@@ -24,7 +24,7 @@ export interface APISeason {
24
24
  }
25
25
  /** /clans?name={name}&limit={limit} */
26
26
  export interface APIClanList {
27
- items: Omit<APIClan, 'memberList'>[];
27
+ items: Omit<APIClan, 'memberList' | 'clanCapital'>[];
28
28
  paging: APIPaging;
29
29
  }
30
30
  export interface APIChatLanguage {
@@ -43,6 +43,9 @@ export interface RESTOptions extends ClientOptions {
43
43
  /** Set this `false` to use `res.ok` property. */
44
44
  rejectIfNotValid?: boolean;
45
45
  }
46
+ export interface PollingClientOptions extends ClientOptions {
47
+ pollingInterval?: number;
48
+ }
46
49
  /** Options for a {@link RequestHandler} */
47
50
  export interface RequestHandlerOptions extends ClientOptions {
48
51
  /** Set this `false` to use `res.ok` property. */
@@ -28,7 +28,7 @@ export declare const PollingEvents: {
28
28
  readonly ClanLoopEnd: "clanLoopEnd";
29
29
  readonly PlayerLoopStart: "playerLoopStart";
30
30
  readonly PlayerLoopEnd: "playerLoopEnd";
31
- readonly WarLoopStart: "warLoopEnd";
31
+ readonly WarLoopStart: "warLoopStart";
32
32
  readonly WarLoopEnd: "warLoopEnd";
33
33
  readonly NewSeasonStart: "newSeasonStart";
34
34
  readonly MaintenanceStart: "maintenanceStart";
@@ -137,7 +137,7 @@ exports.PollingEvents = {
137
137
  ClanLoopEnd: 'clanLoopEnd',
138
138
  PlayerLoopStart: 'playerLoopStart',
139
139
  PlayerLoopEnd: 'playerLoopEnd',
140
- WarLoopStart: 'warLoopEnd',
140
+ WarLoopStart: 'warLoopStart',
141
141
  WarLoopEnd: 'warLoopEnd',
142
142
  NewSeasonStart: 'newSeasonStart',
143
143
  MaintenanceStart: 'maintenanceStart',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "3.0.1-dev.e71b7fa",
3
+ "version": "3.0.2-dev.6c774bd",
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",