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/dist/index.mjs ADDED
@@ -0,0 +1,364 @@
1
+ // src/errors.ts
2
+ var ErrorCode = {
3
+ AUTH_FAILED: "AUTH_FAILED",
4
+ INSUFFICIENT_CREDITS: "INSUFFICIENT_CREDITS",
5
+ INVALID_REQUEST: "INVALID_REQUEST",
6
+ UPSTREAM_ERROR: "UPSTREAM_ERROR",
7
+ SOLVE_FAILED: "SOLVE_FAILED",
8
+ INTERNAL_ERROR: "INTERNAL_ERROR"
9
+ };
10
+ var GatsbieError = class _GatsbieError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "GatsbieError";
14
+ Object.setPrototypeOf(this, _GatsbieError.prototype);
15
+ }
16
+ };
17
+ var APIError = class _APIError extends GatsbieError {
18
+ code;
19
+ details;
20
+ timestamp;
21
+ httpStatus;
22
+ constructor(options) {
23
+ const msg = options.details ? `gatsbie: ${options.code}: ${options.message} (${options.details})` : `gatsbie: ${options.code}: ${options.message}`;
24
+ super(msg);
25
+ this.name = "APIError";
26
+ this.code = options.code;
27
+ this.details = options.details;
28
+ this.timestamp = options.timestamp;
29
+ this.httpStatus = options.httpStatus;
30
+ Object.setPrototypeOf(this, _APIError.prototype);
31
+ }
32
+ /** Check if this is an authentication error. */
33
+ isAuthError() {
34
+ return this.code === ErrorCode.AUTH_FAILED;
35
+ }
36
+ /** Check if this error is due to insufficient credits. */
37
+ isInsufficientCredits() {
38
+ return this.code === ErrorCode.INSUFFICIENT_CREDITS;
39
+ }
40
+ /** Check if this error is due to an invalid request. */
41
+ isInvalidRequest() {
42
+ return this.code === ErrorCode.INVALID_REQUEST;
43
+ }
44
+ /** Check if this error is from an upstream service. */
45
+ isUpstreamError() {
46
+ return this.code === ErrorCode.UPSTREAM_ERROR;
47
+ }
48
+ /** Check if the captcha solving failed. */
49
+ isSolveFailed() {
50
+ return this.code === ErrorCode.SOLVE_FAILED;
51
+ }
52
+ /** Check if this is an internal server error. */
53
+ isInternalError() {
54
+ return this.code === ErrorCode.INTERNAL_ERROR;
55
+ }
56
+ };
57
+ var RequestError = class _RequestError extends GatsbieError {
58
+ constructor(message, cause) {
59
+ super(message);
60
+ this.cause = cause;
61
+ this.name = "RequestError";
62
+ Object.setPrototypeOf(this, _RequestError.prototype);
63
+ }
64
+ };
65
+
66
+ // src/client.ts
67
+ var DEFAULT_BASE_URL = "https://api2.gatsbie.io";
68
+ var DEFAULT_TIMEOUT = 12e4;
69
+ var Client = class {
70
+ apiKey;
71
+ baseUrl;
72
+ timeout;
73
+ /**
74
+ * Create a new Gatsbie API client.
75
+ *
76
+ * @param apiKey - Your Gatsbie API key (should start with 'gats_').
77
+ * @param options - Optional client configuration.
78
+ */
79
+ constructor(apiKey, options = {}) {
80
+ this.apiKey = apiKey;
81
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
82
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
83
+ }
84
+ async request(method, path, body) {
85
+ const controller = new AbortController();
86
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
87
+ try {
88
+ const response = await fetch(`${this.baseUrl}${path}`, {
89
+ method,
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ Authorization: `Bearer ${this.apiKey}`
93
+ },
94
+ body: body ? JSON.stringify(body) : void 0,
95
+ signal: controller.signal
96
+ });
97
+ const data = await response.json();
98
+ if (!response.ok) {
99
+ const error = data.error || {};
100
+ throw new APIError({
101
+ code: error.code || "UNKNOWN",
102
+ message: error.message || "Unknown error",
103
+ details: error.details,
104
+ timestamp: error.timestamp,
105
+ httpStatus: response.status
106
+ });
107
+ }
108
+ return data;
109
+ } catch (err) {
110
+ if (err instanceof APIError) {
111
+ throw err;
112
+ }
113
+ if (err instanceof Error) {
114
+ if (err.name === "AbortError") {
115
+ throw new RequestError("Request timed out", err);
116
+ }
117
+ throw new RequestError(`Request failed: ${err.message}`, err);
118
+ }
119
+ throw new RequestError("Request failed");
120
+ } finally {
121
+ clearTimeout(timeoutId);
122
+ }
123
+ }
124
+ // ========================================================================
125
+ // API Methods
126
+ // ========================================================================
127
+ /**
128
+ * Check the API server health status.
129
+ */
130
+ async health() {
131
+ return this.request("GET", "/health");
132
+ }
133
+ /**
134
+ * Solve a Datadome device check challenge.
135
+ */
136
+ async solveDatadome(request) {
137
+ const body = {
138
+ task_type: "datadome-device-check",
139
+ proxy: request.proxy,
140
+ target_url: request.targetUrl,
141
+ target_method: request.targetMethod ?? "GET"
142
+ };
143
+ const data = await this.request("POST", "/v1/solve/datadome-device-check", body);
144
+ return {
145
+ success: data.success,
146
+ taskId: data.taskId,
147
+ service: data.service,
148
+ solution: {
149
+ datadome: data.solution.datadome,
150
+ userAgent: data.solution.ua
151
+ },
152
+ cost: data.cost,
153
+ solveTime: data.solveTime
154
+ };
155
+ }
156
+ /**
157
+ * Solve a reCAPTCHA v3 challenge.
158
+ */
159
+ async solveRecaptchaV3(request) {
160
+ const body = {
161
+ task_type: "recaptchav3",
162
+ proxy: request.proxy,
163
+ target_url: request.targetUrl,
164
+ site_key: request.siteKey
165
+ };
166
+ if (request.action) body.action = request.action;
167
+ if (request.title) body.title = request.title;
168
+ if (request.enterprise) body.enterprise = request.enterprise;
169
+ const data = await this.request("POST", "/v1/solve/recaptchav3", body);
170
+ return {
171
+ success: data.success,
172
+ taskId: data.taskId,
173
+ service: data.service,
174
+ solution: {
175
+ token: data.solution.token,
176
+ userAgent: data.solution.ua
177
+ },
178
+ cost: data.cost,
179
+ solveTime: data.solveTime
180
+ };
181
+ }
182
+ /**
183
+ * Solve an Akamai bot management challenge.
184
+ */
185
+ async solveAkamai(request) {
186
+ const body = {
187
+ task_type: "akamai",
188
+ proxy: request.proxy,
189
+ target_url: request.targetUrl,
190
+ akamai_js_url: request.akamaiJsUrl
191
+ };
192
+ if (request.pageFp) body.page_fp = request.pageFp;
193
+ const data = await this.request("POST", "/v1/solve/akamai", body);
194
+ return {
195
+ success: data.success,
196
+ taskId: data.taskId,
197
+ service: data.service,
198
+ solution: {
199
+ abck: data.solution._abck,
200
+ bmSz: data.solution.bm_sz,
201
+ userAgent: data.solution.ua,
202
+ country: data.solution.Country,
203
+ usrLocale: data.solution.UsrLocale
204
+ },
205
+ cost: data.cost,
206
+ solveTime: data.solveTime
207
+ };
208
+ }
209
+ /**
210
+ * Solve a Vercel bot protection challenge.
211
+ */
212
+ async solveVercel(request) {
213
+ const body = {
214
+ task_type: "vercel",
215
+ proxy: request.proxy,
216
+ target_url: request.targetUrl
217
+ };
218
+ const data = await this.request("POST", "/v1/solve/vercel", body);
219
+ return {
220
+ success: data.success,
221
+ taskId: data.taskId,
222
+ service: data.service,
223
+ solution: {
224
+ vcrcs: data.solution._vcrcs,
225
+ userAgent: data.solution.ua
226
+ },
227
+ cost: data.cost,
228
+ solveTime: data.solveTime
229
+ };
230
+ }
231
+ /**
232
+ * Solve a Shape antibot challenge.
233
+ */
234
+ async solveShape(request) {
235
+ const body = {
236
+ task_type: "shape",
237
+ proxy: request.proxy,
238
+ target_url: request.targetUrl,
239
+ target_api: request.targetApi,
240
+ shape_js_url: request.shapeJsUrl,
241
+ title: request.title,
242
+ method: request.method
243
+ };
244
+ const data = await this.request("POST", "/v1/solve/shape", body);
245
+ const { ua, ...headers } = data.solution;
246
+ return {
247
+ success: data.success,
248
+ taskId: data.taskId,
249
+ service: data.service,
250
+ solution: {
251
+ headers,
252
+ userAgent: ua
253
+ },
254
+ cost: data.cost,
255
+ solveTime: data.solveTime
256
+ };
257
+ }
258
+ /**
259
+ * Solve a Cloudflare Turnstile challenge.
260
+ */
261
+ async solveTurnstile(request) {
262
+ const body = {
263
+ task_type: "turnstile",
264
+ proxy: request.proxy,
265
+ target_url: request.targetUrl,
266
+ site_key: request.siteKey
267
+ };
268
+ const data = await this.request("POST", "/v1/solve/turnstile", body);
269
+ return {
270
+ success: data.success,
271
+ taskId: data.taskId,
272
+ service: data.service,
273
+ solution: {
274
+ token: data.solution.token,
275
+ userAgent: data.solution.ua
276
+ },
277
+ cost: data.cost,
278
+ solveTime: data.solveTime
279
+ };
280
+ }
281
+ /**
282
+ * Solve a PerimeterX Invisible challenge.
283
+ */
284
+ async solvePerimeterX(request) {
285
+ const body = {
286
+ task_type: "perimeterx_invisible",
287
+ proxy: request.proxy,
288
+ target_url: request.targetUrl,
289
+ perimeterx_js_url: request.perimeterxJsUrl,
290
+ pxAppId: request.pxAppId
291
+ };
292
+ const data = await this.request("POST", "/v1/solve/perimeterx-invisible", body);
293
+ return {
294
+ success: data.success,
295
+ taskId: data.taskId,
296
+ service: data.service,
297
+ solution: {
298
+ cookies: {
299
+ px3: data.solution.perimeterx_cookies._px3,
300
+ pxde: data.solution.perimeterx_cookies._pxde,
301
+ pxvid: data.solution.perimeterx_cookies._pxvid,
302
+ pxcts: data.solution.perimeterx_cookies.pxcts
303
+ },
304
+ userAgent: data.solution.ua
305
+ },
306
+ cost: data.cost,
307
+ solveTime: data.solveTime
308
+ };
309
+ }
310
+ /**
311
+ * Solve a Cloudflare WAF challenge.
312
+ */
313
+ async solveCloudflareWAF(request) {
314
+ const body = {
315
+ task_type: "cloudflare_waf",
316
+ proxy: request.proxy,
317
+ target_url: request.targetUrl,
318
+ target_method: request.targetMethod ?? "GET"
319
+ };
320
+ const data = await this.request("POST", "/v1/solve/cloudflare-waf", body);
321
+ return {
322
+ success: data.success,
323
+ taskId: data.taskId,
324
+ service: data.service,
325
+ solution: {
326
+ cfClearance: data.solution.cf_clearance,
327
+ userAgent: data.solution.ua
328
+ },
329
+ cost: data.cost,
330
+ solveTime: data.solveTime
331
+ };
332
+ }
333
+ /**
334
+ * Solve a Datadome Slider CAPTCHA challenge.
335
+ */
336
+ async solveDatadomeSlider(request) {
337
+ const body = {
338
+ task_type: "datadome-slider",
339
+ proxy: request.proxy,
340
+ target_url: request.targetUrl,
341
+ target_method: request.targetMethod ?? "GET"
342
+ };
343
+ const data = await this.request("POST", "/v1/solve/datadome-slider", body);
344
+ return {
345
+ success: data.success,
346
+ taskId: data.taskId,
347
+ service: data.service,
348
+ solution: {
349
+ datadome: data.solution.datadome,
350
+ userAgent: data.solution.ua
351
+ },
352
+ cost: data.cost,
353
+ solveTime: data.solveTime
354
+ };
355
+ }
356
+ };
357
+ export {
358
+ APIError,
359
+ Client,
360
+ ErrorCode,
361
+ GatsbieError,
362
+ RequestError
363
+ };
364
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\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":[]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "gatsbie",
3
+ "version": "1.0.0",
4
+ "description": "Official Node.js SDK for the Gatsbie Captcha API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch",
20
+ "typecheck": "tsc --noEmit",
21
+ "example": "tsx examples/main.ts"
22
+ },
23
+ "keywords": [
24
+ "captcha",
25
+ "datadome",
26
+ "akamai",
27
+ "turnstile",
28
+ "recaptcha",
29
+ "cloudflare",
30
+ "perimeterx",
31
+ "vercel"
32
+ ],
33
+ "author": "Gatsbie <support@gatsbie.io>",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/jaygatsbie/sdk-nodejs"
38
+ },
39
+ "homepage": "https://gatsbie.io",
40
+ "devDependencies": {
41
+ "@types/node": "^20.10.0",
42
+ "tsup": "^8.0.0",
43
+ "tsx": "^4.6.0",
44
+ "typescript": "^5.3.0"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ }
49
+ }