recognize 2.0.0 → 3.0.0

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/README.md CHANGED
@@ -0,0 +1,217 @@
1
+ # Recognize
2
+
3
+ Lightweight zero-dependency captcha solving client for **RuCaptcha** and **Anti-Captcha** services (API v2).
4
+
5
+ - **0 runtime dependencies** — uses native `fetch` (Node.js 18+)
6
+ - **TypeScript** — full type safety, autocompletion, exported types
7
+ - **Dual ESM/CJS** — works with `import` and `require`
8
+ - **30+ captcha types** — reCAPTCHA, hCaptcha, Turnstile, FunCaptcha, GeeTest, and more
9
+ - **Auto-polling** — waits for result with configurable interval & timeout
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install recognize
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```ts
20
+ import { RuCaptcha } from "recognize";
21
+
22
+ const solver = new RuCaptcha({
23
+ apiKey: "YOUR_API_KEY",
24
+ pollingInterval: 5000, // optional, default 5000ms
25
+ timeout: 180000, // optional, default 180000ms
26
+ });
27
+
28
+ // Check balance
29
+ const balance = await solver.getBalance();
30
+ console.log("Balance:", balance);
31
+
32
+ // Solve reCAPTCHA v2
33
+ const { taskId, solution } = await solver.recaptchaV2(
34
+ "https://example.com",
35
+ "SITE_KEY",
36
+ );
37
+ console.log(solution.gRecaptchaResponse);
38
+
39
+ // Report result
40
+ await solver.reportCorrect(taskId);
41
+ ```
42
+
43
+ ### Anti-Captcha
44
+
45
+ ```ts
46
+ import { AntiCaptcha } from "recognize";
47
+
48
+ const solver = new AntiCaptcha({ apiKey: "YOUR_API_KEY" });
49
+ ```
50
+
51
+ ### Dynamic service selection
52
+
53
+ ```ts
54
+ import { createSolver } from "recognize";
55
+
56
+ const solver = createSolver("rucaptcha", { apiKey: "YOUR_API_KEY" });
57
+ // or
58
+ const solver2 = createSolver("anticaptcha", { apiKey: "YOUR_API_KEY" });
59
+ ```
60
+
61
+ ## Constructor Options
62
+
63
+ | Option | Type | Default | Description |
64
+ | ----------------- | -------- | -------- | ---------------------------- |
65
+ | `apiKey` | `string` | — | **Required.** API key |
66
+ | `pollingInterval` | `number` | `5000` | Polling interval in ms |
67
+ | `timeout` | `number` | `180000` | Max wait time per task in ms |
68
+
69
+ ## API
70
+
71
+ All solving methods return `Promise<TaskResult<T>>` where `TaskResult<T> = { taskId: number, solution: T }`.
72
+
73
+ ### Account
74
+
75
+ | Method | Description |
76
+ | ------------------------- | ------------------------- |
77
+ | `getBalance()` | Get account balance |
78
+ | `reportCorrect(taskId)` | Report correct solution |
79
+ | `reportIncorrect(taskId)` | Report incorrect solution |
80
+
81
+ ### Image & Text
82
+
83
+ | Method | Params | Task Type |
84
+ | ------------------------------ | ------------------------------------------------- | ----------------- |
85
+ | `imageCaptcha(body, options?)` | `body` — Buffer or base64 string | `ImageToTextTask` |
86
+ | `textCaptcha(text, options?)` | `text` — question string | `TextCaptchaTask` |
87
+ | `audioCaptcha(body, lang?)` | `body` — Buffer or base64, `lang` — language code | `AudioTask` |
88
+
89
+ ### reCAPTCHA
90
+
91
+ | Method | Params |
92
+ | -------------------------------------------------------- | ---------------------------------- |
93
+ | `recaptchaV2(url, siteKey, options?)` | Supports proxy via `options.proxy` |
94
+ | `recaptchaV3(url, siteKey, action, minScore?, options?)` | `minScore` default `0.3` |
95
+ | `recaptchaV2Enterprise(url, siteKey, options?)` | Enterprise version |
96
+
97
+ ### hCaptcha
98
+
99
+ ```ts
100
+ await solver.hcaptcha(url, siteKey, options?)
101
+ ```
102
+
103
+ ### Cloudflare Turnstile
104
+
105
+ ```ts
106
+ await solver.turnstile(url, siteKey, options?)
107
+ ```
108
+
109
+ ### FunCaptcha (Arkose Labs)
110
+
111
+ ```ts
112
+ await solver.funcaptcha(url, publicKey, options?)
113
+ ```
114
+
115
+ ### GeeTest
116
+
117
+ ```ts
118
+ await solver.geetest(url, gt, challenge, options?)
119
+ await solver.geetestV4(url, captchaId, options?)
120
+ ```
121
+
122
+ ### Amazon WAF
123
+
124
+ ```ts
125
+ await solver.amazonWaf(url, siteKey, options?)
126
+ ```
127
+
128
+ ### Other Captcha Types
129
+
130
+ | Method | Task Type |
131
+ | -------------------------------------------------------- | --------------------------------- |
132
+ | `keyCaptcha(url, options?)` | `KeyCaptchaTaskProxyless` |
133
+ | `lemin(url, captchaId, apiServer, options?)` | `LeminTaskProxyless` |
134
+ | `capyPuzzle(url, siteKey, options?)` | `CapyTaskProxyless` |
135
+ | `dataDome(url, captchaUrl, userAgent, proxyConfig)` | `DataDomeSliderTask` |
136
+ | `cyberSiara(url, slideMasterUrlId, userAgent, options?)` | `AntiCyberSiAraTaskProxyless` |
137
+ | `mtCaptcha(url, siteKey, options?)` | `MtCaptchaTaskProxyless` |
138
+ | `friendlyCaptcha(url, siteKey, options?)` | `FriendlyCaptchaTaskProxyless` |
139
+ | `cutcaptcha(url, miseryKey, apiKey, options?)` | `CutCaptchaTaskProxyless` |
140
+ | `tencent(url, appId, options?)` | `TencentTaskProxyless` |
141
+ | `atbCaptcha(url, appId, apiServer, options?)` | `AtbCaptchaTaskProxyless` |
142
+ | `yandexSmart(url, siteKey, options?)` | `YandexSmartCaptchaTaskProxyless` |
143
+ | `vkCaptcha(url, siteKey, options?)` | `VKCaptchaTaskProxyless` |
144
+ | `temuCaptcha(url, options?)` | `TemuCaptchaTaskProxyless` |
145
+
146
+ ### Image-Based Tasks
147
+
148
+ | Method | Task Type |
149
+ | ------------------------------------ | ----------------- |
150
+ | `rotateCaptcha(body, options?)` | `RotateTask` |
151
+ | `coordinatesCaptcha(body, options?)` | `CoordinatesTask` |
152
+ | `gridCaptcha(body, options?)` | `GridTask` |
153
+ | `boundingBoxCaptcha(body, options?)` | `BoundingBoxTask` |
154
+ | `drawAroundCaptcha(body, options?)` | `DrawAroundTask` |
155
+
156
+ ### Generic / Custom
157
+
158
+ ```ts
159
+ // Send any task type directly
160
+ await solver.solve<{ token: string }>({
161
+ type: "SomeNewTaskType",
162
+ websiteURL: "https://example.com",
163
+ });
164
+ ```
165
+
166
+ ## Proxy Support
167
+
168
+ Methods that support proxy accept it via options:
169
+
170
+ ```ts
171
+ await solver.recaptchaV2("https://example.com", "SITE_KEY", {
172
+ proxyType: "http",
173
+ proxyAddress: "1.2.3.4",
174
+ proxyPort: 8080,
175
+ proxyLogin: "user",
176
+ proxyPassword: "pass",
177
+ proxy: true,
178
+ });
179
+ ```
180
+
181
+ ## Exported Types
182
+
183
+ ```ts
184
+ import type {
185
+ SolverOptions,
186
+ TaskResult,
187
+ TokenSolution,
188
+ GRecaptchaSolution,
189
+ ImageSolution,
190
+ GeeTestSolution,
191
+ GeeTestV4Solution,
192
+ ProxyOptions,
193
+ RecaptchaV2Options,
194
+ HCaptchaOptions,
195
+ TurnstileOptions,
196
+ // ... and more
197
+ } from "recognize";
198
+ ```
199
+
200
+ ## Migration from v2
201
+
202
+ | v2 (old) | v3 (current) |
203
+ | --------------------------------------- | ------------------------------- |
204
+ | `new Recognize(SOURCE.RUCAPTCHA, {})` | `new RuCaptcha({ apiKey })` |
205
+ | `new Recognize(SOURCE.ANTICAPTCHA, {})` | `new AntiCaptcha({ apiKey })` |
206
+ | `{ key: "..." }` | `{ apiKey: "..." }` |
207
+ | `balanse()` | `getBalance()` |
208
+ | `solvingImage(buff)` | `imageCaptcha(buff)` |
209
+ | `solvingRecaptcha2()` | `recaptchaV2(url, key)` |
210
+ | `solvingRecaptcha3()` | `recaptchaV3(url, key, action)` |
211
+ | `reportGood(id)` | `reportCorrect(taskId)` |
212
+ | `reportBad(id)` | `reportIncorrect(taskId)` |
213
+ | return `{ id, result }` | return `{ taskId, solution }` |
214
+
215
+ ## License
216
+
217
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AntiCaptcha: () => AntiCaptcha,
24
+ RuCaptcha: () => RuCaptcha,
25
+ Solver: () => Solver,
26
+ SolverError: () => SolverError,
27
+ createSolver: () => createSolver
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/solver.ts
32
+ var import_promises = require("timers/promises");
33
+
34
+ // src/errors.ts
35
+ var SolverError = class extends Error {
36
+ errorId;
37
+ errorCode;
38
+ errorDescription;
39
+ constructor(errorId, errorCode, errorDescription) {
40
+ super(errorCode || `Error ${errorId}: ${errorDescription ?? "unknown"}`);
41
+ this.name = "SolverError";
42
+ this.errorId = errorId;
43
+ this.errorCode = errorCode;
44
+ this.errorDescription = errorDescription ?? "";
45
+ }
46
+ };
47
+
48
+ // src/solver.ts
49
+ var Solver = class {
50
+ _baseUrl;
51
+ _clientKey;
52
+ _softId;
53
+ _pollingInterval;
54
+ _timeout;
55
+ constructor(config, options) {
56
+ if (!options.apiKey) throw new Error("apiKey is required");
57
+ this._baseUrl = config.baseUrl;
58
+ this._clientKey = options.apiKey;
59
+ this._softId = config.softId;
60
+ this._pollingInterval = options.pollingInterval ?? 5e3;
61
+ this._timeout = options.timeout ?? 18e4;
62
+ }
63
+ // ── Internal helpers ──────────────────────────────────────────────
64
+ async _post(method, body) {
65
+ const res = await fetch(`${this._baseUrl}/${method}`, {
66
+ method: "POST",
67
+ headers: { "Content-Type": "application/json" },
68
+ body: JSON.stringify(body)
69
+ });
70
+ const data = await res.json();
71
+ if (data.errorId && data.errorId !== 0) {
72
+ throw new SolverError(
73
+ data.errorId,
74
+ data.errorCode ?? "",
75
+ data.errorDescription
76
+ );
77
+ }
78
+ return data;
79
+ }
80
+ async _createTask(task) {
81
+ const data = await this._post("createTask", {
82
+ clientKey: this._clientKey,
83
+ task,
84
+ softId: this._softId
85
+ });
86
+ return data.taskId;
87
+ }
88
+ async _getTaskResult(taskId) {
89
+ const deadline = Date.now() + this._timeout;
90
+ while (Date.now() < deadline) {
91
+ await (0, import_promises.setTimeout)(this._pollingInterval);
92
+ const data = await this._post("getTaskResult", {
93
+ clientKey: this._clientKey,
94
+ taskId
95
+ });
96
+ if (data.status === "ready") return data.solution;
97
+ }
98
+ throw new Error("Timeout waiting for task result");
99
+ }
100
+ async _solve(task) {
101
+ const taskId = await this._createTask(task);
102
+ const solution = await this._getTaskResult(taskId);
103
+ return { taskId, solution };
104
+ }
105
+ // ── Account ───────────────────────────────────────────────────────
106
+ async getBalance() {
107
+ const data = await this._post("getBalance", { clientKey: this._clientKey });
108
+ return data.balance;
109
+ }
110
+ async reportCorrect(taskId) {
111
+ await this._post("reportCorrect", { clientKey: this._clientKey, taskId });
112
+ return true;
113
+ }
114
+ async reportIncorrect(taskId) {
115
+ await this._post("reportIncorrect", { clientKey: this._clientKey, taskId });
116
+ return true;
117
+ }
118
+ // ── Image / Text captchas ────────────────────────────────────────
119
+ async imageCaptcha(body, options = {}) {
120
+ return this._solve({
121
+ type: "ImageToTextTask",
122
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
123
+ ...options
124
+ });
125
+ }
126
+ async textCaptcha(textcaptcha, options = {}) {
127
+ return this._solve({
128
+ type: "TextCaptchaTask",
129
+ ...options,
130
+ textcaptcha
131
+ });
132
+ }
133
+ async audioCaptcha(body, lang = "en") {
134
+ return this._solve({
135
+ type: "AudioTask",
136
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
137
+ lang
138
+ });
139
+ }
140
+ // ── reCAPTCHA ─────────────────────────────────────────────────────
141
+ async recaptchaV2(websiteURL, websiteKey, options = {}) {
142
+ const { proxy, ...rest } = options;
143
+ return this._solve({
144
+ type: proxy ? "RecaptchaV2Task" : "RecaptchaV2TaskProxyless",
145
+ websiteURL,
146
+ websiteKey,
147
+ ...rest
148
+ });
149
+ }
150
+ async recaptchaV3(websiteURL, websiteKey, pageAction, minScore = 0.3, options = {}) {
151
+ return this._solve({
152
+ type: "RecaptchaV3TaskProxyless",
153
+ websiteURL,
154
+ websiteKey,
155
+ pageAction,
156
+ minScore,
157
+ ...options
158
+ });
159
+ }
160
+ async recaptchaV2Enterprise(websiteURL, websiteKey, options = {}) {
161
+ const { proxy, ...rest } = options;
162
+ return this._solve({
163
+ type: proxy ? "RecaptchaV2EnterpriseTask" : "RecaptchaV2EnterpriseTaskProxyless",
164
+ websiteURL,
165
+ websiteKey,
166
+ ...rest
167
+ });
168
+ }
169
+ // ── hCaptcha ──────────────────────────────────────────────────────
170
+ async hcaptcha(websiteURL, websiteKey, options = {}) {
171
+ const { proxy, ...rest } = options;
172
+ return this._solve({
173
+ type: proxy ? "HCaptchaTask" : "HCaptchaTaskProxyless",
174
+ websiteURL,
175
+ websiteKey,
176
+ ...rest
177
+ });
178
+ }
179
+ // ── FunCaptcha (Arkose Labs) ──────────────────────────────────────
180
+ async funcaptcha(websiteURL, websitePublicKey, options = {}) {
181
+ const { proxy, ...rest } = options;
182
+ return this._solve({
183
+ type: proxy ? "FunCaptchaTask" : "FunCaptchaTaskProxyless",
184
+ websiteURL,
185
+ websitePublicKey,
186
+ ...rest
187
+ });
188
+ }
189
+ // ── GeeTest ───────────────────────────────────────────────────────
190
+ async geetest(websiteURL, gt, challenge, options = {}) {
191
+ const { proxy, ...rest } = options;
192
+ return this._solve({
193
+ type: proxy ? "GeeTestTask" : "GeeTestTaskProxyless",
194
+ websiteURL,
195
+ gt,
196
+ challenge,
197
+ ...rest
198
+ });
199
+ }
200
+ async geetestV4(websiteURL, captchaId, options = {}) {
201
+ const { proxy, ...rest } = options;
202
+ return this._solve({
203
+ type: proxy ? "GeeTestTask" : "GeeTestTaskProxyless",
204
+ websiteURL,
205
+ captchaId,
206
+ version: 4,
207
+ ...rest
208
+ });
209
+ }
210
+ // ── Cloudflare Turnstile ──────────────────────────────────────────
211
+ async turnstile(websiteURL, websiteKey, options = {}) {
212
+ const { proxy, ...rest } = options;
213
+ return this._solve({
214
+ type: proxy ? "TurnstileTask" : "TurnstileTaskProxyless",
215
+ websiteURL,
216
+ websiteKey,
217
+ ...rest
218
+ });
219
+ }
220
+ // ── Amazon WAF ────────────────────────────────────────────────────
221
+ async amazonWaf(websiteURL, websiteKey, options = {}) {
222
+ return this._solve({
223
+ type: "AmazonTaskProxyless",
224
+ websiteURL,
225
+ websiteKey,
226
+ ...options
227
+ });
228
+ }
229
+ // ── KeyCaptcha ────────────────────────────────────────────────────
230
+ async keyCaptcha(websiteURL, options = {}) {
231
+ return this._solve({
232
+ type: "KeyCaptchaTaskProxyless",
233
+ websiteURL,
234
+ ...options
235
+ });
236
+ }
237
+ // ── Lemin ─────────────────────────────────────────────────────────
238
+ async lemin(websiteURL, captchaId, apiServer, options = {}) {
239
+ return this._solve({
240
+ type: "LeminTaskProxyless",
241
+ websiteURL,
242
+ captchaId,
243
+ apiServer,
244
+ ...options
245
+ });
246
+ }
247
+ // ── Capy Puzzle ───────────────────────────────────────────────────
248
+ async capyPuzzle(websiteURL, websiteKey, options = {}) {
249
+ return this._solve({
250
+ type: "CapyTaskProxyless",
251
+ websiteURL,
252
+ websiteKey,
253
+ ...options
254
+ });
255
+ }
256
+ // ── DataDome ──────────────────────────────────────────────────────
257
+ async dataDome(websiteURL, captchaUrl, userAgent, proxyConfig) {
258
+ return this._solve({
259
+ type: "DataDomeSliderTask",
260
+ websiteURL,
261
+ captchaUrl,
262
+ userAgent,
263
+ ...proxyConfig
264
+ });
265
+ }
266
+ // ── CyberSiARA ───────────────────────────────────────────────────
267
+ async cyberSiara(websiteURL, slideMasterUrlId, userAgent, options = {}) {
268
+ return this._solve({
269
+ type: "AntiCyberSiAraTaskProxyless",
270
+ websiteURL,
271
+ SlideMasterUrlId: slideMasterUrlId,
272
+ userAgent,
273
+ ...options
274
+ });
275
+ }
276
+ // ── MTCaptcha ─────────────────────────────────────────────────────
277
+ async mtCaptcha(websiteURL, websiteKey, options = {}) {
278
+ return this._solve({
279
+ type: "MtCaptchaTaskProxyless",
280
+ websiteURL,
281
+ websiteKey,
282
+ ...options
283
+ });
284
+ }
285
+ // ── Friendly Captcha ─────────────────────────────────────────────
286
+ async friendlyCaptcha(websiteURL, websiteKey, options = {}) {
287
+ return this._solve({
288
+ type: "FriendlyCaptchaTaskProxyless",
289
+ websiteURL,
290
+ websiteKey,
291
+ ...options
292
+ });
293
+ }
294
+ // ── Cutcaptcha ────────────────────────────────────────────────────
295
+ async cutcaptcha(websiteURL, miseryKey, apiKey, options = {}) {
296
+ return this._solve({
297
+ type: "CutCaptchaTaskProxyless",
298
+ websiteURL,
299
+ miseryKey,
300
+ apiKey,
301
+ ...options
302
+ });
303
+ }
304
+ // ── Tencent ───────────────────────────────────────────────────────
305
+ async tencent(websiteURL, appId, options = {}) {
306
+ return this._solve({
307
+ type: "TencentTaskProxyless",
308
+ websiteURL,
309
+ appId,
310
+ ...options
311
+ });
312
+ }
313
+ // ── atbCAPTCHA ────────────────────────────────────────────────────
314
+ async atbCaptcha(websiteURL, appId, apiServer, options = {}) {
315
+ return this._solve({
316
+ type: "AtbCaptchaTaskProxyless",
317
+ websiteURL,
318
+ appId,
319
+ apiServer,
320
+ ...options
321
+ });
322
+ }
323
+ // ── Rotate ────────────────────────────────────────────────────────
324
+ async rotateCaptcha(body, options = {}) {
325
+ return this._solve({
326
+ type: "RotateTask",
327
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
328
+ ...options
329
+ });
330
+ }
331
+ // ── Coordinates (click) ───────────────────────────────────────────
332
+ async coordinatesCaptcha(body, options = {}) {
333
+ return this._solve({
334
+ type: "CoordinatesTask",
335
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
336
+ ...options
337
+ });
338
+ }
339
+ // ── Grid ──────────────────────────────────────────────────────────
340
+ async gridCaptcha(body, options = {}) {
341
+ return this._solve({
342
+ type: "GridTask",
343
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
344
+ ...options
345
+ });
346
+ }
347
+ // ── Bounding Box ──────────────────────────────────────────────────
348
+ async boundingBoxCaptcha(body, options = {}) {
349
+ return this._solve({
350
+ type: "BoundingBoxTask",
351
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
352
+ ...options
353
+ });
354
+ }
355
+ // ── Draw Around (Canvas) ──────────────────────────────────────────
356
+ async drawAroundCaptcha(body, options = {}) {
357
+ return this._solve({
358
+ type: "DrawAroundTask",
359
+ body: Buffer.isBuffer(body) ? body.toString("base64") : body,
360
+ ...options
361
+ });
362
+ }
363
+ // ── Yandex Smart Captcha ─────────────────────────────────────────
364
+ async yandexSmart(websiteURL, websiteKey, options = {}) {
365
+ return this._solve({
366
+ type: "YandexSmartCaptchaTaskProxyless",
367
+ websiteURL,
368
+ websiteKey,
369
+ ...options
370
+ });
371
+ }
372
+ // ── VK Captcha ────────────────────────────────────────────────────
373
+ async vkCaptcha(websiteURL, websiteKey, options = {}) {
374
+ return this._solve({
375
+ type: "VKCaptchaTaskProxyless",
376
+ websiteURL,
377
+ websiteKey,
378
+ ...options
379
+ });
380
+ }
381
+ // ── Temu Captcha ──────────────────────────────────────────────────
382
+ async temuCaptcha(websiteURL, options = {}) {
383
+ return this._solve({
384
+ type: "TemuCaptchaTaskProxyless",
385
+ websiteURL,
386
+ ...options
387
+ });
388
+ }
389
+ // ── Generic / Custom task ─────────────────────────────────────────
390
+ async solve(task) {
391
+ return this._solve(task);
392
+ }
393
+ };
394
+
395
+ // src/rucaptcha.ts
396
+ var RuCaptcha = class extends Solver {
397
+ constructor(options) {
398
+ super({ baseUrl: "https://api.rucaptcha.com", softId: 768 }, options);
399
+ }
400
+ };
401
+
402
+ // src/anticaptcha.ts
403
+ var AntiCaptcha = class extends Solver {
404
+ constructor(options) {
405
+ super({ baseUrl: "https://api.anti-captcha.com", softId: 720 }, options);
406
+ }
407
+ };
408
+
409
+ // src/index.ts
410
+ var services = {
411
+ rucaptcha: RuCaptcha,
412
+ anticaptcha: AntiCaptcha
413
+ };
414
+ function createSolver(service, options) {
415
+ const ServiceClass = services[service];
416
+ return new ServiceClass(options);
417
+ }
418
+ // Annotate the CommonJS export names for ESM import in node:
419
+ 0 && (module.exports = {
420
+ AntiCaptcha,
421
+ RuCaptcha,
422
+ Solver,
423
+ SolverError,
424
+ createSolver
425
+ });
426
+ //# sourceMappingURL=index.cjs.map