clashofclans.js 3.1.0-internal.ed47e2a → 3.1.1-dev.17c5c72

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/dist/index.mjs CHANGED
@@ -65,4 +65,3 @@ export const Util = mod.Util;
65
65
  export const WarClan = mod.WarClan;
66
66
  export const WarLeagues = mod.WarLeagues;
67
67
  export const WarLogClan = mod.WarLogClan;
68
- export const timeoutSignal = mod.timeoutSignal;
@@ -27,7 +27,6 @@ export interface RequestHandler {
27
27
  */
28
28
  rateLimited: string;
29
29
  }
30
- export declare type ResponseBody = any;
31
30
  /** Represents the class that manages handlers for endpoints. */
32
31
  export declare class RequestHandler extends EventEmitter {
33
32
  #private;
@@ -43,7 +42,6 @@ export declare class RequestHandler extends EventEmitter {
43
42
  private readonly restRequestTimeout;
44
43
  private readonly throttler?;
45
44
  private readonly cached;
46
- private readonly dispatcher;
47
45
  constructor(options?: RequestHandlerOptions);
48
46
  private get _keys();
49
47
  private get _key();
@@ -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");
@@ -10,16 +33,20 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
10
33
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
34
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
35
  };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
13
39
  var _RequestHandler_keyIndex;
14
40
  Object.defineProperty(exports, "__esModule", { value: true });
15
41
  exports.RequestHandler = void 0;
42
+ const node_https_1 = __importDefault(require("node:https"));
16
43
  const node_events_1 = require("node:events");
17
- const undici_1 = require("undici");
44
+ const node_fetch_1 = __importStar(require("node-fetch"));
18
45
  const Constants_1 = require("../util/Constants");
19
46
  const Store_1 = require("../util/Store");
20
- const Util_1 = require("../util/Util");
21
47
  const HTTPError_1 = require("./HTTPError");
22
48
  const IP_REGEX = /\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/g;
49
+ const agent = new node_https_1.default.Agent({ keepAlive: true });
23
50
  /** Represents the class that manages handlers for endpoints. */
24
51
  class RequestHandler extends node_events_1.EventEmitter {
25
52
  constructor(options) {
@@ -35,10 +62,6 @@ class RequestHandler extends node_events_1.EventEmitter {
35
62
  this.cached = options.cache;
36
63
  else
37
64
  this.cached = options?.cache === true ? new Store_1.CacheStore() : null;
38
- this.dispatcher = new undici_1.Pool(new URL(this.baseURL).origin, {
39
- connections: 50,
40
- pipelining: 10
41
- });
42
65
  }
43
66
  get _keys() {
44
67
  return Array.isArray(this.keys) ? this.keys : [this.keys];
@@ -67,39 +90,39 @@ class RequestHandler extends node_events_1.EventEmitter {
67
90
  }
68
91
  async exec(path, options = {}, retries = 0) {
69
92
  try {
70
- const res = await this.dispatcher.request({
71
- path: `/v1${path}`,
93
+ const res = await (0, node_fetch_1.default)(`${this.baseURL}${path}`, {
94
+ agent,
72
95
  body: options.body,
73
- method: 'GET',
74
- signal: (0, Util_1.timeoutSignal)(options.restRequestTimeout ?? this.restRequestTimeout),
96
+ method: options.method,
97
+ timeout: options.restRequestTimeout ?? this.restRequestTimeout,
75
98
  headers: { 'Authorization': `Bearer ${this._key}`, 'Content-Type': 'application/json' }
76
99
  });
77
- if (res.statusCode === 504 && retries < (options.retryLimit ?? this.retryLimit)) {
100
+ if (res.status === 504 && retries < (options.retryLimit ?? this.retryLimit)) {
78
101
  return await this.exec(path, options, ++retries);
79
102
  }
80
- const data = (await res.body.json());
103
+ const data = await res.json();
81
104
  if (this.creds &&
82
- res.statusCode === 403 &&
83
- data?.reason === 'accessDenied.invalidIp' &&
105
+ res.status === 403 &&
106
+ data.reason === 'accessDenied.invalidIp' &&
84
107
  retries < (options.retryLimit ?? this.retryLimit)) {
85
108
  const keys = await this.reValidateKeys().then(() => () => this.login());
86
109
  if (keys.length)
87
110
  return await this.exec(path, options, ++retries);
88
111
  }
89
- const maxAge = Number(res.headers['cache-control']?.split('=')?.[1] ?? 0) * 1000;
90
- if (res.statusCode === 403 && !data?.message && this.rejectIfNotValid) {
91
- throw new HTTPError_1.HTTPError(HTTPError_1.PrivateWarLogError, res.statusCode, path, maxAge);
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);
92
115
  }
93
- if (res.statusCode !== 200 && this.rejectIfNotValid) {
94
- throw new HTTPError_1.HTTPError(data, res.statusCode, path, maxAge, options.method);
116
+ if (!res.ok && this.rejectIfNotValid) {
117
+ throw new HTTPError_1.HTTPError(data, res.status, path, maxAge, options.method);
95
118
  }
96
- if (this.cached && maxAge > 0 && options.cache !== false && res.statusCode === 200) {
97
- await this.cached.set(path, { data, ttl: Date.now() + maxAge, status: res.statusCode }, maxAge);
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);
98
121
  }
99
- return { data: data, maxAge, status: res.statusCode, path, ok: res.statusCode === 200 };
122
+ return { data, maxAge, status: res.status, path, ok: res.status === 200 };
100
123
  }
101
124
  catch (error) {
102
- if (error.code === 'UND_ERR_ABORTED' && retries < (options.retryLimit ?? this.retryLimit)) {
125
+ if (error instanceof node_fetch_1.FetchError && error.type === 'request-timeout' && retries < (options.retryLimit ?? this.retryLimit)) {
103
126
  return this.exec(path, options, ++retries);
104
127
  }
105
128
  if (this.rejectIfNotValid)
@@ -120,9 +143,9 @@ class RequestHandler extends node_events_1.EventEmitter {
120
143
  }
121
144
  async reValidateKeys() {
122
145
  for (const key of this.keys) {
123
- const res = await (0, undici_1.fetch)(`${this.baseURL}/locations?limit=1`, {
146
+ const res = await (0, node_fetch_1.default)(`${this.baseURL}/locations?limit=1`, {
124
147
  method: 'GET',
125
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout),
148
+ timeout: this.restRequestTimeout,
126
149
  headers: { 'Authorization': `Bearer ${key}`, 'Content-Type': 'application/json' }
127
150
  }).catch(() => null);
128
151
  if (res?.status === 403) {
@@ -133,13 +156,13 @@ class RequestHandler extends node_events_1.EventEmitter {
133
156
  }
134
157
  }
135
158
  async login() {
136
- const res = await (0, undici_1.fetch)(`${Constants_1.DevSiteAPIBaseURL}/login`, {
159
+ const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/login`, {
137
160
  method: 'POST',
138
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout),
161
+ timeout: this.restRequestTimeout,
139
162
  headers: { 'Content-Type': 'application/json' },
140
163
  body: JSON.stringify({ email: this.email, password: this.password })
141
164
  });
142
- const data = (await res.json());
165
+ const data = await res.json();
143
166
  if (!res.ok)
144
167
  throw new Error(`Invalid email or password. ${JSON.stringify(data)}`);
145
168
  const ip = await this.getIp(data.temporaryAPIToken);
@@ -148,12 +171,12 @@ class RequestHandler extends node_events_1.EventEmitter {
148
171
  return this.getKeys(res.headers.get('set-cookie'), ip);
149
172
  }
150
173
  async getKeys(cookie, ip) {
151
- const res = await (0, undici_1.fetch)(`${Constants_1.DevSiteAPIBaseURL}/apikey/list`, {
174
+ const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/list`, {
152
175
  method: 'POST',
153
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout),
176
+ timeout: this.restRequestTimeout,
154
177
  headers: { 'Content-Type': 'application/json', cookie }
155
178
  });
156
- const data = (await res.json());
179
+ const data = await res.json();
157
180
  if (!res.ok)
158
181
  throw new Error(`Failed to retrieve the API Keys. ${JSON.stringify(data)}`);
159
182
  // Get all available keys from the developer site.
@@ -190,18 +213,18 @@ class RequestHandler extends node_events_1.EventEmitter {
190
213
  return this.keys;
191
214
  }
192
215
  async revokeKey(keyId, cookie) {
193
- const res = await (0, undici_1.fetch)(`${Constants_1.DevSiteAPIBaseURL}/apikey/revoke`, {
216
+ const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/revoke`, {
194
217
  method: 'POST',
195
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout),
218
+ timeout: this.restRequestTimeout,
196
219
  body: JSON.stringify({ id: keyId }),
197
220
  headers: { 'Content-Type': 'application/json', cookie }
198
221
  });
199
222
  return res.ok;
200
223
  }
201
224
  async createKey(cookie, ip) {
202
- const res = await (0, undici_1.fetch)(`${Constants_1.DevSiteAPIBaseURL}/apikey/create`, {
225
+ const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/create`, {
203
226
  method: 'POST',
204
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout),
227
+ timeout: this.restRequestTimeout,
205
228
  headers: { 'Content-Type': 'application/json', cookie },
206
229
  body: JSON.stringify({
207
230
  cidrRanges: [ip],
@@ -209,7 +232,7 @@ class RequestHandler extends node_events_1.EventEmitter {
209
232
  description: this.keyDescription ?? new Date().toUTCString()
210
233
  })
211
234
  });
212
- const data = (await res.json());
235
+ const data = await res.json();
213
236
  if (!res.ok)
214
237
  throw new Error(`Failed to create API Key. ${JSON.stringify(data)}`);
215
238
  return data.key;
@@ -221,9 +244,7 @@ class RequestHandler extends node_events_1.EventEmitter {
221
244
  return props.cidrs[0].match(IP_REGEX)[0];
222
245
  }
223
246
  catch {
224
- const body = await (0, undici_1.fetch)('https://api.ipify.org', {
225
- signal: (0, Util_1.timeoutSignal)(this.restRequestTimeout)
226
- }).then((res) => res.text());
247
+ const body = await (0, node_fetch_1.default)('https://api.ipify.org', { timeout: this.restRequestTimeout }).then((res) => res.text());
227
248
  return body.match(IP_REGEX)?.[0] ?? null;
228
249
  }
229
250
  }
@@ -1,5 +1,4 @@
1
1
  import { ClanSearchOptions, SearchOptions } from '../types';
2
- export declare function timeoutSignal(timeout: number): AbortSignal;
3
2
  /** Contains various general-purpose utility methods. */
4
3
  export declare class Util extends null {
5
4
  /**
package/dist/util/Util.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Util = exports.timeoutSignal = void 0;
3
+ exports.Util = void 0;
4
4
  const Constants_1 = require("../util/Constants");
5
5
  const TAG_CHARACTERS = '0289PYLQGRJCUV';
6
6
  const params = [
@@ -16,21 +16,6 @@ const params = [
16
16
  'after',
17
17
  'before'
18
18
  ];
19
- function timeoutSignal(timeout) {
20
- if (!Number.isInteger(timeout)) {
21
- throw new TypeError('Expected an integer for the timeout');
22
- }
23
- const controller = new AbortController();
24
- if (timeout > 0) {
25
- const timeoutId = setTimeout(() => {
26
- controller.abort();
27
- }, timeout);
28
- // Allow Node.js processes to exit early if only the timeout is running
29
- timeoutId.unref();
30
- }
31
- return controller.signal;
32
- }
33
- exports.timeoutSignal = timeoutSignal;
34
19
  /** Contains various general-purpose utility methods. */
35
20
  class Util extends null {
36
21
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "3.1.0-internal.ed47e2a",
3
+ "version": "3.1.1-dev.17c5c72",
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",
@@ -42,12 +42,12 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "node-fetch": "^2.6.7",
46
- "undici": "^5.23.0"
45
+ "node-fetch": "^2.6.7"
47
46
  },
48
47
  "devDependencies": {
49
- "@types/node": "^18.6.4",
50
48
  "@types/node-fetch": "^2.5.12",
49
+ "gen-esm-wrapper": "^1.1.3",
50
+ "@types/node": "^18.6.4",
51
51
  "@typescript-eslint/eslint-plugin": "^5.4.0",
52
52
  "@typescript-eslint/parser": "^5.4.0",
53
53
  "dotenv": "^16.0.2",
@@ -56,7 +56,6 @@
56
56
  "eslint-config-prettier": "^8.3.0",
57
57
  "eslint-plugin-import": "^2.26.0",
58
58
  "eslint-plugin-prettier": "^4.0.0",
59
- "gen-esm-wrapper": "^1.1.3",
60
59
  "prettier": "^2.4.1",
61
60
  "rimraf": "^3.0.2",
62
61
  "typescript": "^4.7.4"