clashofclans.js 3.0.0-dev.5d2e14a → 3.0.0-dev.70cb1c7

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
@@ -37,7 +37,7 @@ const client = new Client();
37
37
 
38
38
  ### Custom Polling Event
39
39
 
40
- > **Warning** <br>
40
+ > **Warning** <br />
41
41
  > Events are neither real-time nor supported by the API. They are polled frequently and compared with the cached data. If there is a difference, the event is emitted.
42
42
 
43
43
  ```js
@@ -66,7 +66,7 @@ class Client extends node_events_1.EventEmitter {
66
66
  /** Get capital raid seasons. */
67
67
  async getCapitalRaidSeasons(tag, options) {
68
68
  const { data } = await this.rest.getCapitalRaidSeasons(tag, options);
69
- return data.items.map((entry) => new CapitalRaidSeason_1.CapitalRaidSeason(entry));
69
+ return data.items.map((entry) => new CapitalRaidSeason_1.CapitalRaidSeason(this, entry));
70
70
  }
71
71
  /** Get clan war log. */
72
72
  async getClanWarLog(clanTag, options) {
@@ -75,10 +75,7 @@ class Client extends node_events_1.EventEmitter {
75
75
  }
76
76
  /** Get info about currently running war (normal or friendly) in the clan. */
77
77
  async getClanWar(clanTag, options) {
78
- const { data, maxAge, path, status } = await this.rest.getCurrentWar(clanTag, options);
79
- if (data.state === 'notInWar') {
80
- throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
81
- }
78
+ const { data, maxAge } = await this.rest.getCurrentWar(clanTag, options);
82
79
  return new struct_1.ClanWar(this, data, { clanTag, maxAge });
83
80
  }
84
81
  /**
@@ -159,19 +156,13 @@ class Client extends node_events_1.EventEmitter {
159
156
  }
160
157
  /** Get info about clan war league. */
161
158
  async getClanWarLeagueGroup(clanTag, options) {
162
- const { data, status, path, maxAge } = await this.rest.getClanWarLeagueGroup(clanTag, options);
163
- if (data.state === 'notInWar') {
164
- throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
165
- }
159
+ const { data } = await this.rest.getClanWarLeagueGroup(clanTag, options);
166
160
  return new struct_1.ClanWarLeagueGroup(this, data);
167
161
  }
168
162
  /** Get info about a CWL round by WarTag. */
169
163
  async getClanWarLeagueRound(warTag, options) {
170
164
  const args = typeof warTag === 'string' ? { warTag } : { warTag: warTag.warTag, clanTag: warTag.clanTag };
171
- const { data, maxAge, status, path } = await this.rest.getClanWarLeagueRound(args.warTag, options);
172
- if (data.state === 'notInWar') {
173
- throw new HTTPError_1.HTTPError(HTTPError_1.NotInWarError, status, path, maxAge);
174
- }
165
+ const { data, maxAge } = await this.rest.getClanWarLeagueRound(args.warTag, options);
175
166
  return new struct_1.ClanWar(this, data, { warTag: args.warTag, clanTag: args.clanTag, maxAge });
176
167
  }
177
168
  /** Get info about a player by tag. */
@@ -3,7 +3,7 @@ import { ClientOptions } from '../types';
3
3
  import { PollingEvents } from '../util/Constants';
4
4
  import { Client } from './Client';
5
5
  /**
6
- * Represents Clash of Clans Polling Event Client.
6
+ * Represents a Polling Event Client.
7
7
  * ```js
8
8
  * const { PollingClient } = require('clashofclans.js');
9
9
  * const pollingClient = new PollingClient({ keys: ['***'] });
@@ -5,7 +5,7 @@ const HTTPError_1 = require("../rest/HTTPError");
5
5
  const Constants_1 = require("../util/Constants");
6
6
  const Client_1 = require("./Client");
