clashofclans.js 3.0.0-dev.5d2e14a → 3.0.0-dev.9a00cd8

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,7 +2,7 @@
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.0 (15-10-222)
5
+ ## 3.0.0 (11-01-2023)
6
6
 
7
7
  ### Bug Fixes
8
8
 
@@ -12,7 +12,9 @@ All notable changes to this project will be documented in this file. See [standa
12
12
 
13
13
  ### Features
14
14
 
15
- - Support for clan capital raid seasons `Client#getCapitalRaidSeasons()`
15
+ - Added `Client#getCapitalRaidSeasons()` method.
16
+ - Added `Client#getCapitalLeagues()` method.
17
+ - Added `Client#getClanCapitalRanks()` method.
16
18
 
17
19
  ### Breaking Changes
18
20
 
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
@@ -112,8 +112,10 @@ export declare class Client extends EventEmitter {
112
112
  getPlayers(playerTags: string[], options?: OverrideOptions): Promise<Player[]>;
113
113
  /** Verify Player API token that can be found from the Game settings. */
114
114
  verifyPlayerToken(playerTag: string, token: string, options?: OverrideOptions): Promise<boolean>;
115
- /** Get list of Leagues. */
115
+ /** Get a list of Leagues. */
116
116
  getLeagues(options?: SearchOptions): Promise<League[]>;
117
+ /** Get a list of Capital Leagues. */
118
+ getCapitalLeagues(options?: SearchOptions): Promise<import("../types").APICapitalLeague[]>;
117
119
  /** Get Legend League season Ids. */
118
120
  getLeagueSeasons(options?: SearchOptions): Promise<string[]>;
119
121
  /** Get Legend League season rankings by season Id. */
@@ -146,6 +148,12 @@ export declare class Client extends EventEmitter {
146
148
  * For global ranking, use `global` as `locationId`.
147
149
  */
148
150
  getVersusPlayerRanks(locationId: number | 'global', options?: SearchOptions): Promise<RankedPlayer[]>;
151
+ /**
152
+ * Get clan capital rankings for a specific location.
153
+ *
154
+ * For global ranking, use `global` as `locationId`.
155
+ */
156
+ getClanCapitalRanks(locationId: number | 'global', options?: SearchOptions): Promise<import("../types").APIClanCapitalRanking[]>;
149
157
  /** Get list of clan labels. */
150
158
  getClanLabels(options?: SearchOptions): Promise<Label[]>;
151
159
  /** Get list of player labels. */
@@ -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. */
@@ -190,11 +181,16 @@ class Client extends node_events_1.EventEmitter {
190
181
  const { data } = await this.rest.verifyPlayerToken(playerTag, token, options);
191
182
  return data.status === 'ok';
192
183
  }
193
- /** Get list of Leagues. */
184
+ /** Get a list of Leagues. */
194
185
  async getLeagues(options) {
195
186
  const { data } = await this.rest.getLeagues(options);
196
187
  return data.items.map((entry) => new struct_1.League(entry));
197
188
  }
189
+ /** Get a list of Capital Leagues. */
190
+ async getCapitalLeagues(options) {
191
+ const { data } = await this.rest.getCapitalLeagues(options);
192
+ return data.items;
193
+ }
198
194
  /** Get Legend League season Ids. */
199
195
  async getLeagueSeasons(options) {
200
196
  const { data } = await this.rest.getLeagueSeasons(Constants_1.LegendLeagueId, options);
@@ -251,6 +247,15 @@ class Client extends node_events_1.EventEmitter {
251
247
  const { data } = await this.rest.getVersusPlayerRanks(locationId, options);
252
248
  return data.items.map((entry) => new struct_1.RankedPlayer(this, entry));
253
249
  }
250
+ /**
251
+ * Get clan capital rankings for a specific location.
252
+ *
253
+ * For global ranking, use `global` as `locationId`.
254
+ */
255
+ async getClanCapitalRanks(locationId, options) {
256
+ const { data } = await this.rest.getClanCapitalRanks(locationId, options);
257
+ return data.items;
258
+ }
254
259
  /** Get list of clan labels. */
255
260
  async getClanLabels(options) {
256
261
  const { data } = await this.rest.getClanLabels(options);
@@ -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,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'node:events';
3
3
  import { Util } from '../util/Util';
4
- import { APIClan, APIClanList, APIClanMemberList, APICapitalRaidSeasons, APIClanRankingList, APIClanVersusRankingList, APIClanWar, APIClanWarLeagueGroup, APIClanWarLog, APIGoldPassSeason, APILabelList, APILeague, APILeagueList, APILeagueSeasonList, APILocation, APILocationList, APIPlayer, APIPlayerRankingList, APIPlayerSeasonRankingList, APIPlayerVersusRankingList, APIVerifyToken, APIWarLeague, APIWarLeagueList, SearchOptions, ClanSearchOptions, RESTOptions, OverrideOptions, LoginOptions } from '../types';
4
+ import { APIClan, APIClanList, APIClanMemberList, APICapitalRaidSeasons, APIClanRankingList, APIClanVersusRankingList, APIClanWar, APIClanWarLeagueGroup, APIClanWarLog, APIGoldPassSeason, APILabelList, APILeague, APILeagueList, APILeagueSeasonList, APILocation, APILocationList, APIPlayer, APIPlayerRankingList, APIPlayerSeasonRankingList, APIPlayerVersusRankingList, APIVerifyToken, APIWarLeague, APIWarLeagueList, SearchOptions, ClanSearchOptions, RESTOptions, OverrideOptions, LoginOptions, APICapitalLeagueList, APICapitalLeague, APIClanCapitalRankingList } from '../types';
5
5
  import { RestEvents } from '../util/Constants';
6
6
  import { RequestHandler } from './RequestHandler';
7
7
  export interface IRestEvents {
@@ -72,10 +72,14 @@ export declare class RESTManager extends EventEmitter {
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. */
74
74
  verifyPlayerToken(playerTag: string, token: string, options?: OverrideOptions): Promise<import("../types").Response<APIVerifyToken>>;
75
- /** Get list of Leagues. */
75
+ /** Get a list of Leagues. */
76
76
  getLeagues(options?: SearchOptions): Promise<import("../types").Response<APILeagueList>>;
77
77
  /** Get a League info. */
78
78
  getLeague(leagueId: string | number, options?: OverrideOptions): Promise<import("../types").Response<APILeague>>;
79
+ /** Get a list of Capital leagues. */
80
+ getCapitalLeagues(options?: SearchOptions): Promise<import("../types").Response<APICapitalLeagueList>>;
81
+ /** Get a Capital League info. */
82
+ getCapitalLeague(leagueId: string | number, options?: OverrideOptions): Promise<import("../types").Response<APICapitalLeague>>;
79
83
  /** Get Legend League season Ids. */
80
84
  getLeagueSeasons(leagueId: number, options?: SearchOptions): Promise<import("../types").Response<APILeagueSeasonList>>;
81
85
  /** Get Legend League season rankings by season Id. */
@@ -96,6 +100,8 @@ export declare class RESTManager extends EventEmitter {
96
100
  getVersusClanRanks(locationId: number | string, options?: SearchOptions): Promise<import("../types").Response<APIClanVersusRankingList>>;
97
101
  /** Get player versus rankings for a specific location. */
98
102
  getVersusPlayerRanks(locationId: number | string, options?: SearchOptions): Promise<import("../types").Response<APIPlayerVersusRankingList>>;
103
+ /** Get clan capital rankings for a specific location. */
104
+ getClanCapitalRanks(locationId: number | string, options?: SearchOptions): Promise<import("../types").Response<APIClanCapitalRankingList>>;
99
105
  /** Get list of clan labels. */
100
106
  getClanLabels(options?: SearchOptions): Promise<import("../types").Response<APILabelList>>;
101
107
  /** Get list of player labels. */
@@ -78,7 +78,7 @@ class RESTManager extends node_events_1.EventEmitter {
78
78
  const opts = { method: 'POST', body: JSON.stringify({ token }), ...options };
79
79
  return this.requestHandler.request(`/players/${Util_1.Util.encodeURI(playerTag)}/verifytoken`, opts);
80
80
  }
81
- /** Get list of Leagues. */
81
+ /** Get a list of Leagues. */
82
82
  getLeagues(options) {
83
83
  const query = Util_1.Util.queryString(options);
84
84
  return this.requestHandler.request(`/leagues${query}`, options);
@@ -87,6 +87,15 @@ class RESTManager extends node_events_1.EventEmitter {
87
87
  getLeague(leagueId, options) {
88
88
  return this.requestHandler.request(`/leagues/${leagueId}`, options);
89
89
  }
90
+ /** Get a list of Capital leagues. */
91
+ getCapitalLeagues(options) {
92
+ const query = Util_1.Util.queryString(options);
93
+ return this.requestHandler.request(`/capitalleagues${query}`, options);
94
+ }
95
+ /** Get a Capital League info. */
96
+ getCapitalLeague(leagueId, options) {
97
+ return this.requestHandler.request(`/capitalleagues/${leagueId}`, options);
98
+ }
90
99
  /** Get Legend League season Ids. */
91
100
  getLeagueSeasons(leagueId, options) {
92
101
  const query = Util_1.Util.queryString(options);
@@ -135,6 +144,11 @@ class RESTManager extends node_events_1.EventEmitter {
135
144
  const query = Util_1.Util.queryString(options);
136
145
  return this.requestHandler.request(`/locations/${locationId}/rankings/players-versus${query}`, options);
137
146
  }
147
+ /** Get clan capital rankings for a specific location. */
148
+ getClanCapitalRanks(locationId, options) {
149
+ const query = Util_1.Util.queryString(options);
150
+ return this.requestHandler.request(`/locations/${locationId}/rankings/capitals${query}`, options);
151
+ }
138
152
  /** Get list of clan labels. */
139
153
  getClanLabels(options) {
140
154
  const query = Util_1.Util.queryString(options);
@@ -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;
@@ -1,4 +1,4 @@
1
- import { APIClan, OverrideOptions } from '../types';
1
+ import { APICapitalLeague, APIClan, OverrideOptions } from '../types';
2
2
  import { Client } from '../client/Client';
3
3
  import { ChatLanguage } from './ChatLanguage';
4
4
  import { ClanMember } from './ClanMember';
@@ -29,6 +29,8 @@ export declare class Clan {
29
29
  level: number;
30
30
  /** The clan's trophy count. */
31
31
  points: number;
32
+ /** The clan's capital points. */
33
+ capitalPoints: number;
32
34
  /** The clan's versus trophy count. */
33
35
  versusPoints: number;
34
36
  /** The minimum trophies required to apply to this clan. */
@@ -57,6 +59,10 @@ export declare class Clan {
57
59
  labels: Label[];
58
60
  /** The clan's Clan Capital information */
59
61
  clanCapital: ClanCapital | null;
62
+ /** The clan's capital league. */
63
+ capitalLeague?: APICapitalLeague;
64
+ /** Whether the clan is family friendly. */
65
+ isFamilyFriendly: boolean;
60
66
  /**
61
67
  * List of clan members.
62
68
  * - This property returns empty array for {@link Client.getClans} method.
@@ -35,6 +35,9 @@ class Clan {
35
35
  this.memberCount = data.members;
36
36
  this.labels = data.labels.map((label) => new Label_1.Label(label));
37
37
  this.clanCapital = Object.keys(data.clanCapital).length > 0 ? new ClanCapital_1.ClanCapital(data.clanCapital) : null;
38
+ this.isFamilyFriendly = data.isFamilyFriendly;
39
+ this.capitalPoints = data.clanCapitalPoints;
40
+ this.capitalLeague = data.capitalLeague;
38
41
  this.members = data.memberList?.map((mem) => new ClanMember_1.ClanMember(this.client, mem)) ?? []; // eslint-disable-line
39
42
  }
40
43
  /** Get {@link Player} info for every Player in the clan. */
@@ -1,4 +1,4 @@
1
- import { APIClanMember, OverrideOptions } from '../types';
1
+ import { APIClanMember, APIPlayerHouse, OverrideOptions } from '../types';
2
2
  import { Client } from '../client/Client';
3
3
  import { League } from './League';
4
4
  export declare class ClanMember {
@@ -25,6 +25,8 @@ export declare class ClanMember {
25
25
  donations: number;
26
26
  /** The member's donation received count for this season. */
27
27
  received: number;
28
+ /** The member's player house details. */
29
+ playerHouse?: APIPlayerHouse | null;
28
30
  constructor(client: Client, data: APIClanMember);
29
31
  /** Whether this clan member is in the clan. */
30
32
  get isMember(): boolean;
@@ -18,6 +18,7 @@ class ClanMember {
18
18
  this.clanRank = data.clanRank;
19
19
  this.previousClanRank = data.previousClanRank;
20
20
  this.donations = data.donations;
21
+ this.playerHouse = data.playerHouse ?? null;
21
22
  this.received = data.donationsReceived;
22
23
  }
23
24
  /** Whether this clan member is in the clan. */
@@ -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';
@@ -1,4 +1,4 @@
1
- import { APIPlayer, OverrideOptions } from '../types';
1
+ import { APIPlayer, APIPlayerHouse, OverrideOptions } from '../types';
2
2
  import { Client } from '../client/Client';
3
3
  import { LegendStatistics } from './LegendStatistics';
4
4
  import { Achievement } from './Achievement';
@@ -63,6 +63,8 @@ export declare class Player {
63
63
  spells: Spell[];
64
64
  /** An array of player's heroes (both home base and build base). */
65
65
  heroes: Hero[];
66
+ /** The player's clan capital house details. */
67
+ playerHouse?: APIPlayerHouse | null;
66
68
  constructor(client: Client, data: APIPlayer);
67
69
  /** Whether this clan member is in the clan. */
68
70
  get inClan(): boolean;
@@ -40,6 +40,7 @@ class Player {
40
40
  this.troops = data.troops.map((unit) => new Unit_1.Troop(data, unit));
41
41
  this.spells = data.spells.map((unit) => new Unit_1.Spell(data, unit));
42
42
  this.heroes = data.heroes.map((unit) => new Unit_1.Hero(data, unit));
43
+ this.playerHouse = data.playerHouse ?? null;
43
44
  }
44
45
  /** Whether this clan member is in the clan. */
45
46
  get inClan() {
@@ -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);
@@ -58,6 +58,9 @@ export interface APIClan {
58
58
  labels: APILabel[];
59
59
  memberList: APIClanMember[];
60
60
  clanCapital: APIClanCapital;
61
+ isFamilyFriendly: boolean;
62
+ clanCapitalPoints: number;
63
+ capitalLeague?: APICapitalLeague;
61
64
  }
62
65
  export interface APIClanMember {
63
66
  name: string;
@@ -71,6 +74,13 @@ export interface APIClanMember {
71
74
  previousClanRank: number;
72
75
  donations: number;
73
76
  donationsReceived: number;
77
+ playerHouse?: APIPlayerHouse;
78
+ }
79
+ export interface APIPlayerHouse {
80
+ elements: {
81
+ type: string;
82
+ id: number;
83
+ }[];
74
84
  }
75
85
  export interface APIClanCapital {
76
86
  capitalHallLevel?: number;
@@ -211,16 +221,16 @@ export interface APICapitalRaidSeasonDistrict {
211
221
  }
212
222
  export interface APICapitalRaidSeasonAttackLog {
213
223
  defender: APICapitalRaidSeasonClan;
214
- attackCount: 27;
215
- districtCount: 7;
216
- districtsDestroyed: 7;
224
+ attackCount: number;
225
+ districtCount: number;
226
+ districtsDestroyed: number;
217
227
  districts: APICapitalRaidSeasonDistrict[];
218
228
  }
219
229
  export interface APICapitalRaidSeasonDefenseLog {
220
230
  attacker: APICapitalRaidSeasonClan;
221
- attackCount: 27;
222
- districtCount: 7;
223
- districtsDestroyed: 7;
231
+ attackCount: number;
232
+ districtCount: number;
233
+ districtsDestroyed: number;
224
234
  districts: APICapitalRaidSeasonDistrict[];
225
235
  }
226
236
  export interface APICapitalRaidSeasons {
@@ -257,6 +267,7 @@ export interface APIPlayer {
257
267
  heroes: APIPlayerItem[];
258
268
  spells: APIPlayerItem[];
259
269
  labels: APILabel[];
270
+ playerHouse?: APIPlayerHouse;
260
271
  }
261
272
  export interface APILegendStatistics {
262
273
  previousSeason?: APISeason;
@@ -371,6 +382,22 @@ export interface APIPlayerVersusRanking {
371
382
  previousRank: number;
372
383
  clan?: APIPlayerClan;
373
384
  }
385
+ export interface APIClanCapitalRanking {
386
+ clanLevel: number;
387
+ clanPoints: number;
388
+ location: APILocation;
389
+ members: number;
390
+ tag: string;
391
+ name: string;
392
+ rank: number;
393
+ previousRank: number;
394
+ badgeUrls: APIBadge;
395
+ clanCapitalPoints: number;
396
+ }
397
+ export interface APIClanCapitalRankingList {
398
+ items: APIClanCapitalRanking[];
399
+ paging: APIPaging;
400
+ }
374
401
  /** /leagues */
375
402
  export interface APILeagueList {
376
403
  items: APILeague[];
@@ -404,6 +431,14 @@ export interface APIWarLeague {
404
431
  id: number;
405
432
  name: string;
406
433
  }
434
+ export interface APICapitalLeague {
435
+ id: number;
436
+ name: string;
437
+ }
438
+ export interface APICapitalLeagueList {
439
+ items: APICapitalLeague[];
440
+ paging: APIPaging;
441
+ }
407
442
  export interface APILabel {
408
443
  id: number;
409
444
  name: string;
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.9a00cd8",
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",