proxy-rotator-js 1.1.1 → 1.3.1

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.
Files changed (66) hide show
  1. package/README.md +87 -23
  2. package/assets/GeoLite2-Country.mmdb +0 -0
  3. package/dist/cjs/index.cjs +12 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/{src/Proxy.js → dist/cjs/src/Proxy.cjs} +28 -32
  6. package/dist/cjs/src/Proxy.cjs.map +1 -0
  7. package/dist/cjs/src/ProxyRotator.cjs +323 -0
  8. package/dist/cjs/src/ProxyRotator.cjs.map +1 -0
  9. package/dist/cjs/src/Queue.cjs +64 -0
  10. package/dist/cjs/src/Queue.cjs.map +1 -0
  11. package/dist/cjs/src/utils/geo.cjs +31 -0
  12. package/dist/cjs/src/utils/geo.cjs.map +1 -0
  13. package/dist/cjs/src/utils/makeRequestWithProxy.cjs +26 -0
  14. package/dist/cjs/src/utils/makeRequestWithProxy.cjs.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +5 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/src/Proxy.d.ts +44 -0
  20. package/dist/src/Proxy.d.ts.map +1 -0
  21. package/dist/src/Proxy.js +100 -0
  22. package/dist/src/Proxy.js.map +1 -0
  23. package/dist/src/ProxyRotator.d.ts +104 -0
  24. package/dist/src/ProxyRotator.d.ts.map +1 -0
  25. package/dist/src/ProxyRotator.js +317 -0
  26. package/dist/src/ProxyRotator.js.map +1 -0
  27. package/dist/src/Queue.d.ts +16 -0
  28. package/dist/src/Queue.d.ts.map +1 -0
  29. package/dist/src/Queue.js +61 -0
  30. package/dist/src/Queue.js.map +1 -0
  31. package/dist/src/utils/geo.d.ts +7 -0
  32. package/dist/src/utils/geo.d.ts.map +1 -0
  33. package/dist/src/utils/geo.js +25 -0
  34. package/dist/src/utils/geo.js.map +1 -0
  35. package/dist/src/utils/makeRequestWithProxy.d.ts +13 -0
  36. package/dist/src/utils/makeRequestWithProxy.d.ts.map +1 -0
  37. package/dist/src/utils/makeRequestWithProxy.js +20 -0
  38. package/dist/src/utils/makeRequestWithProxy.js.map +1 -0
  39. package/dist/test/status.d.ts +2 -0
  40. package/dist/test/status.d.ts.map +1 -0
  41. package/dist/test/status.js +103 -0
  42. package/dist/test/status.js.map +1 -0
  43. package/dist/test/status_and_test_output.d.ts +2 -0
  44. package/dist/test/status_and_test_output.d.ts.map +1 -0
  45. package/dist/test/status_and_test_output.js +110 -0
  46. package/dist/test/status_and_test_output.js.map +1 -0
  47. package/dist/test/test.d.ts +2 -0
  48. package/dist/test/test.d.ts.map +1 -0
  49. package/dist/test/test.js +122 -0
  50. package/dist/test/test.js.map +1 -0
  51. package/dist/test/test_proxies.d.ts +2 -0
  52. package/dist/test/test_proxies.d.ts.map +1 -0
  53. package/dist/test/test_proxies.js +20 -0
  54. package/dist/test/test_proxies.js.map +1 -0
  55. package/dist/test/test_proxies_output.d.ts +2 -0
  56. package/dist/test/test_proxies_output.d.ts.map +1 -0
  57. package/dist/test/test_proxies_output.js +62 -0
  58. package/dist/test/test_proxies_output.js.map +1 -0
  59. package/package.json +29 -4
  60. package/index.js +0 -2
  61. package/src/ProxyRotator.js +0 -239
  62. package/src/Queue.js +0 -61
  63. package/src/utils/makeRequestWithProxy.js +0 -21
  64. package/test/options.js +0 -32
  65. package/test/test.js +0 -204
  66. package/test/test_proxies.js +0 -22
