clashofclans.js 3.0.0-dev.392ca4c → 3.0.0-dev.577f128
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 +66 -47
- package/README.md +12 -8
- package/dist/client/Client.d.ts +38 -3
- package/dist/client/Client.js +32 -19
- package/dist/client/PollingClient.d.ts +107 -34
- package/dist/client/PollingClient.js +269 -8
- package/dist/index.d.ts +0 -1
- package/dist/index.js +5 -2
- package/dist/index.mjs +5 -2
- package/dist/rest/HTTPError.d.ts +0 -4
- package/dist/rest/HTTPError.js +1 -5
- package/dist/rest/RESTManager.d.ts +46 -5
- package/dist/rest/RESTManager.js +55 -30
- package/dist/rest/RequestHandler.d.ts +30 -2
- package/dist/rest/RequestHandler.js +69 -33
- package/dist/struct/CapitalRaidSeason.d.ts +49 -0
- package/dist/struct/CapitalRaidSeason.js +40 -0
- package/dist/struct/Clan.d.ts +8 -2
- package/dist/struct/Clan.js +3 -0
- package/dist/struct/ClanCapital.js +1 -1
- package/dist/struct/ClanMember.d.ts +3 -1
- package/dist/struct/ClanMember.js +1 -0
- package/dist/struct/ClanWar.d.ts +15 -3
- package/dist/struct/ClanWar.js +26 -15
- package/dist/struct/Player.d.ts +4 -2
- package/dist/struct/Player.js +1 -0
- package/dist/struct/Ranking.d.ts +1 -1
- package/dist/struct/Unit.d.ts +0 -2
- package/dist/struct/Unit.js +0 -2
- package/dist/struct/index.d.ts +2 -0
- package/dist/struct/index.js +7 -1
- package/dist/types/api.d.ts +93 -0
- package/dist/types/index.js +5 -1
- package/dist/types/lib.d.ts +4 -4
- package/dist/util/Constants.d.ts +38 -3
- package/dist/util/Constants.js +25 -6
- package/dist/util/Util.js +2 -2
- package/dist/util/raw.json +1 -1
- package/package.json +6 -59
- package/dist/client/EventManager.d.ts +0 -86
- package/dist/client/EventManager.js +0 -278
|
@@ -1,6 +1,34 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
1
3
|
import { Response, RequestOptions, LoginOptions, RequestHandlerOptions } from '../types';
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
+
import { IRestEvents } from './RESTManager';
|
|
5
|
+
export interface RequestHandler {
|
|
6
|
+
emit: (<K extends keyof IRestEvents>(event: K, ...args: IRestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, ...args: any[]) => boolean);
|
|
7
|
+
off: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
8
|
+
on: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
9
|
+
once: (<K extends keyof IRestEvents>(event: K, listener: (...args: IRestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof IRestEvents>, listener: (...args: any[]) => void) => this);
|
|
10
|
+
removeAllListeners: (<K extends keyof IRestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof IRestEvents>) => this);
|
|
11
|
+
/**
|
|
12
|
+
* Emitted for general debugging information.
|
|
13
|
+
* @public
|
|
14
|
+
* @event
|
|
15
|
+
*/
|
|
16
|
+
debug: string;
|
|
17
|
+
/**
|
|
18
|
+
* Emitted when the client encounters an error.
|
|
19
|
+
* @public
|
|
20
|
+
* @event
|
|
21
|
+
*/
|
|
22
|
+
error: string;
|
|
23
|
+
/**
|
|
24
|
+
* Emitted when the client is rate limited.
|
|
25
|
+
* @public
|
|
26
|
+
* @event
|
|
27
|
+
*/
|
|
28
|
+
rateLimited: string;
|
|
29
|
+
}
|
|
30
|
+
/** Represents the class that manages handlers for endpoints. */
|
|
31
|
+
export declare class RequestHandler extends EventEmitter {
|
|
4
32
|
#private;
|
|
5
33
|
private email;
|
|
6
34
|
private password;
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
26
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
27
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
@@ -16,16 +39,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
16
39
|
var _RequestHandler_keyIndex;
|
|
17
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
41
|
exports.RequestHandler = void 0;
|
|
42
|
+
const node_https_1 = __importDefault(require("node:https"));
|
|
43
|
+
const node_events_1 = require("node:events");
|
|
44
|
+
const node_fetch_1 = __importStar(require("node-fetch"));
|
|
19
45
|
const Constants_1 = require("../util/Constants");
|
|
20
|
-
const HTTPError_1 = require("./HTTPError");
|
|
21
46
|
const Store_1 = require("../util/Store");
|
|
22
|
-
const
|
|
23
|
-
const https_1 = __importDefault(require("https"));
|
|
47
|
+
const HTTPError_1 = require("./HTTPError");
|
|
24
48
|
const IP_REGEX = /\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/g;
|
|
25
|
-
const agent = new
|
|
26
|
-
/** Represents
|
|
27
|
-
class RequestHandler {
|
|
49
|
+
const agent = new node_https_1.default.Agent({ keepAlive: true });
|
|
50
|
+
/** Represents the class that manages handlers for endpoints. */
|
|
51
|
+
class RequestHandler extends node_events_1.EventEmitter {
|
|
28
52
|
constructor(options) {
|
|
53
|
+
super();
|
|
29
54
|
_RequestHandler_keyIndex.set(this, 0); // eslint-disable-line
|
|
30
55
|
this.keys = options?.keys ?? [];
|
|
31
56
|
this.retryLimit = options?.retryLimit ?? 0;
|
|
@@ -64,35 +89,46 @@ class RequestHandler {
|
|
|
64
89
|
return this.exec(path, options);
|
|
65
90
|
}
|
|
66
91
|
async exec(path, options = {}, retries = 0) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
try {
|
|
93
|
+
const res = await (0, node_fetch_1.default)(`${this.baseURL}${path}`, {
|
|
94
|
+
agent,
|
|
95
|
+
body: options.body,
|
|
96
|
+
method: options.method,
|
|
97
|
+
timeout: options.restRequestTimeout ?? this.restRequestTimeout,
|
|
98
|
+
headers: { 'Authorization': `Bearer ${this._key}`, 'Content-Type': 'application/json' }
|
|
99
|
+
});
|
|
100
|
+
if (res.status === 504 && retries < (options.retryLimit ?? this.retryLimit)) {
|
|
101
|
+
return await this.exec(path, options, ++retries);
|
|
102
|
+
}
|
|
103
|
+
const data = await res.json();
|
|
104
|
+
if (this.creds &&
|
|
105
|
+
res.status === 403 &&
|
|
106
|
+
data.reason === 'accessDenied.invalidIp' &&
|
|
107
|
+
retries < (options.retryLimit ?? this.retryLimit)) {
|
|
108
|
+
const keys = await this.reValidateKeys().then(() => () => this.login());
|
|
109
|
+
if (keys.length)
|
|
110
|
+
return await this.exec(path, options, ++retries);
|
|
111
|
+
}
|
|
112
|
+
const maxAge = Number(res.headers.get('cache-control')?.split('=')?.[1] ?? 0) * 1000;
|
|
113
|
+
if (res.status === 403 && !data?.message && this.rejectIfNotValid) {
|
|
114
|
+
throw new HTTPError_1.HTTPError(HTTPError_1.PrivateWarLogError, res.status, path, maxAge);
|
|
115
|
+
}
|
|
116
|
+
if (!res.ok && this.rejectIfNotValid) {
|
|
117
|
+
throw new HTTPError_1.HTTPError(data, res.status, path, maxAge, options.method);
|
|
118
|
+
}
|
|
119
|
+
if (this.cached && maxAge > 0 && options.cache !== false && res.ok) {
|
|
120
|
+
await this.cached.set(path, { data, ttl: Date.now() + maxAge, status: res.status }, maxAge);
|
|
121
|
+
}
|
|
122
|
+
return { data, maxAge, status: res.status, path, ok: res.status === 200 };
|
|
91
123
|
}
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof node_fetch_1.FetchError && error.type === 'request-timeout' && retries < (options.retryLimit ?? this.retryLimit)) {
|
|
126
|
+
return this.exec(path, options, ++retries);
|
|
127
|
+
}
|
|
128
|
+
if (this.rejectIfNotValid)
|
|
129
|
+
throw error;
|
|
130
|
+
return { data: { message: error.message }, maxAge: 0, status: 500, path, ok: false };
|
|
94
131
|
}
|
|
95
|
-
return { data, maxAge, status: res?.status ?? 504, path, ok: res?.status === 200 };
|
|
96
132
|
}
|
|
97
133
|
async init(options) {
|
|
98
134
|
if (!(options.email && options.password))
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
}
|
|
19
|
+
/** Represents a Capital Raid Season. */
|
|
20
|
+
export declare class CapitalRaidSeason {
|
|
21
|
+
private readonly client;
|
|
22
|
+
/** The state of the raid season. */
|
|
23
|
+
state: 'ongoing' | 'ended';
|
|
24
|
+
/** The start time of the raid season. */
|
|
25
|
+
startTime: Date;
|
|
26
|
+
/** The end time of the raid season. */
|
|
27
|
+
endTime: Date;
|
|
28
|
+
/** The total loot collected from the capital. */
|
|
29
|
+
capitalTotalLoot: number;
|
|
30
|
+
/** The number of raids completed. */
|
|
31
|
+
raidsCompleted: number;
|
|
32
|
+
/** The total number of attacks. */
|
|
33
|
+
totalAttacks: number;
|
|
34
|
+
/** The number of enemy districts destroyed. */
|
|
35
|
+
enemyDistrictsDestroyed: number;
|
|
36
|
+
/** The offensive reward. */
|
|
37
|
+
offensiveReward: number;
|
|
38
|
+
/** The defensive reward. */
|
|
39
|
+
defensiveReward: number;
|
|
40
|
+
/** The members of the raid season. */
|
|
41
|
+
members: APICapitalRaidSeasonMember[];
|
|
42
|
+
/** The attack log of the raid season. */
|
|
43
|
+
attackLog: APICapitalRaidSeasonAttackLog[];
|
|
44
|
+
/** The defense log of the raid season. */
|
|
45
|
+
defenseLog: APICapitalRaidSeasonDefenseLog[];
|
|
46
|
+
constructor(client: Client, data: APICapitalRaidSeason);
|
|
47
|
+
/** Get {@link Player} info for every Player in the clan. */
|
|
48
|
+
fetchMembers(options?: OverrideOptions): Promise<Player[]>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CapitalRaidSeason = exports.CapitalRaidSeasonMember = void 0;
|
|
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;
|
|
16
|
+
/** Represents a Capital Raid Season. */
|
|
17
|
+
class CapitalRaidSeason {
|
|
18
|
+
constructor(client, data) {
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.state = data.state;
|
|
21
|
+
this.startTime = Util_1.Util.formatDate(data.startTime);
|
|
22
|
+
this.endTime = Util_1.Util.formatDate(data.endTime);
|
|
23
|
+
this.capitalTotalLoot = data.capitalTotalLoot;
|
|
24
|
+
this.raidsCompleted = data.raidsCompleted;
|
|
25
|
+
this.totalAttacks = data.totalAttacks;
|
|
26
|
+
this.enemyDistrictsDestroyed = data.enemyDistrictsDestroyed;
|
|
27
|
+
this.offensiveReward = data.offensiveReward;
|
|
28
|
+
this.defensiveReward = data.defensiveReward;
|
|
29
|
+
this.attackLog = data.attackLog;
|
|
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);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.CapitalRaidSeason = CapitalRaidSeason;
|
package/dist/struct/Clan.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { APIClan, OverrideOptions } from '../types';
|
|
1
|
+
import { APICapitalLeague, APIClan, OverrideOptions } from '../types';
|
|
2
|
+
import { Client } from '../client/Client';
|
|
2
3
|
import { ChatLanguage } from './ChatLanguage';
|
|
3
4
|
import { ClanMember } from './ClanMember';
|
|
4
|
-
import { Client } from '../client/Client';
|
|
5
5
|
import { WarLeague } from './WarLeague';
|
|
6
6
|
import type { Player } from './Player';
|
|
7
7
|
import { Location } from './Location';
|
|
@@ -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.
|
package/dist/struct/Clan.js
CHANGED
|
@@ -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. */
|
|
@@ -4,7 +4,7 @@ exports.ClanCapital = void 0;
|
|
|
4
4
|
class ClanCapital {
|
|
5
5
|
constructor(data) {
|
|
6
6
|
this.capitalHallLevel = data.capitalHallLevel ?? null;
|
|
7
|
-
this.districts = data.districts
|
|
7
|
+
this.districts = data.districts ?? null;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
exports.ClanCapital = ClanCapital;
|
|
@@ -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. */
|
package/dist/struct/ClanWar.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
/**
|
|
108
|
-
|
|
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. */
|
package/dist/struct/ClanWar.js
CHANGED
|
@@ -137,26 +137,33 @@ class WarClan {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
exports.WarClan = WarClan;
|
|
140
|
-
/**
|
|
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.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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';
|
package/dist/struct/Player.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { APIPlayer, OverrideOptions } from '../types';
|
|
1
|
+
import { APIPlayer, APIPlayerHouse, OverrideOptions } from '../types';
|
|
2
|
+
import { Client } from '../client/Client';
|
|
2
3
|
import { LegendStatistics } from './LegendStatistics';
|
|
3
4
|
import { Achievement } from './Achievement';
|
|
4
5
|
import { Hero, Spell, Troop } from './Unit';
|
|
5
6
|
import { PlayerClan } from './PlayerClan';
|
|
6
|
-
import { Client } from '../client/Client';
|
|
7
7
|
import { League } from './League';
|
|
8
8
|
import { Label } from './Label';
|
|
9
9
|
/** Represents a Clash of Clans Player. */
|
|
@@ -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;
|
package/dist/struct/Player.js
CHANGED
|
@@ -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() {
|
package/dist/struct/Ranking.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APIClanRanking, APIClanVersusRanking, APIPlayerRanking, APIPlayerVersusRanking } from '../types';
|
|
2
|
-
import { PlayerClan } from './PlayerClan';
|
|
3
2
|
import { Client } from '../client/Client';
|
|
3
|
+
import { PlayerClan } from './PlayerClan';
|
|
4
4
|
import { Location } from './Location';
|
|
5
5
|
import { League } from './League';
|
|
6
6
|
import { Badge } from './Badge';
|
package/dist/struct/Unit.d.ts
CHANGED
package/dist/struct/Unit.js
CHANGED
|
@@ -25,7 +25,6 @@ class Unit {
|
|
|
25
25
|
this.unlockBuilding = original.unlock.building;
|
|
26
26
|
this.unlockBuildingLevel = original.unlock.buildingLevel;
|
|
27
27
|
this.dps = rawUnit.dps[this.level - 1];
|
|
28
|
-
this.resourceType = rawSuperUnit.resource;
|
|
29
28
|
this.trainingTime = rawUnit.trainingTime;
|
|
30
29
|
const origin = data.troops.find((troop) => troop.village === 'home' && troop.name === original.name);
|
|
31
30
|
this.level = origin.level;
|
|
@@ -49,7 +48,6 @@ class Unit {
|
|
|
49
48
|
this.upgradeCost = rawUnit.upgrade.cost[this.level - 1] ?? 0;
|
|
50
49
|
this.upgradeTime = rawUnit.upgrade.time[this.level - 1] ?? 0;
|
|
51
50
|
this.dps = rawUnit.dps[this.level - 1];
|
|
52
|
-
this.resourceType = rawUnit.resourceType;
|
|
53
51
|
this.trainingTime = rawUnit.trainingTime;
|
|
54
52
|
if (rawUnit.category === 'hero')
|
|
55
53
|
this.regenerationTime = rawUnit.regenerationTimes[this.level - 1];
|
package/dist/struct/index.d.ts
CHANGED
package/dist/struct/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -29,3 +33,5 @@ __exportStar(require("./Ranking"), exports);
|
|
|
29
33
|
__exportStar(require("./Season"), exports);
|
|
30
34
|
__exportStar(require("./Unit"), exports);
|
|
31
35
|
__exportStar(require("./WarLeague"), exports);
|
|
36
|
+
__exportStar(require("./ClanCapital"), exports);
|
|
37
|
+
__exportStar(require("./CapitalRaidSeason"), exports);
|
package/dist/types/api.d.ts
CHANGED
|
@@ -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;
|
|
@@ -169,6 +179,64 @@ export interface APIClanWarLeagueClanMember {
|
|
|
169
179
|
export interface APIClanWarLeagueRound {
|
|
170
180
|
warTags: string[];
|
|
171
181
|
}
|
|
182
|
+
export interface APICapitalRaidSeason {
|
|
183
|
+
state: 'ongoing' | 'ended';
|
|
184
|
+
startTime: string;
|
|
185
|
+
endTime: string;
|
|
186
|
+
capitalTotalLoot: number;
|
|
187
|
+
raidsCompleted: number;
|
|
188
|
+
totalAttacks: number;
|
|
189
|
+
enemyDistrictsDestroyed: number;
|
|
190
|
+
offensiveReward: number;
|
|
191
|
+
defensiveReward: number;
|
|
192
|
+
members?: APICapitalRaidSeasonMember[];
|
|
193
|
+
attackLog: APICapitalRaidSeasonAttackLog[];
|
|
194
|
+
defenseLog: APICapitalRaidSeasonDefenseLog[];
|
|
195
|
+
}
|
|
196
|
+
export interface APICapitalRaidSeasonMember {
|
|
197
|
+
tag: string;
|
|
198
|
+
name: string;
|
|
199
|
+
attacks: number;
|
|
200
|
+
attackLimit: number;
|
|
201
|
+
bonusAttackLimit: number;
|
|
202
|
+
capitalResourcesLooted: number;
|
|
203
|
+
}
|
|
204
|
+
export interface APICapitalRaidSeasonClan {
|
|
205
|
+
tag: string;
|
|
206
|
+
name: string;
|
|
207
|
+
level: number;
|
|
208
|
+
badgeUrls: {
|
|
209
|
+
small: string;
|
|
210
|
+
large: string;
|
|
211
|
+
medium: string;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export interface APICapitalRaidSeasonDistrict {
|
|
215
|
+
id: number;
|
|
216
|
+
name: string;
|
|
217
|
+
districtHallLevel: number;
|
|
218
|
+
destructionPercent: number;
|
|
219
|
+
attackCount: number;
|
|
220
|
+
totalLooted: number;
|
|
221
|
+
}
|
|
222
|
+
export interface APICapitalRaidSeasonAttackLog {
|
|
223
|
+
defender: APICapitalRaidSeasonClan;
|
|
224
|
+
attackCount: number;
|
|
225
|
+
districtCount: number;
|
|
226
|
+
districtsDestroyed: number;
|
|
227
|
+
districts: APICapitalRaidSeasonDistrict[];
|
|
228
|
+
}
|
|
229
|
+
export interface APICapitalRaidSeasonDefenseLog {
|
|
230
|
+
attacker: APICapitalRaidSeasonClan;
|
|
231
|
+
attackCount: number;
|
|
232
|
+
districtCount: number;
|
|
233
|
+
districtsDestroyed: number;
|
|
234
|
+
districts: APICapitalRaidSeasonDistrict[];
|
|
235
|
+
}
|
|
236
|
+
export interface APICapitalRaidSeasons {
|
|
237
|
+
items: APICapitalRaidSeason[];
|
|
238
|
+
paging: APIPaging;
|
|
239
|
+
}
|
|
172
240
|
/** /players/{playerTag} */
|
|
173
241
|
export interface APIPlayer {
|
|
174
242
|
name: string;
|
|
@@ -199,6 +267,7 @@ export interface APIPlayer {
|
|
|
199
267
|
heroes: APIPlayerItem[];
|
|
200
268
|
spells: APIPlayerItem[];
|
|
201
269
|
labels: APILabel[];
|
|
270
|
+
playerHouse?: APIPlayerHouse;
|
|
202
271
|
}
|
|
203
272
|
export interface APILegendStatistics {
|
|
204
273
|
previousSeason?: APISeason;
|
|
@@ -313,6 +382,22 @@ export interface APIPlayerVersusRanking {
|
|
|
313
382
|
previousRank: number;
|
|
314
383
|
clan?: APIPlayerClan;
|
|
315
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
|
+
}
|
|
316
401
|
/** /leagues */
|
|
317
402
|
export interface APILeagueList {
|
|
318
403
|
items: APILeague[];
|
|
@@ -346,6 +431,14 @@ export interface APIWarLeague {
|
|
|
346
431
|
id: number;
|
|
347
432
|
name: string;
|
|
348
433
|
}
|
|
434
|
+
export interface APICapitalLeague {
|
|
435
|
+
id: number;
|
|
436
|
+
name: string;
|
|
437
|
+
}
|
|
438
|
+
export interface APICapitalLeagueList {
|
|
439
|
+
items: APICapitalLeague[];
|
|
440
|
+
paging: APIPaging;
|
|
441
|
+
}
|
|
349
442
|
export interface APILabel {
|
|
350
443
|
id: number;
|
|
351
444
|
name: string;
|