7
7
  /**
8
- * Represents Clash of Clans Polling Event Client.
8
+ * Represents a Polling Event Client.
9
9
  * ```js
10
10
  * const { PollingClient } = require('clashofclans.js');
11
11
  * const pollingClient = new PollingClient({ keys: ['***'] });
@@ -148,6 +148,8 @@ class PollingClient extends Client_1.Client {
148
148
  }
149
149
  async maintenanceHandler() {
150
150
  setTimeout(this.maintenanceHandler.bind(this), 10000).unref();
151
+ if (!(this.listenerCount(Constants_1.PollingEvents.MaintenanceStart) && this.listenerCount(Constants_1.PollingEvents.MaintenanceEnd)))
152
+ return;
151
153
  try {
152
154
  const res = await this.rest.getClans({ maxMembers: Math.floor(Math.random() * 40) + 10, limit: 1 });
153
155
  if (res.status === 200 && this.inMaintenance) {
package/dist/index.mjs CHANGED
@@ -8,8 +8,11 @@ export const BatchThrottler = mod.BatchThrottler;
8
8
  export const BuilderTroops = mod.BuilderTroops;
9
9
  export const CWLRounds = mod.CWLRounds;
10
10
  export const CacheStore = mod.CacheStore;
11
+ export const CapitalRaidSeason = mod.CapitalRaidSeason;
12
+ export const CapitalRaidSeasonMember = mod.CapitalRaidSeasonMember;
11
13
  export const ChatLanguage = mod.ChatLanguage;
12
14
  export const Clan = mod.Clan;
15
+ export const ClanCapital = mod.ClanCapital;
13
16
  export const ClanMember = mod.ClanMember;
14
17
  export const ClanWar = mod.ClanWar;
15
18
  export const ClanWarAttack = mod.ClanWarAttack;
@@ -40,7 +43,6 @@ export const Leagues = mod.Leagues;
40
43
  export const LegendLeagueId = mod.LegendLeagueId;
41
44
  export const LegendStatistics = mod.LegendStatistics;
42
45
  export const Location = mod.Location;
43
- export const NotInWarError = mod.NotInWarError;
44
46
  export const Player = mod.Player;
45
47
  export const PlayerClan = mod.PlayerClan;
46
48
  export const PollingClient = mod.PollingClient;
@@ -19,10 +19,6 @@ export declare class HTTPError extends Error {
19
19
  maxAge: number;
20
20
  constructor(error: any, status: number, path: string, maxAge: number, method?: string);
21
21
  }
22
- export declare const NotInWarError: {
23
- message: string;
24
- reason: string;
25
- };
26
22
  export declare const PrivateWarLogError: {
27
23
  message: string;
28
24
  reason: string;
@@ -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.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.',
@@ -32,10 +32,6 @@ class HTTPError extends Error {
32
32
  }
33
33
  }
34
34
  exports.HTTPError = HTTPError;
35
- exports.NotInWarError = {
36
- message: 'Clan is not in war at this moment.',
37
- reason: 'notInWar'
38
- };
39
35
  exports.PrivateWarLogError = {
40
36
  message: 'Access denied, clan war log is private.',
41
37
  reason: 'privateWarLog'
@@ -1,6 +1,24 @@
1
- import { APICapitalRaidSeason, APICapitalRaidSeasonAttackLog, APICapitalRaidSeasonDefenseLog, APICapitalRaidSeasonMember } from '../types';
1
+ import { Client } from '../client/Client';
2
+ import { APICapitalRaidSeason, APICapitalRaidSeasonAttackLog, APICapitalRaidSeasonDefenseLog, APICapitalRaidSeasonMember, OverrideOptions } from '../types';
3
+ import { Player } from './Player';
4
+ export declare class CapitalRaidSeasonMember {
5
+ /** The player's tag. */
6
+ name: string;
7
+ /** The player's name. */
8
+ tag: string;
9
+ /** The number of attacks the player has made. */
10
+ attacks: number;
11
+ /** The number of attacks the player can make. */
12
+ attackLimit: number;
13
+ /** The number of bonus attacks the player can make. */
14
+ bonusAttackLimit: number;
15
+ /** The number of capital resources the player has looted. */
16
+ capitalResourcesLooted: number;
17
+ constructor(data: APICapitalRaidSeasonMember);
18
+ }
2
19
  /** Represents a Capital Raid Season. */