package/README.md CHANGED
@@ -5,13 +5,23 @@ Proxy Rotator
5
5
 
6
6
  ## Introduction
7
7
 
8
- ProxyRotator is a JavaScript class that provides a mechanism for managing a pool of proxies and rotating them based on their availability and status.
8
+ ProxyRotator is a JavaScript class that provides a mechanism for managing a pool of proxies and rotating them based on their availability and status. It supports country geolocation lookup, pool status reporting, and proxy testing with JSON output for programmatic use.
9
9
 
10
10
  ## Installation
11
11
  ```
12
12
  npm install proxy-rotator-js
13
13
  ```
14
14
 
15
+ ### Geolocation (optional)
16
+
17
+ To enable country lookup for proxies, download the GeoLite2-Country database:
18
+
19
+ ```bash
20
+ npm run download:geo
21
+ ```
22
+
23
+ This places `GeoLite2-Country.mmdb` in the `assets` folder. You can also set `GEO_DB_PATH` to point to a custom database location. For the latest data, sign up at [MaxMind](https://www.maxmind.com/) and set `MAXMIND_LICENSE_KEY` when running the download script.
24
+
15
25
  ## Usage
16
26
 
17
27
  ```javascript
@@ -42,33 +52,44 @@ console.log( rotator.next() ) // 'proxy2'
42
52
  ```
43
53
 
44
54
 
45
- Initializes a new instance of ProxyRotator with the given proxies and options. The proxies parameter can be a file path or an array of proxies. The options parameter allows customization of various settings such as revive timer, shuffling, protocol assumption, and more.
46
- Methods
55
+ Initializes a new instance of ProxyRotator with the given proxies and options. The proxies parameter can be a file path or an array of proxies. The options parameter allows customization of various settings such as revive timer, shuffling, protocol assumption, geolocation, and more.
56
+
57
+ **Note:** `add()` and `add_file()` are async when `fetchGeo` is true. Proxies passed to the constructor are added synchronously without geo; use `refreshGeo()` to look up country for them later.
47
58
 
48
59
  ## Methods
49
60
 
50
61
  ```javascript
51
- next() // Rotates the proxy by moving the front proxy to the end of the pool and returns it.
62
+ next(options?) // Rotates the proxy by moving the front proxy to the end of the pool and returns it.
63
+ // Options: { returnAs: 'string' | 'object' } — when 'object', returns proxy with country info.
64
+
65
+ add(proxies) // Adds one or more proxies to the pool. async — fetches country geolocation when fetchGeo is true.
66
+
67
+ add_file(filename) // Parses a file (newline-, space-, or comma-separated) and adds proxies. async.
52
68
 
53
- add(proxies) // Adds one or more proxies to the pool.
69
+ status() // Returns pool status as JSON: { pool, graveyard, config }.
54
70
 
55
- getAlive() // Retrieves a random alive proxy from the pool.
71
+ refreshGeo() // Fetches country geolocation for all proxies (constructor-added proxies start without geo). async.
56
72
 
57
- setAlive(proxy) // Sets a specific proxy to an alive state.
73
+ test_proxies(options?) // Tests proxies. Options: { output: 'console' | 'json' }.
74
+ // Default 'console' — prints to stdout. Use output: 'json' to get results for programmatic use.
58
75
 
59
- setDead(proxy) // Sets a specific proxy to a dead state and moves it to the graveyard.
76
+ getAlive() // Retrieves an alive proxy from the pool.
60
77
 
61
- resurrect(proxy) // Moves a proxy from the graveyard back to the pool.
78
+ setAlive(proxy) // Sets a specific proxy to an alive state.
62
79
 
63
- getPool() // Returns an array of proxies in the pool.
80
+ setDead(proxy) // Sets a specific proxy to a dead state and moves it to the graveyard.
64
81
 
65
- getPoolSize() // Returns the number of proxies in the pool.
82
+ resurect(proxy) // Moves a proxy from the graveyard back to the pool.
66
83
 
67
- getGraveyard() // Returns an array of proxies in the graveyard (dead proxies).
84
+ getPool() // Returns an array of proxy strings in the pool.
68
85
 
69
- getGraveyardSize() // Returns the number of proxies in the graveyard.
86
+ getPoolSize() // Returns the number of proxies in the pool.
70
87
 
71
- remove(proxy) // Removes one or more proxies from the pool.
88
+ getGraveyard() // Returns an array of proxies in the graveyard (dead proxies).
89
+
90
+ getGraveyardSize() // Returns the number of proxies in the graveyard.
91
+
92
+ remove(proxy) // Removes one or more proxies from the pool.
72
93
  ```
73
94
 
74
95
  ## Properties
@@ -86,7 +107,8 @@ const options = {
86
107
  shuffle: true,
87
108
  protocol: 'http',
88
109
  assume_aliveness: true,
89
- check_on_next: true
110
+ check_on_next: true,
111
+ fetchGeo: true
90
112
  };
91
113
 
92
114
  const proxyRotator = new ProxyRotator(proxies, options);
@@ -98,18 +120,58 @@ const proxyRotator = new ProxyRotator(proxies, options);
98
120
  - protocol: Specifies a protocol for all proxies. Default: null.
99
121
  - shuffle: Specifies whether to shuffle the proxies before adding them to the queue. Default: false.
100
122
  - assume_aliveness: Specifies whether to assume all proxies are alive when first added instead of 'new'. Default: false.
101
- - check_on_next: Specifies whether to check if proxies are alive when they are added to the queue. Default: false.
123
+ - check_on_next: Specifies whether to check for resurrection when calling next(). Default: false.
124
+ - fetchGeo: When true, fetches country geolocation (iso, name, continent) when adding proxies. Requires GeoLite2-Country.mmdb. Default: true.
102
125
 
103
126
  ## Testing your Proxies
104
127
 
105
128
  ```javascript
106
129
  import ProxyRotator from 'proxy-rotator-js'
107
130
 
108
- let proxies = ['proxy1', 'proxy2', 'proxy3']
131
+ const proxies = ['proxy1', 'proxy2', 'proxy3']
132
+ const rotator = new ProxyRotator(proxies)
109
133
 
110
- let rotator = new ProxyRotator(proxies, options={})
134
+ // Print results to console (default)
135
+ await rotator.test_proxies()
136
+ // or rotator.test()
111
137
 
112
- rotator.test()
138
+ // Get results as JSON for programmatic use
139
+ const results = await rotator.test_proxies({ output: 'json' })
140
+ // results = { results: [...], summary: { total, working, notWorking } }
141
+ ```
142
+
143
+ ## Pool Status
144
+
145
+ ```javascript
146
+ const status = rotator.status()
147
+ // Returns: { pool: { size, proxies }, graveyard: { size, proxies }, config: { ... } }
148
+ ```
149
+
150
+ ## Geolocation
151
+
152
+ When `fetchGeo` is true (default), proxies added via `add()` or `add_file()` are enriched with country data. Use `returnAs: 'object'` to get the full proxy object including country:
153
+
154
+ ```javascript
155
+ const rotator = new ProxyRotator(null, { fetchGeo: true })
156
+ await rotator.add(['1.2.3.4:8080'])
157
+ const proxy = rotator.next({ returnAs: 'object' })
158
+ // proxy.country → { iso: 'US', name: 'United States', continent: 'NA' }
159
+ ```
160
+
161
+ Proxies loaded via the constructor (file or array) do not get geo by default. Call `refreshGeo()` to populate country for existing proxies:
162
+
163
+ ```javascript
164
+ const rotator = new ProxyRotator(['1.2.3.4:8080'])
165
+ await rotator.refreshGeo()
166
+ const proxy = rotator.next({ returnAs: 'object' })
167
+ // proxy.country now populated
168
+ ```
169
+
170
+ To skip geolocation (e.g. when the database is not available), set `fetchGeo: false`:
171
+
172
+ ```javascript
173
+ const rotator = new ProxyRotator(null, { fetchGeo: false })
174
+ await rotator.add('1.2.3.4:8080')
113
175
  ```
114
176
 
115
177
  ## Getting Started
@@ -165,8 +227,8 @@ console.log(proxyRotator.getGraveyardSize()); // Output: 0
165
227
  console.log(proxyRotator.getPool()); // Output: ['proxy1', 'proxy2', 'proxy3']
166
228
  console.log(proxyRotator.getPoolSize()); // Output: 3
167
229
 
168
- // Call the methods
169
- proxyRotator.add('proxy4');
230
+ // Call the methods (add is async when fetchGeo is true)
231
+ await proxyRotator.add('proxy4');
170
232
  console.log(proxyRotator.getPool()); // Output: ['proxy1', 'proxy2', 'proxy3', 'proxy4']
171
233
  proxyRotator.remove('proxy2');
172
234
  console.log(proxyRotator.getPool()); // Output: ['proxy1', 'proxy3', 'proxy4']
@@ -182,10 +244,12 @@ console.log(proxyRotator.getPool()); // Output: ['proxy1', 'proxy4', 'proxy3']
182
244
  ### Contributing
183
245
 
184
246
  If you would like to contribute to the ProxyRotator project, you can fork the repository and make your desired changes. Feel free to submit a pull request with your improvements or bug fixes. We appreciate your contributions!
185
- License
247
+
248
+ ### License
186
249
 
187
250
  The ProxyRotator class is released under the MIT License. You can freely use and modify it in your projects. Please refer to the license file for more information.
188
- Contact
251
+
252
+ ### Contact
189
253
 
190
254
  If you have any questions, suggestions, or feedback regarding the ProxyRotator class, please me =) Goran Topic @ telegonicaxx@live.com. We appreciate your input and are happy to assist you.
