gatsbie 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/dist/index.d.mts +265 -0
- package/dist/index.d.ts +265 -0
- package/dist/index.js +395 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +364 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
APIError: () => APIError,
|
|
24
|
+
Client: () => Client,
|
|
25
|
+
ErrorCode: () => ErrorCode,
|
|
26
|
+
GatsbieError: () => GatsbieError,
|
|
27
|
+
RequestError: () => RequestError
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/errors.ts
|
|
32
|
+
var ErrorCode = {
|
|
33
|
+
AUTH_FAILED: "AUTH_FAILED",
|
|
34
|
+
INSUFFICIENT_CREDITS: "INSUFFICIENT_CREDITS",
|
|
35
|
+
INVALID_REQUEST: "INVALID_REQUEST",
|
|
36
|
+
UPSTREAM_ERROR: "UPSTREAM_ERROR",
|
|
37
|
+
SOLVE_FAILED: "SOLVE_FAILED",
|
|
38
|
+
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
39
|
+
};
|
|
40
|
+
var GatsbieError = class _GatsbieError extends Error {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.name = "GatsbieError";
|
|
44
|
+
Object.setPrototypeOf(this, _GatsbieError.prototype);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var APIError = class _APIError extends GatsbieError {
|
|
48
|
+
code;
|
|
49
|
+
details;
|
|
50
|
+
timestamp;
|
|
51
|
+
httpStatus;
|
|
52
|
+
constructor(options) {
|
|
53
|
+
const msg = options.details ? `gatsbie: ${options.code}: ${options.message} (${options.details})` : `gatsbie: ${options.code}: ${options.message}`;
|
|
54
|
+
super(msg);
|
|
55
|
+
this.name = "APIError";
|
|
56
|
+
this.code = options.code;
|
|
57
|
+
this.details = options.details;
|
|
58
|
+
this.timestamp = options.timestamp;
|
|
59
|
+
this.httpStatus = options.httpStatus;
|
|
60
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
61
|
+
}
|
|
62
|
+
/** Check if this is an authentication error. */
|
|
63
|
+
isAuthError() {
|
|
64
|
+
return this.code === ErrorCode.AUTH_FAILED;
|
|
65
|
+
}
|
|
66
|
+
/** Check if this error is due to insufficient credits. */
|
|
67
|
+
isInsufficientCredits() {
|
|
68
|
+
return this.code === ErrorCode.INSUFFICIENT_CREDITS;
|
|
69
|
+
}
|
|
70
|
+
/** Check if this error is due to an invalid request. */
|
|
71
|
+
isInvalidRequest() {
|
|
72
|
+
return this.code === ErrorCode.INVALID_REQUEST;
|
|
73
|
+
}
|
|
74
|
+
/** Check if this error is from an upstream service. */
|
|
75
|
+
isUpstreamError() {
|
|
76
|
+
return this.code === ErrorCode.UPSTREAM_ERROR;
|
|
77
|
+
}
|
|
78
|
+
/** Check if the captcha solving failed. */
|
|
79
|
+
isSolveFailed() {
|
|
80
|
+
return this.code === ErrorCode.SOLVE_FAILED;
|
|
81
|
+
}
|
|
82
|
+
/** Check if this is an internal server error. */
|
|
83
|
+
isInternalError() {
|
|
84
|
+
return this.code === ErrorCode.INTERNAL_ERROR;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var RequestError = class _RequestError extends GatsbieError {
|
|
88
|
+
constructor(message, cause) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.cause = cause;
|
|
91
|
+
this.name = "RequestError";
|
|
92
|
+
Object.setPrototypeOf(this, _RequestError.prototype);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// src/client.ts
|
|
97
|
+
var DEFAULT_BASE_URL = "https://api2.gatsbie.io";
|
|
98
|
+
var DEFAULT_TIMEOUT = 12e4;
|
|
99
|
+
var Client = class {
|
|
100
|
+
apiKey;
|
|
101
|
+
baseUrl;
|
|
102
|
+
timeout;
|
|
103
|
+
/**
|
|
104
|
+
* Create a new Gatsbie API client.
|
|
105
|
+
*
|
|
106
|
+
* @param apiKey - Your Gatsbie API key (should start with 'gats_').
|
|
107
|
+
* @param options - Optional client configuration.
|
|
108
|
+
*/
|
|
109
|
+
constructor(apiKey, options = {}) {
|
|
110
|
+
this.apiKey = apiKey;
|
|
111
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
112
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
113
|
+
}
|
|
114
|
+
async request(method, path, body) {
|
|
115
|
+
const controller = new AbortController();
|
|
116
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
117
|
+
try {
|
|
118
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
119
|
+
method,
|
|
120
|
+
headers: {
|
|
121
|
+
"Content-Type": "application/json",
|
|
122
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
123
|
+
},
|
|
124
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
125
|
+
signal: controller.signal
|
|
126
|
+
});
|
|
127
|
+
const data = await response.json();
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const error = data.error || {};
|
|
130
|
+
throw new APIError({
|
|
131
|
+
code: error.code || "UNKNOWN",
|
|
132
|
+
message: error.message || "Unknown error",
|
|
133
|
+
details: error.details,
|
|
134
|
+
timestamp: error.timestamp,
|
|
135
|
+
httpStatus: response.status
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return data;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
if (err instanceof APIError) {
|
|
141
|
+
throw err;
|
|
142
|
+
}
|
|
143
|
+
if (err instanceof Error) {
|
|
144
|
+
if (err.name === "AbortError") {
|
|
145
|
+
throw new RequestError("Request timed out", err);
|
|
146
|
+
}
|
|
147
|
+
throw new RequestError(`Request failed: ${err.message}`, err);
|
|
148
|
+
}
|
|
149
|
+
throw new RequestError("Request failed");
|
|
150
|
+
} finally {
|
|
151
|
+
clearTimeout(timeoutId);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ========================================================================
|
|
155
|
+
// API Methods
|
|
156
|
+
// ========================================================================
|
|
157
|
+
/**
|
|
158
|
+
* Check the API server health status.
|
|
159
|
+
*/
|
|
160
|
+
async health() {
|
|
161
|
+
return this.request("GET", "/health");
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Solve a Datadome device check challenge.
|
|
165
|
+
*/
|
|
166
|
+
async solveDatadome(request) {
|
|
167
|
+
const body = {
|
|
168
|
+
task_type: "datadome-device-check",
|
|
169
|
+
proxy: request.proxy,
|
|
170
|
+
target_url: request.targetUrl,
|
|
171
|
+
target_method: request.targetMethod ?? "GET"
|
|
172
|
+
};
|
|
173
|
+
const data = await this.request("POST", "/v1/solve/datadome-device-check", body);
|
|
174
|
+
return {
|
|
175
|
+
success: data.success,
|
|
176
|
+
taskId: data.taskId,
|
|
177
|
+
service: data.service,
|
|
178
|
+
solution: {
|
|
179
|
+
datadome: data.solution.datadome,
|
|
180
|
+
userAgent: data.solution.ua
|
|
181
|
+
},
|
|
182
|
+
cost: data.cost,
|
|
183
|
+
solveTime: data.solveTime
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Solve a reCAPTCHA v3 challenge.
|
|
188
|
+
*/
|
|
189
|
+
async solveRecaptchaV3(request) {
|
|
190
|
+
const body = {
|
|
191
|
+
task_type: "recaptchav3",
|
|
192
|
+
proxy: request.proxy,
|
|
193
|
+
target_url: request.targetUrl,
|
|
194
|
+
site_key: request.siteKey
|
|
195
|
+
};
|
|
196
|
+
if (request.action) body.action = request.action;
|
|
197
|
+
if (request.title) body.title = request.title;
|
|
198
|
+
if (request.enterprise) body.enterprise = request.enterprise;
|
|
199
|
+
const data = await this.request("POST", "/v1/solve/recaptchav3", body);
|
|
200
|
+
return {
|
|
201
|
+
success: data.success,
|
|
202
|
+
taskId: data.taskId,
|
|
203
|
+
service: data.service,
|
|
204
|
+
solution: {
|
|
205
|
+
token: data.solution.token,
|
|
206
|
+
userAgent: data.solution.ua
|
|
207
|
+
},
|
|
208
|
+
cost: data.cost,
|
|
209
|
+
solveTime: data.solveTime
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Solve an Akamai bot management challenge.
|
|
214
|
+
*/
|
|
215
|
+
async solveAkamai(request) {
|
|
216
|
+
const body = {
|
|
217
|
+
task_type: "akamai",
|
|
218
|
+
proxy: request.proxy,
|
|
219
|
+
target_url: request.targetUrl,
|
|
220
|
+
akamai_js_url: request.akamaiJsUrl
|
|
221
|
+
};
|
|
222
|
+
if (request.pageFp) body.page_fp = request.pageFp;
|
|
223
|
+
const data = await this.request("POST", "/v1/solve/akamai", body);
|
|
224
|
+
return {
|
|
225
|
+
success: data.success,
|
|
226
|
+
taskId: data.taskId,
|
|
227
|
+
service: data.service,
|
|
228
|
+
solution: {
|
|
229
|
+
abck: data.solution._abck,
|
|
230
|
+
bmSz: data.solution.bm_sz,
|
|
231
|
+
userAgent: data.solution.ua,
|
|
232
|
+
country: data.solution.Country,
|
|
233
|
+
usrLocale: data.solution.UsrLocale
|
|
234
|
+
},
|
|
235
|
+
cost: data.cost,
|
|
236
|
+
solveTime: data.solveTime
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Solve a Vercel bot protection challenge.
|
|
241
|
+
*/
|
|
242
|
+
async solveVercel(request) {
|
|
243
|
+
const body = {
|
|
244
|
+
task_type: "vercel",
|
|
245
|
+
proxy: request.proxy,
|
|
246
|
+
target_url: request.targetUrl
|
|
247
|
+
};
|
|
248
|
+
const data = await this.request("POST", "/v1/solve/vercel", body);
|
|
249
|
+
return {
|
|
250
|
+
success: data.success,
|
|
251
|
+
taskId: data.taskId,
|
|
252
|
+
service: data.service,
|
|
253
|
+
solution: {
|
|
254
|
+
vcrcs: data.solution._vcrcs,
|
|
255
|
+
userAgent: data.solution.ua
|
|
256
|
+
},
|
|
257
|
+
cost: data.cost,
|
|
258
|
+
solveTime: data.solveTime
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Solve a Shape antibot challenge.
|
|
263
|
+
*/
|
|
264
|
+
async solveShape(request) {
|
|
265
|
+
const body = {
|
|
266
|
+
task_type: "shape",
|
|
267
|
+
proxy: request.proxy,
|
|
268
|
+
target_url: request.targetUrl,
|
|
269
|
+
target_api: request.targetApi,
|
|
270
|
+
shape_js_url: request.shapeJsUrl,
|
|
271
|
+
title: request.title,
|
|
272
|
+
method: request.method
|
|
273
|
+
};
|
|
274
|
+
const data = await this.request("POST", "/v1/solve/shape", body);
|
|
275
|
+
const { ua, ...headers } = data.solution;
|
|
276
|
+
return {
|
|
277
|
+
success: data.success,
|
|
278
|
+
taskId: data.taskId,
|
|
279
|
+
service: data.service,
|
|
280
|
+
solution: {
|
|
281
|
+
headers,
|
|
282
|
+
userAgent: ua
|
|
283
|
+
},
|
|
284
|
+
cost: data.cost,
|
|
285
|
+
solveTime: data.solveTime
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Solve a Cloudflare Turnstile challenge.
|
|
290
|
+
*/
|
|
291
|
+
async solveTurnstile(request) {
|
|
292
|
+
const body = {
|
|
293
|
+
task_type: "turnstile",
|
|
294
|
+
proxy: request.proxy,
|
|
295
|
+
target_url: request.targetUrl,
|
|
296
|
+
site_key: request.siteKey
|
|
297
|
+
};
|
|
298
|
+
const data = await this.request("POST", "/v1/solve/turnstile", body);
|
|
299
|
+
return {
|
|
300
|
+
success: data.success,
|
|
301
|
+
taskId: data.taskId,
|
|
302
|
+
service: data.service,
|
|
303
|
+
solution: {
|
|
304
|
+
token: data.solution.token,
|
|
305
|
+
userAgent: data.solution.ua
|
|
306
|
+
},
|
|
307
|
+
cost: data.cost,
|
|
308
|
+
solveTime: data.solveTime
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Solve a PerimeterX Invisible challenge.
|
|
313
|
+
*/
|
|
314
|
+
async solvePerimeterX(request) {
|
|
315
|
+
const body = {
|
|
316
|
+
task_type: "perimeterx_invisible",
|
|
317
|
+
proxy: request.proxy,
|
|
318
|
+
target_url: request.targetUrl,
|
|
319
|
+
perimeterx_js_url: request.perimeterxJsUrl,
|
|
320
|
+
pxAppId: request.pxAppId
|
|
321
|
+
};
|
|
322
|
+
const data = await this.request("POST", "/v1/solve/perimeterx-invisible", body);
|
|
323
|
+
return {
|
|
324
|
+
success: data.success,
|
|
325
|
+
taskId: data.taskId,
|
|
326
|
+
service: data.service,
|
|
327
|
+
solution: {
|
|
328
|
+
cookies: {
|
|
329
|
+
px3: data.solution.perimeterx_cookies._px3,
|
|
330
|
+
pxde: data.solution.perimeterx_cookies._pxde,
|
|
331
|
+
pxvid: data.solution.perimeterx_cookies._pxvid,
|
|
332
|
+
pxcts: data.solution.perimeterx_cookies.pxcts
|
|
333
|
+
},
|
|
334
|
+
userAgent: data.solution.ua
|
|
335
|
+
},
|
|
336
|
+
cost: data.cost,
|
|
337
|
+
solveTime: data.solveTime
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Solve a Cloudflare WAF challenge.
|
|
342
|
+
*/
|
|
343
|
+
async solveCloudflareWAF(request) {
|
|
344
|
+
const body = {
|
|
345
|
+
task_type: "cloudflare_waf",
|
|
346
|
+
proxy: request.proxy,
|
|
347
|
+
target_url: request.targetUrl,
|
|
348
|
+
target_method: request.targetMethod ?? "GET"
|
|
349
|
+
};
|
|
350
|
+
const data = await this.request("POST", "/v1/solve/cloudflare-waf", body);
|
|
351
|
+
return {
|
|
352
|
+
success: data.success,
|
|
353
|
+
taskId: data.taskId,
|
|
354
|
+
service: data.service,
|
|
355
|
+
solution: {
|
|
356
|
+
cfClearance: data.solution.cf_clearance,
|
|
357
|
+
userAgent: data.solution.ua
|
|
358
|
+
},
|
|
359
|
+
cost: data.cost,
|
|
360
|
+
solveTime: data.solveTime
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Solve a Datadome Slider CAPTCHA challenge.
|
|
365
|
+
*/
|
|
366
|
+
async solveDatadomeSlider(request) {
|
|
367
|
+
const body = {
|
|
368
|
+
task_type: "datadome-slider",
|
|
369
|
+
proxy: request.proxy,
|
|
370
|
+
target_url: request.targetUrl,
|
|
371
|
+
target_method: request.targetMethod ?? "GET"
|
|
372
|
+
};
|
|
373
|
+
const data = await this.request("POST", "/v1/solve/datadome-slider", body);
|
|
374
|
+
return {
|
|
375
|
+
success: data.success,
|
|
376
|
+
taskId: data.taskId,
|
|
377
|
+
service: data.service,
|
|
378
|
+
solution: {
|
|
379
|
+
datadome: data.solution.datadome,
|
|
380
|
+
userAgent: data.solution.ua
|
|
381
|
+
},
|
|
382
|
+
cost: data.cost,
|
|
383
|
+
solveTime: data.solveTime
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
388
|
+
0 && (module.exports = {
|
|
389
|
+
APIError,
|
|
390
|
+
Client,
|
|
391
|
+
ErrorCode,
|
|
392
|
+
GatsbieError,
|
|
393
|
+
RequestError
|
|
394
|
+
});
|
|
395
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * Gatsbie SDK - Official Node.js SDK for the Gatsbie Captcha API.\n *\n * @example\n * ```typescript\n * import { Client } from \"gatsbie\";\n *\n * const client = new Client(\"gats_your_api_key\");\n *\n * const response = await client.solveTurnstile({\n * proxy: \"http://user:pass@proxy:8080\",\n * targetUrl: \"https://example.com\",\n * siteKey: \"0x4AAAAAAABS7TtLxsNa7Z2e\",\n * });\n *\n * console.log(response.solution.token);\n * ```\n */\n\nexport { Client } from \"./client\";\nexport {\n APIError,\n ErrorCode,\n GatsbieError,\n RequestError,\n} from \"./errors\";\nexport type {\n // Response types\n HealthResponse,\n SolveResponse,\n // Solution types\n AkamaiSolution,\n CloudflareWAFSolution,\n DatadomeSliderSolution,\n DatadomeSolution,\n PerimeterXCookies,\n PerimeterXSolution,\n RecaptchaV3Solution,\n ShapeSolution,\n TurnstileSolution,\n VercelSolution,\n // Request types\n AkamaiRequest,\n CloudflareWAFRequest,\n DatadomeRequest,\n DatadomeSliderRequest,\n PerimeterXRequest,\n RecaptchaV3Request,\n ShapeRequest,\n TurnstileRequest,\n VercelRequest,\n // Options\n ClientOptions,\n} from \"./types\";\n","/**\n * Error codes returned by the Gatsbie API.\n */\nexport const ErrorCode = {\n AUTH_FAILED: \"AUTH_FAILED\",\n INSUFFICIENT_CREDITS: \"INSUFFICIENT_CREDITS\",\n INVALID_REQUEST: \"INVALID_REQUEST\",\n UPSTREAM_ERROR: \"UPSTREAM_ERROR\",\n SOLVE_FAILED: \"SOLVE_FAILED\",\n INTERNAL_ERROR: \"INTERNAL_ERROR\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n/**\n * Base error class for Gatsbie SDK errors.\n */\nexport class GatsbieError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"GatsbieError\";\n Object.setPrototypeOf(this, GatsbieError.prototype);\n }\n}\n\n/**\n * Error thrown when the Gatsbie API returns an error response.\n */\nexport class APIError extends GatsbieError {\n readonly code: string;\n readonly details?: string;\n readonly timestamp?: number;\n readonly httpStatus?: number;\n\n constructor(options: {\n code: string;\n message: string;\n details?: string;\n timestamp?: number;\n httpStatus?: number;\n }) {\n const msg = options.details\n ? `gatsbie: ${options.code}: ${options.message} (${options.details})`\n : `gatsbie: ${options.code}: ${options.message}`;\n super(msg);\n this.name = \"APIError\";\n this.code = options.code;\n this.details = options.details;\n this.timestamp = options.timestamp;\n this.httpStatus = options.httpStatus;\n Object.setPrototypeOf(this, APIError.prototype);\n }\n\n /** Check if this is an authentication error. */\n isAuthError(): boolean {\n return this.code === ErrorCode.AUTH_FAILED;\n }\n\n /** Check if this error is due to insufficient credits. */\n isInsufficientCredits(): boolean {\n return this.code === ErrorCode.INSUFFICIENT_CREDITS;\n }\n\n /** Check if this error is due to an invalid request. */\n isInvalidRequest(): boolean {\n return this.code === ErrorCode.INVALID_REQUEST;\n }\n\n /** Check if this error is from an upstream service. */\n isUpstreamError(): boolean {\n return this.code === ErrorCode.UPSTREAM_ERROR;\n }\n\n /** Check if the captcha solving failed. */\n isSolveFailed(): boolean {\n return this.code === ErrorCode.SOLVE_FAILED;\n }\n\n /** Check if this is an internal server error. */\n isInternalError(): boolean {\n return this.code === ErrorCode.INTERNAL_ERROR;\n }\n}\n\n/**\n * Error thrown when a request fails (network error, timeout, etc.).\n */\nexport class RequestError extends GatsbieError {\n constructor(message: string, public readonly cause?: Error) {\n super(message);\n this.name = \"RequestError\";\n Object.setPrototypeOf(this, RequestError.prototype);\n }\n}\n","import { APIError, RequestError } from \"./errors\";\nimport type {\n AkamaiRequest,\n AkamaiSolution,\n ClientOptions,\n CloudflareWAFRequest,\n CloudflareWAFSolution,\n DatadomeRequest,\n DatadomeSliderRequest,\n DatadomeSliderSolution,\n DatadomeSolution,\n HealthResponse,\n PerimeterXRequest,\n PerimeterXSolution,\n RecaptchaV3Request,\n RecaptchaV3Solution,\n ShapeRequest,\n ShapeSolution,\n SolveResponse,\n TurnstileRequest,\n TurnstileSolution,\n VercelRequest,\n VercelSolution,\n} from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://api2.gatsbie.io\";\nconst DEFAULT_TIMEOUT = 120000;\n\n/**\n * Gatsbie API client.\n *\n * @example\n * ```typescript\n * const client = new Client(\"gats_your_api_key\");\n *\n * const response = await client.solveTurnstile({\n * proxy: \"http://user:pass@proxy:8080\",\n * targetUrl: \"https://example.com\",\n * siteKey: \"0x4AAAAAAABS7TtLxsNa7Z2e\",\n * });\n *\n * console.log(response.solution.token);\n * ```\n */\nexport class Client {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n\n /**\n * Create a new Gatsbie API client.\n *\n * @param apiKey - Your Gatsbie API key (should start with 'gats_').\n * @param options - Optional client configuration.\n */\n constructor(apiKey: string, options: ClientOptions = {}) {\n this.apiKey = apiKey;\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n\n if (!response.ok) {\n const error = (data.error as Record<string, unknown>) || {};\n throw new APIError({\n code: (error.code as string) || \"UNKNOWN\",\n message: (error.message as string) || \"Unknown error\",\n details: error.details as string | undefined,\n timestamp: error.timestamp as number | undefined,\n httpStatus: response.status,\n });\n }\n\n return data as T;\n } catch (err) {\n if (err instanceof APIError) {\n throw err;\n }\n if (err instanceof Error) {\n if (err.name === \"AbortError\") {\n throw new RequestError(\"Request timed out\", err);\n }\n throw new RequestError(`Request failed: ${err.message}`, err);\n }\n throw new RequestError(\"Request failed\");\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n // ========================================================================\n // API Methods\n // ========================================================================\n\n /**\n * Check the API server health status.\n */\n async health(): Promise<HealthResponse> {\n return this.request<HealthResponse>(\"GET\", \"/health\");\n }\n\n /**\n * Solve a Datadome device check challenge.\n */\n async solveDatadome(\n request: DatadomeRequest\n ): Promise<SolveResponse<DatadomeSolution>> {\n const body = {\n task_type: \"datadome-device-check\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n target_method: request.targetMethod ?? \"GET\",\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { datadome: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/datadome-device-check\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n datadome: data.solution.datadome,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a reCAPTCHA v3 challenge.\n */\n async solveRecaptchaV3(\n request: RecaptchaV3Request\n ): Promise<SolveResponse<RecaptchaV3Solution>> {\n const body: Record<string, unknown> = {\n task_type: \"recaptchav3\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n site_key: request.siteKey,\n };\n if (request.action) body.action = request.action;\n if (request.title) body.title = request.title;\n if (request.enterprise) body.enterprise = request.enterprise;\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { token: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/recaptchav3\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n token: data.solution.token,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve an Akamai bot management challenge.\n */\n async solveAkamai(\n request: AkamaiRequest\n ): Promise<SolveResponse<AkamaiSolution>> {\n const body: Record<string, unknown> = {\n task_type: \"akamai\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n akamai_js_url: request.akamaiJsUrl,\n };\n if (request.pageFp) body.page_fp = request.pageFp;\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: {\n _abck: string;\n bm_sz: string;\n ua: string;\n Country?: string;\n UsrLocale?: string;\n };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/akamai\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n abck: data.solution._abck,\n bmSz: data.solution.bm_sz,\n userAgent: data.solution.ua,\n country: data.solution.Country,\n usrLocale: data.solution.UsrLocale,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a Vercel bot protection challenge.\n */\n async solveVercel(\n request: VercelRequest\n ): Promise<SolveResponse<VercelSolution>> {\n const body = {\n task_type: \"vercel\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { _vcrcs: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/vercel\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n vcrcs: data.solution._vcrcs,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a Shape antibot challenge.\n */\n async solveShape(\n request: ShapeRequest\n ): Promise<SolveResponse<ShapeSolution>> {\n const body = {\n task_type: \"shape\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n target_api: request.targetApi,\n shape_js_url: request.shapeJsUrl,\n title: request.title,\n method: request.method,\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: Record<string, string>;\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/shape\", body);\n\n // Shape returns dynamic headers, extract ua separately\n const { ua, ...headers } = data.solution;\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n headers,\n userAgent: ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a Cloudflare Turnstile challenge.\n */\n async solveTurnstile(\n request: TurnstileRequest\n ): Promise<SolveResponse<TurnstileSolution>> {\n const body = {\n task_type: \"turnstile\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n site_key: request.siteKey,\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { token: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/turnstile\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n token: data.solution.token,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a PerimeterX Invisible challenge.\n */\n async solvePerimeterX(\n request: PerimeterXRequest\n ): Promise<SolveResponse<PerimeterXSolution>> {\n const body = {\n task_type: \"perimeterx_invisible\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n perimeterx_js_url: request.perimeterxJsUrl,\n pxAppId: request.pxAppId,\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: {\n perimeterx_cookies: {\n _px3: string;\n _pxde: string;\n _pxvid: string;\n pxcts: string;\n };\n ua: string;\n };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/perimeterx-invisible\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n cookies: {\n px3: data.solution.perimeterx_cookies._px3,\n pxde: data.solution.perimeterx_cookies._pxde,\n pxvid: data.solution.perimeterx_cookies._pxvid,\n pxcts: data.solution.perimeterx_cookies.pxcts,\n },\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a Cloudflare WAF challenge.\n */\n async solveCloudflareWAF(\n request: CloudflareWAFRequest\n ): Promise<SolveResponse<CloudflareWAFSolution>> {\n const body = {\n task_type: \"cloudflare_waf\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n target_method: request.targetMethod ?? \"GET\",\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { cf_clearance: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/cloudflare-waf\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n cfClearance: data.solution.cf_clearance,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n\n /**\n * Solve a Datadome Slider CAPTCHA challenge.\n */\n async solveDatadomeSlider(\n request: DatadomeSliderRequest\n ): Promise<SolveResponse<DatadomeSliderSolution>> {\n const body = {\n task_type: \"datadome-slider\",\n proxy: request.proxy,\n target_url: request.targetUrl,\n target_method: request.targetMethod ?? \"GET\",\n };\n\n const data = await this.request<{\n success: boolean;\n taskId: string;\n service: string;\n solution: { datadome: string; ua: string };\n cost: number;\n solveTime: number;\n }>(\"POST\", \"/v1/solve/datadome-slider\", body);\n\n return {\n success: data.success,\n taskId: data.taskId,\n service: data.service,\n solution: {\n datadome: data.solution.datadome,\n userAgent: data.solution.ua,\n },\n cost: data.cost,\n solveTime: data.solveTime,\n };\n }\n}\n"],"mappings":"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","names":[]}
|