3
20
  export declare class CapitalRaidSeason {
21
+ private readonly client;
4
22
  /** The state of the raid season. */
5
23
  state: 'ongoing' | 'ended';
6
24
  /** The start time of the raid season. */
@@ -25,5 +43,7 @@ export declare class CapitalRaidSeason {
25
43
  attackLog: APICapitalRaidSeasonAttackLog[];
26
44
  /** The defense log of the raid season. */
27
45
  defenseLog: APICapitalRaidSeasonDefenseLog[];
28
- constructor(data: APICapitalRaidSeason);
46
+ constructor(client: Client, data: APICapitalRaidSeason);
47
+ /** Get {@link Player} info for every Player in the clan. */
48
+ fetchMembers(options?: OverrideOptions): Promise<Player[]>;
29
49
  }
@@ -1,10 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CapitalRaidSeason = void 0;
3
+ exports.CapitalRaidSeason = exports.CapitalRaidSeasonMember = void 0;
4
4
  const Util_1 = require("../util/Util");
5
+ class CapitalRaidSeasonMember {
6
+ constructor(data) {
7
+ this.tag = data.tag;
8
+ this.name = data.name;
9
+ this.attacks = data.attacks;
10
+ this.attackLimit = data.attackLimit;
11
+ this.bonusAttackLimit = data.bonusAttackLimit;
12
+ this.capitalResourcesLooted = data.capitalResourcesLooted;
13
+ }
14
+ }
15
+ exports.CapitalRaidSeasonMember = CapitalRaidSeasonMember;
5
16
  /** Represents a Capital Raid Season. */
6
17
  class CapitalRaidSeason {
7
- constructor(data) {
18
+ constructor(client, data) {
19
+ this.client = client;
8
20
  this.state = data.state;
9
21
  this.startTime = Util_1.Util.formatDate(data.startTime);
10
22
  this.endTime = Util_1.Util.formatDate(data.endTime);
@@ -14,9 +26,15 @@ class CapitalRaidSeason {
14
26
  this.enemyDistrictsDestroyed = data.enemyDistrictsDestroyed;
15
27
  this.offensiveReward = data.offensiveReward;
16
28
  this.defensiveReward = data.defensiveReward;
17
- this.members = data.members ?? [];
18
29
  this.attackLog = data.attackLog;
19
30
  this.defenseLog = data.defenseLog;
31
+ this.members = (data.members ?? []).map((member) => new CapitalRaidSeasonMember(member));
32
+ }
33
+ /** Get {@link Player} info for every Player in the clan. */
34
+ async fetchMembers(options) {
35
+ return (await Promise.allSettled(this.members.map((m) => this.client.getPlayer(m.tag, { ...options, ignoreRateLimit: true }))))
36
+ .filter((res) => res.status === 'fulfilled')
37
+ .map((res) => res.value);
20
38
  }
21
39
  }
22
40
  exports.CapitalRaidSeason = CapitalRaidSeason;
@@ -101,11 +101,21 @@ export declare class WarClan {
101
101
  /** Get clan's formatted link to open clan in-game. */
102
102
  get shareLink(): string;
103
103
  }
104
- /** Represents a Clan War in Clash of Clans. */
104
+ /**
105
+ * Represents a Clan War in Clash of Clans.
106
+ *
107
+ * :::caution
108
+ * It's recommended to see if ClanWar#state is `notInWar` available before performing operations or reading data from it. You can check this with data.ok property.
109
+ * :::
110
+ */
105
111
  export declare class ClanWar {
106
112
  client: Client;
107
- /** The clan's current war state. */
108
- state: 'preparation' | 'inWar' | 'warEnded';
113
+ /**
114
+ * The clan's current war state.
115
+ *
116
+ * :warning: Other properties won't be available if the state is `notInWar`.
117
+ */
118
+ state: 'preparation' | 'inWar' | 'warEnded' | 'notInWar';
109
119
  /** The number of players on each side. */
110
120
  teamSize: number;
111
121
  /** The number of attacks each member has. */
@@ -135,6 +145,8 @@ export declare class ClanWar {
135
145
  getAttack(attackerTag: string, defenderTag: string): ClanWarAttack | null;
136
146
  /** Return a list of {@link ClanWarAttack} for the defenderTag provided. */
137
147
  getDefenses(defenderTag: string): ClanWarAttack[];
148
+ /** Whether the clan is not in war. */
149
+ get isNotInWar(): boolean;
138
150
  /** Whether this is a Battle Day. */
139
151
  get isBattleDay(): boolean;
140
152
  /** Whether this is a Preparation Day. */
@@ -137,26 +137,33 @@ class WarClan {
137
137
  }
138
138
  }
139
139
  exports.WarClan = WarClan;
140
- /** Represents a Clan War in Clash of Clans. */
140
+ /**
141
+ * Represents a Clan War in Clash of Clans.
142
+ *
143
+ * :::caution
144
+ * It's recommended to see if ClanWar#state is `notInWar` available before performing operations or reading data from it. You can check this with data.ok property.
145
+ * :::
146
+ */
141
147
  class ClanWar {
142
148
  constructor(client, data, extra) {
143
149
  Object.defineProperty(this, 'client', { value: client });
144
- // @ts-expect-error
145
150
  this.state = data.state;
146
- this.teamSize = data.teamSize;
147
- this.attacksPerMember = data.attacksPerMember ?? (extra.warTag ? 1 : 2);
148
- this.preparationStartTime = client.util.formatDate(data.preparationStartTime);
149
- this.startTime = client.util.formatDate(data.startTime);
150
- this.endTime = client.util.formatDate(data.endTime);
151
- this.warTag = extra.warTag ?? null;
152
- let [clan, opponent] = [data.clan, data.opponent];
153
- const clanTag = extra.clanTag && client.util.formatTag(extra.clanTag);
154
- if (clanTag && [data.clan.tag, data.opponent.tag].includes(clanTag)) {
155
- clan = data.clan.tag === clanTag ? data.clan : data.opponent;
156
- opponent = data.clan.tag === clan.tag ? data.opponent : data.clan;
151
+ if (this.state !== 'notInWar') {
152
+ this.teamSize = data.teamSize;
153
+ this.attacksPerMember = data.attacksPerMember ?? (extra.warTag ? 1 : 2);
154
+ this.preparationStartTime = client.util.formatDate(data.preparationStartTime);
155
+ this.startTime = client.util.formatDate(data.startTime);
156
+ this.endTime = client.util.formatDate(data.endTime);
157
+ this.warTag = extra.warTag ?? null;
158
+ let [clan, opponent] = [data.clan, data.opponent];
159
+ const clanTag = extra.clanTag && client.util.formatTag(extra.clanTag);
160
+ if (clanTag && [data.clan.tag, data.opponent.tag].includes(clanTag)) {
161
+ clan = data.clan.tag === clanTag ? data.clan : data.opponent;
162
+ opponent = data.clan.tag === clan.tag ? data.opponent : data.clan;
163
+ }
164
+ this.clan = new WarClan(this, clan);
165
+ this.opponent = new WarClan(this, opponent);
157
166
  }
158
- this.clan = new WarClan(this, clan);
159
- this.opponent = new WarClan(this, opponent);
160
167
  this.maxAge = extra.maxAge;
161
168
  }
162
169
  /** Return a {@link ClanWarMember} with the tag provided. */
@@ -178,6 +185,10 @@ class ClanWar {
178
185
  }
179
186
  return this.opponent.attacks.filter((atk) => atk.defenderTag === defenderTag);
180
187
  }
188
+ /** Whether the clan is not in war. */
189
+ get isNotInWar() {
190
+ return this.state === 'notInWar';
191
+ }
181
192
  /** Whether this is a Battle Day. */
182
193
  get isBattleDay() {
183
194
  return this.state === 'inWar';
@@ -17,3 +17,5 @@ export * from './Ranking';
17
17
  export * from './Season';
18
18
  export * from './Unit';
19
19
  export * from './WarLeague';
20
+ export * from './ClanCapital';
21
+ export * from './CapitalRaidSeason';
@@ -33,3 +33,5 @@ __exportStar(require("./Ranking"), exports);
33
33
  __exportStar(require("./Season"), exports);
34
34
  __exportStar(require("./Unit"), exports);
35
35
  __exportStar(require("./WarLeague"), exports);
36
+ __exportStar(require("./ClanCapital"), exports);
37
+ __exportStar(require("./CapitalRaidSeason"), exports);
@@ -211,16 +211,16 @@ export interface APICapitalRaidSeasonDistrict {
211
211
  }
212
212
  export interface APICapitalRaidSeasonAttackLog {
213
213
  defender: APICapitalRaidSeasonClan;
214
- attackCount: 27;
215
- districtCount: 7;
216
- districtsDestroyed: 7;
214
+ attackCount: number;
215
+ districtCount: number;
216
+ districtsDestroyed: number;
217
217
  districts: APICapitalRaidSeasonDistrict[];
218
218
  }
219
219
  export interface APICapitalRaidSeasonDefenseLog {
220
220
  attacker: APICapitalRaidSeasonClan;
221
- attackCount: 27;
222
- districtCount: 7;
223
- districtsDestroyed: 7;
221
+ attackCount: number;
222
+ districtCount: number;
223
+ districtsDestroyed: number;
224
224
  districts: APICapitalRaidSeasonDistrict[];
225
225
  }
226
226
  export interface APICapitalRaidSeasons {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "3.0.0-dev.5d2e14a",
3
+ "version": "3.0.0-dev.70cb1c7",
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",