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 +0 -1
- package/dist/rest/RequestHandler.d.ts +0 -2
- package/dist/rest/RequestHandler.js +60 -39
- package/dist/util/Util.d.ts +0 -1
- package/dist/util/Util.js +1 -16
- package/package.json +4 -5
package/dist/index.mjs
CHANGED
|
@@ -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
|
|
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
|
|
71
|
-
|
|
93
|
+
const res = await (0, node_fetch_1.default)(`${this.baseURL}${path}`, {
|
|
94
|
+
agent,
|
|
72
95
|
body: options.body,
|
|
73
|
-
method:
|
|
74
|
-
|
|
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.
|
|
100
|
+
if (res.status === 504 && retries < (options.retryLimit ?? this.retryLimit)) {
|
|
78
101
|
return await this.exec(path, options, ++retries);
|
|
79
102
|
}
|
|
80
|
-
const data =
|
|
103
|
+
const data = await res.json();
|
|
81
104
|
if (this.creds &&
|
|
82
|
-
res.
|
|
83
|
-
data
|
|
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
|
|
90
|
-
if (res.
|
|
91
|
-
throw new HTTPError_1.HTTPError(HTTPError_1.PrivateWarLogError, res.
|
|
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.
|
|
94
|
-
throw new HTTPError_1.HTTPError(data, res.
|
|
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.
|
|
97
|
-
await this.cached.set(path, { data, ttl: Date.now() + maxAge, status: res.
|
|
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
|
|
122
|
+
return { data, maxAge, status: res.status, path, ok: res.status === 200 };
|
|
100
123
|
}
|
|
101
124
|
catch (error) {
|
|
102
|
-
if (error.
|
|
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,
|
|
146
|
+
const res = await (0, node_fetch_1.default)(`${this.baseURL}/locations?limit=1`, {
|
|
124
147
|
method: 'GET',
|
|
125
|
-
|
|
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,
|
|
159
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/login`, {
|
|
137
160
|
method: 'POST',
|
|
138
|
-
|
|
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 =
|
|
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,
|
|
174
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/list`, {
|
|
152
175
|
method: 'POST',
|
|
153
|
-
|
|
176
|
+
timeout: this.restRequestTimeout,
|
|
154
177
|
headers: { 'Content-Type': 'application/json', cookie }
|
|
155
178
|
});
|
|
156
|
-
const data =
|
|
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,
|
|
216
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/revoke`, {
|
|
194
217
|
method: 'POST',
|
|
195
|
-
|
|
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,
|
|
225
|
+
const res = await (0, node_fetch_1.default)(`${Constants_1.DevSiteAPIBaseURL}/apikey/create`, {
|
|
203
226
|
method: 'POST',
|
|
204
|
-
|
|
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 =
|
|
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,
|
|
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
|
}
|
package/dist/util/Util.d.ts
CHANGED
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 =
|
|
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.
|
|
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"
|