From b507202ad67ca6e3f54318cab440502809b85309 Mon Sep 17 00:00:00 2001 From: Kirill Bushmin Date: Thu, 30 Jul 2026 10:23:49 +0300 Subject: [PATCH 1/3] CCL-8455 updated lib --- .eslintignore | 14 + .github/workflows/on_pull_request.yml | 13 +- .github/workflows/on_push.yml | 13 +- .gitignore | 3 +- README.md | 60 ++-- js-fix-esm-imports.js | 43 +++ package-lock.json | 6 +- package.json | 19 +- src/CapMonsterCloudClient.ts | 32 ++ src/CapMonsterCloudClientFactory.i.spec.ts | 270 ++++++++++++++- src/GetResultTimeouts.ts | 11 +- src/GetTaskResult.ts | 8 +- src/Requests/AlibabaRequest/AlibabaRequest.ts | 23 ++ .../AlibabaRequest/AlibabaRequestBase.ts | 52 +++ src/Requests/AlibabaRequest/index.ts | 1 + .../AltchaRequest/AltchaRequestBase.ts | 6 +- .../AmazonRequest/AmazonRequestBase.ts | 22 +- .../BasiliskRequest/BasiliskRequestBase.ts | 2 +- .../BinanceRequest/BinanceRequestBase.ts | 2 +- src/Requests/CaptchaRequestBase.ts | 18 + .../CastleRequest/CastleRequestBase.ts | 2 +- src/Requests/CommonCaptchaRequest.ts | 40 +++ src/Requests/ComplexImageRequestBase.ts | 2 +- .../ComplexImageTaskRecognitionRequestBase.ts | 1 + .../DataDomeRequest/DataDomeRequestBase.ts | 2 +- .../FriendlyRequest/FriendlyRequest.ts | 23 ++ .../FriendlyRequest/FriendlyRequestBase.ts | 52 +++ src/Requests/FriendlyRequest/index.ts | 1 + .../FunCaptchaRequestBase.ts | 20 +- .../GeeTestRequest/GeeTestRequestBase.ts | 2 +- .../HCaptchaRequest/HCaptchaRequestBase.ts | 2 +- src/Requests/HuntRequest/HuntRequestBase.ts | 2 +- src/Requests/ImpervaRequest/ImpervaRequest.ts | 14 +- .../ImpervaRequest/ImpervaRequestBase.ts | 40 ++- src/Requests/ImpervaRequest/index.ts | 1 + .../MTCaptchaRequest/MTCaptchaRequestBase.ts | 2 +- .../ProsopoRequest/ProsopoRequestBase.ts | 2 +- .../RecaptchaV2EnterpriseRequestBase.ts | 18 +- .../RecaptchaV2RequestBase.ts | 11 +- .../RecaptchaV3EnterpriseRequestBase.ts | 2 +- src/Requests/RecaptchaV3ProxylessRequest.ts | 11 +- src/Requests/RequestsSerialization.u.spec.ts | 311 +++++++++++++++++- src/Requests/TSPDRequest/TSPDRequestBase.ts | 2 +- src/Requests/Task.ts | 8 +- src/Requests/TemuRequest/TemuRequestBase.ts | 2 +- src/Requests/TenDIRequest/TenDIRequestBase.ts | 15 +- .../TurnstileRequest/Turnstile.i.spec.ts | 3 +- .../TurnstileRequest/TurnstileRequest.ts | 3 + .../TurnstileRequest/TurnstileRequestBase.ts | 2 +- .../YidunRequest/YuidunRequestBase.ts | 2 +- src/Responses/AlibabaResponse.ts | 5 + src/Responses/CommonCaptchaResponse.ts | 1 + src/Responses/FriendlyResponse.ts | 5 + src/index.ts | 18 +- tsconfig.esm.json | 9 + 55 files changed, 1133 insertions(+), 121 deletions(-) create mode 100644 .eslintignore create mode 100644 js-fix-esm-imports.js create mode 100644 src/Requests/AlibabaRequest/AlibabaRequest.ts create mode 100644 src/Requests/AlibabaRequest/AlibabaRequestBase.ts create mode 100644 src/Requests/AlibabaRequest/index.ts create mode 100644 src/Requests/CommonCaptchaRequest.ts create mode 100644 src/Requests/FriendlyRequest/FriendlyRequest.ts create mode 100644 src/Requests/FriendlyRequest/FriendlyRequestBase.ts create mode 100644 src/Requests/FriendlyRequest/index.ts create mode 100644 src/Responses/AlibabaResponse.ts create mode 100644 src/Responses/CommonCaptchaResponse.ts create mode 100644 src/Responses/FriendlyResponse.ts create mode 100644 tsconfig.esm.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c5518cc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,14 @@ +node_modules +dist +coverage +*.log + +# TypeScript +*.d.ts + +# IDE +.vscode +.idea + +# OS +.DS_Store \ No newline at end of file diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml index 64ddc74..db3463e 100644 --- a/.github/workflows/on_pull_request.yml +++ b/.github/workflows/on_pull_request.yml @@ -11,13 +11,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 with: - node-version: 16.x - - name: yarn install - run: yarn install + node-version: 22.x + cache: npm + - name: npm ci + run: npm ci - name: tsc uses: icrawl/action-tsc@v1 - run: npm run build diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 429602b..85efdfb 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -11,14 +11,15 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: 22.x registry-url: 'https://registry.npmjs.org' - - name: yarn install - run: yarn install + cache: npm + - name: npm ci + run: npm ci - name: tsc uses: icrawl/action-tsc@v1 - run: npm run build diff --git a/.gitignore b/.gitignore index 2a797b1..970f14a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ dist/ node_modules/ -.idea \ No newline at end of file +.idea +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 021074b..24b85cb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # Zennolab CapMonsterCloud JS Client -> [!IMPORTANT] -> This repository has been moved and is no longer maintained. -> -> New repository: [https://github.com/CapMonsterCloud/client-js](https://github.com/CapMonsterCloud/client-js) -> -> Please update your references and use the new repository for all future development. - - Official JS client library for [capmonster.cloud](https://capmonster.cloud/) captcha recognition service ## Installation @@ -44,6 +36,30 @@ run() }); ``` +## Usage with CommonCaptcha + +Use `CommonCaptcha` when you want to pass a full task payload directly, for example when a new captcha type is not yet covered by a dedicated request class. + +```javascript +const { CapMonsterCloudClientFactory, ClientOptions, CommonCaptcha } = require('@zennolab_com/capmonstercloud-client'); + +async function run() { + const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({ clientKey: '' })); + + const commonCaptcha = new CommonCaptcha({ + task: { + type: 'RecaptchaV2Task', + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high', + websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + }, + }); + + console.log(await cmcClient.Solve(commonCaptcha)); +} + +run(); +``` + ## Usage with Browser (with or without Typescript) Browser implementation use [fetch](https://caniuse.com/fetch) instead of [http(s)](https://nodejs.org/api/http.html). @@ -83,26 +99,32 @@ DEBUG=cmc-* node app.js ## Supported captcha recognition requests: +- [AlibabaRequest](https://docs.capmonster.cloud/docs/captchas/alibaba-task/) +- [AltchaRequest](https://zenno.link/doc-altcha-en) - [AmazonRequest](https://zenno.link/doc-amazon-en) - [BasiliskRequest](https://zenno.link/doc-basilisk-en) - [BinanceRequest](https://zenno.link/doc-binance-en) +- [CastleRequest](https://zenno.link/castle-en) +- [ComplexImageFunCaptchaRequest](https://zenno.link/doc-complextask-rc-en) +- [ComplexImageHCaptchaRequest](https://zenno.link/doc-complextask-hc-en) +- [ComplexImageRecaptchaRequest](https://zenno.link/doc-complextask-rc-en) +- [ComplexImageTaskRecognitionRequest](https://zenno.link/doc-complex-image-recognition) - [DataDomeRequest](https://zenno.link/doc-datadome-en) +- [FriendlyRequest](https://docs.capmonster.cloud/docs/captchas/friendly-task/) +- [FunCaptchaRequest](https://docs.capmonster.cloud/docs/captchas/funcaptcha-task/) - [GeeTestRequest](https://zenno.link/doc-geetest-proxy-en) -- [HcaptchaComplexImageTaskRequest](https://zenno.link/doc-complextask-hc-en) +- [HCaptchaRequest](https://docs.capmonster.cloud/docs/captchas/) +- [HuntRequest](https://zenno.link/hunt-en) - [ImageToTextRequest](https://zenno.link/doc-ImageToTextTask-en) -- [ImpervaRequest](https://zenno.link/doc-imperva-en) -- [MTCaptcha](https://zenno.link/doc-mt-captcha-en) +- [ImpervaRequest](https://docs.capmonster.cloud/docs/captchas/incapsula/) +- [MTCaptchaRequest](https://zenno.link/doc-mt-captcha-en) - [ProsopoRequest](https://zenno.link/doc-prosopo-en) -- [RecaptchaComplexImageTaskRequest](https://zenno.link/doc-complextask-rc-en) - [RecaptchaV2EnterpriseRequest](https://zenno.link/doc-recaptcha2e-proxy-en) -- [RecaptchaV3EnterpriseRequest](https://zenno.link/doc-recaptcha3e-proxy-en) - [RecaptchaV2Request](https://zenno.link/doc-recaptcha2-proxy-en) +- [RecaptchaV3EnterpriseRequest](https://zenno.link/doc-recaptcha3e-proxy-en) - [RecaptchaV3ProxylessRequest](https://zenno.link/doc-recaptcha3-en) -- [Temu](https://zenno.link/doc-temu-en) +- [TemuRequest](https://zenno.link/doc-temu-en) - [TenDIRequest](https://zenno.link/doc-tendi-en) +- [TSPDRequest](https://zenno.link/tspd-en) - [TurnstileRequest](https://zenno.link/doc-turnstile-proxy-en) -- [Yidun](https://zenno.link/doc-yidun-en) -- [Altcha](https://zenno.link/doc-altcha-en) -- [Castle](https://zenno.link/castle-en) -- [TSPD](https://zenno.link/tspd-en) -- [Hunt](https://zenno.link/hunt-en) +- [YidunRequest](https://zenno.link/doc-yidun-en) diff --git a/js-fix-esm-imports.js b/js-fix-esm-imports.js new file mode 100644 index 0000000..9a17509 --- /dev/null +++ b/js-fix-esm-imports.js @@ -0,0 +1,43 @@ +/* eslint @typescript-eslint/no-var-requires: 0 */ +const fs = require('fs'); +const path = require('path'); + +const esmDir = path.join(__dirname, 'dist', 'esm'); + +function walk(dir) { + return fs.readdirSync(dir).flatMap((entry) => { + const fullPath = path.join(dir, entry); + return fs.statSync(fullPath).isDirectory() ? walk(fullPath) : [fullPath]; + }); +} + +function resolveImportPath(filePath, importPath) { + if (!importPath.startsWith('.')) { + return importPath; + } + + const absoluteTarget = path.resolve(path.dirname(filePath), importPath); + if (fs.existsSync(`${absoluteTarget}.js`)) { + return `${importPath}.js`; + } + + if (fs.existsSync(path.join(absoluteTarget, 'index.js'))) { + return `${importPath}/index.js`; + } + + return importPath; +} + +function fixImports(filePath) { + const source = fs.readFileSync(filePath, 'utf8'); + const fixed = source.replace(/(from\s+['"])([^'"]+)(['"])/g, (_, prefix, importPath, suffix) => { + return `${prefix}${resolveImportPath(filePath, importPath)}${suffix}`; + }); + fs.writeFileSync(filePath, fixed); +} + +if (fs.existsSync(esmDir)) { + walk(esmDir) + .filter((filePath) => filePath.endsWith('.js')) + .forEach(fixImports); +} diff --git a/package-lock.json b/package-lock.json index b7a40ff..1667c8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@zennolab_com/capmonstercloud-client", - "version": "1.9.0", + "version": "2.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@zennolab_com/capmonstercloud-client", - "version": "1.9.0", + "version": "2.8.0", "license": "ISC", "dependencies": { "debug": "^4.3.4" @@ -26,7 +26,7 @@ "typescript": "^4.7.4" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/@ampproject/remapping": { diff --git a/package.json b/package.json index aa662bd..ad0f918 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,20 @@ { "name": "@zennolab_com/capmonstercloud-client", - "version": "2.6.1", + "version": "2.8.0", "description": "Official JS client library for https://capmonster.cloud/ captcha recognition service", "main": "dist/index.js", + "module": "dist/esm/index.js", "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/esm/index.js", + "require": "./dist/index.js", + "default": "./dist/esm/index.js" + } + }, "engines": { - "node": ">=10" + "node": ">=18" }, "files": [ "dist" @@ -21,10 +30,12 @@ "ZennoPoster" ], "scripts": { - "build": "node js-rimraf.js && npx tsc", + "build": "node js-rimraf.js && npx tsc && npx tsc -p tsconfig.esm.json && node js-fix-esm-imports.js && node -e \"require('fs').writeFileSync('dist/esm/package.json', JSON.stringify({ type: 'module' }, null, 2))\"", "test": "jest", "test-unit": "jest -c jest.config.unit.js", - "test-integr": "jest -c jest.config.integration.js" + "test-integr": "jest -c jest.config.integration.js", + "lint": "eslint . --ext .ts,.js", + "lint:fix": "eslint . --ext .ts,.js --fix" }, "author": "", "license": "ISC", diff --git a/src/CapMonsterCloudClient.ts b/src/CapMonsterCloudClient.ts index 566296e..accb184 100644 --- a/src/CapMonsterCloudClient.ts +++ b/src/CapMonsterCloudClient.ts @@ -63,6 +63,12 @@ import { TSPDRequest } from './Requests/TSPDRequest'; import { TSPDResponse } from './Responses/TSPDResponse'; import { HuntRequest } from './Requests/HuntRequest'; import { HuntResponse } from './Responses/HuntResponse'; +import { AlibabaRequest } from './Requests/AlibabaRequest'; +import { AlibabaResponse } from './Responses/AlibabaResponse'; +import { FriendlyRequest } from './Requests/FriendlyRequest'; +import { FriendlyResponse } from './Responses/FriendlyResponse'; +import { CommonCaptchaRequest } from './Requests/CommonCaptchaRequest'; +import { CommonCaptchaResponse } from './Responses/CommonCaptchaResponse'; /** * Base type for capmonster.cloud Client exceptions @@ -295,6 +301,24 @@ export class CapMonsterCloudClient { resultTimeouts?: GetResultTimeouts, cancellationController?: AbortController, ): Promise>; + /** + * Solve Alibaba task + * You will get response within 10 - 180 secs period depending on service workload. + */ + public async Solve( + task: AlibabaRequest, + resultTimeouts?: GetResultTimeouts, + cancellationController?: AbortController, + ): Promise>; + /** + * Solve Friendly Captcha task + * You will get response within 10 - 180 secs period depending on service workload. + */ + public async Solve( + task: FriendlyRequest, + resultTimeouts?: GetResultTimeouts, + cancellationController?: AbortController, + ): Promise>; /** * Solve TenDI task * You will get response within 10 - 180 secs period depending on service workload. @@ -424,6 +448,14 @@ export class CapMonsterCloudClient { resultTimeouts?: GetResultTimeouts, cancellationController?: AbortController, ): Promise>; + /** + * Solve CommonCaptchaRequest task. + */ + public async Solve( + task: CommonCaptchaRequest, + resultTimeouts?: GetResultTimeouts, + cancellationController?: AbortController, + ): Promise>; /** * Solve {Task} task */ diff --git a/src/CapMonsterCloudClientFactory.i.spec.ts b/src/CapMonsterCloudClientFactory.i.spec.ts index bdb7a56..100c8cb 100644 --- a/src/CapMonsterCloudClientFactory.i.spec.ts +++ b/src/CapMonsterCloudClientFactory.i.spec.ts @@ -22,6 +22,9 @@ import { MTCaptchaRequest } from './Requests/MTCaptchaRequest'; import { CastleRequest } from './Requests/CastleRequest'; import { TSPDRequest } from './Requests/TSPDRequest'; import { HuntRequest } from './Requests/HuntRequest'; +import { AlibabaRequest } from './Requests/AlibabaRequest'; +import { FriendlyRequest } from './Requests/FriendlyRequest'; +import { CommonCaptchaRequest } from './Requests/CommonCaptchaRequest'; const { version } = require('../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires @@ -128,6 +131,45 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(await srv.destroy()).toBeUndefined(); }); + it('should call createTask and getTaskResult methods with specified objects for CommonCaptchaRequest', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":7654321}' }, + { responseBody: '{"errorId":0,"status":"ready","solution":{"gRecaptchaResponse":"answer"}}' }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const commonCaptchaRequest = new CommonCaptchaRequest({ + task: { + type: 'RecaptchaV2Task', + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high', + websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + }, + }); + + const task = await cmcClient.Solve(commonCaptchaRequest, { + firstRequestDelay: 0, + requestsInterval: 1000, + timeout: 1000, + }); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"RecaptchaV2Task","websiteURL":"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high","websiteKey":"6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":7654321}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.gRecaptchaResponse', 'answer'); + + expect(await srv.destroy()).toBeUndefined(); + }); + it('should call createTask with proxy parameters and getTaskResult methods with specified objects', async () => { expect.assertions(5); @@ -180,7 +222,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', userAgent: 'userAgent', }); @@ -215,7 +257,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', userAgent: 'userAgent', }); @@ -244,7 +286,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', userAgent: 'userAgent', }); @@ -266,7 +308,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(srv.caughtRequests[0]).toHaveProperty( 'body', - '{"clientKey":"","task":{"type":"NoCaptchaTask","websiteURL":"websiteURL","websiteKey":"websiteKey","userAgent":"userAgent"},"softId":54}', + '{"clientKey":"","task":{"type":"NoCaptchaTask","websiteURL":"https://example.com","websiteKey":"websiteKey","userAgent":"userAgent"},"softId":54}', ); expect(task).toBeInstanceOf(CaptchaResult); expect(task.solution).toBeUndefined(); @@ -290,7 +332,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', userAgent: 'userAgent', nocache: true, @@ -313,7 +355,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(srv.caughtRequests[0]).toHaveProperty( 'body', - '{"clientKey":"","task":{"type":"NoCaptchaTask","nocache":true,"websiteURL":"websiteURL","websiteKey":"websiteKey","userAgent":"userAgent"},"softId":54}', + '{"clientKey":"","task":{"type":"NoCaptchaTask","nocache":true,"websiteURL":"https://example.com","websiteKey":"websiteKey","userAgent":"userAgent"},"softId":54}', ); expect(task).toBeInstanceOf(CaptchaResult); expect(task.solution).toBeUndefined(); @@ -337,7 +379,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', }); @@ -350,7 +392,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(srv.caughtRequests[0]).toHaveProperty( 'body', - '{"clientKey":"","task":{"type":"NoCaptchaTask","websiteURL":"websiteURL","websiteKey":"websiteKey"},"softId":54}', + '{"clientKey":"","task":{"type":"NoCaptchaTask","websiteURL":"https://example.com","websiteKey":"websiteKey"},"softId":54}', ); expect(task).toBeInstanceOf(CaptchaResult); expect(task.solution).toBeUndefined(); @@ -377,7 +419,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', }); @@ -406,7 +448,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { ); const recaptchaV2Request = new RecaptchaV2Request({ - websiteURL: 'websiteURL', + websiteURL: 'https://example.com', websiteKey: 'websiteKey', }); @@ -735,6 +777,44 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(await srv.destroy()).toBeUndefined(); }); + it('should solve Imperva Task', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":1234567}' }, + { + responseBody: + '{"errorId":0,"status":"ready","solution":{"domains": { "site.com" : { "cookies": { "___utmvc": "NMB", "reese84": "reese84"}} } }}', + }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const impervaRequest = new ImpervaRequest({ + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle', + metadata: { + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'l/LsGnrvyB9lNhXI8borDKa2IGc', + }, + }); + + const task = await cmcClient.Solve(impervaRequest); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle","metadata":{"incapsulaScriptUrl":"_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3","incapsulaCookies":"l/LsGnrvyB9lNhXI8borDKa2IGc"},"class":"Imperva"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.domains', { 'site.com': { cookies: { ___utmvc: 'NMB', reese84: 'reese84' } } }); + + expect(await srv.destroy()).toBeUndefined(); + }); + it('should solve Imperva Task with Proxy', async () => { expect.assertions(5); @@ -755,8 +835,8 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { const impervaRequest = new ImpervaRequest({ websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle', metadata: { - incapsulaScriptBase64: 'dmFyIF8weGQ2ZmU9Wydce..eDUzXHg2YV', - incapsulaSessionCookie: 'l/LsGnrvyB9lNhXI8borDKa2IGc', + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'l/LsGnrvyB9lNhXI8borDKa2IGc', }, proxy: { proxyType: 'http', @@ -771,7 +851,7 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(srv.caughtRequests[0]).toHaveProperty( 'body', - '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle","metadata":{"incapsulaScriptBase64":"dmFyIF8weGQ2ZmU9Wydce..eDUzXHg2YV","incapsulaSessionCookie":"l/LsGnrvyB9lNhXI8borDKa2IGc"},"class":"Imperva","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=middle","metadata":{"incapsulaScriptUrl":"_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3","incapsulaCookies":"l/LsGnrvyB9lNhXI8borDKa2IGc"},"class":"Imperva","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', ); expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); expect(task).toHaveProperty('solution'); @@ -1303,4 +1383,168 @@ describe('Check integration tests for CapMonsterCloudClientFactory()', () => { expect(await srv.destroy()).toBeUndefined(); }); + + it('should solve Alibaba Task', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":1234567}' }, + { + responseBody: + '{"errorId":0,"status":"ready","solution":{"data":{"tokens":"{\\"sceneId\\":\\"1ww7426c4\\",\\"certifyId\\":\\"kBjCxX2W2c\\"}"}}}', + }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const alibabaRequest = new AlibabaRequest({ + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + }, + }); + + const task = await cmcClient.Solve(alibabaRequest); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://www.example.com","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","metadata":{"sceneId":"1ww7426c4","prefix":"dlw3kug"},"class":"alibaba"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.data.tokens'); + + expect(await srv.destroy()).toBeUndefined(); + }); + + it('should solve Alibaba Task with Proxy', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":1234567}' }, + { + responseBody: + '{"errorId":0,"status":"ready","solution":{"data":{"tokens":"{\\"sceneId\\":\\"1ww7426c4\\",\\"certifyId\\":\\"kBjCxX2W2c\\"}"}}}', + }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const alibabaRequest = new AlibabaRequest({ + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + }, + proxy: { + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }); + + const task = await cmcClient.Solve(alibabaRequest); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://www.example.com","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","metadata":{"sceneId":"1ww7426c4","prefix":"dlw3kug"},"class":"alibaba","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.data.tokens'); + + expect(await srv.destroy()).toBeUndefined(); + }); + + it('should solve Friendly Task', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":1234567}' }, + { responseBody: '{"errorId":0,"status":"ready","solution":{"data":{"token":"friendly-token"}}}' }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const friendlyRequest = new FriendlyRequest({ + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + }); + + const task = await cmcClient.Solve(friendlyRequest); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://example.com","websiteKey":"FFMGEMAD2K3JJ35P","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","metadata":{"apiGetLib":"https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js"},"class":"friendly"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.data.token', 'friendly-token'); + + expect(await srv.destroy()).toBeUndefined(); + }); + + it('should solve Friendly Task with Proxy', async () => { + expect.assertions(5); + + const srv = await createServerMock({ + responses: [ + { responseBody: '{"errorId":0,"taskId":1234567}' }, + { responseBody: '{"errorId":0,"status":"ready","solution":{"data":{"token":"friendly-token"}}}' }, + ], + }); + + const cmcClient = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: '', serviceUrl: `http://localhost:${srv.address.port}` }), + ); + + const friendlyRequest = new FriendlyRequest({ + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + proxy: { + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }); + + const task = await cmcClient.Solve(friendlyRequest); + + expect(srv.caughtRequests[0]).toHaveProperty( + 'body', + '{"clientKey":"","task":{"type":"CustomTask","websiteURL":"https://example.com","websiteKey":"FFMGEMAD2K3JJ35P","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","metadata":{"apiGetLib":"https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js"},"class":"friendly","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', + ); + expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":1234567}'); + expect(task).toHaveProperty('solution'); + expect(task).toHaveProperty('solution.data.token', 'friendly-token'); + + expect(await srv.destroy()).toBeUndefined(); + }); }); diff --git a/src/GetResultTimeouts.ts b/src/GetResultTimeouts.ts index d794736..cef0930 100644 --- a/src/GetResultTimeouts.ts +++ b/src/GetResultTimeouts.ts @@ -1,4 +1,5 @@ import { Task } from './Requests/Task'; +import { CommonCaptchaRequest } from './Requests/CommonCaptchaRequest'; import { TaskType } from './TaskType'; export type GetResultTimeouts = { @@ -118,7 +119,13 @@ export const MTCaptchaTaskTimeouts = { } as GetResultTimeouts; export function detectResultTimeouts(task: Task): GetResultTimeouts { - switch (task.type) { + if (task instanceof CommonCaptchaRequest) { + return CustomTaskTimeouts; + } + + const taskType = task.type; + + switch (taskType) { case TaskType.FunCaptchaTask: return FunCaptchaTimeouts; case TaskType.GeeTestTask: @@ -154,6 +161,6 @@ export function detectResultTimeouts(task: Task): GetResultTimeouts { case TaskType.MTCaptchaTask: return MTCaptchaTaskTimeouts; default: - throw new Error(`Could not detect result timeouts for provided task type = ${task.type}`); + throw new Error(`Could not detect result timeouts for provided task type = ${taskType}`); } } diff --git a/src/GetTaskResult.ts b/src/GetTaskResult.ts index c955cc5..7302b35 100644 --- a/src/GetTaskResult.ts +++ b/src/GetTaskResult.ts @@ -18,6 +18,9 @@ import { AltchaResponse } from './Responses/AltchaResponse'; import { CastleResponse } from './Responses/CastleResponse'; import { TSPDResponse } from './Responses/TSPDResponse'; import { HuntResponse } from './Responses/HuntResponse'; +import { AlibabaResponse } from './Responses/AlibabaResponse'; +import { FriendlyResponse } from './Responses/FriendlyResponse'; +import { CommonCaptchaResponse } from './Responses/CommonCaptchaResponse'; export enum TaskResultType { Failed = 'Failed', @@ -53,7 +56,10 @@ export type TaskCompletedSolution = | AltchaResponse | CastleResponse | TSPDResponse - | HuntResponse; + | HuntResponse + | AlibabaResponse + | FriendlyResponse + | CommonCaptchaResponse; export type TaskCompleted = { type: TaskResultType.Completed; diff --git a/src/Requests/AlibabaRequest/AlibabaRequest.ts b/src/Requests/AlibabaRequest/AlibabaRequest.ts new file mode 100644 index 0000000..aef13e3 --- /dev/null +++ b/src/Requests/AlibabaRequest/AlibabaRequest.ts @@ -0,0 +1,23 @@ +import { TaskType } from '../../TaskType'; +import { AlibabaRequestBase, AlibabaRequestBaseIn } from './AlibabaRequestBase'; +import { ProxyInfo, ProxyInfoIn } from '../ProxyInfo'; + +export type AlibabaRequestIn = Pick> & { + proxy?: ProxyInfoIn; +}; + +/** + * Alibaba Captcha recognition request. + * {@link https://docs.capmonster.cloud/docs/captchas/alibaba-task/} + */ +export class AlibabaRequest extends AlibabaRequestBase { + public declare class: 'alibaba'; + + constructor({ proxy, ...argsObj }: AlibabaRequestIn) { + super({ type: TaskType.CustomTask, _class: 'alibaba', ...argsObj }); + + if (proxy) { + Object.assign(this, new ProxyInfo(proxy)); + } + } +} diff --git a/src/Requests/AlibabaRequest/AlibabaRequestBase.ts b/src/Requests/AlibabaRequest/AlibabaRequestBase.ts new file mode 100644 index 0000000..88a6ed9 --- /dev/null +++ b/src/Requests/AlibabaRequest/AlibabaRequestBase.ts @@ -0,0 +1,52 @@ +import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase'; + +export type AlibabaMetadata = { + sceneId: string; + prefix: string; + userId?: string; + userUserId?: string; + verifyType?: string; + region?: string; + UserCertifyId?: string; + apiGetLib?: string; +}; + +export type AlibabaRequestBaseIn = { + websiteURL: string; + userAgent?: string; + metadata: AlibabaMetadata; + _class: string; +} & CaptchaRequestBaseIn; + +/** + * Base Alibaba recognition request + */ +export abstract class AlibabaRequestBase extends CaptchaRequestBase { + /** + * Address of a webpage with Alibaba Captcha. + */ + public websiteURL!: string; + + /** + * Browser User-Agent. Pass only the actual UA from Windows OS + */ + public userAgent?: string; + + /** + * Additional metadata required to solve Alibaba Captcha. + */ + public metadata!: AlibabaMetadata; + + /** + * Class of captcha object + */ + public class: string; + + constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: AlibabaRequestBaseIn) { + super({ type, nocache }); + this.websiteURL = this.validateWebsiteURL(websiteURL); + this.userAgent = userAgent; + this.metadata = metadata; + this.class = _class; + } +} diff --git a/src/Requests/AlibabaRequest/index.ts b/src/Requests/AlibabaRequest/index.ts new file mode 100644 index 0000000..7f89037 --- /dev/null +++ b/src/Requests/AlibabaRequest/index.ts @@ -0,0 +1 @@ +export * from './AlibabaRequest'; diff --git a/src/Requests/AltchaRequest/AltchaRequestBase.ts b/src/Requests/AltchaRequest/AltchaRequestBase.ts index 9530b66..bfbf671 100644 --- a/src/Requests/AltchaRequest/AltchaRequestBase.ts +++ b/src/Requests/AltchaRequest/AltchaRequestBase.ts @@ -2,6 +2,7 @@ import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase' export type AltchaRequestBaseIn = { websiteURL: string; + websiteKey: string; userAgent?: string; _class: string; metadata: Metadata; @@ -43,9 +44,10 @@ export abstract class AltchaRequestBase extends CaptchaRequestBase { */ public class: string; - constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: AltchaRequestBaseIn) { + constructor({ type, nocache, websiteURL, websiteKey, userAgent, metadata, _class }: AltchaRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); + this.websiteKey = websiteKey; this.metadata = metadata; this.userAgent = userAgent; this.class = _class; diff --git a/src/Requests/AmazonRequest/AmazonRequestBase.ts b/src/Requests/AmazonRequest/AmazonRequestBase.ts index f9b35b6..1225344 100644 --- a/src/Requests/AmazonRequest/AmazonRequestBase.ts +++ b/src/Requests/AmazonRequest/AmazonRequestBase.ts @@ -8,6 +8,7 @@ export type AmazonRequestBaseIn = { context: string; iv: string; cookieSolution?: boolean; + userAgent?: string; } & CaptchaRequestBaseIn; /** @@ -49,14 +50,31 @@ export abstract class AmazonRequestBase extends CaptchaRequestBase { */ public cookieSolution?: boolean = false; - constructor({ type, nocache, websiteURL, challengeScript, captchaScript, websiteKey, context, iv, cookieSolution }: AmazonRequestBaseIn) { + /** + * Browser User-Agent. Pass only the actual UA from Windows OS. + */ + public userAgent?: string; + + constructor({ + type, + nocache, + websiteURL, + challengeScript, + captchaScript, + websiteKey, + context, + iv, + cookieSolution, + userAgent, + }: AmazonRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.challengeScript = challengeScript; this.captchaScript = captchaScript; this.websiteKey = websiteKey; this.context = context; this.iv = iv; this.cookieSolution = cookieSolution; + this.userAgent = userAgent; } } diff --git a/src/Requests/BasiliskRequest/BasiliskRequestBase.ts b/src/Requests/BasiliskRequest/BasiliskRequestBase.ts index 1a60c72..0f5fdb4 100644 --- a/src/Requests/BasiliskRequest/BasiliskRequestBase.ts +++ b/src/Requests/BasiliskRequest/BasiliskRequestBase.ts @@ -33,7 +33,7 @@ export abstract class BasiliskRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, websiteKey, _class }: BasiliskRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.userAgent = userAgent; this.class = _class; diff --git a/src/Requests/BinanceRequest/BinanceRequestBase.ts b/src/Requests/BinanceRequest/BinanceRequestBase.ts index 61984e7..d48e26c 100644 --- a/src/Requests/BinanceRequest/BinanceRequestBase.ts +++ b/src/Requests/BinanceRequest/BinanceRequestBase.ts @@ -33,7 +33,7 @@ export abstract class BinanceRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, websiteKey, validateId }: BinanceRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.validateId = validateId; this.userAgent = userAgent; diff --git a/src/Requests/CaptchaRequestBase.ts b/src/Requests/CaptchaRequestBase.ts index f617615..cac2d5d 100644 --- a/src/Requests/CaptchaRequestBase.ts +++ b/src/Requests/CaptchaRequestBase.ts @@ -2,6 +2,20 @@ import { TaskType } from '../TaskType'; export type CaptchaRequestBaseIn = { type: TaskType; nocache?: boolean }; +export function validateWebsiteURL(websiteURL: string): string { + try { + const url = new URL(websiteURL); + + if (url.protocol === 'http:' || url.protocol === 'https:') { + return websiteURL; + } + } catch { + // Handled by the error below to keep one public validation message. + } + + throw new Error('websiteURL must be a valid http or https URL'); +} + /** * Base captcha recognition request */ @@ -21,4 +35,8 @@ export abstract class CaptchaRequestBase { this.type = type; this.nocache = nocache; } + + protected validateWebsiteURL(websiteURL: string): string { + return validateWebsiteURL(websiteURL); + } } diff --git a/src/Requests/CastleRequest/CastleRequestBase.ts b/src/Requests/CastleRequest/CastleRequestBase.ts index a5a5ec2..a927a72 100644 --- a/src/Requests/CastleRequest/CastleRequestBase.ts +++ b/src/Requests/CastleRequest/CastleRequestBase.ts @@ -69,7 +69,7 @@ export abstract class CastleRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, websiteKey, userAgent, metadata, _class }: CastleRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.userAgent = userAgent; this.metadata = metadata; diff --git a/src/Requests/CommonCaptchaRequest.ts b/src/Requests/CommonCaptchaRequest.ts new file mode 100644 index 0000000..2e0cf69 --- /dev/null +++ b/src/Requests/CommonCaptchaRequest.ts @@ -0,0 +1,40 @@ +import { validateWebsiteURL } from './CaptchaRequestBase'; + +export type CommonCaptchaTask = { + type: string; + websiteURL?: string; + nocache?: boolean; + [key: string]: unknown; +}; + +export type CommonCaptchaRequestIn = { + task: CommonCaptchaTask; +}; + +/** + * Common captcha recognition request for passing a full task payload. + */ +export class CommonCaptchaRequest { + public type: string; + + public websiteURL?: string; + + public nocache?: boolean; + + [key: string]: unknown; + + constructor({ task }: CommonCaptchaRequestIn) { + if (task.type.trim().length === 0) { + throw new Error('task.type must be a non-empty string'); + } + + if (task.websiteURL !== undefined) { + validateWebsiteURL(task.websiteURL); + } + + Object.assign(this, task); + this.type = task.type; + } +} + +export class CommonCaptcha extends CommonCaptchaRequest {} diff --git a/src/Requests/ComplexImageRequestBase.ts b/src/Requests/ComplexImageRequestBase.ts index 93de55b..003fd45 100644 --- a/src/Requests/ComplexImageRequestBase.ts +++ b/src/Requests/ComplexImageRequestBase.ts @@ -48,6 +48,6 @@ export class ComplexImageRequestBase extends CaptchaRequestBase { this.imagesBase64 = imagesBase64; this.metadata = metaData; this.userAgent = userAgent; - this.websiteURL = websiteURL; + this.websiteURL = websiteURL === undefined ? undefined : this.validateWebsiteURL(websiteURL); } } diff --git a/src/Requests/ComplexImageTaskRecognitionRequestBase.ts b/src/Requests/ComplexImageTaskRecognitionRequestBase.ts index cd746d3..6a062fc 100644 --- a/src/Requests/ComplexImageTaskRecognitionRequestBase.ts +++ b/src/Requests/ComplexImageTaskRecognitionRequestBase.ts @@ -3,6 +3,7 @@ import { CaptchaRequestBase, CaptchaRequestBaseIn } from './CaptchaRequestBase'; type metaData = { Task: string; TaskArgument?: string; + PayloadType?: string; }; export type ComplexImageRecognitionRequestBaseIn = { diff --git a/src/Requests/DataDomeRequest/DataDomeRequestBase.ts b/src/Requests/DataDomeRequest/DataDomeRequestBase.ts index e164d2d..2fa11f2 100644 --- a/src/Requests/DataDomeRequest/DataDomeRequestBase.ts +++ b/src/Requests/DataDomeRequest/DataDomeRequestBase.ts @@ -54,7 +54,7 @@ export abstract class DataDomeRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: DataDomeRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.metadata = metadata; this.userAgent = userAgent; this.class = _class; diff --git a/src/Requests/FriendlyRequest/FriendlyRequest.ts b/src/Requests/FriendlyRequest/FriendlyRequest.ts new file mode 100644 index 0000000..7dafeb4 --- /dev/null +++ b/src/Requests/FriendlyRequest/FriendlyRequest.ts @@ -0,0 +1,23 @@ +import { TaskType } from '../../TaskType'; +import { FriendlyRequestBase, FriendlyRequestBaseIn } from './FriendlyRequestBase'; +import { ProxyInfo, ProxyInfoIn } from '../ProxyInfo'; + +export type FriendlyRequestIn = Pick> & { + proxy?: ProxyInfoIn; +}; + +/** + * Friendly Captcha recognition request. + * {@link https://docs.capmonster.cloud/docs/captchas/friendly-task/} + */ +export class FriendlyRequest extends FriendlyRequestBase { + public declare class: 'friendly'; + + constructor({ proxy, ...argsObj }: FriendlyRequestIn) { + super({ type: TaskType.CustomTask, _class: 'friendly', ...argsObj }); + + if (proxy) { + Object.assign(this, new ProxyInfo(proxy)); + } + } +} diff --git a/src/Requests/FriendlyRequest/FriendlyRequestBase.ts b/src/Requests/FriendlyRequest/FriendlyRequestBase.ts new file mode 100644 index 0000000..d03b56d --- /dev/null +++ b/src/Requests/FriendlyRequest/FriendlyRequestBase.ts @@ -0,0 +1,52 @@ +import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase'; + +export type FriendlyMetadata = { + apiGetLib: string; +}; + +export type FriendlyRequestBaseIn = { + websiteURL: string; + websiteKey: string; + userAgent?: string; + metadata: FriendlyMetadata; + _class: string; +} & CaptchaRequestBaseIn; + +/** + * Base Friendly Captcha recognition request + */ +export abstract class FriendlyRequestBase extends CaptchaRequestBase { + /** + * Address of a webpage with Friendly Captcha. + */ + public websiteURL!: string; + + /** + * Friendly Captcha sitekey. + */ + public websiteKey!: string; + + /** + * Browser User-Agent. Pass only the actual UA from Windows OS + */ + public userAgent?: string; + + /** + * Additional metadata required to solve Friendly Captcha. + */ + public metadata!: FriendlyMetadata; + + /** + * Class of captcha object + */ + public class: string; + + constructor({ type, nocache, websiteURL, websiteKey, userAgent, metadata, _class }: FriendlyRequestBaseIn) { + super({ type, nocache }); + this.websiteURL = this.validateWebsiteURL(websiteURL); + this.websiteKey = websiteKey; + this.userAgent = userAgent; + this.metadata = metadata; + this.class = _class; + } +} diff --git a/src/Requests/FriendlyRequest/index.ts b/src/Requests/FriendlyRequest/index.ts new file mode 100644 index 0000000..32c0dcc --- /dev/null +++ b/src/Requests/FriendlyRequest/index.ts @@ -0,0 +1 @@ +export * from './FriendlyRequest'; diff --git a/src/Requests/FunCaptchaRequest/FunCaptchaRequestBase.ts b/src/Requests/FunCaptchaRequest/FunCaptchaRequestBase.ts index 60f1e68..911370d 100644 --- a/src/Requests/FunCaptchaRequest/FunCaptchaRequestBase.ts +++ b/src/Requests/FunCaptchaRequest/FunCaptchaRequestBase.ts @@ -6,6 +6,7 @@ export type FunCaptchaRequestBaseIn = { funcaptchaApiJSSubdomain?: string; data?: string; cookies?: string; + userAgent?: string; } & CaptchaRequestBaseIn; /** @@ -49,12 +50,27 @@ export abstract class FunCaptchaRequestBase extends CaptchaRequestBase { */ public cookies?: string; - constructor({ type, nocache, websiteURL, websitePublicKey, funcaptchaApiJSSubdomain, data, cookies }: FunCaptchaRequestBaseIn) { + /** + * Browser's User-Agent which is used in emulation. + */ + public userAgent?: string; + + constructor({ + type, + nocache, + websiteURL, + websitePublicKey, + funcaptchaApiJSSubdomain, + data, + cookies, + userAgent, + }: FunCaptchaRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websitePublicKey = websitePublicKey; this.funcaptchaApiJSSubdomain = funcaptchaApiJSSubdomain; this.data = data; this.cookies = cookies; + this.userAgent = userAgent; } } diff --git a/src/Requests/GeeTestRequest/GeeTestRequestBase.ts b/src/Requests/GeeTestRequest/GeeTestRequestBase.ts index 07643fd..f259404 100644 --- a/src/Requests/GeeTestRequest/GeeTestRequestBase.ts +++ b/src/Requests/GeeTestRequest/GeeTestRequestBase.ts @@ -86,7 +86,7 @@ export abstract class GeeTestRequestBase extends CaptchaRequestBase { initParameters, }: GeeTestRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.gt = gt; this.challenge = challenge; this.geetestApiServerSubdomain = geetestApiServerSubdomain; diff --git a/src/Requests/HCaptchaRequest/HCaptchaRequestBase.ts b/src/Requests/HCaptchaRequest/HCaptchaRequestBase.ts index f2b9154..055d08f 100644 --- a/src/Requests/HCaptchaRequest/HCaptchaRequestBase.ts +++ b/src/Requests/HCaptchaRequest/HCaptchaRequestBase.ts @@ -58,7 +58,7 @@ export abstract class HCaptchaRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, websiteKey, isInvisible, data, userAgent, cookies, fallbackToActualUA }: HCaptchaRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.isInvisible = isInvisible; this.data = data; diff --git a/src/Requests/HuntRequest/HuntRequestBase.ts b/src/Requests/HuntRequest/HuntRequestBase.ts index 2948aea..a7bfc0a 100644 --- a/src/Requests/HuntRequest/HuntRequestBase.ts +++ b/src/Requests/HuntRequest/HuntRequestBase.ts @@ -55,7 +55,7 @@ export abstract class HuntRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: HuntRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.userAgent = userAgent; this.metadata = metadata; this.class = _class; diff --git a/src/Requests/ImpervaRequest/ImpervaRequest.ts b/src/Requests/ImpervaRequest/ImpervaRequest.ts index 03ee77d..5213540 100644 --- a/src/Requests/ImpervaRequest/ImpervaRequest.ts +++ b/src/Requests/ImpervaRequest/ImpervaRequest.ts @@ -2,16 +2,22 @@ import { TaskType } from '../../TaskType'; import { ImpervaRequestBase, ImpervaRequestBaseIn } from './ImpervaRequestBase'; import { ProxyInfo, ProxyInfoIn } from '../ProxyInfo'; -export type ImpervaRequestIn = Pick> & { proxy: ProxyInfoIn }; +export type ImpervaRequestIn = Pick> & { + proxy?: ProxyInfoIn; +}; + /** - * Imperva recognition request. - * {@link https://zenno.link/doc-imperva-en} + * Imperva (Incapsula) recognition request. + * {@link https://docs.capmonster.cloud/docs/captchas/incapsula/} */ export class ImpervaRequest extends ImpervaRequestBase { public declare class: 'Imperva'; constructor({ proxy, ...argsObj }: ImpervaRequestIn) { super({ type: TaskType.CustomTask, _class: 'Imperva', ...argsObj }); - Object.assign(this, new ProxyInfo(proxy)); + + if (proxy) { + Object.assign(this, new ProxyInfo(proxy)); + } } } diff --git a/src/Requests/ImpervaRequest/ImpervaRequestBase.ts b/src/Requests/ImpervaRequest/ImpervaRequestBase.ts index c593692..bc66266 100644 --- a/src/Requests/ImpervaRequest/ImpervaRequestBase.ts +++ b/src/Requests/ImpervaRequest/ImpervaRequestBase.ts @@ -1,44 +1,54 @@ import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase'; +export type ImpervaMetadata = { + /** + * Incapsula JS resource path or URL. + * @example "_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3" + */ + incapsulaScriptUrl: string; + /** + * Cookies from the Incapsula challenge page (`document.cookie` or `Set-Cookie` header). + * @example "incap_ses_1166_2930313=...; visid_incap_2930313=..." + */ + incapsulaCookies: string; + /** + * Reese84 fingerprint endpoint (request path ending with `?d=site.com`). + */ + reese84UrlEndpoint?: string; +}; + export type ImpervaRequestBaseIn = { websiteURL: string; - metadata: { - incapsulaScriptBase64: string; - incapsulaSessionCookie: string; - reese84UrlEndpoint?: string; - }; + metadata: ImpervaMetadata; userAgent?: string; _class: string; } & CaptchaRequestBaseIn; /** - * Base Imperva recognition request + * Base Imperva (Incapsula) recognition request. + * {@link https://docs.capmonster.cloud/docs/captchas/incapsula/} */ export abstract class ImpervaRequestBase extends CaptchaRequestBase { /** - * Address of a webpage with Imperva. + * Address of the main page where Incapsula is located. */ public websiteURL!: string; - public metadata: { - incapsulaScriptBase64: string; - incapsulaSessionCookie: string; - reese84UrlEndpoint?: string; - }; + public metadata: ImpervaMetadata; /** - * Browser User-Agent. Pass only the actual UA from Windows OS + * Browser User-Agent. Pass only the actual UA from Windows OS. */ public userAgent?: string; /** - * Class of captcha object + * Class of captcha object. */ public class: string; constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: ImpervaRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.metadata = metadata; this.userAgent = userAgent; this.class = _class; diff --git a/src/Requests/ImpervaRequest/index.ts b/src/Requests/ImpervaRequest/index.ts index b1c8f85..5dda248 100644 --- a/src/Requests/ImpervaRequest/index.ts +++ b/src/Requests/ImpervaRequest/index.ts @@ -1 +1,2 @@ export * from './ImpervaRequest'; +export type { ImpervaMetadata } from './ImpervaRequestBase'; diff --git a/src/Requests/MTCaptchaRequest/MTCaptchaRequestBase.ts b/src/Requests/MTCaptchaRequest/MTCaptchaRequestBase.ts index 9280386..35291d5 100644 --- a/src/Requests/MTCaptchaRequest/MTCaptchaRequestBase.ts +++ b/src/Requests/MTCaptchaRequest/MTCaptchaRequestBase.ts @@ -39,7 +39,7 @@ export abstract class MTCaptchaRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, websiteKey, userAgent, pageAction, isInvisible }: MTCaptchaRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.userAgent = userAgent; this.pageAction = pageAction; diff --git a/src/Requests/ProsopoRequest/ProsopoRequestBase.ts b/src/Requests/ProsopoRequest/ProsopoRequestBase.ts index 782a94e..4b9a34f 100644 --- a/src/Requests/ProsopoRequest/ProsopoRequestBase.ts +++ b/src/Requests/ProsopoRequest/ProsopoRequestBase.ts @@ -21,7 +21,7 @@ export abstract class ProsopoRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, websiteKey }: ProsopoRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; } } diff --git a/src/Requests/RecaptchaV2EnterpriseRequest/RecaptchaV2EnterpriseRequestBase.ts b/src/Requests/RecaptchaV2EnterpriseRequest/RecaptchaV2EnterpriseRequestBase.ts index 5854148..60cf243 100644 --- a/src/Requests/RecaptchaV2EnterpriseRequest/RecaptchaV2EnterpriseRequestBase.ts +++ b/src/Requests/RecaptchaV2EnterpriseRequest/RecaptchaV2EnterpriseRequestBase.ts @@ -7,6 +7,8 @@ export type RecaptchaV2EnterpriseRequestBaseIn = { recaptchaDataSValue?: string; userAgent?: string; pageAction?: string; + apiDomain?: string; + cookies?: string; } & CaptchaRequestBaseIn; /** @@ -59,6 +61,16 @@ export abstract class RecaptchaV2EnterpriseRequestBase extends CaptchaRequestBas // The action name passed to grecaptcha.execute(). public pageAction?: string; + /** + * Domain that hosts the reCAPTCHA API interface. + */ + public apiDomain?: string; + + /** + * Additional cookies which we must use during interaction with target page or Google. + */ + public cookies?: string; + constructor({ type, nocache, @@ -68,13 +80,17 @@ export abstract class RecaptchaV2EnterpriseRequestBase extends CaptchaRequestBas recaptchaDataSValue, userAgent, pageAction, + apiDomain, + cookies, }: RecaptchaV2EnterpriseRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.enterprisePayload = enterprisePayload; this.recaptchaDataSValue = recaptchaDataSValue; this.userAgent = userAgent; this.pageAction = pageAction; + this.apiDomain = apiDomain; + this.cookies = cookies; } } diff --git a/src/Requests/RecaptchaV2Request/RecaptchaV2RequestBase.ts b/src/Requests/RecaptchaV2Request/RecaptchaV2RequestBase.ts index 51b8ac3..9e71ca9 100644 --- a/src/Requests/RecaptchaV2Request/RecaptchaV2RequestBase.ts +++ b/src/Requests/RecaptchaV2Request/RecaptchaV2RequestBase.ts @@ -6,6 +6,7 @@ export type RecaptchaV2RequestBaseIn = { recaptchaDataSValue?: string; userAgent?: string; cookies?: string; + isInvisible?: boolean; } & CaptchaRequestBaseIn; /** @@ -43,12 +44,18 @@ export abstract class RecaptchaV2RequestBase extends CaptchaRequestBase { */ public cookies?: string; - constructor({ type, nocache, websiteURL, websiteKey, recaptchaDataSValue, userAgent, cookies }: RecaptchaV2RequestBaseIn) { + /** + * Set true for invisible version of reCAPTCHA v2. + */ + public isInvisible?: boolean; + + constructor({ type, nocache, websiteURL, websiteKey, recaptchaDataSValue, userAgent, cookies, isInvisible }: RecaptchaV2RequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.recaptchaDataSValue = recaptchaDataSValue; this.userAgent = userAgent; this.cookies = cookies; + this.isInvisible = isInvisible; } } diff --git a/src/Requests/RecaptchaV3EnterpriseRequest/RecaptchaV3EnterpriseRequestBase.ts b/src/Requests/RecaptchaV3EnterpriseRequest/RecaptchaV3EnterpriseRequestBase.ts index 12131da..f83c314 100644 --- a/src/Requests/RecaptchaV3EnterpriseRequest/RecaptchaV3EnterpriseRequestBase.ts +++ b/src/Requests/RecaptchaV3EnterpriseRequest/RecaptchaV3EnterpriseRequestBase.ts @@ -38,7 +38,7 @@ export abstract class RecaptchaV3EnterpriseRequestBase extends CaptchaRequestBas constructor({ type, nocache, websiteURL, websiteKey, userAgent, pageAction, minScore }: RecaptchaV3EnterpriseRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.userAgent = userAgent; this.pageAction = pageAction; diff --git a/src/Requests/RecaptchaV3ProxylessRequest.ts b/src/Requests/RecaptchaV3ProxylessRequest.ts index 8b9af49..12d2a14 100644 --- a/src/Requests/RecaptchaV3ProxylessRequest.ts +++ b/src/Requests/RecaptchaV3ProxylessRequest.ts @@ -6,6 +6,7 @@ type RecaptchaV3RequestIn = { websiteKey: string; minScore?: number; pageAction?: string; + isEnterprise?: boolean; } & CaptchaRequestBaseIn; export type RecaptchaV3ProxylessRequestIn = Pick>; @@ -44,11 +45,17 @@ export class RecaptchaV3ProxylessRequest extends CaptchaRequestBase { */ public pageAction: string; - constructor({ nocache, websiteURL, websiteKey, minScore, pageAction = 'verify' }: RecaptchaV3ProxylessRequestIn) { + /** + * Set true to solve reCAPTCHA v3 Enterprise with the same request shape. + */ + public isEnterprise?: boolean; + + constructor({ nocache, websiteURL, websiteKey, minScore, pageAction = 'verify', isEnterprise }: RecaptchaV3ProxylessRequestIn) { super({ type: TaskType.RecaptchaV3TaskProxyless, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.minScore = minScore; this.pageAction = pageAction; + this.isEnterprise = isEnterprise; } } diff --git a/src/Requests/RequestsSerialization.u.spec.ts b/src/Requests/RequestsSerialization.u.spec.ts index b42d787..2084854 100644 --- a/src/Requests/RequestsSerialization.u.spec.ts +++ b/src/Requests/RequestsSerialization.u.spec.ts @@ -1,4 +1,5 @@ import { DataDomeRequest } from './DataDomeRequest'; +import { ImpervaRequest } from './ImpervaRequest'; import { SerializeObject } from './RequestsSerialization'; import { CapMonsterModules } from '../CapMonsterModules'; import { RecaptchaV2Request } from './RecaptchaV2Request'; @@ -14,9 +15,44 @@ import { ComplexImageRecaptchaRequest } from './ComplexImageRecaptchaRequest'; import { ComplexImageFunCaptchaRequest } from './ComplexImageFunCaptchaRequest'; import { AmazonRequest } from './AmazonRequest'; import { AltchaRequest } from './AltchaRequest'; +import { AlibabaRequest } from './AlibabaRequest'; +import { FriendlyRequest } from './FriendlyRequest'; import { RecaptchaV3EnterpriseRequest } from './RecaptchaV3EnterpriseRequest'; +import { CommonCaptchaRequest } from './CommonCaptchaRequest'; describe('Check unit tests for SerializeObject()', () => { + it(`should serialize CommonCaptchaRequest`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new CommonCaptchaRequest({ + task: { + type: 'RecaptchaV2Task', + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high', + websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'RecaptchaV2Task', + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high', + websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + }, + }); + }); + + it(`should throw for invalid websiteURL`, () => { + expect( + () => + new RecaptchaV2Request({ + websiteURL: 'websiteURL', + websiteKey: 'websiteKey', + }), + ).toThrow('websiteURL must be a valid http or https URL'); + }); + it(`should serialize RecaptchaV2ProxylessRequest`, () => { const serialized = SerializeObject({ clientKey: '', @@ -26,6 +62,7 @@ describe('Check unit tests for SerializeObject()', () => { recaptchaDataSValue: 'some data-s value', userAgent: 'PostmanRuntime/7.29.0', cookies: 'cookieA=value#A;cookieB=value#B', + isInvisible: true, }), }); @@ -38,6 +75,7 @@ describe('Check unit tests for SerializeObject()', () => { recaptchaDataSValue: 'some data-s value', userAgent: 'PostmanRuntime/7.29.0', cookies: 'cookieA=value#A;cookieB=value#B', + isInvisible: true, }, }); }); @@ -51,6 +89,7 @@ describe('Check unit tests for SerializeObject()', () => { recaptchaDataSValue: 'some data-s value', userAgent: 'PostmanRuntime/7.29.0', cookies: 'cookieA=value#A;cookieB=value#B', + isInvisible: true, proxy: { proxyType: 'socks4', proxyAddress: 'https://proxy.com', @@ -75,6 +114,7 @@ describe('Check unit tests for SerializeObject()', () => { proxyPort: 6045, proxyLogin: 'login', proxyPassword: 'p@ssword', + isInvisible: true, }, }); }); @@ -114,6 +154,7 @@ describe('Check unit tests for SerializeObject()', () => { websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', minScore: 0.6, pageAction: 'some-action', + isEnterprise: true, }), }); @@ -125,6 +166,7 @@ describe('Check unit tests for SerializeObject()', () => { websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', minScore: 0.6, pageAction: 'some-action', + isEnterprise: true, }, }); }); @@ -137,6 +179,7 @@ describe('Check unit tests for SerializeObject()', () => { websitePublicKey: '69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC', data: '{"blob":"dyXvXANMbHj1iDyz.Qj97JtSqR2n%2BuoY1V%2FbdgbrG7p%2FmKiqdU9AwJ6MifEt0np4vfYn6TTJDJEfZDlcz9Q1XMn9przeOV%2FCr2%2FIpi%2FC1s%3D"}', funcaptchaApiJSSubdomain: 'mywebsite-api.funcaptcha.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', }), }); @@ -148,6 +191,7 @@ describe('Check unit tests for SerializeObject()', () => { websitePublicKey: '69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC', data: '{"blob":"dyXvXANMbHj1iDyz.Qj97JtSqR2n%2BuoY1V%2FbdgbrG7p%2FmKiqdU9AwJ6MifEt0np4vfYn6TTJDJEfZDlcz9Q1XMn9przeOV%2FCr2%2FIpi%2FC1s%3D"}', funcaptchaApiJSSubdomain: 'mywebsite-api.funcaptcha.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', }, }); }); @@ -160,6 +204,7 @@ describe('Check unit tests for SerializeObject()', () => { websitePublicKey: '69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC', data: '{"blob":"dyXvXANMbHj1iDyz.Qj97JtSqR2n%2BuoY1V%2FbdgbrG7p%2FmKiqdU9AwJ6MifEt0np4vfYn6TTJDJEfZDlcz9Q1XMn9przeOV%2FCr2%2FIpi%2FC1s%3D"}', funcaptchaApiJSSubdomain: 'mywebsite-api.funcaptcha.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', proxy: { proxyType: 'socks5', proxyAddress: 'https://proxy.com', @@ -178,6 +223,7 @@ describe('Check unit tests for SerializeObject()', () => { websitePublicKey: '69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC', data: '{"blob":"dyXvXANMbHj1iDyz.Qj97JtSqR2n%2BuoY1V%2FbdgbrG7p%2FmKiqdU9AwJ6MifEt0np4vfYn6TTJDJEfZDlcz9Q1XMn9przeOV%2FCr2%2FIpi%2FC1s%3D"}', funcaptchaApiJSSubdomain: 'mywebsite-api.funcaptcha.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', proxyType: 'socks5', proxyAddress: 'https://proxy.com', proxyPort: 6045, @@ -206,7 +252,7 @@ describe('Check unit tests for SerializeObject()', () => { websiteKey: '472fc7af-86a4-4382-9a49-ca9090474471', isInvisible: true, data: 'some data', - userAgent: expect(null == undefined).toBe(true), + userAgent: expect(true).toBe(true), }, }); }); @@ -237,7 +283,7 @@ describe('Check unit tests for SerializeObject()', () => { websiteKey: '472fc7af-86a4-4382-9a49-ca9090474471', isInvisible: true, data: 'some data', - userAgent: expect(null == undefined).toBe(true), + userAgent: expect(true).toBe(true), proxyType: 'https', proxyAddress: 'https://proxy.com', proxyPort: 6045, @@ -381,6 +427,8 @@ describe('Check unit tests for SerializeObject()', () => { enterprisePayload: { s: 'SOME_ADDITIONAL_TOKEN', }, + apiDomain: 'www.recaptcha.net', + cookies: 'cookieA=value#A', }), }); @@ -393,6 +441,8 @@ describe('Check unit tests for SerializeObject()', () => { enterprisePayload: { s: 'SOME_ADDITIONAL_TOKEN', }, + apiDomain: 'www.recaptcha.net', + cookies: 'cookieA=value#A', }, }); }); @@ -408,6 +458,8 @@ describe('Check unit tests for SerializeObject()', () => { s: 'SOME_ADDITIONAL_TOKEN', }, pageAction: 'login', + apiDomain: 'www.recaptcha.net', + cookies: 'cookieA=value#A', proxy: { proxyType: 'http', proxyAddress: '8.8.8.8', @@ -433,6 +485,9 @@ describe('Check unit tests for SerializeObject()', () => { proxyLogin: 'proxyLoginHere', proxyPassword: 'proxyPasswordHere', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.132 Safari/537.36', + pageAction: 'login', + apiDomain: 'www.recaptcha.net', + cookies: 'cookieA=value#A', }, }); }); @@ -550,7 +605,7 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new DataDomeRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { captchaUrl: 'https://geo.captcha-delivery.com/captcha/?initialCid=12434324', @@ -565,7 +620,7 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'DataDome', - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { captchaUrl: 'https://geo.captcha-delivery.com/captcha/?initialCid=12434324', @@ -580,7 +635,7 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new DataDomeRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { captchaUrl: 'https://geo.captcha-delivery.com/captcha/?initialCid=12434324', @@ -601,7 +656,7 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'DataDome', - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { captchaUrl: 'https://geo.captcha-delivery.com/captcha/?initialCid=12434324', @@ -616,11 +671,80 @@ describe('Check unit tests for SerializeObject()', () => { }); }); + it(`should serialize ImpervaRequest`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new ImpervaRequest({ + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'incap_ses_1166_2930313=br7iX33ZNCtf3HlpEXcuEDzz72cAAAAA0suDnBGrq/iA0J4oERYzjQ==', + reese84UrlEndpoint: 'Built-with-the-For-hopence-Hurleysurfecting-the-', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'Imperva', + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'incap_ses_1166_2930313=br7iX33ZNCtf3HlpEXcuEDzz72cAAAAA0suDnBGrq/iA0J4oERYzjQ==', + reese84UrlEndpoint: 'Built-with-the-For-hopence-Hurleysurfecting-the-', + }, + }, + }); + }); + + it(`should serialize ImpervaRequest with proxy`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new ImpervaRequest({ + websiteURL: 'https://www.example.com', + metadata: { + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'incap_ses_1166_2930313=br7iX33ZNCtf3HlpEXcuEDzz72cAAAAA0suDnBGrq/iA0J4oERYzjQ==', + }, + proxy: { + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'Imperva', + websiteURL: 'https://www.example.com', + metadata: { + incapsulaScriptUrl: '_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3', + incapsulaCookies: 'incap_ses_1166_2930313=br7iX33ZNCtf3HlpEXcuEDzz72cAAAAA0suDnBGrq/iA0J4oERYzjQ==', + }, + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }); + }); + it(`should serialize AltchaRequest`, () => { const serialized = SerializeObject({ clientKey: '', task: new AltchaRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', + websiteKey: 'websiteKey', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { challenge: '3dd28253be6cc0c54d95f7f98c517e68744597cc6e66109619d1ac975c39181c', @@ -636,7 +760,8 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'altcha', - websiteURL: 'site.com', + websiteURL: 'https://site.com', + websiteKey: 'websiteKey', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { challenge: '3dd28253be6cc0c54d95f7f98c517e68744597cc6e66109619d1ac975c39181c', @@ -652,7 +777,8 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new AltchaRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', + websiteKey: 'websiteKey', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { challenge: '3dd28253be6cc0c54d95f7f98c517e68744597cc6e66109619d1ac975c39181c', @@ -675,7 +801,8 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'altcha', - websiteURL: 'site.com', + websiteURL: 'https://site.com', + websiteKey: 'websiteKey', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', metadata: { challenge: '3dd28253be6cc0c54d95f7f98c517e68744597cc6e66109619d1ac975c39181c', @@ -696,9 +823,12 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new TenDIRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + metadata: { + captchaUrl: 'https://example.com/captcha', + }, }), }); @@ -707,9 +837,12 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'TenDI', - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + metadata: { + captchaUrl: 'https://example.com/captcha', + }, }, }); }); @@ -718,9 +851,12 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new TenDIRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + metadata: { + captchaUrl: 'https://example.com/captcha', + }, proxy: { proxyType: 'socks4', proxyAddress: 'https://proxy.com', @@ -736,9 +872,12 @@ describe('Check unit tests for SerializeObject()', () => { task: { type: 'CustomTask', class: 'TenDI', - websiteURL: 'site.com', + websiteURL: 'https://site.com', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + metadata: { + captchaUrl: 'https://example.com/captcha', + }, proxyType: 'socks4', proxyAddress: 'https://proxy.com', proxyPort: 6045, @@ -752,12 +891,13 @@ describe('Check unit tests for SerializeObject()', () => { const serialized = SerializeObject({ clientKey: '', task: new AmazonRequest({ - websiteURL: 'site.com', + websiteURL: 'https://site.com', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', challengeScript: 'https://41bcdd4fb3cb.610cd090.us-east-1.token.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/challenge.js', captchaScript: 'https://41bcdd4fb3cb.610cd090.us-east-1.captcha.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/captcha.js', context: 'qoJYgnKsc...aormh/dYYK+Y=', iv: 'CgAAXFFFFSAAABVk', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', }), }); @@ -765,12 +905,151 @@ describe('Check unit tests for SerializeObject()', () => { clientKey: '', task: { type: 'AmazonTask', - websiteURL: 'site.com', + websiteURL: 'https://site.com', websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', challengeScript: 'https://41bcdd4fb3cb.610cd090.us-east-1.token.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/challenge.js', captchaScript: 'https://41bcdd4fb3cb.610cd090.us-east-1.captcha.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/captcha.js', context: 'qoJYgnKsc...aormh/dYYK+Y=', iv: 'CgAAXFFFFSAAABVk', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + }, + }); + }); + + it(`should serialize AlibabaRequest`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new AlibabaRequest({ + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'alibaba', + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + }, + }, + }); + }); + + it(`should serialize AlibabaRequest with proxy`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new AlibabaRequest({ + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + userId: 'HpadJlQnz2zSKcSmjXBaqQvjYUvP4jMJIk/ZwGNDNiM=', + }, + proxy: { + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'alibaba', + websiteURL: 'https://www.example.com', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + sceneId: '1ww7426c4', + prefix: 'dlw3kug', + userId: 'HpadJlQnz2zSKcSmjXBaqQvjYUvP4jMJIk/ZwGNDNiM=', + }, + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }); + }); + + it(`should serialize FriendlyRequest`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new FriendlyRequest({ + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'friendly', + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + }, + }); + }); + + it(`should serialize FriendlyRequest with proxy`, () => { + const serialized = SerializeObject({ + clientKey: '', + task: new FriendlyRequest({ + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + proxy: { + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', + }, + }), + }); + + expect(serialized).toMatchObject({ + clientKey: '', + task: { + type: 'CustomTask', + class: 'friendly', + websiteURL: 'https://example.com', + websiteKey: 'FFMGEMAD2K3JJ35P', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + metadata: { + apiGetLib: 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.15/widget.module.min.js', + }, + proxyType: 'http', + proxyAddress: '8.8.8.8', + proxyPort: 8080, + proxyLogin: 'proxyLoginHere', + proxyPassword: 'proxyPasswordHere', }, }); }); diff --git a/src/Requests/TSPDRequest/TSPDRequestBase.ts b/src/Requests/TSPDRequest/TSPDRequestBase.ts index f732941..a79e842 100644 --- a/src/Requests/TSPDRequest/TSPDRequestBase.ts +++ b/src/Requests/TSPDRequest/TSPDRequestBase.ts @@ -54,7 +54,7 @@ export abstract class TSPDRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: TSPDRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.userAgent = userAgent; this.metadata = metadata; this.class = _class; diff --git a/src/Requests/Task.ts b/src/Requests/Task.ts index 741de75..b9ad1b4 100644 --- a/src/Requests/Task.ts +++ b/src/Requests/Task.ts @@ -23,7 +23,10 @@ import { YidunRequest } from './YidunRequest'; import { MTCaptchaRequest } from './MTCaptchaRequest'; import { CastleRequest } from './CastleRequest'; import { HuntRequest } from './HuntRequest'; +import { AlibabaRequest } from './AlibabaRequest'; +import { FriendlyRequest } from './FriendlyRequest'; import { TSPDRequest } from './TSPDRequest'; +import { CommonCaptchaRequest } from './CommonCaptchaRequest'; /** * Universal type for recognition request @@ -54,4 +57,7 @@ export type Task = | MTCaptchaRequest | CastleRequest | TSPDRequest - | HuntRequest; + | HuntRequest + | AlibabaRequest + | FriendlyRequest + | CommonCaptchaRequest; diff --git a/src/Requests/TemuRequest/TemuRequestBase.ts b/src/Requests/TemuRequest/TemuRequestBase.ts index 04acf99..b0b2526 100644 --- a/src/Requests/TemuRequest/TemuRequestBase.ts +++ b/src/Requests/TemuRequest/TemuRequestBase.ts @@ -36,7 +36,7 @@ export abstract class TemuRequestBase extends CaptchaRequestBase { constructor({ type, nocache, websiteURL, userAgent, metadata, _class }: TemuRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.metadata = metadata; this.userAgent = userAgent; this.class = _class; diff --git a/src/Requests/TenDIRequest/TenDIRequestBase.ts b/src/Requests/TenDIRequest/TenDIRequestBase.ts index 3bfb2d9..0893f23 100644 --- a/src/Requests/TenDIRequest/TenDIRequestBase.ts +++ b/src/Requests/TenDIRequest/TenDIRequestBase.ts @@ -1,9 +1,14 @@ import { CaptchaRequestBase, CaptchaRequestBaseIn } from '../CaptchaRequestBase'; +export type TenDIMetadata = { + captchaUrl?: string; +}; + export type TenDIRequestBaseIn = { websiteURL: string; websiteKey: string; userAgent?: string; + metadata?: TenDIMetadata; _class: string; } & CaptchaRequestBaseIn; @@ -26,16 +31,22 @@ export abstract class TenDIRequestBase extends CaptchaRequestBase { */ public userAgent?: string; + /** + * Additional metadata required to solve TenDI. + */ + public metadata?: TenDIMetadata; + /** * Class of captcha object */ public class: string; - constructor({ type, nocache, websiteURL, userAgent, websiteKey, _class }: TenDIRequestBaseIn) { + constructor({ type, nocache, websiteURL, userAgent, websiteKey, metadata, _class }: TenDIRequestBaseIn) { super({ type, nocache }); - this.websiteURL = websiteURL; + this.websiteURL = this.validateWebsiteURL(websiteURL); this.websiteKey = websiteKey; this.userAgent = userAgent; + this.metadata = metadata; this.class = _class; } } diff --git a/src/Requests/TurnstileRequest/Turnstile.i.spec.ts b/src/Requests/TurnstileRequest/Turnstile.i.spec.ts index 4acaed3..2d30b5f 100644 --- a/src/Requests/TurnstileRequest/Turnstile.i.spec.ts +++ b/src/Requests/TurnstileRequest/Turnstile.i.spec.ts @@ -33,6 +33,7 @@ describe('Check integration tests for TurnstileTask', () => { pageData: 'pageDataHere', data: 'dataHere', htmlPageBase64: 'htmlPageBase64Here', + apiJsUrl: 'https://challenges.cloudflare.com/turnstile/v0/api.js', userAgent: 'userAgentHere', }); @@ -40,7 +41,7 @@ describe('Check integration tests for TurnstileTask', () => { expect(srv.caughtRequests[0]).toHaveProperty( 'body', - '{"clientKey":"","task":{"type":"TurnstileTask","websiteURL":"https://tsinvisble.zlsupport.com","websiteKey":"0x4AAAAAAABUY0VLtOUMAHxE","cloudflareTaskType":"cf_clearance","userAgent":"userAgentHere","htmlPageBase64":"htmlPageBase64Here","data":"dataHere","pageData":"pageDataHere","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', + '{"clientKey":"","task":{"type":"TurnstileTask","websiteURL":"https://tsinvisble.zlsupport.com","websiteKey":"0x4AAAAAAABUY0VLtOUMAHxE","cloudflareTaskType":"cf_clearance","userAgent":"userAgentHere","htmlPageBase64":"htmlPageBase64Here","data":"dataHere","pageData":"pageDataHere","apiJsUrl":"https://challenges.cloudflare.com/turnstile/v0/api.js","proxyType":"http","proxyAddress":"8.8.8.8","proxyPort":8080,"proxyLogin":"proxyLoginHere","proxyPassword":"proxyPasswordHere"},"softId":54}', ); expect(srv.caughtRequests[1]).toHaveProperty('body', '{"clientKey":"","taskId":7654322}'); expect(task).toHaveProperty('solution'); diff --git a/src/Requests/TurnstileRequest/TurnstileRequest.ts b/src/Requests/TurnstileRequest/TurnstileRequest.ts index 6a7b62e..cd720f8 100644 --- a/src/Requests/TurnstileRequest/TurnstileRequest.ts +++ b/src/Requests/TurnstileRequest/TurnstileRequest.ts @@ -17,6 +17,7 @@ export type TurnstileCfClearanceType = Pick; diff --git a/src/Responses/FriendlyResponse.ts b/src/Responses/FriendlyResponse.ts new file mode 100644 index 0000000..b19a135 --- /dev/null +++ b/src/Responses/FriendlyResponse.ts @@ -0,0 +1,5 @@ +export type FriendlyResponse = { + data: { + token: string; + }; +}; diff --git a/src/index.ts b/src/index.ts index 8619b8d..8b975e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,7 +20,7 @@ import { DataDomeRequest, DataDomeRequestIn } from './Requests/DataDomeRequest'; import { TenDIRequest, TenDIRequestIn } from './Requests/TenDIRequest'; import { AmazonRequest, AmazonRequestIn } from './Requests/AmazonRequest'; import { BasiliskRequest, BasiliskRequestIn } from './Requests/BasiliskRequest'; -import { ImpervaRequest, ImpervaRequestIn } from './Requests/ImpervaRequest'; +import { ImpervaRequest, ImpervaRequestIn, ImpervaMetadata } from './Requests/ImpervaRequest'; import { BinanceRequest, BinanceRequestIn } from './Requests/BinanceRequest'; import { ComplexImageRecognitionRequestIn, ComplexImageTaskRecognitionRequest } from './Requests/ComplexImageTaskRecognitionRequest'; import { ProsopoRequest, ProsopoRequestIn } from './Requests/ProsopoRequest'; @@ -31,6 +31,9 @@ import { CastleRequest, CastleRequestIn } from './Requests/CastleRequest'; import { TSPDRequest, TSPDRequestIn } from './Requests/TSPDRequest'; import { HuntRequest, HuntRequestIn } from './Requests/HuntRequest'; import { AltchaRequest, AltchaRequestIn } from './Requests/AltchaRequest'; +import { AlibabaRequest, AlibabaRequestIn } from './Requests/AlibabaRequest'; +import { FriendlyRequest, FriendlyRequestIn } from './Requests/FriendlyRequest'; +import { CommonCaptcha, CommonCaptchaRequest, CommonCaptchaRequestIn, CommonCaptchaTask } from './Requests/CommonCaptchaRequest'; export default { CapMonsterCloudClientFactory, @@ -61,7 +64,11 @@ export default { TSPDRequest, HuntRequest, AltchaRequest, + AlibabaRequest, + FriendlyRequest, RecaptchaV3EnterpriseRequest, + CommonCaptchaRequest, + CommonCaptcha, }; export { @@ -103,6 +110,7 @@ export { BasiliskRequestIn, ImpervaRequest, ImpervaRequestIn, + ImpervaMetadata, BinanceRequest, BinanceRequestIn, ComplexImageTaskRecognitionRequest, @@ -123,6 +131,14 @@ export { HuntRequestIn, AltchaRequest, AltchaRequestIn, + AlibabaRequest, + AlibabaRequestIn, + FriendlyRequest, + FriendlyRequestIn, RecaptchaV3EnterpriseRequest, RecaptchaV3EnterpriseRequestIn, + CommonCaptchaRequest, + CommonCaptcha, + CommonCaptchaRequestIn, + CommonCaptchaTask, }; diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 0000000..a29e338 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ES2020", + "moduleResolution": "node", + "outDir": "dist/esm", + "declaration": false + } +} From 89444812c5f6f2dcfd5794db81a3fb2a4091e400 Mon Sep 17 00:00:00 2001 From: Kirill Bushmin Date: Thu, 30 Jul 2026 12:41:57 +0300 Subject: [PATCH 2/3] CCL-8455 updated lib --- README.md | 58 ++++- package-lock.json | 551 +++++++++++++++++++++++----------------------- package.json | 6 +- 3 files changed, 337 insertions(+), 278 deletions(-) diff --git a/README.md b/README.md index 24b85cb..5ca1eb7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,63 @@ Official JS client library for [capmonster.cloud](https://capmonster.cloud/) cap Via [NPM](https://www.npmjs.com/package/@zennolab_com/capmonstercloud-client): - npm i @zennolab_com/capmonstercloud-client +```bash +npm i @zennolab_com/capmonstercloud-client +``` + +## Quick Start + +1. Get your API key in the [CapMonster Cloud dashboard](https://capmonster.cloud/). +2. Install the package (see above). +3. Copy a snippet below, replace `YOUR_API_KEY`, and run it. + +### reCAPTCHA v2 + +```ts +import { + CapMonsterCloudClientFactory, + ClientOptions, + RecaptchaV2Request, +} from '@zennolab_com/capmonstercloud-client'; + +const client = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: 'YOUR_API_KEY' }), +); + +const result = await client.Solve( + new RecaptchaV2Request({ + websiteURL: 'https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high', + websiteKey: '6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd', + }), +); + +console.log(result.solution); // { gRecaptchaResponse: '...' } +``` + +### Cloudflare Turnstile + +```ts +import { + CapMonsterCloudClientFactory, + ClientOptions, + TurnstileRequest, +} from '@zennolab_com/capmonstercloud-client'; + +const client = CapMonsterCloudClientFactory.Create( + new ClientOptions({ clientKey: 'YOUR_API_KEY' }), +); + +const result = await client.Solve( + new TurnstileRequest({ + websiteURL: 'https://tsinvisble.zlsupport.com', + websiteKey: '0x4AAAAAAABUY0VLtOUMAHxE', + }), +); + +console.log(result.solution); // { token: '...' } +``` + +For CommonJS (`require`), see the Node usage section below. ## Usage with Node (with or without Typescript) diff --git a/package-lock.json b/package-lock.json index 1667c8b..6d2a287 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,28 +29,14 @@ "node": ">=18" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -59,9 +45,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz", - "integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -69,22 +55,22 @@ } }, "node_modules/@babel/core": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", - "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helpers": "^7.27.1", - "@babel/parser": "^7.27.1", - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -110,16 +96,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", - "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.1", - "@babel/types": "^7.27.1", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -127,14 +113,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -153,30 +139,40 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz", - "integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -196,9 +192,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -206,9 +202,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -216,9 +212,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -226,27 +222,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", - "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", - "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -495,58 +491,48 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", - "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.1", - "@babel/parser": "^7.27.1", - "@babel/template": "^7.27.1", - "@babel/types": "^7.27.1", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", - "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -702,9 +688,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", "dev": true, "license": "MIT", "dependencies": { @@ -1070,34 +1056,31 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -1112,9 +1095,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1572,9 +1555,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1674,13 +1657,6 @@ "node": ">=8" } }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -1808,21 +1784,39 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.7.tgz", + "integrity": "sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/braces": { @@ -1839,9 +1833,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", - "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -1859,10 +1853,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001716", - "electron-to-chromium": "^1.5.149", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -1922,9 +1917,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001718", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", - "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -2045,13 +2040,6 @@ "dev": true, "license": "MIT" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2191,26 +2179,10 @@ "node": ">=6.0.0" } }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/electron-to-chromium": { - "version": "1.5.155", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz", - "integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==", + "version": "1.5.398", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.398.tgz", + "integrity": "sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==", "dev": true, "license": "ISC" }, @@ -2652,39 +2624,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2731,9 +2670,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz", + "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==", "dev": true, "license": "ISC" }, @@ -2898,6 +2837,28 @@ "dev": true, "license": "MIT" }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3191,25 +3152,6 @@ "node": ">=8" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -3801,10 +3743,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -4033,16 +3985,29 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/ms": { @@ -4065,6 +4030,13 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4073,11 +4045,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -4275,9 +4250,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4629,9 +4604,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -4883,20 +4858,19 @@ } }, "node_modules/ts-jest": { - "version": "29.3.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.4.tgz", - "integrity": "sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==", + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", "dev": true, "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", - "ejs": "^3.1.10", "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.2", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -4908,11 +4882,12 @@ }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" }, "peerDependenciesMeta": { "@babel/core": { @@ -4929,6 +4904,9 @@ }, "esbuild": { "optional": true + }, + "jest-util": { + "optional": true } } }, @@ -5018,6 +4996,20 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -5026,9 +5018,9 @@ "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -5117,6 +5109,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index ad0f918..480a6f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zennolab_com/capmonstercloud-client", - "version": "2.8.0", + "version": "2.8.1", "description": "Official JS client library for https://capmonster.cloud/ captcha recognition service", "main": "dist/index.js", "module": "dist/esm/index.js", @@ -55,5 +55,9 @@ }, "dependencies": { "debug": "^4.3.4" + }, + "overrides": { + "minimatch": "^10.1.1", + "brace-expansion": "^5.0.8" } } From 71c8bf24c0dc4eb0fd7e6e10f2a1a7f2724d9333 Mon Sep 17 00:00:00 2001 From: Kirill Bushmin Date: Thu, 30 Jul 2026 13:09:28 +0300 Subject: [PATCH 3/3] CCL-8455 up version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 480a6f0..aab620d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zennolab_com/capmonstercloud-client", - "version": "2.8.1", + "version": "2.9.0", "description": "Official JS client library for https://capmonster.cloud/ captcha recognition service", "main": "dist/index.js", "module": "dist/esm/index.js",