191
255
 
Binary file
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Proxy = exports.ProxyRotator = void 0;
7
+ const ProxyRotator_js_1 = __importDefault(require("./src/ProxyRotator.cjs"));
8
+ exports.ProxyRotator = ProxyRotator_js_1.default;
9
+ const Proxy_js_1 = __importDefault(require("./src/Proxy.cjs"));
10
+ exports.Proxy = Proxy_js_1.default;
11
+ exports.default = ProxyRotator_js_1.default;
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":";;;;;;AAAA,4EAAiD;AAIxC,uBAJF,yBAAY,CAIE;AAHrB,8DAAmC;AAGZ,gBAHhB,kBAAK,CAGgB;AAD5B,kBAAe,yBAAY,CAAC"}
@@ -1,40 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
1
3
  class Proxy {
2
- constructor(proxy, protocol = null, assumeAlive = false) {
3
- // if proxy string starts with protocol
4
- if( proxy.includes('://') ){
4
+ constructor(proxy, protocol = null, assumeAlive = false, country = null) {
5
+ this.country = null;
6
+ if (proxy.includes('://')) {
5
7
  this.protocol = proxy.split('://')[0];
6
8
  this.ip = proxy.split('://')[1].split(':')[0];
7
9
  this.host = this.ip;
8
10
  this.port = proxy.split('://')[1].split(':')[1];
9
- } else { // if proxy string does not start with protocol
11
+ }
12
+ else {
10
13
  this.protocol = protocol;
11
14
  this.ip = proxy.split(':')[0];
12
15
  this.host = this.ip;
13
16
  this.port = proxy.split(':')[1];
14
17
  }
15
- // the proxy
16
- this.proxy = `${(this.protocol)? this.protocol+'://' : ''}${this.ip}:${this.port}`;
17
- // status can be 'new', 'alive', 'dead'
18
- this.status = (assumeAlive)? 'alive' : 'new';
18
+ this.proxy = `${this.protocol ? this.protocol + '://' : ''}${this.ip}:${this.port}`;
19
+ this.status = assumeAlive ? 'alive' : 'new';
19
20
  this.changeTimeStamp = Date.now();
20
- }
21
- // method to return as string
22
- proxy() {
23
- return `${(this.protocol)? this.protocol+'://' : ''}${this.ip}:${this.port}`;
21
+ this.country = country ?? null;
24
22
  }
25
23
  toString() {
26
- return `${(this.protocol)? this.protocol+'://' : ''}${this.ip}:${this.port}`;
24
+ return `${this.protocol ? this.protocol + '://' : ''}${this.ip}:${this.port}`;
27
25
  }
28
- // method to return as obj
29
26
  get() {
30
27
  return {
31
28
  protocol: this.protocol,
32
29
  ip: this.ip,
33
30
  host: this.host,
34
31
  port: this.port,
32
+ country: this.country ?? undefined,
35
33
  };
36
34
  }
37
- // method to return as obj
38
35
  obj() {
39
36
  return {
40
37
  protocol: this.protocol,
@@ -42,27 +39,30 @@ class Proxy {
42
39
  host: this.host,
43
40
  port: this.port,
44
41
  status: this.status,
45
- changeTimeStamp: this.changeTimeStamp
46
- }
42
+ changeTimeStamp: this.changeTimeStamp,
43
+ country: this.country ?? undefined,
44
+ };
45
+ }
46
+ setCountry(country) {
47
+ this.country = country;
47
48
  }
48
- // mark proxy as dead
49
49
  kill() {
50
50
  this.status = 'dead';
51
51
  this.changeTimeStamp = Date.now();
52
52
  }
53
53
  setDead() {
54
- this.status = 'dead'
54
+ this.status = 'dead';
55
55
  this.changeTimeStamp = Date.now();
56
56
  }
57
- setAlive(){
58
- this.status = 'alive'
57
+ setAlive() {
58
+ this.status = 'alive';
59
59
  this.changeTimeStamp = Date.now();
60
60
  }
61
- setNew() {
62
- this.status = 'new'
61
+ setNew() {
62
+ this.status = 'new';
63
63
  this.changeTimeStamp = Date.now();
64
64
  }
65
- isDead() {
65
+ isDead() {
66
66
  return this.status === 'dead';
67
67
  }
68
68
  isAlive() {
@@ -79,13 +79,9 @@ class Proxy {
79
79
  this.status = 'new';
80
80
  this.changeTimeStamp = Date.now();
81
81
  }
82
- status() {
83
- return this.status;
84
- }
85
82
  equals(proxy) {
86
- if (typeof proxy === 'string')
87
- proxy = new Proxy(proxy);
88
- return (this.ip === proxy.ip && this.port === proxy.port);
83
+ const other = typeof proxy === 'string' ? new Proxy(proxy) : proxy;
84
+ return this.ip === other.ip && this.port === other.port;
89
85
  }
90
86
  timeSinceStatusChange() {
91
87
  return Date.now() - this.changeTimeStamp;
@@ -103,5 +99,5 @@ class Proxy {
103
99
  return this.protocol;
104
100
  }
105
101
  }
106
-
107
- export default Proxy;
102
+ exports.default = Proxy;
103
+ //# sourceMappingURL=Proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../../src/Proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const Queue_js_1 = __importDefault(require("./Queue.cjs"));
9
+ const Proxy_js_1 = __importDefault(require("./Proxy.cjs"));
10
+ const makeRequestWithProxy_js_1 = __importDefault(require("./utils/makeRequestWithProxy.cjs"));
11
+ const geo_js_1 = require("./utils/geo.cjs");
12
+ class ProxyRotator {
13
+ constructor(proxies, options = {}) {
14
+ this.graveyard = [];
15
+ this.test = this.test_proxies;
16
+ this.pool = new Queue_js_1.default();
17
+ const { returnAs, revive_timer, shuffle, protocol, assume_aliveness, check_on_next, fetchGeo = true, } = options;
18
+ this.revive_timer = revive_timer ?? 1000 * 60 * 30;
19
+ this.returnAs = returnAs ? this._handleReturnAsInput(returnAs) ?? 'string' : 'string';
20
+ this.protocol = protocol ?? null;
21
+ this.shuffle = shuffle ?? false;
22
+ this.assume_aliveness = assume_aliveness ?? false;
23
+ this.check_on_next = check_on_next ?? false;
24
+ this.fetchGeo = fetchGeo;
25
+ if (proxies == null) {
26
+ // no proxies
27
+ }
28
+ else if (typeof proxies === 'string') {
29
+ this._processOne(proxies);
30
+ }
31
+ else if (this._isArray(proxies)) {
32
+ for (const item of proxies)
33
+ this._processOne(item);
34
+ }
35
+ if (this.shuffle) {
36
+ const shuffled = this._shuffleArray(this.pool.toArray());
37
+ this.pool = new Queue_js_1.default();
38
+ shuffled.forEach((p) => this.pool.enqueue(p));
39
+ }
40
+ }
41
+ getGraveyard() {
42
+ return this.graveyard.map((p) => p.proxy);
43
+ }
44
+ getGraveyardSize() {
45
+ return this.graveyard.length;
46
+ }
47
+ getPool() {
48
+ return this.pool.toArray().map((p) => p.proxy);
49
+ }
50
+ getPoolSize() {
51
+ return this.pool.size;
52
+ }
53
+ /** Returns the status of the pool as a JSON-serializable object. */
54
+ status() {
55
+ return {
56
+ pool: {
57
+ size: this.pool.size,
58
+ proxies: this.getPool(),
59
+ },
60
+ graveyard: {
61
+ size: this.graveyard.length,
62
+ proxies: this.getGraveyard(),
63
+ },
64
+ config: {
65
+ revive_timer: this.revive_timer,
66
+ returnAs: this.returnAs,
67
+ protocol: this.protocol,
68
+ shuffle: this.shuffle,
69
+ assume_aliveness: this.assume_aliveness,
70
+ check_on_next: this.check_on_next,
71
+ fetchGeo: this.fetchGeo,
72
+ },
73
+ };
74
+ }
75
+ async add(proxies) {
76
+ if (this._isArray(proxies)) {
77
+ for (const proxy of proxies)
78
+ await this._add(proxy);
79
+ }
80
+ else {
81
+ await this._add(proxies);
82
+ }
83
+ }
84
+ /** Parse a file of proxies (newline-, space-, or comma-separated) and add each to the pool. */
85
+ async add_file(filename) {
86
+ const parsed = this._parseFile(filename);
87
+ for (const p of parsed)
88
+ await this._add(p);
89
+ }
90
+ /** Fetch country geolocation for all proxies in pool and graveyard. */
91
+ async refreshGeo() {
92
+ const all = [...this.pool.toArray(), ...this.graveyard];
93
+ for (const p of all) {
94
+ try {
95
+ const country = await (0, geo_js_1.getCountryFromIp)(p.ip);
96
+ p.setCountry(country);
97
+ }
98
+ catch {
99
+ // ignore
100
+ }
101
+ }
102
+ }
103
+ async _add(proxy) {
104
+ let country = null;
105
+ if (this.fetchGeo) {
106
+ try {
107
+ const ip = proxy.includes('://') ? proxy.split('://')[1].split(':')[0] : proxy.split(':')[0];
108
+ country = await (0, geo_js_1.getCountryFromIp)(ip);
109
+ }
110
+ catch {
111
+ // ignore geo lookup errors
112
+ }
113
+ }
114
+ const p = new Proxy_js_1.default(proxy, this.protocol, this.assume_aliveness, country);
115
+ this.pool.enqueue(p);
116
+ }
117
+ /** Treat a string as either a file path (add all proxies from file) or a single proxy "ip:port" / "protocol://ip:port". */
118
+ _processOne(item) {
119
+ if (this._isFilePath(item)) {
120
+ const parsed = this._parseFile(item);
121
+ for (const p of parsed)
122
+ this._addSync(p);
123
+ }
124
+ else {
125
+ this._addSync(item);
126
+ }
127
+ }
128
+ /** Sync add used by constructor (no geo). Use add() for geo lookup. */
129
+ _addSync(proxy) {
130
+ const p = new Proxy_js_1.default(proxy, this.protocol, this.assume_aliveness, null);
131
+ this.pool.enqueue(p);
132
+ }
133
+ /** True if the string is an existing file path. */
134
+ _isFilePath(s) {
135
+ try {
136
+ const resolved = path_1.default.resolve(s);
137
+ return fs_1.default.existsSync(resolved) && fs_1.default.statSync(resolved).isFile();
138
+ }
139
+ catch {
140
+ return false;
141
+ }
142
+ }
143
+ remove(proxy) {
144
+ if (this._isArray(proxy)) {
145
+ for (const p of proxy)
146
+ this._remove(p);
147
+ }
148
+ else {
149
+ this._remove(proxy);
150
+ }
151
+ }
152
+ _remove(proxy) {
153
+ this.pool.toArray().forEach((p, i) => {
154
+ if (p.equals(proxy))
155
+ this.pool.removeAt(i);
156
+ });
157
+ }
158
+ getAlive() {
159
+ const proxies = this.pool.toArray();
160
+ for (const proxy of proxies) {
161
+ if (proxy.isAlive())
162
+ return proxy.proxy;
163
+ }
164
+ return undefined;
165
+ }
166
+ setAlive(proxy) {
167
+ const proxies = this.pool.toArray();
168
+ for (const p of proxies) {
169
+ if (p.equals(proxy)) {
170
+ p.setAlive();
171
+ return;
172
+ }
173
+ }
174
+ for (const p of this.graveyard) {
175
+ if (p.equals(proxy)) {
176
+ this.resurect(p);
177
+ return;
178
+ }
179
+ }
180
+ }
181
+ resurect(proxy) {
182
+ const p = this.graveyard.find((x) => x.equals(proxy));
183
+ if (!p)
184
+ return;
185
+ this.graveyard = this.graveyard.filter((x) => !x.equals(proxy));
186
+ p.setNew();
187
+ this.pool.enqueue(p);
188
+ }
189
+ setDead(proxy) {
190
+ this.pool.toArray().forEach((p, i) => {
191
+ if (p.equals(proxy)) {
192
+ p.setDead();
193
+ this.pool.removeAt(i);
194
+ this.graveyard.push(p);
195
+ }
196
+ });
197
+ setTimeout(() => this.resurect(proxy), this.revive_timer);
198
+ }
199
+ kill(proxy) {
200
+ this.setDead(proxy);
201
+ }
202
+ next(options = {}) {
203
+ let { returnAs } = options;
204
+ if (this.check_on_next)
205
+ this._resurection();
206
+ if (this.pool.size === 0)
207
+ return null;
208
+ const proxy = this.pool.dequeue();
209
+ this.pool.enqueue(proxy);
210
+ const resolvedReturnAs = returnAs
211
+ ? this._handleReturnAsInput(returnAs)
212
+ : this.returnAs;
213
+ if (resolvedReturnAs === 'string')
214
+ return proxy.toString();
215
+ if (resolvedReturnAs === 'object')
216
+ return proxy.obj();
217
+ return null;
218
+ }
219
+ _shuffleArray(array) {
220
+ for (let i = array.length - 1; i > 0; i--) {
221
+ const j = Math.floor(Math.random() * (i + 1));
222
+ const temp = array[i];
223
+ array[i] = array[j];
224
+ array[j] = temp;
225
+ }
226
+ return array;
227
+ }
228
+ _handleReturnAsInput(proxyType) {
229
+ if (typeof proxyType === 'string') {
230
+ proxyType = proxyType.toLowerCase();
231
+ if (proxyType === 'str')
232
+ proxyType = 'string';
233
+ if (proxyType === 'obj')
234
+ proxyType = 'object';
235
+ if (proxyType !== 'string' && proxyType !== 'object') {
236
+ console.error('proxyType must be either "string" or "object"');
237
+ return null;
238
+ }
239
+ return proxyType;
240
+ }
241
+ return null;
242
+ }
243
+ _parseFile(filename) {
244
+ const str = fs_1.default.readFileSync(filename, 'utf8');
245
+ let strList = str.split('\n').filter((s) => s.length > 0);
246
+ if (strList.length === 1)
247
+ strList = str.split(' ');
248
+ if (strList.length === 1)
249
+ strList = str.split(',');
250
+ strList = strList
251
+ .map((s) => s.replace(',', ''))
252
+ .map((s) => s.trim())
253
+ .filter((s) => s.length > 0);
254
+ return strList;
255
+ }
256
+ _isArray(value) {
257
+ return (!!value &&
258
+ typeof value === 'object' &&
259
+ value.constructor === Array);
260
+ }
261
+ _resurection() {
262
+ for (const proxy of this.graveyard) {
263
+ if (proxy.isDead() &&
264
+ proxy.timeSinceStatusChange() >= this.revive_timer) {
265
+ this.resurect(proxy);
266
+ }
267
+ }
268
+ }
269
+ async test_proxies(options) {
270
+ const log = (options?.output ?? 'console') === 'console';
271
+ const poolProxies = this.pool.toArray();
272
+ const results = [];
273
+ if (log)
274
+ console.log('--- Testing Proxies ---');
275
+ for (const p of poolProxies) {
276
+ const proxyConfig = { host: p.host, port: p.port };
277
+ const proxyStr = p.proxy;
278
+ if (log)
279
+ console.log(`Testing proxy ${proxyStr}...`);
280
+ const response = await (0, makeRequestWithProxy_js_1.default)(proxyConfig, {
281
+ quiet: !log,
282
+ });
283
+ const working = response?.ip === proxyConfig.host;
284
+ const result = {
285
+ proxy: proxyStr,
286
+ working,
287
+ expectedIp: proxyConfig.host,
288
+ actualIp: response?.ip ?? null,
289
+ };
290
+ if (response == null) {
291
+ result.error = 'Request failed or timed out';
292
+ }
293
+ results.push(result);
294
+ if (log) {
295
+ if (working) {
296
+ console.log(`Proxy ${proxyStr} is working.`);
297
+ }
298
+ else {
299
+ console.log(`Proxy ${proxyStr} is not working.`);
300
+ }
301
+ }
302
+ }
303
+ const workingCount = results.filter((r) => r.working).length;
304
+ const notWorkingCount = results.length - workingCount;
305
+ if (log) {
306
+ console.log('--- Statistics ---');
307
+ console.log(`Total proxies: ${results.length}`);
308
+ console.log(`Working proxies: ${workingCount}`);
309
+ console.log(`Not working proxies: ${notWorkingCount}`);
310
+ }
311
+ const payload = {
312
+ results,
313
+ summary: {
314
+ total: results.length,
315
+ working: workingCount,
316
+ notWorking: notWorkingCount,
317
+ },
318
+ };
319
+ return log ? undefined : payload;
320
+ }
321
+ }
322
+ exports.default = ProxyRotator;
323
+ //# sourceMappingURL=ProxyRotator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProxyRotator.js","sourceRoot":"","sources":["../../../src/ProxyRotator.ts"],"names":[],"mappings":"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"}