clashofclans.js 2.0.1-dev.ba82327 → 2.0.2-dev.ff41115

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,6 +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
+ ## 2.0.2 (2021-11-30)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Return `null` for `RankedPlayer.clan` if they are not in the clan. ([#73](https://github.com/clashperk/clashofclans.js/pull/73)) ([ba82327](https://github.com/clashperk/clashofclans.js/commit/ba8232740f4ca9af2bcc7971aca3574612ef25b6))
10
+ - `OverrideOptions` added for `Client#getClans` and `RESTManager#getClans` ([#73](https://github.com/clashperk/clashofclans.js/pull/73)) ([ba82327](https://github.com/clashperk/clashofclans.js/commit/ba8232740f4ca9af2bcc7971aca3574612ef25b6))
11
+ - `SeasonRankedPlayer` class for legend league ranking. ([#73](https://github.com/clashperk/clashofclans.js/pull/73)) ([ba82327](https://github.com/clashperk/clashofclans.js/commit/ba8232740f4ca9af2bcc7971aca3574612ef25b6))
12
+
5
13
  ## 2.0.1 (2021-11-27)
6
14
 
7
15
  ### Bug Fixes
@@ -21,4 +29,3 @@ This new version is a complete TypeScript rewrite to convert everything from pla
21
29
  - Override Request Options ([#36](https://github.com/clashperk/clashofclans.js/issues/36)) ([42d7fdd](https://github.com/clashperk/clashofclans.js/commit/42d7fdd36262cc46f23b731f8cffb9daea19d3b0))
22
30
  - Internal Caching Options ([#53](https://github.com/clashperk/clashofclans.js/issues/53)) ([984451d](https://github.com/clashperk/clashofclans.js/commit/30ea3240c11866008d0dae514468c0fdbb34ffd0))
23
31
  - Additional Properties for Player Units ([#65](https://github.com/clashperk/clashofclans.js/pull/65)) ([aa1696](https://github.com/clashperk/clashofclans.js/commit/aa1696243d96d4fed0250b4282c60522a6482343))
24
-
@@ -34,14 +34,14 @@ class EventManager {
34
34
  /** Add clan tags to clan events. */
35
35
  addClans(tags) {
36
36
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
37
- this._clanTags.add(this.client.util.parseTag(tag));
37
+ this._clanTags.add(this.client.util.formatTag(tag));
38
38
  }
39
39
  return this;
40
40
  }
41
41
  /** Delete clan tags from clan events. */
42
42
  deleteClans(tags) {
43
43
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
44
- const key = this.client.util.parseTag(tag);
44
+ const key = this.client.util.formatTag(tag);
45
45
  this._clans.delete(key);
46
46
  this._clanTags.delete(key);
47
47
  }
@@ -50,14 +50,14 @@ class EventManager {
50
50
  /** Add player tags for player events. */
51
51
  addPlayers(tags) {
52
52
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
53
- this._playerTags.add(this.client.util.parseTag(tag));
53
+ this._playerTags.add(this.client.util.formatTag(tag));
54
54
  }
55
55
  return this;
56
56
  }
57
57
  /** Delete player tags from player events. */
58
58
  deletePlayers(tags) {
59
59
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
60
- const key = this.client.util.parseTag(tag);
60
+ const key = this.client.util.formatTag(tag);
61
61
  this._players.delete(key);
62
62
  this._playerTags.delete(key);
63
63
  }
@@ -66,14 +66,14 @@ class EventManager {
66
66
  /** Add clan tags for war events. */
67
67
  addWars(tags) {
68
68
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
69
- this._warTags.add(this.client.util.parseTag(tag));
69
+ this._warTags.add(this.client.util.formatTag(tag));
70
70
  }
71
71
  return this;
72
72
  }
73
73
  /** Delete clan tags from war events. */
74
74
  deleteWars(tags) {
75
75
  for (const tag of Array.isArray(tags) ? tags : [tags]) {
76
- const key = this.client.util.parseTag(tag);
76
+ const key = this.client.util.formatTag(tag);
77
77
  this._wars.delete(`${key}:${1}`);
78
78
  this._wars.delete(`${key}:${2}`);
79
79
  this._warTags.delete(key);
@@ -134,13 +134,13 @@ class ClanWar {
134
134
  // @ts-expect-error
135
135
  this.state = data.state;
136
136
  this.teamSize = data.teamSize;
137
- this.attacksPerMember = data.attacksPerMember;
138
- this.preparationStartTime = client.util.parseDate(data.preparationStartTime);
139
- this.startTime = client.util.parseDate(data.startTime);
140
- this.endTime = client.util.parseDate(data.endTime);
137
+ this.attacksPerMember = data.attacksPerMember ?? extra.warTag ? 1 : 2;
138
+ this.preparationStartTime = client.util.formatDate(data.preparationStartTime);
139
+ this.startTime = client.util.formatDate(data.startTime);
140
+ this.endTime = client.util.formatDate(data.endTime);
141
141
  this.warTag = extra.warTag ?? null;
142
142
  let [clan, opponent] = [data.clan, data.opponent];
143
- const clanTag = extra.clanTag && client.util.parseTag(extra.clanTag);
143
+ const clanTag = extra.clanTag && client.util.formatTag(extra.clanTag);
144
144
  if (clanTag && [data.clan.tag, data.opponent.tag].includes(clanTag)) {
145
145
  clan = data.clan.tag === clanTag ? data.clan : data.opponent;
146
146
  opponent = data.clan.tag === clan.tag ? data.opponent : data.clan;
@@ -28,7 +28,7 @@ class ClanWarLog {
28
28
  constructor(client, data) {
29
29
  this.client = client;
30
30
  this.result = data.result ?? null;
31
- this.endTime = Util_1.Util.parseDate(data.endTime);
31
+ this.endTime = Util_1.Util.formatDate(data.endTime);
32
32
  this.teamSize = data.teamSize;
33
33
  this.attacksPerMember = data.attacksPerMember ?? null;
34
34
  this.clan = new WarLogClan(data.clan);
@@ -14,8 +14,8 @@ exports.Season = Season;
14
14
  /** Represents a gold pass season. */
15
15
  class GoldPassSeason {
16
16
  constructor(data) {
17
- this.startTime = Util_1.Util.parseDate(data.startTime);
18
- this.endTime = Util_1.Util.parseDate(data.endTime);
17
+ this.startTime = Util_1.Util.formatDate(data.startTime);
18
+ this.endTime = Util_1.Util.formatDate(data.endTime);
19
19
  }
20
20
  }
21
21
  exports.GoldPassSeason = GoldPassSeason;
@@ -84,7 +84,8 @@ export interface APIClanWar {
84
84
  endTime: string;
85
85
  clan: APIWarClan;
86
86
  opponent: APIWarClan;
87
- attacksPerMember: number;
87
+ /** This property is not available for CWL */
88
+ attacksPerMember?: number;
88
89
  }
89
90
  export interface APIWarClan {
90
91
  tag: string;
@@ -1,17 +1,39 @@
1
1
  /** Contains various general-purpose utility methods. */
2
2
  export declare class Util extends null {
3
- /** Encode a game tag. */
4
- static encodeTag(tag: string): string;
5
- /** Parse a game tag. */
3
+ /**
4
+ * Corrects malformed tags to match how they are formatted.
5
+ * ```ts
6
+ * Util.formatTag("PccVqqGO"); // #PCCVQQG0
7
+ * ```
8
+ */
9
+ static formatTag(tag: string): string;
10
+ /** @internal */
6
11
  static parseTag(tag: string): string;
7
- /** Parse API Date to JavaScript Date. */
8
- static parseDate(time: string): Date;
9
- /** Get URL search params. */
12
+ /** Encodes a tag as a valid component of a URI. */
13
+ static encodeTag(tag: string): string;
14
+ static isValidTag(tag: string): boolean;
15
+ /**
16
+ * Encode tag string into 64bit unsigned integer string.
17
+ * ```ts
18
+ * Util.encodeTagToId('#PCCVQQG0'); // '510915076'
19
+ * ```
20
+ */
21
+ static encodeTagToId(tag: string): string;
22
+ /**
23
+ * Decode 64bit unsigned integer string into tag string with hash.
24
+ * ```ts
25
+ * Util.decodeTagToId('510915076'); // '#PCCVQQG0'
26
+ * ```
27
+ */
28
+ static decodeIdToTag(id: string): string;
29
+ /** Converts API Date to JavaScript Date. */
30
+ static formatDate(date: string): Date;
31
+ /** Returns a string containing a query string suitable for use in a URL. */
10
32
  static queryString(options?: {}): string;
11
33
  private static getSeasonEnd;
12
34
  /** Get current trophy season Id. */
13
35
  static getSeasonId(): string;
14
- /** Get current trophy season end time. */
36
+ /** Get current trophy season end date. */
15
37
  static getSeasonEndTime(date?: Date): Date;
16
38
  static allSettled<T>(values: Promise<T>[]): Promise<T[]>;
17
39
  static delay(ms: number): Promise<unknown>;
package/dist/util/Util.js CHANGED
@@ -1,21 +1,65 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Util = void 0;
4
+ const TAG_CHARACTERS = '0289PYLQGRJCUV';
4
5
  /** Contains various general-purpose utility methods. */
5
6
  class Util extends null {
6
- /** Encode a game tag. */
7
- static encodeTag(tag) {
8
- return encodeURIComponent(this.parseTag(tag));
7
+ /**
8
+ * Corrects malformed tags to match how they are formatted.
9
+ * ```ts
10
+ * Util.formatTag("PccVqqGO"); // #PCCVQQG0
11
+ * ```
12
+ */
13
+ static formatTag(tag) {
14
+ return this.parseTag(tag);
9
15
  }
10
- /** Parse a game tag. */
16
+ /** @internal */
11
17
  static parseTag(tag) {
12
- return `#${tag.toUpperCase().replace(/O/g, '0').replace(/^#/g, '')}`;
18
+ return `#${tag.toUpperCase().replace(/O/g, '0').replace(/^#/g, '').replace(/\s/g, '')}`;
19
+ }
20
+ /** Encodes a tag as a valid component of a URI. */
21
+ static encodeTag(tag) {
22
+ return encodeURIComponent(this.formatTag(tag));
23
+ }
24
+ static isValidTag(tag) {
25
+ return /^#?[0289PYLQGRJCUV]{3,}$/.test(tag);
26
+ }
27
+ /**
28
+ * Encode tag string into 64bit unsigned integer string.
29
+ * ```ts
30
+ * Util.encodeTagToId('#PCCVQQG0'); // '510915076'
31
+ * ```
32
+ */
33
+ static encodeTagToId(tag) {
34
+ const formatted = this.formatTag(tag).substring(1);
35
+ if (!this.isValidTag(formatted)) {
36
+ throw new Error(`Failed to encode tag ${formatted}. RegExp matching failed.`);
37
+ }
38
+ const result = formatted.split('').reduce((sum, char) => sum * 14n + BigInt(TAG_CHARACTERS.indexOf(char)), 0n);
39
+ return result.toString();
40
+ }
41
+ /**
42
+ * Decode 64bit unsigned integer string into tag string with hash.
43
+ * ```ts
44
+ * Util.decodeTagToId('510915076'); // '#PCCVQQG0'
45
+ * ```
46
+ */
47
+ static decodeIdToTag(id) {
48
+ let [bigint, tag] = [BigInt(id), ''];
49
+ while (bigint !== 0n) {
50
+ const index = Number(bigint % 14n);
51
+ tag = TAG_CHARACTERS[index] + tag;
52
+ bigint /= 14n;
53
+ }
54
+ return `#${tag}`;
13
55
  }
14
- /** Parse API Date to JavaScript Date. */
15
- static parseDate(time) {
16
- return new Date(`${time.slice(0, 4)}-${time.slice(4, 6)}-${time.slice(6, 8)}T${time.slice(9, 11)}:${time.slice(11, 13)}:${time.slice(13)}`);
56
+ /** Converts API Date to JavaScript Date. */
57
+ static formatDate(date) {
58
+ const YYYY_MM_DD = `${date.slice(0, 4)}-${date.slice(4, 6)}-${date.slice(6, 8)}`;
59
+ const HH_MM_SS = `${date.slice(9, 11)}:${date.slice(11, 13)}:${date.slice(13)}`;
60
+ return new Date(`${YYYY_MM_DD}T${HH_MM_SS}`);
17
61
  }
18
- /** Get URL search params. */
62
+ /** Returns a string containing a query string suitable for use in a URL. */
19
63
  static queryString(options = {}) {
20
64
  const query = new URLSearchParams(options);
21
65
  for (const key of ['cache', 'force', 'retryLimit', 'ignoreRateLimit', 'restRequestTimeout'])
@@ -37,7 +81,7 @@ class Util extends null {
37
81
  static getSeasonId() {
38
82
  return this.getSeasonEndTime().toISOString().substring(0, 7);
39
83
  }
40
- /** Get current trophy season end time. */
84
+ /** Get current trophy season end date. */
41
85
  static getSeasonEndTime(date = new Date()) {
42
86
  return this.getSeasonEnd(date.getUTCMonth() + 1);
43
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "2.0.1-dev.ba82327",
3
+ "version": "2.0.2-dev.ff41115",
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",
@@ -12,6 +12,9 @@
12
12
  "test": "eslint --ext .ts --ignore-path .gitignore .",
13
13
  "lint": "eslint --fix --ext .ts --ignore-path .gitignore ."
14
14
  },
15
+ "files": [
16
+ "dist"
17
+ ],
15
18
  "repository": {
16
19
  "type": "git",
17
20
  "url": "https://github.com/clashperk/clashofclans.js.git"