nonecap 0.9.6 → 0.10.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 +38 -1
- package/dist/index.cjs +23 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -8
- package/dist/index.d.ts +159 -8
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ try {
|
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
The error subclasses are `AuthenticationError` (401), `PermissionError` (403), `InsufficientCreditsError` (402, with `KeyCreditLimitError` when one API key hit its own cap), `ValidationError` (422/400, with a `param` naming the bad field; `PayloadTooLargeError` for 413 and `UnsupportedMediaTypeError` for 415), `NotFoundError` (404), `ConflictError` (409), `RateLimitError` (429, with `ConcurrencyLimitError`, `SitekeyRateLimitedError`, `ProxyUnavailableError` (your own proxy is refusing connections) and `RateCappedError` (your account reached its submit rate cap on this sitekey, or your own-proxy sessions for it are at their limit) telling them apart; `retryAfter` is the seconds the API asked you to wait), `APIError` (5xx, with `ServiceUnavailableError` for a maintenance pause), and `ConnectionError` (the request never landed). Every error from a response carries `requestId`, the id to quote to support.
|
|
74
|
+
The error subclasses are `AuthenticationError` (401), `PermissionError` (403), `InsufficientCreditsError` (402, with `KeyCreditLimitError` when one API key hit its own cap), `ValidationError` (422/400, with a `param` naming the bad field; `PayloadTooLargeError` for 413 and `UnsupportedMediaTypeError` for 415), `NotFoundError` (404), `ConflictError` (409), `RateLimitError` (429, with `ConcurrencyLimitError`, `SitekeyRateLimitedError`, `ProxyUnavailableError` (your own proxy is refusing connections) and `RateCappedError` (your account reached its submit rate cap on this sitekey, or your own-proxy sessions for it are at their limit) telling them apart; `retryAfter` is the seconds the API asked you to wait), `RecognitionFailedError` (422 from `recognize()` when no answer came back, nothing charged), `APIError` (5xx, with `ServiceUnavailableError` for a maintenance pause), and `ConnectionError` (the request never landed). Every error from a response carries `requestId`, the id to quote to support.
|
|
75
75
|
|
|
76
76
|
`SolveFailedError` carries the full `solve`. `solve.error.code` is a `SolveErrorCode`, `solve.error.reason` a typed sub-reason or `null` (`proxy_rejected`, `sitekey_rate_limited`, …), and `solve.error.retryable` says whether resubmitting the same request unchanged can succeed; `err.retryable`, `err.reason` and `err.solveCode` are shortcuts to those fields. Failed solves are never charged.
|
|
77
77
|
|
|
@@ -194,6 +194,43 @@ if (batch.failed > 0) {
|
|
|
194
194
|
|
|
195
195
|
Reporting the same solve again corrects the earlier verdict, so retries and late fixes are safe. You can report any of your own solved solves within ~30 days of the solve; corrections to something you already reported are never cut off by that window.
|
|
196
196
|
|
|
197
|
+
## Recognizing images
|
|
198
|
+
|
|
199
|
+
If you run your own browser and only need the answer to a challenge, send the instruction and images to `recognize()`. The answer comes back in the same response: no token, no polling.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
const { id, data } = await nc.recognize({
|
|
203
|
+
type: "hcaptcha",
|
|
204
|
+
task: "Please click each image containing a bus",
|
|
205
|
+
image_data: tiles, // base64 or data: URIs, 1-27 tiles; or image_urls with hCaptcha image URLs
|
|
206
|
+
});
|
|
207
|
+
// data: boolean[], one per tile, in the order you sent them
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
For a click-the-point challenge send exactly one image with `type: "hcaptcha_area_select"`. `data` is the first point as `{ x, y, w: 0, h: 0 }` and `points` lists every point to click, all in percent of the image.
|
|
211
|
+
|
|
212
|
+
You can also send the challenge as hCaptcha served it, in NopeCHA's v1 recognition shape:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
const result = await nc.recognize({
|
|
216
|
+
data: {
|
|
217
|
+
request_type: "image_drag_drop", // or image_label_binary, image_label_area_select
|
|
218
|
+
requester_question: { en: "Drag the piece into place" },
|
|
219
|
+
tasklist: [{ task_key, datapoint_uri, entities }],
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`image_label_binary` answers pages of 9 booleans (`boolean[][]`), `image_label_area_select` one box per task (`null` when there is no point) plus `points` per task, and `image_drag_drop` the drop box for each entity per task. The return type follows the request, so TypeScript knows which one you got.
|
|
225
|
+
|
|
226
|
+
When no answer comes back the call throws `RecognitionFailedError` and nothing is charged. An answered call's charge is final. You can tell us whether the answer worked on the challenge, which helps us track accuracy; it is optional, free, and does not refund the call:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
await nc.reportRecognitionOutcome(id, solved ? "solved" : "failed");
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The first report for an id sticks; a repeat returns it unchanged. Calls are capped per API key by your account's concurrency limit, so a burst over it gets `ConcurrencyLimitError` or `RateLimitError` with `retryAfter` set.
|
|
233
|
+
|
|
197
234
|
## Lower-level API
|
|
198
235
|
|
|
199
236
|
`solve()` is the convenient path. When you want control over submission and polling, the raw resource methods map one to one to the REST API.
|
package/dist/index.cjs
CHANGED
|
@@ -51,6 +51,8 @@ var ProxyUnavailableError = class extends RateLimitError {
|
|
|
51
51
|
};
|
|
52
52
|
var RateCappedError = class extends RateLimitError {
|
|
53
53
|
};
|
|
54
|
+
var RecognitionFailedError = class extends NoneCapError {
|
|
55
|
+
};
|
|
54
56
|
var APIError = class extends NoneCapError {
|
|
55
57
|
};
|
|
56
58
|
var ServiceUnavailableError = class extends APIError {
|
|
@@ -127,6 +129,8 @@ function errorFromResponse(status, code, message, param, extra = {}) {
|
|
|
127
129
|
case "rate_limited":
|
|
128
130
|
case "ext_daily_limit":
|
|
129
131
|
return new RateLimitError(message, opts);
|
|
132
|
+
case "recognition_failed":
|
|
133
|
+
return new RecognitionFailedError(message, opts);
|
|
130
134
|
case "maintenance":
|
|
131
135
|
return new ServiceUnavailableError(message, opts);
|
|
132
136
|
default:
|
|
@@ -135,7 +139,7 @@ function errorFromResponse(status, code, message, param, extra = {}) {
|
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
// src/version.ts
|
|
138
|
-
var VERSION = "0.
|
|
142
|
+
var VERSION = "0.10.0";
|
|
139
143
|
|
|
140
144
|
// src/client.ts
|
|
141
145
|
var DEFAULT_BASE_URL = "https://api.nonecap.com";
|
|
@@ -304,6 +308,23 @@ var NoneCap = class {
|
|
|
304
308
|
me(options = {}) {
|
|
305
309
|
return this.#request("GET", "/v1/me", { signal: options.signal });
|
|
306
310
|
}
|
|
311
|
+
recognize(params, options = {}) {
|
|
312
|
+
return this.#request("POST", "/v1/recognize", {
|
|
313
|
+
body: params,
|
|
314
|
+
signal: options.signal
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Report whether a {@link NoneCap.recognize} answer worked on the challenge.
|
|
319
|
+
* Optional and free; it feeds NoneCap's accuracy stats and never refunds the
|
|
320
|
+
* call. The first report for an id sticks: a repeat returns it unchanged.
|
|
321
|
+
*/
|
|
322
|
+
reportRecognitionOutcome(id, result, options = {}) {
|
|
323
|
+
return this.#request("POST", "/v1/recognize/outcome", {
|
|
324
|
+
body: { id, result },
|
|
325
|
+
signal: options.signal
|
|
326
|
+
});
|
|
327
|
+
}
|
|
307
328
|
/**
|
|
308
329
|
* Submit a solve and wait for it to finish, returning the solved solve.
|
|
309
330
|
*
|
|
@@ -545,6 +566,7 @@ exports.PermissionError = PermissionError;
|
|
|
545
566
|
exports.ProxyUnavailableError = ProxyUnavailableError;
|
|
546
567
|
exports.RateCappedError = RateCappedError;
|
|
547
568
|
exports.RateLimitError = RateLimitError;
|
|
569
|
+
exports.RecognitionFailedError = RecognitionFailedError;
|
|
548
570
|
exports.ServiceUnavailableError = ServiceUnavailableError;
|
|
549
571
|
exports.SitekeyRateLimitedError = SitekeyRateLimitedError;
|
|
550
572
|
exports.SolveFailedError = SolveFailedError;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/version.ts","../src/client.ts"],"names":[],"mappings":";;;AAMO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA;AAAA,EAE7B,IAAA;AAAA;AAAA,EAEA,MAAA;AAAA;AAAA,EAEA,KAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,UAAA;AAAA,EAET,WAAA,CACE,OAAA,EACA,IAAA,GAMI,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,OAAO,GAAA,CAAA,MAAA,CAAW,IAAA;AACvB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC3B,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AAEvB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAGO,IAAM,mBAAA,GAAN,cAAkC,YAAA,CAAa;AAAC;AAGhD,IAAM,eAAA,GAAN,cAA8B,YAAA,CAAa;AAAC;AAG5C,IAAM,wBAAA,GAAN,cAAuC,YAAA,CAAa;AAAC;AAGrD,IAAM,mBAAA,GAAN,cAAkC,wBAAA,CAAyB;AAAC;AAG5D,IAAM,eAAA,GAAN,cAA8B,YAAA,CAAa;AAAC;AAG5C,IAAM,oBAAA,GAAN,cAAmC,eAAA,CAAgB;AAAC;AAGpD,IAAM,yBAAA,GAAN,cAAwC,eAAA,CAAgB;AAAC;AAGzD,IAAM,aAAA,GAAN,cAA4B,YAAA,CAAa;AAAC;AAG1C,IAAM,aAAA,GAAN,cAA4B,YAAA,CAAa;AAAC;AAG1C,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAC;AAG3C,IAAM,qBAAA,GAAN,cAAoC,cAAA,CAAe;AAAC;AAIpD,IAAM,uBAAA,GAAN,cAAsC,cAAA,CAAe;AAAC;AAKtD,IAAM,qBAAA,GAAN,cAAoC,cAAA,CAAe;AAAC;AAKpD,IAAM,eAAA,GAAN,cAA8B,cAAA,CAAe;AAAC;AAG9C,IAAM,QAAA,GAAN,cAAuB,YAAA,CAAa;AAAC;AAGrC,IAAM,uBAAA,GAAN,cAAsC,QAAA,CAAS;AAAC;AAGhD,IAAM,eAAA,GAAN,cAA8B,YAAA,CAAa;AAAC;AAO5C,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA,EACxC,KAAA;AAAA,EAET,YAAY,KAAA,EAAc;AACxB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA,CAAA,GAAK,KAAA,CAAM,MAAA;AACnF,IAAA,KAAA,CAAM,CAAA,MAAA,EAAS,MAAM,EAAE,CAAA,CAAA,EAAI,MAAM,MAAM,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,CAAA,EAAK;AAAA,MACrD,IAAA,EAAM,MAAA;AAAA,MACN,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA;AAAA,EAGA,IAAI,SAAA,GAAoB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,IAAA,IAAQ,KAAK,KAAA,CAAM,MAAA;AAAA,EAC9C;AAAA;AAAA,EAGA,IAAI,MAAA,GAAwB;AAC1B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,MAAA,IAAU,IAAA;AAAA,EACrC;AAAA;AAAA,EAGA,IAAI,SAAA,GAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,SAAA,IAAa,KAAA;AAAA,EACxC;AACF;AAQO,IAAM,YAAA,GAAN,cAA2B,YAAA,CAAa;AAAA;AAAA,EAEpC,OAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EAET,WAAA,CACE,OAAA,EACA,IAAA,GAMI,EAAC,EACL;AACA,IAAA,KAAA,CAAM,SAAS,IAAI,CAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAAA,EACpB;AACF;AAGO,SAAS,kBACd,MAAA,EACA,IAAA,EACA,SACA,KAAA,EACA,KAAA,GAAqD,EAAC,EACxC;AACd,EAAA,MAAM,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,GAAG,KAAA,EAAM;AAC7C,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,cAAA;AACH,MAAA,OAAO,IAAI,mBAAA,CAAoB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC9C,KAAK,WAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC1C,KAAK,sBAAA;AACH,MAAA,OAAO,IAAI,wBAAA,CAAyB,OAAA,EAAS,IAAI,CAAA;AAAA,IACnD,KAAK,2BAAA;AACH,MAAA,OAAO,IAAI,mBAAA,CAAoB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC9C,KAAK,iBAAA;AAAA,IACL,KAAK,kBAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC1C,KAAK,mBAAA;AACH,MAAA,OAAO,IAAI,oBAAA,CAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC/C,KAAK,wBAAA;AACH,MAAA,OAAO,IAAI,yBAAA,CAA0B,OAAA,EAAS,IAAI,CAAA;AAAA,IACpD,KAAK,WAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,IAAI,CAAA;AAAA,IACxC,KAAK,UAAA;AACH,MAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,IAAI,CAAA;AAAA,IACxC,KAAK,4BAAA;AACH,MAAA,OAAO,IAAI,qBAAA,CAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,IAChD,KAAK,sBAAA;AACH,MAAA,OAAO,IAAI,uBAAA,CAAwB,OAAA,EAAS,IAAI,CAAA;AAAA,IAClD,KAAK,mBAAA;AACH,MAAA,OAAO,IAAI,qBAAA,CAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,IAChD,KAAK,aAAA;AACH,MAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AAAA,IAC1C,KAAK,cAAA;AAAA,IACL,KAAK,iBAAA;AACH,MAAA,OAAO,IAAI,cAAA,CAAe,OAAA,EAAS,IAAI,CAAA;AAAA,IACzC,KAAK,aAAA;AACH,MAAA,OAAO,IAAI,uBAAA,CAAwB,OAAA,EAAS,IAAI,CAAA;AAAA,IAClD;AACE,MAAA,OAAO,IAAI,QAAA,CAAS,OAAA,EAAS,IAAI,CAAA;AAAA;AAEvC;;;ACnMO,IAAM,OAAA,GAAU,OAAA;;;ACcvB,IAAM,gBAAA,GAAmB,yBAAA;AACzB,IAAM,UAAA,GAAa,cAAc,OAAO,CAAA,CAAA;AAExC,IAAM,gBAAA,GAAmB,EAAA;AAElB,IAAM,kBAAA,GAAqB;AAClC,IAAM,QAAA,uBAAyC,GAAA,CAAI;AAAA,EACjD,QAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGM,SAAS,WAAW,MAAA,EAA8B;AACvD,EAAA,OAAO,QAAA,CAAS,IAAI,MAAM,CAAA;AAC5B;AAuEO,IAAM,UAAN,MAAc;AAAA,EACV,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,OAAA,EAAyB;AACnC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAC/B,MAAA,MAAM,IAAI,YAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,MAAA;AACvB,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACxE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,OAAA,IAAW,GAAA;AACnC,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,KAAA,IAAU,UAAA,CAAW,KAAA;AACvC,IAAA,IAAI,CAAC,CAAA,EAAG;AACN,MAAA,MAAM,IAAI,YAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AAAA,EAChB;AAAA;AAAA,EAGS,MAAA,GAAS;AAAA;AAAA,IAEhB,MAAA,EAAQ,CAAC,MAAA,EAA2B,OAAA,GAAuB,EAAC,KAC1D,IAAA,CAAK,QAAA,CAAgB,MAAA,EAAQ,YAAA,EAAc;AAAA,MACzC,IAAA,EAAM,MAAA;AAAA,MACN,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK;AAAA,MAC5B,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA,EAAS,IAAA,CAAK,eAAA,CAAgB,OAAA,CAAQ,IAAI,CAAA;AAAA,MAC1C,MAAA,EAAQ,CAAC,GAAG;AAAA,KACb,CAAA;AAAA;AAAA,IAGH,QAAA,EAAU,CAAC,EAAA,EAAY,OAAA,GAAuB,EAAC,KAC7C,IAAA,CAAK,QAAA,CAAgB,KAAA,EAAO,CAAA,WAAA,EAAc,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA,EAAI;AAAA,MAClE,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK;AAAA,MAC5B,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA,EAAS,IAAA,CAAK,eAAA,CAAgB,OAAA,CAAQ,IAAI,CAAA;AAAA,MAC1C,MAAA,EAAQ,CAAC,GAAG;AAAA,KACb,CAAA;AAAA;AAAA,IAGH,MAAA,EAAQ,CAAC,EAAA,EAAY,OAAA,GAAoC,EAAC,KACxD,IAAA,CAAK,QAAA,CAAgB,QAAA,EAAU,CAAA,WAAA,EAAc,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA,EAAI;AAAA,MACrE,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiBH,KAAA,EAAO,OACL,MAAA,EACA,OAAA,GAA6B,EAAC,KACL;AACzB,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAA;AACzE,MAAA,OAAO,IAAI,WAAA,CAAY,IAAA,EAAM,KAAK,CAAA;AAAA,IACpC,CAAA;AAAA;AAAA,IAGA,IAAA,EAAM,CAAC,MAAA,GAA0B,EAAC,EAAG,OAAA,GAAoC,EAAC,KACxE,IAAA,CAAK,QAAA,CAAoB,KAAA,EAAO,YAAA,EAAc;AAAA,MAC5C,KAAA,EAAO;AAAA,QACL,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,gBAAgB,MAAA,CAAO,cAAA;AAAA,QACvB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,MAAM,MAAA,CAAO;AAAA,OACf;AAAA,MACA,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASH,OAAA,EAAS,CACP,MAAA,GAA0B,EAAC,EAC3B,OAAA,GAAoC,EAAC,KACJ,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,OAAO;AAAA,GAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUS,QAAA,GAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYlB,MAAA,EAAQ,CAAC,MAAA,EAAwB,OAAA,GAAoC,EAAC,KAAyB;AAC7F,MAAA,MAAM,EAAE,QAAA,EAAU,GAAG,MAAA,EAAO,GAAI,MAAA;AAChC,MAAA,OAAO,IAAA,CAAK,QAAA;AAAA,QACV,MAAA;AAAA,QACA,CAAA,WAAA,EAAc,kBAAA,CAAmB,QAAQ,CAAC,CAAA,SAAA,CAAA;AAAA,QAC1C,EAAE,IAAA,EAAM,YAAA,CAAa,MAAM,CAAA,EAAG,MAAA,EAAQ,QAAQ,MAAA;AAAO,OACvD;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmBA,UAAA,EAAY,OACV,OAAA,EACA,OAAA,GAAoC,EAAC,KACV;AAC3B,MAAA,MAAM,MAAA,GAAwB;AAAA,QAC5B,MAAA,EAAQ,gBAAA;AAAA,QACR,QAAA,EAAU,CAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,SAAA,EAAW,CAAA;AAAA,QACX,MAAA,EAAQ,CAAA;AAAA,QACR,SAAS;AAAC,OACZ;AAMA,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,KAAK,kBAAA,EAAoB;AAC3D,QAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,QAAA,CAAwB,QAAQ,cAAA,EAAgB;AAAA,UACvE,IAAA,EAAM,EAAE,QAAA,EAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,kBAAkB,CAAA,CAAE,GAAA,CAAI,YAAY,CAAA,EAAE;AAAA,UAC7E,QAAQ,OAAA,CAAQ;AAAA,SACjB,CAAA;AACD,QAAA,MAAA,CAAO,YAAY,KAAA,CAAM,QAAA;AACzB,QAAA,MAAA,CAAO,WAAW,KAAA,CAAM,OAAA;AACxB,QAAA,MAAA,CAAO,aAAa,KAAA,CAAM,SAAA;AAC1B,QAAA,MAAA,CAAO,UAAU,KAAA,CAAM,MAAA;AACvB,QAAA,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,GAAG,KAAA,CAAM,OAAO,CAAA;AAAA,MACtC;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AAAA;AAAA,EAGA,EAAA,CAAG,OAAA,GAAoC,EAAC,EAAqB;AAC3D,IAAA,OAAO,IAAA,CAAK,SAAkB,KAAA,EAAO,QAAA,EAAU,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,KAAA,CAAM,MAAA,EAA2B,OAAA,GAA8B,EAAC,EAAmB;AACvF,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,QAAQ,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAA;AACzE,IAAA,OAAO,MAAA,CAAO,OAAO,OAAO,CAAA;AAAA,EAC9B;AAAA;AAAA,EAIA,gBAAgB,IAAA,EAAmC;AACjD,IAAA,IAAI,IAAA,KAAS,QAAW,OAAO,MAAA;AAE/B,IAAA,OAAO,OAAO,GAAA,GAAO,IAAA;AAAA,EACvB;AAAA,EAEA,OAAO,QAAA,CACL,MAAA,EACA,OAAA,EAC8B;AAC9B,IAAA,IAAI,SAAS,MAAA,CAAO,cAAA;AACpB,IAAA,WAAS;AACP,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,cAAA,EAAgB,MAAA,EAAO,EAAG,OAAO,CAAA;AAClF,MAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,IAAA,EAAM,MAAM,KAAA;AACrC,MAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AAC9C,MAAA,MAAA,GAAS,KAAK,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,CAAG,EAAA;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,QAAA,CAAY,MAAA,EAAgB,IAAA,EAAc,OAAA,GAA0B,EAAC,EAAe;AACxF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,WAAW,IAAI,CAAA;AACxC,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxD,QAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,EAAA,EAAI,GAAA,CAAI,aAAa,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,OAAO,CAAA,CAAA;AAAA,MACrC,MAAA,EAAQ,kBAAA;AAAA;AAAA,MAER,YAAA,EAAc;AAAA,KAChB;AACA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAW;AAC9B,MAAA,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAC1B,MAAA,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,OAAA,IAAW,IAAA,CAAK,QAAA;AAC1C,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,CAAM,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,SAAS,CAAA,GAAA,CAAK,CAAC,CAAA,EAAG,SAAS,CAAA;AACvH,IAAA,MAAM,UAAU,MAAM,UAAA,CAAW,KAAA,CAAM,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAC7D,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,IAAI,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS,OAAA,EAAQ;AAAA,WAC/B,OAAA,CAAQ,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACvE;AAEA,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,UAAS,EAAG;AAAA,QACtC,MAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM,QAAA;AAAA,QACN,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,cAAc,MAAM,GAAA;AACvC,MAAA,IAAI,OAAA,CAAQ,GAAG,CAAA,EAAG;AAEhB,QAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,OAAA,EAAS,MAAM,OAAA,CAAQ,MAAA,CAAO,MAAA,YAAkB,KAAA,GAChE,OAAA,CAAQ,MAAA,CAAO,MAAA,GACf,IAAI,aAAa,kBAAkB,CAAA;AACvC,QAAA,MAAM,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,SAAS,CAAA,GAAA,CAAK,CAAA;AAAA,MAClE;AACA,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,CAAA,mCAAA,EAAsC,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAM,IAAc,OAAO,CAAA;AAAA,OAChF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,OAAA,CAAQ,MAAA,EAAQ,mBAAA,CAAoB,OAAA,EAAS,OAAO,CAAA;AAAA,IACtD;AAEA,IAAA,OAAO,KAAK,MAAA,CAAU,GAAA,EAAK,OAAA,CAAQ,MAAA,IAAU,EAAE,CAAA;AAAA,EACjD;AAAA,EAEA,MAAM,MAAA,CAAU,GAAA,EAAe,MAAA,EAA8B;AAC3D,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MACxB,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAI,QAAA;AAAA,UACR,CAAA,mCAAA,EAAsC,IAAI,MAAM,CAAA,GAAA,EAAM,KAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,UACxE,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA;AAAO,SACvB;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,IAAI,EAAA,IAAM,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AACzC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA;AAGjB,IAAA,MAAM,WAAW,QAAA,EAAU,KAAA;AAC3B,IAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACnD,IAAA,MAAM,UAAA,GAAa,kBAAkB,IAAA,IAAQ,OAAA,CAAQ,KAAK,aAAa,CAAA,GAAI,MAAA,CAAO,aAAa,CAAA,GAAI,MAAA;AACnG,IAAA,MAAM,iBAAA;AAAA,MACJ,GAAA,CAAI,MAAA;AAAA,MACJ,QAAA,EAAU,IAAA;AAAA,MACV,QAAA,EAAU,OAAA,IAAW,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAA;AAAA,MACvC,UAAU,KAAA,IAAS,IAAA;AAAA,MACnB,EAAE,SAAA,EAAW,QAAA,EAAU,UAAA,IAAc,GAAA,CAAI,QAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA,EAAW,UAAA;AAAW,KAChG;AAAA,EACF;AACF;AAWO,IAAM,cAAN,MAAkB;AAAA;AAAA,EAEd,EAAA;AAAA,EAEA,OAAA;AAAA;AAAA,EAET,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EAEA,WAAA,CAAY,QAAiB,KAAA,EAAc;AACzC,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,KAAK,KAAA,CAAM,EAAA;AAAA,EAClB;AAAA;AAAA,EAGA,IAAI,KAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAA,CAAO,OAAA,GAA8B,EAAC,EAAmB;AACvD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,SAAA;AAChC,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,SAAA;AAChC,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,CAAE,QAAQ,MAAM;AAG5C,MAAA,IAAI,IAAA,CAAK,SAAA,KAAc,GAAA,EAAK,IAAA,CAAK,SAAA,GAAY,MAAA;AAAA,IAC/C,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,SAAA,GAAY,GAAA;AACjB,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,MAAA,CAAO,OAAA,GAAoC,EAAC,EAAmB;AACnE,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA,IACjE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,EAAE,GAAA,YAAe,aAAA,CAAA,EAAgB,MAAM,GAAA;AAE3C,MAAA,IAAA,CAAK,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,QAAA,CAAS,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,CAAC,KAAK,SAAA,IAAa,UAAA,CAAW,KAAK,MAAA,CAAO,MAAM,CAAA,EAAG,IAAA,CAAK,cAAA,EAAe;AAC3E,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAA,GAAiC;AAC/B,IAAA,MAAM,UACJ,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,QAAA,GACnB,QAAQ,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,GAC3B,QAAQ,MAAA,CAAO,IAAI,gBAAA,CAAiB,IAAA,CAAK,MAAM,CAAC,CAAA;AAGtD,IAAA,OAAA,CAAQ,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AACtB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAA;AACjB,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,OAAA,EAA6C;AACvD,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,IAAA;AACnC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAE9B,IAAA,WAAS;AAEP,MAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,SAAA;AAChC,MAAA,IAAI,WAAW,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,OAAO,KAAK,cAAA,EAAe;AAC/D,MAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,QAAA,EAAU;AAC1B,QAAA,MAAM,IAAI,YAAA;AAAA,UACR,CAAA,MAAA,EAAS,KAAK,EAAE,CAAA,uBAAA,EAA0B,OAAO,CAAA,iBAAA,EAAoB,IAAA,CAAK,OAAO,MAAM,CAAA,EAAA,CAAA;AAAA,UACvF,EAAE,OAAA,EAAS,IAAA,CAAK,EAAA,EAAI,KAAA,EAAO,KAAK,MAAA;AAAO,SACzC;AAAA,MACF;AACA,MAAA,IAAA,CAAK,SAAS,MAAM,IAAA,CAAK,QAAQ,MAAA,CAAO,QAAA,CAAS,KAAK,EAAA,EAAI;AAAA,QACxD,IAAA,EAAM,YAAY,QAAQ,CAAA;AAAA,QAC1B,QAAQ,OAAA,CAAQ;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AACF;AAQA,SAAS,YAAY,QAAA,EAA0B;AAC7C,EAAA,MAAM,YAAY,IAAA,CAAK,IAAA,CAAA,CAAM,WAAW,IAAA,CAAK,GAAA,MAAS,GAAI,CAAA;AAC1D,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,gBAAA,EAAkB,SAAS,CAAC,CAAA;AAC1D;AAEA,SAAS,QAAQ,GAAA,EAAuB;AACtC,EAAA,OAAO,GAAA,YAAe,KAAA,IAAS,GAAA,CAAI,IAAA,KAAS,YAAA;AAC9C;AAGA,SAAS,aAAa,MAAA,EAAmE;AACvF,EAAA,MAAM,IAAA,GAAgC,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,EAAQ;AAChE,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,EAAW,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACtD,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AACxD,EAAA,IAAI,MAAA,CAAO,gBAAgB,MAAA,EAAW;AACpC,IAAA,IAAA,CAAK,WAAA,GACH,OAAO,WAAA,YAAuB,IAAA,GAAO,OAAO,WAAA,CAAY,WAAA,KAAgB,MAAA,CAAO,WAAA;AAAA,EACnF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,aAAa,MAAA,EAAiD;AACrE,EAAA,MAAM,EAAE,QAAA,EAAU,GAAG,MAAA,EAAO,GAAI,MAAA;AAChC,EAAA,OAAO,EAAE,QAAA,EAAU,GAAG,YAAA,CAAa,MAAM,CAAA,EAAE;AAC7C","file":"index.cjs","sourcesContent":["import type { ErrorCode, Solve } from \"./types.js\";\n\n/**\n * Base class for every error this library throws. Catch `NoneCapError` to\n * handle all of them, or catch a subclass to handle one kind.\n */\nexport class NoneCapError extends Error {\n /** Machine-readable error code from the API envelope, when there is one. */\n readonly code: ErrorCode | undefined;\n /** HTTP status, when the error came from a response. */\n readonly status: number | undefined;\n /** The request field that was rejected, for validation errors. */\n readonly param: string | null;\n /** The API's correlation id for this request (`X-Request-Id`); quote it to support. */\n readonly requestId: string | undefined;\n /** Seconds to wait before retrying, when the API sent `Retry-After`. */\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n requestId?: string;\n retryAfter?: number;\n } = {},\n ) {\n super(message);\n this.name = new.target.name;\n this.code = opts.code;\n this.status = opts.status;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId;\n this.retryAfter = opts.retryAfter;\n // Restore the prototype chain when compiled down to ES5-era targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — the API key is missing, malformed, or revoked. */\nexport class AuthenticationError extends NoneCapError {}\n\n/** 403 — the key is valid but not allowed to do this (scope or locked account). */\nexport class PermissionError extends NoneCapError {}\n\n/** 402 — the account is out of credits. */\nexport class InsufficientCreditsError extends NoneCapError {}\n\n/** 402 — this API key reached its own credit limit (the account may still have credits). */\nexport class KeyCreditLimitError extends InsufficientCreditsError {}\n\n/** 422 / 400 — the request was rejected. `param` names the offending field. */\nexport class ValidationError extends NoneCapError {}\n\n/** 413 — the request body exceeds the route's size limit. */\nexport class PayloadTooLargeError extends ValidationError {}\n\n/** 415 — a JSON route was called without `Content-Type: application/json`. */\nexport class UnsupportedMediaTypeError extends ValidationError {}\n\n/** 404 — no such resource. */\nexport class NotFoundError extends NoneCapError {}\n\n/** 409 — the solve is already in a terminal state (e.g. cancelling a finished solve). */\nexport class ConflictError extends NoneCapError {}\n\n/** 429 — back off and retry; `retryAfter` (seconds) is set when the API sent it. */\nexport class RateLimitError extends NoneCapError {}\n\n/** 429 — too many solves in flight for this account. Wait for one to finish. */\nexport class ConcurrencyLimitError extends RateLimitError {}\n\n/** 429 — hCaptcha is refusing challenges for this sitekey, so the submit was shed.\n * Wait `retryAfter` seconds; the message says whether a different proxy pool can help. */\nexport class SitekeyRateLimitedError extends RateLimitError {}\n\n/** 429 — nearly every recent solve through the proxy you supplied failed because the\n * proxy refused the connection, so submits through it are shed. Fix the proxy or\n * switch exit; `retryAfter` says when the next submit is let through to re-check it. */\nexport class ProxyUnavailableError extends RateLimitError {}\n\n/** 429 — your account has a submit rate cap on this sitekey and reached it for the\n * trailing minute, or your own-proxy sessions for this sitekey are at their limit.\n * Nothing was charged; wait `retryAfter` seconds. */\nexport class RateCappedError extends RateLimitError {}\n\n/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */\nexport class APIError extends NoneCapError {}\n\n/** 503 — new solves are paused for maintenance. Retry shortly. */\nexport class ServiceUnavailableError extends APIError {}\n\n/** The request never reached the API (DNS, TCP, TLS, timeout, offline). */\nexport class ConnectionError extends NoneCapError {}\n\n/**\n * Thrown by {@link NoneCap.solve} when a solve reaches a terminal state without\n * a token: `failed`, `expired`, or `cancelled`. The full solve is attached so\n * you can inspect `solve.error` and timings.\n */\nexport class SolveFailedError extends NoneCapError {\n readonly solve: Solve;\n\n constructor(solve: Solve) {\n const detail = solve.error ? `${solve.error.code}: ${solve.error.message}` : solve.status;\n super(`Solve ${solve.id} ${solve.status} (${detail})`, {\n code: undefined,\n status: undefined,\n });\n this.solve = solve;\n }\n\n /** `solve.error.code`, e.g. `proxy_error`; the status when no error object came back. */\n get solveCode(): string {\n return this.solve.error?.code ?? this.solve.status;\n }\n\n /** `solve.error.reason`, the typed sub-reason, or null. */\n get reason(): string | null {\n return this.solve.error?.reason ?? null;\n }\n\n /** Whether re-submitting the same request unchanged can succeed. */\n get retryable(): boolean {\n return this.solve.error?.retryable ?? false;\n }\n}\n\n/**\n * Thrown by {@link NoneCap.solve} (and {@link SolveHandle.result}) when the\n * client-side timeout elapses first. When the timeout came from waiting on a\n * solve, `solveId` and the last-known `solve` are attached so you can still\n * cancel the in-flight solve. They are `undefined` for transport-level timeouts.\n */\nexport class TimeoutError extends NoneCapError {\n /** The id of the in-flight solve, when the timeout came from a solve wait. */\n readonly solveId: string | undefined;\n /** The last-known solve state, so you can cancel it after a wait timed out. */\n readonly solve: Solve | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n solveId?: string;\n solve?: Solve;\n } = {},\n ) {\n super(message, opts);\n this.solveId = opts.solveId;\n this.solve = opts.solve;\n }\n}\n\n/** Map an API error envelope (plus HTTP status) to the right error subclass. */\nexport function errorFromResponse(\n status: number,\n code: ErrorCode | undefined,\n message: string,\n param: string | null,\n extra: { requestId?: string; retryAfter?: number } = {},\n): NoneCapError {\n const opts = { code, status, param, ...extra };\n switch (code) {\n case \"unauthorized\":\n return new AuthenticationError(message, opts);\n case \"forbidden\":\n case \"account_locked\":\n return new PermissionError(message, opts);\n case \"insufficient_credits\":\n return new InsufficientCreditsError(message, opts);\n case \"key_credit_limit_exceeded\":\n return new KeyCreditLimitError(message, opts);\n case \"invalid_request\":\n case \"validation_error\":\n case \"expired_window\":\n return new ValidationError(message, opts);\n case \"payload_too_large\":\n return new PayloadTooLargeError(message, opts);\n case \"unsupported_media_type\":\n return new UnsupportedMediaTypeError(message, opts);\n case \"not_found\":\n case \"not_eligible\":\n return new NotFoundError(message, opts);\n case \"conflict\":\n return new ConflictError(message, opts);\n case \"concurrency_limit_exceeded\":\n return new ConcurrencyLimitError(message, opts);\n case \"sitekey_rate_limited\":\n return new SitekeyRateLimitedError(message, opts);\n case \"proxy_unavailable\":\n return new ProxyUnavailableError(message, opts);\n case \"rate_capped\":\n return new RateCappedError(message, opts);\n case \"rate_limited\":\n case \"ext_daily_limit\":\n return new RateLimitError(message, opts);\n case \"maintenance\":\n return new ServiceUnavailableError(message, opts);\n default:\n return new APIError(message, opts);\n }\n}\n","/**\n * The published package version, sent as the `User-Agent` on every request.\n *\n * Hardcoded rather than imported from package.json: a JSON import would need\n * `resolveJsonModule` and would resolve differently under the ESM and CJS\n * builds. Bump it in the SAME commit as package.json: the drift check is the\n * `Version constant matches package.json` step in ci.yml and lives ONLY there,\n * so `npm test` and `tsc` both stay green on a mismatch (test/version.test.ts\n * asserts the User-Agent uses VERSION, never that VERSION is right).\n */\nexport const VERSION = \"0.9.6\";\n","import {\n APIError,\n ConflictError,\n ConnectionError,\n NoneCapError,\n SolveFailedError,\n TimeoutError,\n errorFromResponse,\n} from \"./errors.js\";\nimport type {\n Account,\n ErrorCode,\n Feedback,\n FeedbackBatch,\n FeedbackReport,\n Solve,\n SolveCreateParams,\n SolveList,\n SolveListParams,\n SolveStatus,\n} from \"./types.js\";\n\nimport { VERSION } from \"./version.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.nonecap.com\";\nconst USER_AGENT = `nonecap-js/${VERSION}`;\n/** The API caps server-side long-poll at 90 seconds. */\nconst MAX_WAIT_SECONDS = 90;\n/** The API caps one `POST /v1/feedback` call at 500 items. */\nexport const FEEDBACK_BATCH_MAX = 500;\nconst TERMINAL: ReadonlySet<SolveStatus> = new Set([\n \"solved\",\n \"failed\",\n \"cancelled\",\n \"expired\",\n]);\n\n/** Is this a terminal solve status? */\nexport function isTerminal(status: SolveStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** A `fetch` implementation. Defaults to the global `fetch`. */\nexport type FetchLike = (\n input: string,\n init?: RequestInit,\n) => Promise<Response>;\n\n/** Options for constructing a {@link NoneCap} client. */\nexport interface NoneCapOptions {\n /** Your NoneCap API key. Find it at https://dashboard.nonecap.com. */\n apiKey: string;\n /** Override the API base URL. Defaults to https://api.nonecap.com. */\n baseURL?: string;\n /**\n * Per-request timeout in milliseconds for a single HTTP call. Defaults to\n * 100000 (just above the 90s server long-poll). Note this bounds one HTTP\n * round trip, not the whole {@link NoneCap.solve} wait — use the `timeout`\n * option on `solve()` for that.\n */\n timeout?: number;\n /** Inject a custom `fetch` (for testing, proxies, or non-standard runtimes). */\n fetch?: FetchLike;\n}\n\n/** Per-call options for the long-polling endpoints. */\nexport interface WaitOptions {\n /**\n * Hold the connection open up to this many seconds (1–90) waiting for the\n * solve to finish before responding. Omit to return immediately.\n */\n wait?: number;\n /** Abort the request. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solve} and {@link SolveHandle.result}. */\nexport interface SolveHelperOptions {\n /**\n * Give up after this many milliseconds and throw {@link TimeoutError}.\n * Defaults to 180000 (3 minutes).\n */\n timeout?: number;\n /** Abort waiting. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solves.start}. */\nexport interface SolveStartOptions {\n /** Abort the submission. */\n signal?: AbortSignal;\n}\n\ninterface RequestOptions {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n signal?: AbortSignal;\n /** Override the per-request timeout for this call (used by long polls). */\n timeout?: number;\n /** HTTP statuses to treat as success in addition to 2xx (e.g. 202). */\n expect?: number[];\n}\n\n/**\n * The NoneCap API client.\n *\n * ```ts\n * const nc = new NoneCap({ apiKey: process.env.NONECAP_KEY! });\n * const { token } = await nc.solve({ type: \"hcaptcha\", sitekey, url });\n * ```\n */\nexport class NoneCap {\n readonly #apiKey: string;\n readonly #baseURL: string;\n readonly #timeout: number;\n readonly #fetch: FetchLike;\n\n constructor(options: NoneCapOptions) {\n if (!options || !options.apiKey) {\n throw new NoneCapError(\n \"A NoneCap API key is required. Pass it as `new NoneCap({ apiKey })`.\",\n );\n }\n this.#apiKey = options.apiKey;\n this.#baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#timeout = options.timeout ?? 100_000;\n const f = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new NoneCapError(\n \"No `fetch` available. Use Node 18+, or pass a `fetch` in the client options.\",\n );\n }\n this.#fetch = f;\n }\n\n /** Operations on solves. */\n readonly solves = {\n /** Submit a solve. Pass `{ wait }` to hold the connection until it finishes. */\n create: (params: SolveCreateParams, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"POST\", \"/v1/solves\", {\n body: params,\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Fetch a solve by id. Pass `{ wait }` to long-poll until it finishes. */\n retrieve: (id: string, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"GET\", `/v1/solves/${encodeURIComponent(id)}`, {\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Cancel a pending or in-flight solve. */\n cancel: (id: string, options: { signal?: AbortSignal } = {}): Promise<Solve> =>\n this.#request<Solve>(\"DELETE\", `/v1/solves/${encodeURIComponent(id)}`, {\n signal: options.signal,\n }),\n\n /**\n * Submit a solve and return a {@link SolveHandle} for it.\n *\n * Unlike {@link NoneCap.solve}, this returns as soon as the submission is\n * accepted, so `handle.id` is available immediately. Use the handle to\n * `cancel()` the solve or `await handle.result()` for the finished solve.\n *\n * ```ts\n * const handle = await nc.solves.start({ type: \"hcaptcha\", sitekey, url });\n * // ...later, e.g. on shutdown:\n * await handle.cancel();\n * // or wait for it:\n * const { token } = await handle.result();\n * ```\n */\n start: async (\n params: SolveCreateParams,\n options: SolveStartOptions = {},\n ): Promise<SolveHandle> => {\n const solve = await this.solves.create(params, { signal: options.signal });\n return new SolveHandle(this, solve);\n },\n\n /** Fetch one page of solves. */\n list: (params: SolveListParams = {}, options: { signal?: AbortSignal } = {}): Promise<SolveList> =>\n this.#request<SolveList>(\"GET\", \"/v1/solves\", {\n query: {\n limit: params.limit,\n starting_after: params.starting_after,\n status: params.status,\n type: params.type,\n },\n signal: options.signal,\n }),\n\n /**\n * Iterate every solve across pages, newest first.\n *\n * ```ts\n * for await (const solve of nc.solves.listAll()) { ... }\n * ```\n */\n listAll: (\n params: SolveListParams = {},\n options: { signal?: AbortSignal } = {},\n ): AsyncIterableIterator<Solve> => this.#listAll(params, options),\n };\n\n /**\n * Report what your downstream target did with the tokens we minted.\n *\n * Feedback is free, own-solves-only, and idempotent per solve id: reporting\n * the same solve again corrects the earlier verdict. Only `solved` solves can\n * be reported, and only within the API's reporting window (~30 days from the\n * solve; corrections to an already-reported solve are never re-gated by it).\n */\n readonly feedback = {\n /**\n * Report one solve's downstream outcome, returning the recorded feedback.\n *\n * Unlike {@link NoneCap.feedback.reportMany}, a rejected report throws:\n * {@link NotFoundError} if the solve isn't yours or never minted a token,\n * {@link ValidationError} if a field is wrong or the reporting window closed.\n *\n * ```ts\n * await nc.feedback.report({ solve_id: solve.id, outcome: \"rejected\", reason: \"...\" });\n * ```\n */\n report: (report: FeedbackReport, options: { signal?: AbortSignal } = {}): Promise<Feedback> => {\n const { solve_id, ...fields } = report;\n return this.#request<Feedback>(\n \"POST\",\n `/v1/solves/${encodeURIComponent(solve_id)}/feedback`,\n { body: toWireFields(fields), signal: options.signal },\n );\n },\n\n /**\n * Report many verdicts at once — the path to use at volume. Buffer verdicts\n * as you learn them and flush them here.\n *\n * The call succeeds even when individual items are rejected: each is\n * resolved on its own so one stale id never discards the rest. Check\n * `failed` rather than relying on a thrown error.\n *\n * More than {@link FEEDBACK_BATCH_MAX} reports are split across sequential\n * requests and merged into one result, in request order. An empty array is\n * a no-op that returns an empty batch without a request.\n *\n * ```ts\n * const batch = await nc.feedback.reportMany(buffer);\n * if (batch.failed) console.warn(batch.results.filter((r) => r.status === \"error\"));\n * ```\n */\n reportMany: async (\n reports: readonly FeedbackReport[],\n options: { signal?: AbortSignal } = {},\n ): Promise<FeedbackBatch> => {\n const merged: FeedbackBatch = {\n object: \"feedback_batch\",\n recorded: 0,\n updated: 0,\n unchanged: 0,\n failed: 0,\n results: [],\n };\n // Chunks are sent in order and the server upserts last-write-wins, so a\n // solve reported twice still ends at its last value. Duplicates split\n // across a chunk boundary each get written, though, so the earlier one\n // reports `recorded`/`updated` where a single request would say\n // `unchanged`.\n for (let i = 0; i < reports.length; i += FEEDBACK_BATCH_MAX) {\n const batch = await this.#request<FeedbackBatch>(\"POST\", \"/v1/feedback\", {\n body: { feedback: reports.slice(i, i + FEEDBACK_BATCH_MAX).map(toWireReport) },\n signal: options.signal,\n });\n merged.recorded += batch.recorded;\n merged.updated += batch.updated;\n merged.unchanged += batch.unchanged;\n merged.failed += batch.failed;\n merged.results.push(...batch.results);\n }\n return merged;\n },\n };\n\n /** Fetch your account, including the current credit balance. */\n me(options: { signal?: AbortSignal } = {}): Promise<Account> {\n return this.#request<Account>(\"GET\", \"/v1/me\", { signal: options.signal });\n }\n\n /**\n * Submit a solve and wait for it to finish, returning the solved solve.\n *\n * Uses the server's long-poll under the hood and keeps polling until the\n * solve is terminal or `timeout` elapses. Throws {@link SolveFailedError} if\n * the solve fails/expires/is cancelled, or {@link TimeoutError} on timeout.\n *\n * This is sugar for `(await solves.start(params)).result(options)`. When you\n * need to cancel the solve while it runs, use {@link NoneCap.solves.start}\n * and keep the {@link SolveHandle}.\n */\n async solve(params: SolveCreateParams, options: SolveHelperOptions = {}): Promise<Solve> {\n const handle = await this.solves.start(params, { signal: options.signal });\n return handle.result(options);\n }\n\n // -- internals ------------------------------------------------------------\n\n #timeoutForWait(wait?: number): number | undefined {\n if (wait === undefined) return undefined;\n // Give the socket a margin beyond the server's long-poll window.\n return wait * 1000 + 15_000;\n }\n\n async *#listAll(\n params: SolveListParams,\n options: { signal?: AbortSignal },\n ): AsyncIterableIterator<Solve> {\n let cursor = params.starting_after;\n for (;;) {\n const page = await this.solves.list({ ...params, starting_after: cursor }, options);\n for (const solve of page.data) yield solve;\n if (!page.has_more || page.data.length === 0) return;\n cursor = page.data[page.data.length - 1]!.id;\n }\n }\n\n async #request<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const url = new URL(this.#baseURL + path);\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== \"\") url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n Accept: \"application/json\",\n // Browsers drop this as a forbidden header; on Node it identifies the SDK.\n \"User-Agent\": USER_AGENT,\n };\n let bodyInit: string | undefined;\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyInit = JSON.stringify(options.body);\n }\n\n const controller = new AbortController();\n const timeoutMs = options.timeout ?? this.#timeout;\n const timer = setTimeout(() => controller.abort(new TimeoutError(`Request timed out after ${timeoutMs}ms.`)), timeoutMs);\n const onAbort = () => controller.abort(options.signal?.reason);\n if (options.signal) {\n if (options.signal.aborted) onAbort();\n else options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n let res: Response;\n try {\n res = await this.#fetch(url.toString(), {\n method,\n headers,\n body: bodyInit,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof TimeoutError) throw err;\n if (isAbort(err)) {\n // A caller-supplied signal aborting surfaces as the caller's reason.\n if (options.signal?.aborted) throw options.signal.reason instanceof Error\n ? options.signal.reason\n : new NoneCapError(\"Request aborted.\");\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms.`);\n }\n throw new ConnectionError(\n `Could not reach the NoneCap API at ${this.#baseURL}: ${(err as Error).message}`,\n );\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n return this.#parse<T>(res, options.expect ?? []);\n }\n\n async #parse<T>(res: Response, expect: number[]): Promise<T> {\n const text = await res.text();\n let json: unknown;\n if (text) {\n try {\n json = JSON.parse(text);\n } catch {\n throw new APIError(\n `Unexpected non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n { status: res.status },\n );\n }\n }\n\n if (res.ok || expect.includes(res.status)) {\n return json as T;\n }\n\n const envelope = json as\n | { error?: { code?: ErrorCode; message?: string; param?: string | null; request_id?: string } }\n | undefined;\n const apiError = envelope?.error;\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw !== null && /^\\d+$/.test(retryAfterRaw) ? Number(retryAfterRaw) : undefined;\n throw errorFromResponse(\n res.status,\n apiError?.code,\n apiError?.message ?? `HTTP ${res.status}`,\n apiError?.param ?? null,\n { requestId: apiError?.request_id ?? res.headers.get(\"x-request-id\") ?? undefined, retryAfter },\n );\n }\n}\n\n/**\n * A handle on a started solve, returned by {@link NoneCap.solves.start}.\n *\n * The handle is the cancellable lifecycle object for one solve. It is a plain\n * object, not a promise: `await`ing it does nothing useful. Wait for the result\n * with {@link SolveHandle.result}, and cancel with {@link SolveHandle.cancel}.\n * You do not construct it yourself — `solves.start()` hands you one with `id`\n * already resolved.\n */\nexport class SolveHandle {\n /** The id of the started solve, available as soon as `start()` resolved. */\n readonly id: string;\n\n readonly #client: NoneCap;\n /** The latest solve state we have seen, from the create, polls, or cancel. */\n #solve: Solve;\n /**\n * The cached TERMINAL outcome: resolves to the solved solve, or rejects with\n * {@link SolveFailedError} if terminal-but-not-solved. Only ever set once the\n * solve actually reaches a terminal state, so it is safe to replay forever. A\n * timed-out wait does NOT settle this — it is retryable.\n */\n #terminal: Promise<Solve> | undefined;\n /** The poll currently in flight, shared by concurrent result() callers. */\n #inflight: Promise<Solve> | undefined;\n\n constructor(client: NoneCap, solve: Solve) {\n this.#client = client;\n this.#solve = solve;\n this.id = solve.id;\n }\n\n /** The last-known solve state for this handle. */\n get solve(): Solve {\n return this.#solve;\n }\n\n /**\n * Long-poll until the solve is terminal, returning the solved solve. Throws\n * {@link SolveFailedError} if it fails/expires/is cancelled, or\n * {@link TimeoutError} on timeout (with `solveId`/`solve` attached so you can\n * still {@link SolveHandle.cancel} it).\n *\n * Memoizes the *terminal* outcome: once the solve actually finishes, every\n * later call returns that same settled result. A {@link TimeoutError} is not\n * memoized — it just means this wait gave up, so a later call (e.g. with a\n * larger `timeout`) resumes polling. Concurrent calls share one in-flight\n * poll, so they never issue duplicate requests. The first caller's\n * `timeout`/`signal` drive the shared poll; a later call starts a fresh one.\n */\n result(options: SolveHelperOptions = {}): Promise<Solve> {\n if (this.#terminal) return this.#terminal;\n if (this.#inflight) return this.#inflight;\n const run = this.#poll(options).finally(() => {\n // Free the slot so a retry can re-poll after a timeout; a terminal\n // outcome is already memoized in #terminal and wins on the next call.\n if (this.#inflight === run) this.#inflight = undefined;\n });\n this.#inflight = run;\n return run;\n }\n\n /**\n * Cancel the solve. Cancelled solves are never charged, so this is for clean\n * shutdown / freeing slots / stopping early, not cost protection.\n *\n * If the solve already reached a terminal state the API answers 409; that is\n * not an error a caller cares about, so this swallows {@link ConflictError}\n * and returns the current solve state instead. A cancel that lands on a\n * terminal state (cancelled, or whatever the 409-swallow read back) settles\n * this handle's {@link SolveHandle.result}, so any in-flight or later wait\n * stops polling and reflects that terminal state.\n */\n async cancel(options: { signal?: AbortSignal } = {}): Promise<Solve> {\n try {\n this.#solve = await this.#client.solves.cancel(this.id, options);\n } catch (err) {\n if (!(err instanceof ConflictError)) throw err;\n // Already terminal — report the real state rather than the 409.\n this.#solve = await this.#client.solves.retrieve(this.id, options);\n }\n if (!this.#terminal && isTerminal(this.#solve.status)) this.#cacheTerminal();\n return this.#solve;\n }\n\n /**\n * Build and memoize the terminal outcome from the current `#solve`. The\n * precondition is that `#solve` is terminal and `#terminal` is unset.\n */\n #cacheTerminal(): Promise<Solve> {\n const settled =\n this.#solve.status === \"solved\"\n ? Promise.resolve(this.#solve)\n : Promise.reject(new SolveFailedError(this.#solve));\n // Never let the memoized rejection surface as an unhandled rejection; real\n // callers read it explicitly through result().\n settled.catch(() => {});\n this.#terminal = settled;\n return settled;\n }\n\n async #poll(options: SolveHelperOptions): Promise<Solve> {\n const timeout = options.timeout ?? 180_000;\n const deadline = Date.now() + timeout;\n\n for (;;) {\n // cancel() (or a previous poll) may have already settled this handle.\n if (this.#terminal) return this.#terminal;\n if (isTerminal(this.#solve.status)) return this.#cacheTerminal();\n if (Date.now() >= deadline) {\n throw new TimeoutError(\n `Solve ${this.id} did not finish within ${timeout}ms (last status: ${this.#solve.status}).`,\n { solveId: this.id, solve: this.#solve },\n );\n }\n this.#solve = await this.#client.solves.retrieve(this.id, {\n wait: waitSeconds(deadline),\n signal: options.signal,\n });\n }\n }\n}\n\n/**\n * The `wait` value for the next long-poll: whole seconds until `deadline`,\n * clamped to the server's 1–90 window. The floor of 1 keeps the param valid,\n * so callers must decide whether the deadline has passed with the clock, not\n * with this return value.\n */\nfunction waitSeconds(deadline: number): number {\n const remaining = Math.ceil((deadline - Date.now()) / 1000);\n return Math.max(1, Math.min(MAX_WAIT_SECONDS, remaining));\n}\n\nfunction isAbort(err: unknown): boolean {\n return err instanceof Error && err.name === \"AbortError\";\n}\n\n/** The fields of a report, ready for the wire: a `Date` becomes an ISO string. */\nfunction toWireFields(fields: Omit<FeedbackReport, \"solve_id\">): Record<string, unknown> {\n const wire: Record<string, unknown> = { outcome: fields.outcome };\n if (fields.reason !== undefined) wire.reason = fields.reason;\n if (fields.context !== undefined) wire.context = fields.context;\n if (fields.reported_at !== undefined) {\n wire.reported_at =\n fields.reported_at instanceof Date ? fields.reported_at.toISOString() : fields.reported_at;\n }\n return wire;\n}\n\nfunction toWireReport(report: FeedbackReport): Record<string, unknown> {\n const { solve_id, ...fields } = report;\n return { solve_id, ...toWireFields(fields) };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/version.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ErrorCode, Solve } from \"./types.js\";\n\n/**\n * Base class for every error this library throws. Catch `NoneCapError` to\n * handle all of them, or catch a subclass to handle one kind.\n */\nexport class NoneCapError extends Error {\n /** Machine-readable error code from the API envelope, when there is one. */\n readonly code: ErrorCode | undefined;\n /** HTTP status, when the error came from a response. */\n readonly status: number | undefined;\n /** The request field that was rejected, for validation errors. */\n readonly param: string | null;\n /** The API's correlation id for this request (`X-Request-Id`); quote it to support. */\n readonly requestId: string | undefined;\n /** Seconds to wait before retrying, when the API sent `Retry-After`. */\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n requestId?: string;\n retryAfter?: number;\n } = {},\n ) {\n super(message);\n this.name = new.target.name;\n this.code = opts.code;\n this.status = opts.status;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId;\n this.retryAfter = opts.retryAfter;\n // Restore the prototype chain when compiled down to ES5-era targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — the API key is missing, malformed, or revoked. */\nexport class AuthenticationError extends NoneCapError {}\n\n/** 403 — the key is valid but not allowed to do this (scope or locked account). */\nexport class PermissionError extends NoneCapError {}\n\n/** 402 — the account is out of credits. */\nexport class InsufficientCreditsError extends NoneCapError {}\n\n/** 402 — this API key reached its own credit limit (the account may still have credits). */\nexport class KeyCreditLimitError extends InsufficientCreditsError {}\n\n/** 422 / 400 — the request was rejected. `param` names the offending field. */\nexport class ValidationError extends NoneCapError {}\n\n/** 413 — the request body exceeds the route's size limit. */\nexport class PayloadTooLargeError extends ValidationError {}\n\n/** 415 — a JSON route was called without `Content-Type: application/json`. */\nexport class UnsupportedMediaTypeError extends ValidationError {}\n\n/** 404 — no such resource. */\nexport class NotFoundError extends NoneCapError {}\n\n/** 409 — the solve is already in a terminal state (e.g. cancelling a finished solve). */\nexport class ConflictError extends NoneCapError {}\n\n/** 429 — back off and retry; `retryAfter` (seconds) is set when the API sent it. */\nexport class RateLimitError extends NoneCapError {}\n\n/** 429 — too many solves in flight for this account. Wait for one to finish. */\nexport class ConcurrencyLimitError extends RateLimitError {}\n\n/** 429 — hCaptcha is refusing challenges for this sitekey, so the submit was shed.\n * Wait `retryAfter` seconds; the message says whether a different proxy pool can help. */\nexport class SitekeyRateLimitedError extends RateLimitError {}\n\n/** 429 — nearly every recent solve through the proxy you supplied failed because the\n * proxy refused the connection, so submits through it are shed. Fix the proxy or\n * switch exit; `retryAfter` says when the next submit is let through to re-check it. */\nexport class ProxyUnavailableError extends RateLimitError {}\n\n/** 429 — your account has a submit rate cap on this sitekey and reached it for the\n * trailing minute, or your own-proxy sessions for this sitekey are at their limit.\n * Nothing was charged; wait `retryAfter` seconds. */\nexport class RateCappedError extends RateLimitError {}\n\n/** 422 — {@link NoneCap.recognize} produced no answer for these images, or the challenge\n * type is not supported. Nothing was charged. */\nexport class RecognitionFailedError extends NoneCapError {}\n\n/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */\nexport class APIError extends NoneCapError {}\n\n/** 503 — new solves are paused for maintenance. Retry shortly. */\nexport class ServiceUnavailableError extends APIError {}\n\n/** The request never reached the API (DNS, TCP, TLS, timeout, offline). */\nexport class ConnectionError extends NoneCapError {}\n\n/**\n * Thrown by {@link NoneCap.solve} when a solve reaches a terminal state without\n * a token: `failed`, `expired`, or `cancelled`. The full solve is attached so\n * you can inspect `solve.error` and timings.\n */\nexport class SolveFailedError extends NoneCapError {\n readonly solve: Solve;\n\n constructor(solve: Solve) {\n const detail = solve.error ? `${solve.error.code}: ${solve.error.message}` : solve.status;\n super(`Solve ${solve.id} ${solve.status} (${detail})`, {\n code: undefined,\n status: undefined,\n });\n this.solve = solve;\n }\n\n /** `solve.error.code`, e.g. `proxy_error`; the status when no error object came back. */\n get solveCode(): string {\n return this.solve.error?.code ?? this.solve.status;\n }\n\n /** `solve.error.reason`, the typed sub-reason, or null. */\n get reason(): string | null {\n return this.solve.error?.reason ?? null;\n }\n\n /** Whether re-submitting the same request unchanged can succeed. */\n get retryable(): boolean {\n return this.solve.error?.retryable ?? false;\n }\n}\n\n/**\n * Thrown by {@link NoneCap.solve} (and {@link SolveHandle.result}) when the\n * client-side timeout elapses first. When the timeout came from waiting on a\n * solve, `solveId` and the last-known `solve` are attached so you can still\n * cancel the in-flight solve. They are `undefined` for transport-level timeouts.\n */\nexport class TimeoutError extends NoneCapError {\n /** The id of the in-flight solve, when the timeout came from a solve wait. */\n readonly solveId: string | undefined;\n /** The last-known solve state, so you can cancel it after a wait timed out. */\n readonly solve: Solve | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n solveId?: string;\n solve?: Solve;\n } = {},\n ) {\n super(message, opts);\n this.solveId = opts.solveId;\n this.solve = opts.solve;\n }\n}\n\n/** Map an API error envelope (plus HTTP status) to the right error subclass. */\nexport function errorFromResponse(\n status: number,\n code: ErrorCode | undefined,\n message: string,\n param: string | null,\n extra: { requestId?: string; retryAfter?: number } = {},\n): NoneCapError {\n const opts = { code, status, param, ...extra };\n switch (code) {\n case \"unauthorized\":\n return new AuthenticationError(message, opts);\n case \"forbidden\":\n case \"account_locked\":\n return new PermissionError(message, opts);\n case \"insufficient_credits\":\n return new InsufficientCreditsError(message, opts);\n case \"key_credit_limit_exceeded\":\n return new KeyCreditLimitError(message, opts);\n case \"invalid_request\":\n case \"validation_error\":\n case \"expired_window\":\n return new ValidationError(message, opts);\n case \"payload_too_large\":\n return new PayloadTooLargeError(message, opts);\n case \"unsupported_media_type\":\n return new UnsupportedMediaTypeError(message, opts);\n case \"not_found\":\n case \"not_eligible\":\n return new NotFoundError(message, opts);\n case \"conflict\":\n return new ConflictError(message, opts);\n case \"concurrency_limit_exceeded\":\n return new ConcurrencyLimitError(message, opts);\n case \"sitekey_rate_limited\":\n return new SitekeyRateLimitedError(message, opts);\n case \"proxy_unavailable\":\n return new ProxyUnavailableError(message, opts);\n case \"rate_capped\":\n return new RateCappedError(message, opts);\n case \"rate_limited\":\n case \"ext_daily_limit\":\n return new RateLimitError(message, opts);\n case \"recognition_failed\":\n return new RecognitionFailedError(message, opts);\n case \"maintenance\":\n return new ServiceUnavailableError(message, opts);\n default:\n return new APIError(message, opts);\n }\n}\n","/**\n * The published package version, sent as the `User-Agent` on every request.\n *\n * Hardcoded rather than imported from package.json: a JSON import would need\n * `resolveJsonModule` and would resolve differently under the ESM and CJS\n * builds. Bump it in the SAME commit as package.json: the drift check is the\n * `Version constant matches package.json` step in ci.yml and lives ONLY there,\n * so `npm test` and `tsc` both stay green on a mismatch (test/version.test.ts\n * asserts the User-Agent uses VERSION, never that VERSION is right).\n */\nexport const VERSION = \"0.10.0\";\n","import {\n APIError,\n ConflictError,\n ConnectionError,\n NoneCapError,\n SolveFailedError,\n TimeoutError,\n errorFromResponse,\n} from \"./errors.js\";\nimport type {\n Account,\n ErrorCode,\n Feedback,\n FeedbackBatch,\n FeedbackReport,\n RecognitionOutcome,\n RecognitionOutcomeResult,\n RecognizeAreaSelectParams,\n RecognizeAreaSelectResult,\n RecognizeBinaryParams,\n RecognizeBinaryResult,\n RecognizeParams,\n RecognizeResult,\n RecognizeTasklistAreaSelectResult,\n RecognizeTasklistBinaryResult,\n RecognizeTasklistDragDropResult,\n RecognizeTasklistParams,\n Solve,\n SolveCreateParams,\n SolveList,\n SolveListParams,\n SolveStatus,\n} from \"./types.js\";\n\nimport { VERSION } from \"./version.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.nonecap.com\";\nconst USER_AGENT = `nonecap-js/${VERSION}`;\n/** The API caps server-side long-poll at 90 seconds. */\nconst MAX_WAIT_SECONDS = 90;\n/** The API caps one `POST /v1/feedback` call at 500 items. */\nexport const FEEDBACK_BATCH_MAX = 500;\nconst TERMINAL: ReadonlySet<SolveStatus> = new Set([\n \"solved\",\n \"failed\",\n \"cancelled\",\n \"expired\",\n]);\n\n/** Is this a terminal solve status? */\nexport function isTerminal(status: SolveStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** A `fetch` implementation. Defaults to the global `fetch`. */\nexport type FetchLike = (\n input: string,\n init?: RequestInit,\n) => Promise<Response>;\n\n/** Options for constructing a {@link NoneCap} client. */\nexport interface NoneCapOptions {\n /** Your NoneCap API key. Find it at https://dashboard.nonecap.com. */\n apiKey: string;\n /** Override the API base URL. Defaults to https://api.nonecap.com. */\n baseURL?: string;\n /**\n * Per-request timeout in milliseconds for a single HTTP call. Defaults to\n * 100000 (just above the 90s server long-poll). Note this bounds one HTTP\n * round trip, not the whole {@link NoneCap.solve} wait — use the `timeout`\n * option on `solve()` for that.\n */\n timeout?: number;\n /** Inject a custom `fetch` (for testing, proxies, or non-standard runtimes). */\n fetch?: FetchLike;\n}\n\n/** Per-call options for the long-polling endpoints. */\nexport interface WaitOptions {\n /**\n * Hold the connection open up to this many seconds (1–90) waiting for the\n * solve to finish before responding. Omit to return immediately.\n */\n wait?: number;\n /** Abort the request. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solve} and {@link SolveHandle.result}. */\nexport interface SolveHelperOptions {\n /**\n * Give up after this many milliseconds and throw {@link TimeoutError}.\n * Defaults to 180000 (3 minutes).\n */\n timeout?: number;\n /** Abort waiting. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solves.start}. */\nexport interface SolveStartOptions {\n /** Abort the submission. */\n signal?: AbortSignal;\n}\n\ninterface RequestOptions {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n signal?: AbortSignal;\n /** Override the per-request timeout for this call (used by long polls). */\n timeout?: number;\n /** HTTP statuses to treat as success in addition to 2xx (e.g. 202). */\n expect?: number[];\n}\n\n/**\n * The NoneCap API client.\n *\n * ```ts\n * const nc = new NoneCap({ apiKey: process.env.NONECAP_KEY! });\n * const { token } = await nc.solve({ type: \"hcaptcha\", sitekey, url });\n * ```\n */\nexport class NoneCap {\n readonly #apiKey: string;\n readonly #baseURL: string;\n readonly #timeout: number;\n readonly #fetch: FetchLike;\n\n constructor(options: NoneCapOptions) {\n if (!options || !options.apiKey) {\n throw new NoneCapError(\n \"A NoneCap API key is required. Pass it as `new NoneCap({ apiKey })`.\",\n );\n }\n this.#apiKey = options.apiKey;\n this.#baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#timeout = options.timeout ?? 100_000;\n const f = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new NoneCapError(\n \"No `fetch` available. Use Node 18+, or pass a `fetch` in the client options.\",\n );\n }\n this.#fetch = f;\n }\n\n /** Operations on solves. */\n readonly solves = {\n /** Submit a solve. Pass `{ wait }` to hold the connection until it finishes. */\n create: (params: SolveCreateParams, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"POST\", \"/v1/solves\", {\n body: params,\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Fetch a solve by id. Pass `{ wait }` to long-poll until it finishes. */\n retrieve: (id: string, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"GET\", `/v1/solves/${encodeURIComponent(id)}`, {\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Cancel a pending or in-flight solve. */\n cancel: (id: string, options: { signal?: AbortSignal } = {}): Promise<Solve> =>\n this.#request<Solve>(\"DELETE\", `/v1/solves/${encodeURIComponent(id)}`, {\n signal: options.signal,\n }),\n\n /**\n * Submit a solve and return a {@link SolveHandle} for it.\n *\n * Unlike {@link NoneCap.solve}, this returns as soon as the submission is\n * accepted, so `handle.id` is available immediately. Use the handle to\n * `cancel()` the solve or `await handle.result()` for the finished solve.\n *\n * ```ts\n * const handle = await nc.solves.start({ type: \"hcaptcha\", sitekey, url });\n * // ...later, e.g. on shutdown:\n * await handle.cancel();\n * // or wait for it:\n * const { token } = await handle.result();\n * ```\n */\n start: async (\n params: SolveCreateParams,\n options: SolveStartOptions = {},\n ): Promise<SolveHandle> => {\n const solve = await this.solves.create(params, { signal: options.signal });\n return new SolveHandle(this, solve);\n },\n\n /** Fetch one page of solves. */\n list: (params: SolveListParams = {}, options: { signal?: AbortSignal } = {}): Promise<SolveList> =>\n this.#request<SolveList>(\"GET\", \"/v1/solves\", {\n query: {\n limit: params.limit,\n starting_after: params.starting_after,\n status: params.status,\n type: params.type,\n },\n signal: options.signal,\n }),\n\n /**\n * Iterate every solve across pages, newest first.\n *\n * ```ts\n * for await (const solve of nc.solves.listAll()) { ... }\n * ```\n */\n listAll: (\n params: SolveListParams = {},\n options: { signal?: AbortSignal } = {},\n ): AsyncIterableIterator<Solve> => this.#listAll(params, options),\n };\n\n /**\n * Report what your downstream target did with the tokens we minted.\n *\n * Feedback is free, own-solves-only, and idempotent per solve id: reporting\n * the same solve again corrects the earlier verdict. Only `solved` solves can\n * be reported, and only within the API's reporting window (~30 days from the\n * solve; corrections to an already-reported solve are never re-gated by it).\n */\n readonly feedback = {\n /**\n * Report one solve's downstream outcome, returning the recorded feedback.\n *\n * Unlike {@link NoneCap.feedback.reportMany}, a rejected report throws:\n * {@link NotFoundError} if the solve isn't yours or never minted a token,\n * {@link ValidationError} if a field is wrong or the reporting window closed.\n *\n * ```ts\n * await nc.feedback.report({ solve_id: solve.id, outcome: \"rejected\", reason: \"...\" });\n * ```\n */\n report: (report: FeedbackReport, options: { signal?: AbortSignal } = {}): Promise<Feedback> => {\n const { solve_id, ...fields } = report;\n return this.#request<Feedback>(\n \"POST\",\n `/v1/solves/${encodeURIComponent(solve_id)}/feedback`,\n { body: toWireFields(fields), signal: options.signal },\n );\n },\n\n /**\n * Report many verdicts at once — the path to use at volume. Buffer verdicts\n * as you learn them and flush them here.\n *\n * The call succeeds even when individual items are rejected: each is\n * resolved on its own so one stale id never discards the rest. Check\n * `failed` rather than relying on a thrown error.\n *\n * More than {@link FEEDBACK_BATCH_MAX} reports are split across sequential\n * requests and merged into one result, in request order. An empty array is\n * a no-op that returns an empty batch without a request.\n *\n * ```ts\n * const batch = await nc.feedback.reportMany(buffer);\n * if (batch.failed) console.warn(batch.results.filter((r) => r.status === \"error\"));\n * ```\n */\n reportMany: async (\n reports: readonly FeedbackReport[],\n options: { signal?: AbortSignal } = {},\n ): Promise<FeedbackBatch> => {\n const merged: FeedbackBatch = {\n object: \"feedback_batch\",\n recorded: 0,\n updated: 0,\n unchanged: 0,\n failed: 0,\n results: [],\n };\n // Chunks are sent in order and the server upserts last-write-wins, so a\n // solve reported twice still ends at its last value. Duplicates split\n // across a chunk boundary each get written, though, so the earlier one\n // reports `recorded`/`updated` where a single request would say\n // `unchanged`.\n for (let i = 0; i < reports.length; i += FEEDBACK_BATCH_MAX) {\n const batch = await this.#request<FeedbackBatch>(\"POST\", \"/v1/feedback\", {\n body: { feedback: reports.slice(i, i + FEEDBACK_BATCH_MAX).map(toWireReport) },\n signal: options.signal,\n });\n merged.recorded += batch.recorded;\n merged.updated += batch.updated;\n merged.unchanged += batch.unchanged;\n merged.failed += batch.failed;\n merged.results.push(...batch.results);\n }\n return merged;\n },\n };\n\n /** Fetch your account, including the current credit balance. */\n me(options: { signal?: AbortSignal } = {}): Promise<Account> {\n return this.#request<Account>(\"GET\", \"/v1/me\", { signal: options.signal });\n }\n\n /**\n * Recognize a challenge's images: send the instruction and images, get the\n * answer back in the same response. No token, no polling.\n *\n * An answered call's charge is final. Throws {@link RecognitionFailedError}\n * when no answer came back (nothing is charged then), {@link ValidationError}\n * for a malformed request.\n *\n * ```ts\n * const { id, data } = await nc.recognize({\n * type: \"hcaptcha\",\n * task: \"Please click each image containing a bus\",\n * image_data: tiles, // base64\n * });\n * ```\n */\n recognize(params: RecognizeBinaryParams, options?: { signal?: AbortSignal }): Promise<RecognizeBinaryResult>;\n recognize(params: RecognizeAreaSelectParams, options?: { signal?: AbortSignal }): Promise<RecognizeAreaSelectResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_label_binary\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistBinaryResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_label_area_select\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistAreaSelectResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_drag_drop\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistDragDropResult>;\n recognize(params: RecognizeParams, options?: { signal?: AbortSignal }): Promise<RecognizeResult>;\n recognize(params: RecognizeParams, options: { signal?: AbortSignal } = {}): Promise<RecognizeResult> {\n return this.#request<RecognizeResult>(\"POST\", \"/v1/recognize\", {\n body: params,\n signal: options.signal,\n });\n }\n\n /**\n * Report whether a {@link NoneCap.recognize} answer worked on the challenge.\n * Optional and free; it feeds NoneCap's accuracy stats and never refunds the\n * call. The first report for an id sticks: a repeat returns it unchanged.\n */\n reportRecognitionOutcome(\n id: string,\n result: RecognitionOutcome,\n options: { signal?: AbortSignal } = {},\n ): Promise<RecognitionOutcomeResult> {\n return this.#request<RecognitionOutcomeResult>(\"POST\", \"/v1/recognize/outcome\", {\n body: { id, result },\n signal: options.signal,\n });\n }\n\n /**\n * Submit a solve and wait for it to finish, returning the solved solve.\n *\n * Uses the server's long-poll under the hood and keeps polling until the\n * solve is terminal or `timeout` elapses. Throws {@link SolveFailedError} if\n * the solve fails/expires/is cancelled, or {@link TimeoutError} on timeout.\n *\n * This is sugar for `(await solves.start(params)).result(options)`. When you\n * need to cancel the solve while it runs, use {@link NoneCap.solves.start}\n * and keep the {@link SolveHandle}.\n */\n async solve(params: SolveCreateParams, options: SolveHelperOptions = {}): Promise<Solve> {\n const handle = await this.solves.start(params, { signal: options.signal });\n return handle.result(options);\n }\n\n // -- internals ------------------------------------------------------------\n\n #timeoutForWait(wait?: number): number | undefined {\n if (wait === undefined) return undefined;\n // Give the socket a margin beyond the server's long-poll window.\n return wait * 1000 + 15_000;\n }\n\n async *#listAll(\n params: SolveListParams,\n options: { signal?: AbortSignal },\n ): AsyncIterableIterator<Solve> {\n let cursor = params.starting_after;\n for (;;) {\n const page = await this.solves.list({ ...params, starting_after: cursor }, options);\n for (const solve of page.data) yield solve;\n if (!page.has_more || page.data.length === 0) return;\n cursor = page.data[page.data.length - 1]!.id;\n }\n }\n\n async #request<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const url = new URL(this.#baseURL + path);\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== \"\") url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n Accept: \"application/json\",\n // Browsers drop this as a forbidden header; on Node it identifies the SDK.\n \"User-Agent\": USER_AGENT,\n };\n let bodyInit: string | undefined;\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyInit = JSON.stringify(options.body);\n }\n\n const controller = new AbortController();\n const timeoutMs = options.timeout ?? this.#timeout;\n const timer = setTimeout(() => controller.abort(new TimeoutError(`Request timed out after ${timeoutMs}ms.`)), timeoutMs);\n const onAbort = () => controller.abort(options.signal?.reason);\n if (options.signal) {\n if (options.signal.aborted) onAbort();\n else options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n let res: Response;\n try {\n res = await this.#fetch(url.toString(), {\n method,\n headers,\n body: bodyInit,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof TimeoutError) throw err;\n if (isAbort(err)) {\n // A caller-supplied signal aborting surfaces as the caller's reason.\n if (options.signal?.aborted) throw options.signal.reason instanceof Error\n ? options.signal.reason\n : new NoneCapError(\"Request aborted.\");\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms.`);\n }\n throw new ConnectionError(\n `Could not reach the NoneCap API at ${this.#baseURL}: ${(err as Error).message}`,\n );\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n return this.#parse<T>(res, options.expect ?? []);\n }\n\n async #parse<T>(res: Response, expect: number[]): Promise<T> {\n const text = await res.text();\n let json: unknown;\n if (text) {\n try {\n json = JSON.parse(text);\n } catch {\n throw new APIError(\n `Unexpected non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n { status: res.status },\n );\n }\n }\n\n if (res.ok || expect.includes(res.status)) {\n return json as T;\n }\n\n const envelope = json as\n | { error?: { code?: ErrorCode; message?: string; param?: string | null; request_id?: string } }\n | undefined;\n const apiError = envelope?.error;\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw !== null && /^\\d+$/.test(retryAfterRaw) ? Number(retryAfterRaw) : undefined;\n throw errorFromResponse(\n res.status,\n apiError?.code,\n apiError?.message ?? `HTTP ${res.status}`,\n apiError?.param ?? null,\n { requestId: apiError?.request_id ?? res.headers.get(\"x-request-id\") ?? undefined, retryAfter },\n );\n }\n}\n\n/**\n * A handle on a started solve, returned by {@link NoneCap.solves.start}.\n *\n * The handle is the cancellable lifecycle object for one solve. It is a plain\n * object, not a promise: `await`ing it does nothing useful. Wait for the result\n * with {@link SolveHandle.result}, and cancel with {@link SolveHandle.cancel}.\n * You do not construct it yourself — `solves.start()` hands you one with `id`\n * already resolved.\n */\nexport class SolveHandle {\n /** The id of the started solve, available as soon as `start()` resolved. */\n readonly id: string;\n\n readonly #client: NoneCap;\n /** The latest solve state we have seen, from the create, polls, or cancel. */\n #solve: Solve;\n /**\n * The cached TERMINAL outcome: resolves to the solved solve, or rejects with\n * {@link SolveFailedError} if terminal-but-not-solved. Only ever set once the\n * solve actually reaches a terminal state, so it is safe to replay forever. A\n * timed-out wait does NOT settle this — it is retryable.\n */\n #terminal: Promise<Solve> | undefined;\n /** The poll currently in flight, shared by concurrent result() callers. */\n #inflight: Promise<Solve> | undefined;\n\n constructor(client: NoneCap, solve: Solve) {\n this.#client = client;\n this.#solve = solve;\n this.id = solve.id;\n }\n\n /** The last-known solve state for this handle. */\n get solve(): Solve {\n return this.#solve;\n }\n\n /**\n * Long-poll until the solve is terminal, returning the solved solve. Throws\n * {@link SolveFailedError} if it fails/expires/is cancelled, or\n * {@link TimeoutError} on timeout (with `solveId`/`solve` attached so you can\n * still {@link SolveHandle.cancel} it).\n *\n * Memoizes the *terminal* outcome: once the solve actually finishes, every\n * later call returns that same settled result. A {@link TimeoutError} is not\n * memoized — it just means this wait gave up, so a later call (e.g. with a\n * larger `timeout`) resumes polling. Concurrent calls share one in-flight\n * poll, so they never issue duplicate requests. The first caller's\n * `timeout`/`signal` drive the shared poll; a later call starts a fresh one.\n */\n result(options: SolveHelperOptions = {}): Promise<Solve> {\n if (this.#terminal) return this.#terminal;\n if (this.#inflight) return this.#inflight;\n const run = this.#poll(options).finally(() => {\n // Free the slot so a retry can re-poll after a timeout; a terminal\n // outcome is already memoized in #terminal and wins on the next call.\n if (this.#inflight === run) this.#inflight = undefined;\n });\n this.#inflight = run;\n return run;\n }\n\n /**\n * Cancel the solve. Cancelled solves are never charged, so this is for clean\n * shutdown / freeing slots / stopping early, not cost protection.\n *\n * If the solve already reached a terminal state the API answers 409; that is\n * not an error a caller cares about, so this swallows {@link ConflictError}\n * and returns the current solve state instead. A cancel that lands on a\n * terminal state (cancelled, or whatever the 409-swallow read back) settles\n * this handle's {@link SolveHandle.result}, so any in-flight or later wait\n * stops polling and reflects that terminal state.\n */\n async cancel(options: { signal?: AbortSignal } = {}): Promise<Solve> {\n try {\n this.#solve = await this.#client.solves.cancel(this.id, options);\n } catch (err) {\n if (!(err instanceof ConflictError)) throw err;\n // Already terminal — report the real state rather than the 409.\n this.#solve = await this.#client.solves.retrieve(this.id, options);\n }\n if (!this.#terminal && isTerminal(this.#solve.status)) this.#cacheTerminal();\n return this.#solve;\n }\n\n /**\n * Build and memoize the terminal outcome from the current `#solve`. The\n * precondition is that `#solve` is terminal and `#terminal` is unset.\n */\n #cacheTerminal(): Promise<Solve> {\n const settled =\n this.#solve.status === \"solved\"\n ? Promise.resolve(this.#solve)\n : Promise.reject(new SolveFailedError(this.#solve));\n // Never let the memoized rejection surface as an unhandled rejection; real\n // callers read it explicitly through result().\n settled.catch(() => {});\n this.#terminal = settled;\n return settled;\n }\n\n async #poll(options: SolveHelperOptions): Promise<Solve> {\n const timeout = options.timeout ?? 180_000;\n const deadline = Date.now() + timeout;\n\n for (;;) {\n // cancel() (or a previous poll) may have already settled this handle.\n if (this.#terminal) return this.#terminal;\n if (isTerminal(this.#solve.status)) return this.#cacheTerminal();\n if (Date.now() >= deadline) {\n throw new TimeoutError(\n `Solve ${this.id} did not finish within ${timeout}ms (last status: ${this.#solve.status}).`,\n { solveId: this.id, solve: this.#solve },\n );\n }\n this.#solve = await this.#client.solves.retrieve(this.id, {\n wait: waitSeconds(deadline),\n signal: options.signal,\n });\n }\n }\n}\n\n/**\n * The `wait` value for the next long-poll: whole seconds until `deadline`,\n * clamped to the server's 1–90 window. The floor of 1 keeps the param valid,\n * so callers must decide whether the deadline has passed with the clock, not\n * with this return value.\n */\nfunction waitSeconds(deadline: number): number {\n const remaining = Math.ceil((deadline - Date.now()) / 1000);\n return Math.max(1, Math.min(MAX_WAIT_SECONDS, remaining));\n}\n\nfunction isAbort(err: unknown): boolean {\n return err instanceof Error && err.name === \"AbortError\";\n}\n\n/** The fields of a report, ready for the wire: a `Date` becomes an ISO string. */\nfunction toWireFields(fields: Omit<FeedbackReport, \"solve_id\">): Record<string, unknown> {\n const wire: Record<string, unknown> = { outcome: fields.outcome };\n if (fields.reason !== undefined) wire.reason = fields.reason;\n if (fields.context !== undefined) wire.context = fields.context;\n if (fields.reported_at !== undefined) {\n wire.reported_at =\n fields.reported_at instanceof Date ? fields.reported_at.toISOString() : fields.reported_at;\n }\n return wire;\n}\n\nfunction toWireReport(report: FeedbackReport): Record<string, unknown> {\n const { solve_id, ...fields } = report;\n return { solve_id, ...toWireFields(fields) };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -24,13 +24,9 @@ interface SolveCreateBase {
|
|
|
24
24
|
/** The page URL the captcha is served on. */
|
|
25
25
|
url: string;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* wire. Every solve presents its own coherent browser identity (user agent, client hints,
|
|
31
|
-
* language header and proof-of-work all describing one machine); a caller-supplied string
|
|
32
|
-
* replaced only some of those and made the request contradict itself. Safe to remove.
|
|
33
|
-
* To submit the token as the browser that earned it, read the solve's `user_agent`.
|
|
27
|
+
* Optional. Send the user agent of the browser that loaded the page, as is.
|
|
28
|
+
* On most sites it changes nothing; on some it is required for the token to be accepted.
|
|
29
|
+
* If you do not have it, leave the field out.
|
|
34
30
|
*/
|
|
35
31
|
user_agent?: string;
|
|
36
32
|
/** Proxy to route the solve through, as a structured object or a URL string. */
|
|
@@ -261,6 +257,113 @@ interface FeedbackBatch {
|
|
|
261
257
|
/** One entry per report you sent, in request order. */
|
|
262
258
|
results: FeedbackResult[];
|
|
263
259
|
}
|
|
260
|
+
/** An image, as bare base64 or a `data:` URI (PNG, JPEG, WebP or GIF, up to 1.5 MiB). */
|
|
261
|
+
type RecognizeImage = string;
|
|
262
|
+
/** Send the images inline (`image_data`) or as hCaptcha image URLs the API fetches (`image_urls`), never both. */
|
|
263
|
+
type RecognizeImages = {
|
|
264
|
+
image_data: RecognizeImage[];
|
|
265
|
+
image_urls?: never;
|
|
266
|
+
} | {
|
|
267
|
+
image_urls: string[];
|
|
268
|
+
image_data?: never;
|
|
269
|
+
};
|
|
270
|
+
interface RecognizeSimpleBase {
|
|
271
|
+
/** The challenge's instruction, e.g. `"Please click each image containing a bus"`. */
|
|
272
|
+
task: string;
|
|
273
|
+
/** The challenge's example images, when it shows any. */
|
|
274
|
+
image_examples?: RecognizeImage[];
|
|
275
|
+
/** The site's bare domain (`example.com`), when you know it. */
|
|
276
|
+
host?: string;
|
|
277
|
+
}
|
|
278
|
+
/** A grid challenge: 1–27 tiles, answered with one boolean per tile. */
|
|
279
|
+
type RecognizeBinaryParams = RecognizeSimpleBase & RecognizeImages & {
|
|
280
|
+
type: "hcaptcha";
|
|
281
|
+
};
|
|
282
|
+
/** A click-the-point challenge: exactly one image. */
|
|
283
|
+
type RecognizeAreaSelectParams = RecognizeSimpleBase & RecognizeImages & {
|
|
284
|
+
type: "hcaptcha_area_select";
|
|
285
|
+
};
|
|
286
|
+
/** The `request_type` of a full hCaptcha tasklist. */
|
|
287
|
+
type RecognizeRequestType = "image_label_binary" | "image_label_area_select" | "image_drag_drop";
|
|
288
|
+
/** A draggable piece of an `image_drag_drop` task. */
|
|
289
|
+
interface RecognizeEntity {
|
|
290
|
+
entity_id: string;
|
|
291
|
+
/** The piece's image, as base64 or an hCaptcha image URL. */
|
|
292
|
+
entity_uri?: string;
|
|
293
|
+
coords: [number, number];
|
|
294
|
+
size: [number, number];
|
|
295
|
+
}
|
|
296
|
+
/** One task of a tasklist. */
|
|
297
|
+
interface RecognizeTask {
|
|
298
|
+
task_key: string;
|
|
299
|
+
/** The task's image, as base64 or an hCaptcha image URL. */
|
|
300
|
+
datapoint_uri: string;
|
|
301
|
+
entities?: RecognizeEntity[];
|
|
302
|
+
}
|
|
303
|
+
/** The challenge as hCaptcha served it (NopeCHA's v1 recognition body). */
|
|
304
|
+
interface RecognizeTasklistParams<R extends RecognizeRequestType = RecognizeRequestType> {
|
|
305
|
+
data: {
|
|
306
|
+
request_type: R;
|
|
307
|
+
requester_question: {
|
|
308
|
+
en: string;
|
|
309
|
+
};
|
|
310
|
+
requester_question_example?: string[];
|
|
311
|
+
request_config?: Record<string, unknown>;
|
|
312
|
+
tasklist: RecognizeTask[];
|
|
313
|
+
};
|
|
314
|
+
/** The site's bare domain (`example.com`), when you know it. */
|
|
315
|
+
host?: string;
|
|
316
|
+
}
|
|
317
|
+
/** Parameters for {@link NoneCap.recognize}. */
|
|
318
|
+
type RecognizeParams = RecognizeBinaryParams | RecognizeAreaSelectParams | RecognizeTasklistParams;
|
|
319
|
+
/** A point, in percent of the image's width and height. */
|
|
320
|
+
interface RecognizePoint {
|
|
321
|
+
x: number;
|
|
322
|
+
y: number;
|
|
323
|
+
}
|
|
324
|
+
/** A box, in percent of the image. Area-select answers are a point: `w` and `h` are 0. */
|
|
325
|
+
interface RecognizeBox {
|
|
326
|
+
x: number;
|
|
327
|
+
y: number;
|
|
328
|
+
w: number;
|
|
329
|
+
h: number;
|
|
330
|
+
}
|
|
331
|
+
/** Where to drop one entity: a box centred on the drop point, sized by the entity's `size`. */
|
|
332
|
+
interface RecognizeDrop extends RecognizeBox {
|
|
333
|
+
entity_id: string;
|
|
334
|
+
}
|
|
335
|
+
/** The answer to a {@link NoneCap.recognize} call. `data` takes the shape of the request. */
|
|
336
|
+
interface RecognizeResult<D = unknown> {
|
|
337
|
+
/** The recognition's id (`extsess_…`), for {@link NoneCap.reportRecognitionOutcome}. */
|
|
338
|
+
id: string;
|
|
339
|
+
data: D;
|
|
340
|
+
/** Credits charged for this call. Final: reporting the outcome does not refund it. */
|
|
341
|
+
credits_charged: number;
|
|
342
|
+
}
|
|
343
|
+
/** `type: "hcaptcha"`: one boolean per tile, in request order. */
|
|
344
|
+
type RecognizeBinaryResult = RecognizeResult<boolean[]>;
|
|
345
|
+
/** `type: "hcaptcha_area_select"`: the first point to click, plus every point for multi-click wordings. */
|
|
346
|
+
interface RecognizeAreaSelectResult extends RecognizeResult<RecognizeBox> {
|
|
347
|
+
points: RecognizePoint[];
|
|
348
|
+
}
|
|
349
|
+
/** `image_label_binary`: pages of 9 booleans, one per task. */
|
|
350
|
+
type RecognizeTasklistBinaryResult = RecognizeResult<boolean[][]>;
|
|
351
|
+
/** `image_label_area_select`: per task, the first point (null when none) and every point. */
|
|
352
|
+
interface RecognizeTasklistAreaSelectResult extends RecognizeResult<(RecognizeBox | null)[]> {
|
|
353
|
+
points: RecognizePoint[][];
|
|
354
|
+
}
|
|
355
|
+
/** `image_drag_drop`: per task, where to drop each entity. */
|
|
356
|
+
type RecognizeTasklistDragDropResult = RecognizeResult<RecognizeDrop[][]>;
|
|
357
|
+
/** Whether the answer worked on the challenge. */
|
|
358
|
+
type RecognitionOutcome = "solved" | "failed";
|
|
359
|
+
/** The result of {@link NoneCap.reportRecognitionOutcome}. */
|
|
360
|
+
interface RecognitionOutcomeResult {
|
|
361
|
+
id: string;
|
|
362
|
+
/** The recorded outcome. The first report sticks: a repeat returns it unchanged. */
|
|
363
|
+
result: RecognitionOutcome;
|
|
364
|
+
/** Always 0: reporting an outcome never refunds the call. */
|
|
365
|
+
refunded_credits: number;
|
|
366
|
+
}
|
|
264
367
|
/** Your account, including the current credit balance. */
|
|
265
368
|
interface Account {
|
|
266
369
|
object: "account";
|
|
@@ -283,6 +386,8 @@ type ErrorCode = "unauthorized" | "forbidden" | "account_locked" | "insufficient
|
|
|
283
386
|
| "not_eligible"
|
|
284
387
|
/** Feedback: a first report arrived after the reporting window closed. */
|
|
285
388
|
| "expired_window"
|
|
389
|
+
/** 422: `/v1/recognize` produced no answer for the images; nothing was charged. */
|
|
390
|
+
| "recognition_failed"
|
|
286
391
|
/** 503: new solves are paused for maintenance. Retry shortly. */
|
|
287
392
|
| "maintenance"
|
|
288
393
|
/** 413: the request body exceeds the route's size limit. */
|
|
@@ -447,6 +552,48 @@ declare class NoneCap {
|
|
|
447
552
|
me(options?: {
|
|
448
553
|
signal?: AbortSignal;
|
|
449
554
|
}): Promise<Account>;
|
|
555
|
+
/**
|
|
556
|
+
* Recognize a challenge's images: send the instruction and images, get the
|
|
557
|
+
* answer back in the same response. No token, no polling.
|
|
558
|
+
*
|
|
559
|
+
* An answered call's charge is final. Throws {@link RecognitionFailedError}
|
|
560
|
+
* when no answer came back (nothing is charged then), {@link ValidationError}
|
|
561
|
+
* for a malformed request.
|
|
562
|
+
*
|
|
563
|
+
* ```ts
|
|
564
|
+
* const { id, data } = await nc.recognize({
|
|
565
|
+
* type: "hcaptcha",
|
|
566
|
+
* task: "Please click each image containing a bus",
|
|
567
|
+
* image_data: tiles, // base64
|
|
568
|
+
* });
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
recognize(params: RecognizeBinaryParams, options?: {
|
|
572
|
+
signal?: AbortSignal;
|
|
573
|
+
}): Promise<RecognizeBinaryResult>;
|
|
574
|
+
recognize(params: RecognizeAreaSelectParams, options?: {
|
|
575
|
+
signal?: AbortSignal;
|
|
576
|
+
}): Promise<RecognizeAreaSelectResult>;
|
|
577
|
+
recognize(params: RecognizeTasklistParams<"image_label_binary">, options?: {
|
|
578
|
+
signal?: AbortSignal;
|
|
579
|
+
}): Promise<RecognizeTasklistBinaryResult>;
|
|
580
|
+
recognize(params: RecognizeTasklistParams<"image_label_area_select">, options?: {
|
|
581
|
+
signal?: AbortSignal;
|
|
582
|
+
}): Promise<RecognizeTasklistAreaSelectResult>;
|
|
583
|
+
recognize(params: RecognizeTasklistParams<"image_drag_drop">, options?: {
|
|
584
|
+
signal?: AbortSignal;
|
|
585
|
+
}): Promise<RecognizeTasklistDragDropResult>;
|
|
586
|
+
recognize(params: RecognizeParams, options?: {
|
|
587
|
+
signal?: AbortSignal;
|
|
588
|
+
}): Promise<RecognizeResult>;
|
|
589
|
+
/**
|
|
590
|
+
* Report whether a {@link NoneCap.recognize} answer worked on the challenge.
|
|
591
|
+
* Optional and free; it feeds NoneCap's accuracy stats and never refunds the
|
|
592
|
+
* call. The first report for an id sticks: a repeat returns it unchanged.
|
|
593
|
+
*/
|
|
594
|
+
reportRecognitionOutcome(id: string, result: RecognitionOutcome, options?: {
|
|
595
|
+
signal?: AbortSignal;
|
|
596
|
+
}): Promise<RecognitionOutcomeResult>;
|
|
450
597
|
/**
|
|
451
598
|
* Submit a solve and wait for it to finish, returning the solved solve.
|
|
452
599
|
*
|
|
@@ -576,6 +723,10 @@ declare class ProxyUnavailableError extends RateLimitError {
|
|
|
576
723
|
* Nothing was charged; wait `retryAfter` seconds. */
|
|
577
724
|
declare class RateCappedError extends RateLimitError {
|
|
578
725
|
}
|
|
726
|
+
/** 422 — {@link NoneCap.recognize} produced no answer for these images, or the challenge
|
|
727
|
+
* type is not supported. Nothing was charged. */
|
|
728
|
+
declare class RecognitionFailedError extends NoneCapError {
|
|
729
|
+
}
|
|
579
730
|
/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */
|
|
580
731
|
declare class APIError extends NoneCapError {
|
|
581
732
|
}
|
|
@@ -620,4 +771,4 @@ declare class TimeoutError extends NoneCapError {
|
|
|
620
771
|
});
|
|
621
772
|
}
|
|
622
773
|
|
|
623
|
-
export { APIError, type Account, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, type ErrorCode, type ErrorEnvelope, FEEDBACK_BATCH_MAX, type Feedback, type FeedbackBatch, type FeedbackOutcome, type FeedbackReport, type FeedbackResult, type FeedbackStatus, type FetchLike, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, type NoneCapOptions, NotFoundError, PayloadTooLargeError, PermissionError, type Proxy, ProxyUnavailableError, RateCappedError, RateLimitError, ServiceUnavailableError, SitekeyRateLimitedError, type Solve, type SolveCreateParams, type SolveError, type SolveErrorCode, type SolveErrorReason, SolveFailedError, SolveHandle, type SolveHelperOptions, type SolveList, type SolveListParams, type SolveStartOptions, type SolveStatus, type SolveType, type SolveWarning, TimeoutError, UnsupportedMediaTypeError, ValidationError, type WaitOptions, isTerminal };
|
|
774
|
+
export { APIError, type Account, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, type ErrorCode, type ErrorEnvelope, FEEDBACK_BATCH_MAX, type Feedback, type FeedbackBatch, type FeedbackOutcome, type FeedbackReport, type FeedbackResult, type FeedbackStatus, type FetchLike, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, type NoneCapOptions, NotFoundError, PayloadTooLargeError, PermissionError, type Proxy, ProxyUnavailableError, RateCappedError, RateLimitError, RecognitionFailedError, type RecognitionOutcome, type RecognitionOutcomeResult, type RecognizeAreaSelectParams, type RecognizeAreaSelectResult, type RecognizeBinaryParams, type RecognizeBinaryResult, type RecognizeBox, type RecognizeDrop, type RecognizeEntity, type RecognizeImage, type RecognizeImages, type RecognizeParams, type RecognizePoint, type RecognizeRequestType, type RecognizeResult, type RecognizeTask, type RecognizeTasklistAreaSelectResult, type RecognizeTasklistBinaryResult, type RecognizeTasklistDragDropResult, type RecognizeTasklistParams, ServiceUnavailableError, SitekeyRateLimitedError, type Solve, type SolveCreateParams, type SolveError, type SolveErrorCode, type SolveErrorReason, SolveFailedError, SolveHandle, type SolveHelperOptions, type SolveList, type SolveListParams, type SolveStartOptions, type SolveStatus, type SolveType, type SolveWarning, TimeoutError, UnsupportedMediaTypeError, ValidationError, type WaitOptions, isTerminal };
|
package/dist/index.d.ts
CHANGED
|
@@ -24,13 +24,9 @@ interface SolveCreateBase {
|
|
|
24
24
|
/** The page URL the captcha is served on. */
|
|
25
25
|
url: string;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* wire. Every solve presents its own coherent browser identity (user agent, client hints,
|
|
31
|
-
* language header and proof-of-work all describing one machine); a caller-supplied string
|
|
32
|
-
* replaced only some of those and made the request contradict itself. Safe to remove.
|
|
33
|
-
* To submit the token as the browser that earned it, read the solve's `user_agent`.
|
|
27
|
+
* Optional. Send the user agent of the browser that loaded the page, as is.
|
|
28
|
+
* On most sites it changes nothing; on some it is required for the token to be accepted.
|
|
29
|
+
* If you do not have it, leave the field out.
|
|
34
30
|
*/
|
|
35
31
|
user_agent?: string;
|
|
36
32
|
/** Proxy to route the solve through, as a structured object or a URL string. */
|
|
@@ -261,6 +257,113 @@ interface FeedbackBatch {
|
|
|
261
257
|
/** One entry per report you sent, in request order. */
|
|
262
258
|
results: FeedbackResult[];
|
|
263
259
|
}
|
|
260
|
+
/** An image, as bare base64 or a `data:` URI (PNG, JPEG, WebP or GIF, up to 1.5 MiB). */
|
|
261
|
+
type RecognizeImage = string;
|
|
262
|
+
/** Send the images inline (`image_data`) or as hCaptcha image URLs the API fetches (`image_urls`), never both. */
|
|
263
|
+
type RecognizeImages = {
|
|
264
|
+
image_data: RecognizeImage[];
|
|
265
|
+
image_urls?: never;
|
|
266
|
+
} | {
|
|
267
|
+
image_urls: string[];
|
|
268
|
+
image_data?: never;
|
|
269
|
+
};
|
|
270
|
+
interface RecognizeSimpleBase {
|
|
271
|
+
/** The challenge's instruction, e.g. `"Please click each image containing a bus"`. */
|
|
272
|
+
task: string;
|
|
273
|
+
/** The challenge's example images, when it shows any. */
|
|
274
|
+
image_examples?: RecognizeImage[];
|
|
275
|
+
/** The site's bare domain (`example.com`), when you know it. */
|
|
276
|
+
host?: string;
|
|
277
|
+
}
|
|
278
|
+
/** A grid challenge: 1–27 tiles, answered with one boolean per tile. */
|
|
279
|
+
type RecognizeBinaryParams = RecognizeSimpleBase & RecognizeImages & {
|
|
280
|
+
type: "hcaptcha";
|
|
281
|
+
};
|
|
282
|
+
/** A click-the-point challenge: exactly one image. */
|
|
283
|
+
type RecognizeAreaSelectParams = RecognizeSimpleBase & RecognizeImages & {
|
|
284
|
+
type: "hcaptcha_area_select";
|
|
285
|
+
};
|
|
286
|
+
/** The `request_type` of a full hCaptcha tasklist. */
|
|
287
|
+
type RecognizeRequestType = "image_label_binary" | "image_label_area_select" | "image_drag_drop";
|
|
288
|
+
/** A draggable piece of an `image_drag_drop` task. */
|
|
289
|
+
interface RecognizeEntity {
|
|
290
|
+
entity_id: string;
|
|
291
|
+
/** The piece's image, as base64 or an hCaptcha image URL. */
|
|
292
|
+
entity_uri?: string;
|
|
293
|
+
coords: [number, number];
|
|
294
|
+
size: [number, number];
|
|
295
|
+
}
|
|
296
|
+
/** One task of a tasklist. */
|
|
297
|
+
interface RecognizeTask {
|
|
298
|
+
task_key: string;
|
|
299
|
+
/** The task's image, as base64 or an hCaptcha image URL. */
|
|
300
|
+
datapoint_uri: string;
|
|
301
|
+
entities?: RecognizeEntity[];
|
|
302
|
+
}
|
|
303
|
+
/** The challenge as hCaptcha served it (NopeCHA's v1 recognition body). */
|
|
304
|
+
interface RecognizeTasklistParams<R extends RecognizeRequestType = RecognizeRequestType> {
|
|
305
|
+
data: {
|
|
306
|
+
request_type: R;
|
|
307
|
+
requester_question: {
|
|
308
|
+
en: string;
|
|
309
|
+
};
|
|
310
|
+
requester_question_example?: string[];
|
|
311
|
+
request_config?: Record<string, unknown>;
|
|
312
|
+
tasklist: RecognizeTask[];
|
|
313
|
+
};
|
|
314
|
+
/** The site's bare domain (`example.com`), when you know it. */
|
|
315
|
+
host?: string;
|
|
316
|
+
}
|
|
317
|
+
/** Parameters for {@link NoneCap.recognize}. */
|
|
318
|
+
type RecognizeParams = RecognizeBinaryParams | RecognizeAreaSelectParams | RecognizeTasklistParams;
|
|
319
|
+
/** A point, in percent of the image's width and height. */
|
|
320
|
+
interface RecognizePoint {
|
|
321
|
+
x: number;
|
|
322
|
+
y: number;
|
|
323
|
+
}
|
|
324
|
+
/** A box, in percent of the image. Area-select answers are a point: `w` and `h` are 0. */
|
|
325
|
+
interface RecognizeBox {
|
|
326
|
+
x: number;
|
|
327
|
+
y: number;
|
|
328
|
+
w: number;
|
|
329
|
+
h: number;
|
|
330
|
+
}
|
|
331
|
+
/** Where to drop one entity: a box centred on the drop point, sized by the entity's `size`. */
|
|
332
|
+
interface RecognizeDrop extends RecognizeBox {
|
|
333
|
+
entity_id: string;
|
|
334
|
+
}
|
|
335
|
+
/** The answer to a {@link NoneCap.recognize} call. `data` takes the shape of the request. */
|
|
336
|
+
interface RecognizeResult<D = unknown> {
|
|
337
|
+
/** The recognition's id (`extsess_…`), for {@link NoneCap.reportRecognitionOutcome}. */
|
|
338
|
+
id: string;
|
|
339
|
+
data: D;
|
|
340
|
+
/** Credits charged for this call. Final: reporting the outcome does not refund it. */
|
|
341
|
+
credits_charged: number;
|
|
342
|
+
}
|
|
343
|
+
/** `type: "hcaptcha"`: one boolean per tile, in request order. */
|
|
344
|
+
type RecognizeBinaryResult = RecognizeResult<boolean[]>;
|
|
345
|
+
/** `type: "hcaptcha_area_select"`: the first point to click, plus every point for multi-click wordings. */
|
|
346
|
+
interface RecognizeAreaSelectResult extends RecognizeResult<RecognizeBox> {
|
|
347
|
+
points: RecognizePoint[];
|
|
348
|
+
}
|
|
349
|
+
/** `image_label_binary`: pages of 9 booleans, one per task. */
|
|
350
|
+
type RecognizeTasklistBinaryResult = RecognizeResult<boolean[][]>;
|
|
351
|
+
/** `image_label_area_select`: per task, the first point (null when none) and every point. */
|
|
352
|
+
interface RecognizeTasklistAreaSelectResult extends RecognizeResult<(RecognizeBox | null)[]> {
|
|
353
|
+
points: RecognizePoint[][];
|
|
354
|
+
}
|
|
355
|
+
/** `image_drag_drop`: per task, where to drop each entity. */
|
|
356
|
+
type RecognizeTasklistDragDropResult = RecognizeResult<RecognizeDrop[][]>;
|
|
357
|
+
/** Whether the answer worked on the challenge. */
|
|
358
|
+
type RecognitionOutcome = "solved" | "failed";
|
|
359
|
+
/** The result of {@link NoneCap.reportRecognitionOutcome}. */
|
|
360
|
+
interface RecognitionOutcomeResult {
|
|
361
|
+
id: string;
|
|
362
|
+
/** The recorded outcome. The first report sticks: a repeat returns it unchanged. */
|
|
363
|
+
result: RecognitionOutcome;
|
|
364
|
+
/** Always 0: reporting an outcome never refunds the call. */
|
|
365
|
+
refunded_credits: number;
|
|
366
|
+
}
|
|
264
367
|
/** Your account, including the current credit balance. */
|
|
265
368
|
interface Account {
|
|
266
369
|
object: "account";
|
|
@@ -283,6 +386,8 @@ type ErrorCode = "unauthorized" | "forbidden" | "account_locked" | "insufficient
|
|
|
283
386
|
| "not_eligible"
|
|
284
387
|
/** Feedback: a first report arrived after the reporting window closed. */
|
|
285
388
|
| "expired_window"
|
|
389
|
+
/** 422: `/v1/recognize` produced no answer for the images; nothing was charged. */
|
|
390
|
+
| "recognition_failed"
|
|
286
391
|
/** 503: new solves are paused for maintenance. Retry shortly. */
|
|
287
392
|
| "maintenance"
|
|
288
393
|
/** 413: the request body exceeds the route's size limit. */
|
|
@@ -447,6 +552,48 @@ declare class NoneCap {
|
|
|
447
552
|
me(options?: {
|
|
448
553
|
signal?: AbortSignal;
|
|
449
554
|
}): Promise<Account>;
|
|
555
|
+
/**
|
|
556
|
+
* Recognize a challenge's images: send the instruction and images, get the
|
|
557
|
+
* answer back in the same response. No token, no polling.
|
|
558
|
+
*
|
|
559
|
+
* An answered call's charge is final. Throws {@link RecognitionFailedError}
|
|
560
|
+
* when no answer came back (nothing is charged then), {@link ValidationError}
|
|
561
|
+
* for a malformed request.
|
|
562
|
+
*
|
|
563
|
+
* ```ts
|
|
564
|
+
* const { id, data } = await nc.recognize({
|
|
565
|
+
* type: "hcaptcha",
|
|
566
|
+
* task: "Please click each image containing a bus",
|
|
567
|
+
* image_data: tiles, // base64
|
|
568
|
+
* });
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
recognize(params: RecognizeBinaryParams, options?: {
|
|
572
|
+
signal?: AbortSignal;
|
|
573
|
+
}): Promise<RecognizeBinaryResult>;
|
|
574
|
+
recognize(params: RecognizeAreaSelectParams, options?: {
|
|
575
|
+
signal?: AbortSignal;
|
|
576
|
+
}): Promise<RecognizeAreaSelectResult>;
|
|
577
|
+
recognize(params: RecognizeTasklistParams<"image_label_binary">, options?: {
|
|
578
|
+
signal?: AbortSignal;
|
|
579
|
+
}): Promise<RecognizeTasklistBinaryResult>;
|
|
580
|
+
recognize(params: RecognizeTasklistParams<"image_label_area_select">, options?: {
|
|
581
|
+
signal?: AbortSignal;
|
|
582
|
+
}): Promise<RecognizeTasklistAreaSelectResult>;
|
|
583
|
+
recognize(params: RecognizeTasklistParams<"image_drag_drop">, options?: {
|
|
584
|
+
signal?: AbortSignal;
|
|
585
|
+
}): Promise<RecognizeTasklistDragDropResult>;
|
|
586
|
+
recognize(params: RecognizeParams, options?: {
|
|
587
|
+
signal?: AbortSignal;
|
|
588
|
+
}): Promise<RecognizeResult>;
|
|
589
|
+
/**
|
|
590
|
+
* Report whether a {@link NoneCap.recognize} answer worked on the challenge.
|
|
591
|
+
* Optional and free; it feeds NoneCap's accuracy stats and never refunds the
|
|
592
|
+
* call. The first report for an id sticks: a repeat returns it unchanged.
|
|
593
|
+
*/
|
|
594
|
+
reportRecognitionOutcome(id: string, result: RecognitionOutcome, options?: {
|
|
595
|
+
signal?: AbortSignal;
|
|
596
|
+
}): Promise<RecognitionOutcomeResult>;
|
|
450
597
|
/**
|
|
451
598
|
* Submit a solve and wait for it to finish, returning the solved solve.
|
|
452
599
|
*
|
|
@@ -576,6 +723,10 @@ declare class ProxyUnavailableError extends RateLimitError {
|
|
|
576
723
|
* Nothing was charged; wait `retryAfter` seconds. */
|
|
577
724
|
declare class RateCappedError extends RateLimitError {
|
|
578
725
|
}
|
|
726
|
+
/** 422 — {@link NoneCap.recognize} produced no answer for these images, or the challenge
|
|
727
|
+
* type is not supported. Nothing was charged. */
|
|
728
|
+
declare class RecognitionFailedError extends NoneCapError {
|
|
729
|
+
}
|
|
579
730
|
/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */
|
|
580
731
|
declare class APIError extends NoneCapError {
|
|
581
732
|
}
|
|
@@ -620,4 +771,4 @@ declare class TimeoutError extends NoneCapError {
|
|
|
620
771
|
});
|
|
621
772
|
}
|
|
622
773
|
|
|
623
|
-
export { APIError, type Account, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, type ErrorCode, type ErrorEnvelope, FEEDBACK_BATCH_MAX, type Feedback, type FeedbackBatch, type FeedbackOutcome, type FeedbackReport, type FeedbackResult, type FeedbackStatus, type FetchLike, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, type NoneCapOptions, NotFoundError, PayloadTooLargeError, PermissionError, type Proxy, ProxyUnavailableError, RateCappedError, RateLimitError, ServiceUnavailableError, SitekeyRateLimitedError, type Solve, type SolveCreateParams, type SolveError, type SolveErrorCode, type SolveErrorReason, SolveFailedError, SolveHandle, type SolveHelperOptions, type SolveList, type SolveListParams, type SolveStartOptions, type SolveStatus, type SolveType, type SolveWarning, TimeoutError, UnsupportedMediaTypeError, ValidationError, type WaitOptions, isTerminal };
|
|
774
|
+
export { APIError, type Account, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, type ErrorCode, type ErrorEnvelope, FEEDBACK_BATCH_MAX, type Feedback, type FeedbackBatch, type FeedbackOutcome, type FeedbackReport, type FeedbackResult, type FeedbackStatus, type FetchLike, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, type NoneCapOptions, NotFoundError, PayloadTooLargeError, PermissionError, type Proxy, ProxyUnavailableError, RateCappedError, RateLimitError, RecognitionFailedError, type RecognitionOutcome, type RecognitionOutcomeResult, type RecognizeAreaSelectParams, type RecognizeAreaSelectResult, type RecognizeBinaryParams, type RecognizeBinaryResult, type RecognizeBox, type RecognizeDrop, type RecognizeEntity, type RecognizeImage, type RecognizeImages, type RecognizeParams, type RecognizePoint, type RecognizeRequestType, type RecognizeResult, type RecognizeTask, type RecognizeTasklistAreaSelectResult, type RecognizeTasklistBinaryResult, type RecognizeTasklistDragDropResult, type RecognizeTasklistParams, ServiceUnavailableError, SitekeyRateLimitedError, type Solve, type SolveCreateParams, type SolveError, type SolveErrorCode, type SolveErrorReason, SolveFailedError, SolveHandle, type SolveHelperOptions, type SolveList, type SolveListParams, type SolveStartOptions, type SolveStatus, type SolveType, type SolveWarning, TimeoutError, UnsupportedMediaTypeError, ValidationError, type WaitOptions, isTerminal };
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,8 @@ var ProxyUnavailableError = class extends RateLimitError {
|
|
|
49
49
|
};
|
|
50
50
|
var RateCappedError = class extends RateLimitError {
|
|
51
51
|
};
|
|
52
|
+
var RecognitionFailedError = class extends NoneCapError {
|
|
53
|
+
};
|
|
52
54
|
var APIError = class extends NoneCapError {
|
|
53
55
|
};
|
|
54
56
|
var ServiceUnavailableError = class extends APIError {
|
|
@@ -125,6 +127,8 @@ function errorFromResponse(status, code, message, param, extra = {}) {
|
|
|
125
127
|
case "rate_limited":
|
|
126
128
|
case "ext_daily_limit":
|
|
127
129
|
return new RateLimitError(message, opts);
|
|
130
|
+
case "recognition_failed":
|
|
131
|
+
return new RecognitionFailedError(message, opts);
|
|
128
132
|
case "maintenance":
|
|
129
133
|
return new ServiceUnavailableError(message, opts);
|
|
130
134
|
default:
|
|
@@ -133,7 +137,7 @@ function errorFromResponse(status, code, message, param, extra = {}) {
|
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
// src/version.ts
|
|
136
|
-
var VERSION = "0.
|
|
140
|
+
var VERSION = "0.10.0";
|
|
137
141
|
|
|
138
142
|
// src/client.ts
|
|
139
143
|
var DEFAULT_BASE_URL = "https://api.nonecap.com";
|
|
@@ -302,6 +306,23 @@ var NoneCap = class {
|
|
|
302
306
|
me(options = {}) {
|
|
303
307
|
return this.#request("GET", "/v1/me", { signal: options.signal });
|
|
304
308
|
}
|
|
309
|
+
recognize(params, options = {}) {
|
|
310
|
+
return this.#request("POST", "/v1/recognize", {
|
|
311
|
+
body: params,
|
|
312
|
+
signal: options.signal
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Report whether a {@link NoneCap.recognize} answer worked on the challenge.
|
|
317
|
+
* Optional and free; it feeds NoneCap's accuracy stats and never refunds the
|
|
318
|
+
* call. The first report for an id sticks: a repeat returns it unchanged.
|
|
319
|
+
*/
|
|
320
|
+
reportRecognitionOutcome(id, result, options = {}) {
|
|
321
|
+
return this.#request("POST", "/v1/recognize/outcome", {
|
|
322
|
+
body: { id, result },
|
|
323
|
+
signal: options.signal
|
|
324
|
+
});
|
|
325
|
+
}
|
|
305
326
|
/**
|
|
306
327
|
* Submit a solve and wait for it to finish, returning the solved solve.
|
|
307
328
|
*
|
|
@@ -527,6 +548,6 @@ function toWireReport(report) {
|
|
|
527
548
|
return { solve_id, ...toWireFields(fields) };
|
|
528
549
|
}
|
|
529
550
|
|
|
530
|
-
export { APIError, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, FEEDBACK_BATCH_MAX, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, NotFoundError, PayloadTooLargeError, PermissionError, ProxyUnavailableError, RateCappedError, RateLimitError, ServiceUnavailableError, SitekeyRateLimitedError, SolveFailedError, SolveHandle, TimeoutError, UnsupportedMediaTypeError, ValidationError, isTerminal };
|
|
551
|
+
export { APIError, AuthenticationError, ConcurrencyLimitError, ConflictError, ConnectionError, FEEDBACK_BATCH_MAX, InsufficientCreditsError, KeyCreditLimitError, NoneCap, NoneCapError, NotFoundError, PayloadTooLargeError, PermissionError, ProxyUnavailableError, RateCappedError, RateLimitError, RecognitionFailedError, ServiceUnavailableError, SitekeyRateLimitedError, SolveFailedError, SolveHandle, TimeoutError, UnsupportedMediaTypeError, ValidationError, isTerminal };
|
|
531
552
|
//# sourceMappingURL=index.js.map
|
|
532
553
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/version.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ErrorCode, Solve } from \"./types.js\";\n\n/**\n * Base class for every error this library throws. Catch `NoneCapError` to\n * handle all of them, or catch a subclass to handle one kind.\n */\nexport class NoneCapError extends Error {\n /** Machine-readable error code from the API envelope, when there is one. */\n readonly code: ErrorCode | undefined;\n /** HTTP status, when the error came from a response. */\n readonly status: number | undefined;\n /** The request field that was rejected, for validation errors. */\n readonly param: string | null;\n /** The API's correlation id for this request (`X-Request-Id`); quote it to support. */\n readonly requestId: string | undefined;\n /** Seconds to wait before retrying, when the API sent `Retry-After`. */\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n requestId?: string;\n retryAfter?: number;\n } = {},\n ) {\n super(message);\n this.name = new.target.name;\n this.code = opts.code;\n this.status = opts.status;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId;\n this.retryAfter = opts.retryAfter;\n // Restore the prototype chain when compiled down to ES5-era targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — the API key is missing, malformed, or revoked. */\nexport class AuthenticationError extends NoneCapError {}\n\n/** 403 — the key is valid but not allowed to do this (scope or locked account). */\nexport class PermissionError extends NoneCapError {}\n\n/** 402 — the account is out of credits. */\nexport class InsufficientCreditsError extends NoneCapError {}\n\n/** 402 — this API key reached its own credit limit (the account may still have credits). */\nexport class KeyCreditLimitError extends InsufficientCreditsError {}\n\n/** 422 / 400 — the request was rejected. `param` names the offending field. */\nexport class ValidationError extends NoneCapError {}\n\n/** 413 — the request body exceeds the route's size limit. */\nexport class PayloadTooLargeError extends ValidationError {}\n\n/** 415 — a JSON route was called without `Content-Type: application/json`. */\nexport class UnsupportedMediaTypeError extends ValidationError {}\n\n/** 404 — no such resource. */\nexport class NotFoundError extends NoneCapError {}\n\n/** 409 — the solve is already in a terminal state (e.g. cancelling a finished solve). */\nexport class ConflictError extends NoneCapError {}\n\n/** 429 — back off and retry; `retryAfter` (seconds) is set when the API sent it. */\nexport class RateLimitError extends NoneCapError {}\n\n/** 429 — too many solves in flight for this account. Wait for one to finish. */\nexport class ConcurrencyLimitError extends RateLimitError {}\n\n/** 429 — hCaptcha is refusing challenges for this sitekey, so the submit was shed.\n * Wait `retryAfter` seconds; the message says whether a different proxy pool can help. */\nexport class SitekeyRateLimitedError extends RateLimitError {}\n\n/** 429 — nearly every recent solve through the proxy you supplied failed because the\n * proxy refused the connection, so submits through it are shed. Fix the proxy or\n * switch exit; `retryAfter` says when the next submit is let through to re-check it. */\nexport class ProxyUnavailableError extends RateLimitError {}\n\n/** 429 — your account has a submit rate cap on this sitekey and reached it for the\n * trailing minute, or your own-proxy sessions for this sitekey are at their limit.\n * Nothing was charged; wait `retryAfter` seconds. */\nexport class RateCappedError extends RateLimitError {}\n\n/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */\nexport class APIError extends NoneCapError {}\n\n/** 503 — new solves are paused for maintenance. Retry shortly. */\nexport class ServiceUnavailableError extends APIError {}\n\n/** The request never reached the API (DNS, TCP, TLS, timeout, offline). */\nexport class ConnectionError extends NoneCapError {}\n\n/**\n * Thrown by {@link NoneCap.solve} when a solve reaches a terminal state without\n * a token: `failed`, `expired`, or `cancelled`. The full solve is attached so\n * you can inspect `solve.error` and timings.\n */\nexport class SolveFailedError extends NoneCapError {\n readonly solve: Solve;\n\n constructor(solve: Solve) {\n const detail = solve.error ? `${solve.error.code}: ${solve.error.message}` : solve.status;\n super(`Solve ${solve.id} ${solve.status} (${detail})`, {\n code: undefined,\n status: undefined,\n });\n this.solve = solve;\n }\n\n /** `solve.error.code`, e.g. `proxy_error`; the status when no error object came back. */\n get solveCode(): string {\n return this.solve.error?.code ?? this.solve.status;\n }\n\n /** `solve.error.reason`, the typed sub-reason, or null. */\n get reason(): string | null {\n return this.solve.error?.reason ?? null;\n }\n\n /** Whether re-submitting the same request unchanged can succeed. */\n get retryable(): boolean {\n return this.solve.error?.retryable ?? false;\n }\n}\n\n/**\n * Thrown by {@link NoneCap.solve} (and {@link SolveHandle.result}) when the\n * client-side timeout elapses first. When the timeout came from waiting on a\n * solve, `solveId` and the last-known `solve` are attached so you can still\n * cancel the in-flight solve. They are `undefined` for transport-level timeouts.\n */\nexport class TimeoutError extends NoneCapError {\n /** The id of the in-flight solve, when the timeout came from a solve wait. */\n readonly solveId: string | undefined;\n /** The last-known solve state, so you can cancel it after a wait timed out. */\n readonly solve: Solve | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n solveId?: string;\n solve?: Solve;\n } = {},\n ) {\n super(message, opts);\n this.solveId = opts.solveId;\n this.solve = opts.solve;\n }\n}\n\n/** Map an API error envelope (plus HTTP status) to the right error subclass. */\nexport function errorFromResponse(\n status: number,\n code: ErrorCode | undefined,\n message: string,\n param: string | null,\n extra: { requestId?: string; retryAfter?: number } = {},\n): NoneCapError {\n const opts = { code, status, param, ...extra };\n switch (code) {\n case \"unauthorized\":\n return new AuthenticationError(message, opts);\n case \"forbidden\":\n case \"account_locked\":\n return new PermissionError(message, opts);\n case \"insufficient_credits\":\n return new InsufficientCreditsError(message, opts);\n case \"key_credit_limit_exceeded\":\n return new KeyCreditLimitError(message, opts);\n case \"invalid_request\":\n case \"validation_error\":\n case \"expired_window\":\n return new ValidationError(message, opts);\n case \"payload_too_large\":\n return new PayloadTooLargeError(message, opts);\n case \"unsupported_media_type\":\n return new UnsupportedMediaTypeError(message, opts);\n case \"not_found\":\n case \"not_eligible\":\n return new NotFoundError(message, opts);\n case \"conflict\":\n return new ConflictError(message, opts);\n case \"concurrency_limit_exceeded\":\n return new ConcurrencyLimitError(message, opts);\n case \"sitekey_rate_limited\":\n return new SitekeyRateLimitedError(message, opts);\n case \"proxy_unavailable\":\n return new ProxyUnavailableError(message, opts);\n case \"rate_capped\":\n return new RateCappedError(message, opts);\n case \"rate_limited\":\n case \"ext_daily_limit\":\n return new RateLimitError(message, opts);\n case \"maintenance\":\n return new ServiceUnavailableError(message, opts);\n default:\n return new APIError(message, opts);\n }\n}\n","/**\n * The published package version, sent as the `User-Agent` on every request.\n *\n * Hardcoded rather than imported from package.json: a JSON import would need\n * `resolveJsonModule` and would resolve differently under the ESM and CJS\n * builds. Bump it in the SAME commit as package.json: the drift check is the\n * `Version constant matches package.json` step in ci.yml and lives ONLY there,\n * so `npm test` and `tsc` both stay green on a mismatch (test/version.test.ts\n * asserts the User-Agent uses VERSION, never that VERSION is right).\n */\nexport const VERSION = \"0.9.6\";\n","import {\n APIError,\n ConflictError,\n ConnectionError,\n NoneCapError,\n SolveFailedError,\n TimeoutError,\n errorFromResponse,\n} from \"./errors.js\";\nimport type {\n Account,\n ErrorCode,\n Feedback,\n FeedbackBatch,\n FeedbackReport,\n Solve,\n SolveCreateParams,\n SolveList,\n SolveListParams,\n SolveStatus,\n} from \"./types.js\";\n\nimport { VERSION } from \"./version.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.nonecap.com\";\nconst USER_AGENT = `nonecap-js/${VERSION}`;\n/** The API caps server-side long-poll at 90 seconds. */\nconst MAX_WAIT_SECONDS = 90;\n/** The API caps one `POST /v1/feedback` call at 500 items. */\nexport const FEEDBACK_BATCH_MAX = 500;\nconst TERMINAL: ReadonlySet<SolveStatus> = new Set([\n \"solved\",\n \"failed\",\n \"cancelled\",\n \"expired\",\n]);\n\n/** Is this a terminal solve status? */\nexport function isTerminal(status: SolveStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** A `fetch` implementation. Defaults to the global `fetch`. */\nexport type FetchLike = (\n input: string,\n init?: RequestInit,\n) => Promise<Response>;\n\n/** Options for constructing a {@link NoneCap} client. */\nexport interface NoneCapOptions {\n /** Your NoneCap API key. Find it at https://dashboard.nonecap.com. */\n apiKey: string;\n /** Override the API base URL. Defaults to https://api.nonecap.com. */\n baseURL?: string;\n /**\n * Per-request timeout in milliseconds for a single HTTP call. Defaults to\n * 100000 (just above the 90s server long-poll). Note this bounds one HTTP\n * round trip, not the whole {@link NoneCap.solve} wait — use the `timeout`\n * option on `solve()` for that.\n */\n timeout?: number;\n /** Inject a custom `fetch` (for testing, proxies, or non-standard runtimes). */\n fetch?: FetchLike;\n}\n\n/** Per-call options for the long-polling endpoints. */\nexport interface WaitOptions {\n /**\n * Hold the connection open up to this many seconds (1–90) waiting for the\n * solve to finish before responding. Omit to return immediately.\n */\n wait?: number;\n /** Abort the request. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solve} and {@link SolveHandle.result}. */\nexport interface SolveHelperOptions {\n /**\n * Give up after this many milliseconds and throw {@link TimeoutError}.\n * Defaults to 180000 (3 minutes).\n */\n timeout?: number;\n /** Abort waiting. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solves.start}. */\nexport interface SolveStartOptions {\n /** Abort the submission. */\n signal?: AbortSignal;\n}\n\ninterface RequestOptions {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n signal?: AbortSignal;\n /** Override the per-request timeout for this call (used by long polls). */\n timeout?: number;\n /** HTTP statuses to treat as success in addition to 2xx (e.g. 202). */\n expect?: number[];\n}\n\n/**\n * The NoneCap API client.\n *\n * ```ts\n * const nc = new NoneCap({ apiKey: process.env.NONECAP_KEY! });\n * const { token } = await nc.solve({ type: \"hcaptcha\", sitekey, url });\n * ```\n */\nexport class NoneCap {\n readonly #apiKey: string;\n readonly #baseURL: string;\n readonly #timeout: number;\n readonly #fetch: FetchLike;\n\n constructor(options: NoneCapOptions) {\n if (!options || !options.apiKey) {\n throw new NoneCapError(\n \"A NoneCap API key is required. Pass it as `new NoneCap({ apiKey })`.\",\n );\n }\n this.#apiKey = options.apiKey;\n this.#baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#timeout = options.timeout ?? 100_000;\n const f = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new NoneCapError(\n \"No `fetch` available. Use Node 18+, or pass a `fetch` in the client options.\",\n );\n }\n this.#fetch = f;\n }\n\n /** Operations on solves. */\n readonly solves = {\n /** Submit a solve. Pass `{ wait }` to hold the connection until it finishes. */\n create: (params: SolveCreateParams, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"POST\", \"/v1/solves\", {\n body: params,\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Fetch a solve by id. Pass `{ wait }` to long-poll until it finishes. */\n retrieve: (id: string, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"GET\", `/v1/solves/${encodeURIComponent(id)}`, {\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Cancel a pending or in-flight solve. */\n cancel: (id: string, options: { signal?: AbortSignal } = {}): Promise<Solve> =>\n this.#request<Solve>(\"DELETE\", `/v1/solves/${encodeURIComponent(id)}`, {\n signal: options.signal,\n }),\n\n /**\n * Submit a solve and return a {@link SolveHandle} for it.\n *\n * Unlike {@link NoneCap.solve}, this returns as soon as the submission is\n * accepted, so `handle.id` is available immediately. Use the handle to\n * `cancel()` the solve or `await handle.result()` for the finished solve.\n *\n * ```ts\n * const handle = await nc.solves.start({ type: \"hcaptcha\", sitekey, url });\n * // ...later, e.g. on shutdown:\n * await handle.cancel();\n * // or wait for it:\n * const { token } = await handle.result();\n * ```\n */\n start: async (\n params: SolveCreateParams,\n options: SolveStartOptions = {},\n ): Promise<SolveHandle> => {\n const solve = await this.solves.create(params, { signal: options.signal });\n return new SolveHandle(this, solve);\n },\n\n /** Fetch one page of solves. */\n list: (params: SolveListParams = {}, options: { signal?: AbortSignal } = {}): Promise<SolveList> =>\n this.#request<SolveList>(\"GET\", \"/v1/solves\", {\n query: {\n limit: params.limit,\n starting_after: params.starting_after,\n status: params.status,\n type: params.type,\n },\n signal: options.signal,\n }),\n\n /**\n * Iterate every solve across pages, newest first.\n *\n * ```ts\n * for await (const solve of nc.solves.listAll()) { ... }\n * ```\n */\n listAll: (\n params: SolveListParams = {},\n options: { signal?: AbortSignal } = {},\n ): AsyncIterableIterator<Solve> => this.#listAll(params, options),\n };\n\n /**\n * Report what your downstream target did with the tokens we minted.\n *\n * Feedback is free, own-solves-only, and idempotent per solve id: reporting\n * the same solve again corrects the earlier verdict. Only `solved` solves can\n * be reported, and only within the API's reporting window (~30 days from the\n * solve; corrections to an already-reported solve are never re-gated by it).\n */\n readonly feedback = {\n /**\n * Report one solve's downstream outcome, returning the recorded feedback.\n *\n * Unlike {@link NoneCap.feedback.reportMany}, a rejected report throws:\n * {@link NotFoundError} if the solve isn't yours or never minted a token,\n * {@link ValidationError} if a field is wrong or the reporting window closed.\n *\n * ```ts\n * await nc.feedback.report({ solve_id: solve.id, outcome: \"rejected\", reason: \"...\" });\n * ```\n */\n report: (report: FeedbackReport, options: { signal?: AbortSignal } = {}): Promise<Feedback> => {\n const { solve_id, ...fields } = report;\n return this.#request<Feedback>(\n \"POST\",\n `/v1/solves/${encodeURIComponent(solve_id)}/feedback`,\n { body: toWireFields(fields), signal: options.signal },\n );\n },\n\n /**\n * Report many verdicts at once — the path to use at volume. Buffer verdicts\n * as you learn them and flush them here.\n *\n * The call succeeds even when individual items are rejected: each is\n * resolved on its own so one stale id never discards the rest. Check\n * `failed` rather than relying on a thrown error.\n *\n * More than {@link FEEDBACK_BATCH_MAX} reports are split across sequential\n * requests and merged into one result, in request order. An empty array is\n * a no-op that returns an empty batch without a request.\n *\n * ```ts\n * const batch = await nc.feedback.reportMany(buffer);\n * if (batch.failed) console.warn(batch.results.filter((r) => r.status === \"error\"));\n * ```\n */\n reportMany: async (\n reports: readonly FeedbackReport[],\n options: { signal?: AbortSignal } = {},\n ): Promise<FeedbackBatch> => {\n const merged: FeedbackBatch = {\n object: \"feedback_batch\",\n recorded: 0,\n updated: 0,\n unchanged: 0,\n failed: 0,\n results: [],\n };\n // Chunks are sent in order and the server upserts last-write-wins, so a\n // solve reported twice still ends at its last value. Duplicates split\n // across a chunk boundary each get written, though, so the earlier one\n // reports `recorded`/`updated` where a single request would say\n // `unchanged`.\n for (let i = 0; i < reports.length; i += FEEDBACK_BATCH_MAX) {\n const batch = await this.#request<FeedbackBatch>(\"POST\", \"/v1/feedback\", {\n body: { feedback: reports.slice(i, i + FEEDBACK_BATCH_MAX).map(toWireReport) },\n signal: options.signal,\n });\n merged.recorded += batch.recorded;\n merged.updated += batch.updated;\n merged.unchanged += batch.unchanged;\n merged.failed += batch.failed;\n merged.results.push(...batch.results);\n }\n return merged;\n },\n };\n\n /** Fetch your account, including the current credit balance. */\n me(options: { signal?: AbortSignal } = {}): Promise<Account> {\n return this.#request<Account>(\"GET\", \"/v1/me\", { signal: options.signal });\n }\n\n /**\n * Submit a solve and wait for it to finish, returning the solved solve.\n *\n * Uses the server's long-poll under the hood and keeps polling until the\n * solve is terminal or `timeout` elapses. Throws {@link SolveFailedError} if\n * the solve fails/expires/is cancelled, or {@link TimeoutError} on timeout.\n *\n * This is sugar for `(await solves.start(params)).result(options)`. When you\n * need to cancel the solve while it runs, use {@link NoneCap.solves.start}\n * and keep the {@link SolveHandle}.\n */\n async solve(params: SolveCreateParams, options: SolveHelperOptions = {}): Promise<Solve> {\n const handle = await this.solves.start(params, { signal: options.signal });\n return handle.result(options);\n }\n\n // -- internals ------------------------------------------------------------\n\n #timeoutForWait(wait?: number): number | undefined {\n if (wait === undefined) return undefined;\n // Give the socket a margin beyond the server's long-poll window.\n return wait * 1000 + 15_000;\n }\n\n async *#listAll(\n params: SolveListParams,\n options: { signal?: AbortSignal },\n ): AsyncIterableIterator<Solve> {\n let cursor = params.starting_after;\n for (;;) {\n const page = await this.solves.list({ ...params, starting_after: cursor }, options);\n for (const solve of page.data) yield solve;\n if (!page.has_more || page.data.length === 0) return;\n cursor = page.data[page.data.length - 1]!.id;\n }\n }\n\n async #request<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const url = new URL(this.#baseURL + path);\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== \"\") url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n Accept: \"application/json\",\n // Browsers drop this as a forbidden header; on Node it identifies the SDK.\n \"User-Agent\": USER_AGENT,\n };\n let bodyInit: string | undefined;\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyInit = JSON.stringify(options.body);\n }\n\n const controller = new AbortController();\n const timeoutMs = options.timeout ?? this.#timeout;\n const timer = setTimeout(() => controller.abort(new TimeoutError(`Request timed out after ${timeoutMs}ms.`)), timeoutMs);\n const onAbort = () => controller.abort(options.signal?.reason);\n if (options.signal) {\n if (options.signal.aborted) onAbort();\n else options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n let res: Response;\n try {\n res = await this.#fetch(url.toString(), {\n method,\n headers,\n body: bodyInit,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof TimeoutError) throw err;\n if (isAbort(err)) {\n // A caller-supplied signal aborting surfaces as the caller's reason.\n if (options.signal?.aborted) throw options.signal.reason instanceof Error\n ? options.signal.reason\n : new NoneCapError(\"Request aborted.\");\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms.`);\n }\n throw new ConnectionError(\n `Could not reach the NoneCap API at ${this.#baseURL}: ${(err as Error).message}`,\n );\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n return this.#parse<T>(res, options.expect ?? []);\n }\n\n async #parse<T>(res: Response, expect: number[]): Promise<T> {\n const text = await res.text();\n let json: unknown;\n if (text) {\n try {\n json = JSON.parse(text);\n } catch {\n throw new APIError(\n `Unexpected non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n { status: res.status },\n );\n }\n }\n\n if (res.ok || expect.includes(res.status)) {\n return json as T;\n }\n\n const envelope = json as\n | { error?: { code?: ErrorCode; message?: string; param?: string | null; request_id?: string } }\n | undefined;\n const apiError = envelope?.error;\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw !== null && /^\\d+$/.test(retryAfterRaw) ? Number(retryAfterRaw) : undefined;\n throw errorFromResponse(\n res.status,\n apiError?.code,\n apiError?.message ?? `HTTP ${res.status}`,\n apiError?.param ?? null,\n { requestId: apiError?.request_id ?? res.headers.get(\"x-request-id\") ?? undefined, retryAfter },\n );\n }\n}\n\n/**\n * A handle on a started solve, returned by {@link NoneCap.solves.start}.\n *\n * The handle is the cancellable lifecycle object for one solve. It is a plain\n * object, not a promise: `await`ing it does nothing useful. Wait for the result\n * with {@link SolveHandle.result}, and cancel with {@link SolveHandle.cancel}.\n * You do not construct it yourself — `solves.start()` hands you one with `id`\n * already resolved.\n */\nexport class SolveHandle {\n /** The id of the started solve, available as soon as `start()` resolved. */\n readonly id: string;\n\n readonly #client: NoneCap;\n /** The latest solve state we have seen, from the create, polls, or cancel. */\n #solve: Solve;\n /**\n * The cached TERMINAL outcome: resolves to the solved solve, or rejects with\n * {@link SolveFailedError} if terminal-but-not-solved. Only ever set once the\n * solve actually reaches a terminal state, so it is safe to replay forever. A\n * timed-out wait does NOT settle this — it is retryable.\n */\n #terminal: Promise<Solve> | undefined;\n /** The poll currently in flight, shared by concurrent result() callers. */\n #inflight: Promise<Solve> | undefined;\n\n constructor(client: NoneCap, solve: Solve) {\n this.#client = client;\n this.#solve = solve;\n this.id = solve.id;\n }\n\n /** The last-known solve state for this handle. */\n get solve(): Solve {\n return this.#solve;\n }\n\n /**\n * Long-poll until the solve is terminal, returning the solved solve. Throws\n * {@link SolveFailedError} if it fails/expires/is cancelled, or\n * {@link TimeoutError} on timeout (with `solveId`/`solve` attached so you can\n * still {@link SolveHandle.cancel} it).\n *\n * Memoizes the *terminal* outcome: once the solve actually finishes, every\n * later call returns that same settled result. A {@link TimeoutError} is not\n * memoized — it just means this wait gave up, so a later call (e.g. with a\n * larger `timeout`) resumes polling. Concurrent calls share one in-flight\n * poll, so they never issue duplicate requests. The first caller's\n * `timeout`/`signal` drive the shared poll; a later call starts a fresh one.\n */\n result(options: SolveHelperOptions = {}): Promise<Solve> {\n if (this.#terminal) return this.#terminal;\n if (this.#inflight) return this.#inflight;\n const run = this.#poll(options).finally(() => {\n // Free the slot so a retry can re-poll after a timeout; a terminal\n // outcome is already memoized in #terminal and wins on the next call.\n if (this.#inflight === run) this.#inflight = undefined;\n });\n this.#inflight = run;\n return run;\n }\n\n /**\n * Cancel the solve. Cancelled solves are never charged, so this is for clean\n * shutdown / freeing slots / stopping early, not cost protection.\n *\n * If the solve already reached a terminal state the API answers 409; that is\n * not an error a caller cares about, so this swallows {@link ConflictError}\n * and returns the current solve state instead. A cancel that lands on a\n * terminal state (cancelled, or whatever the 409-swallow read back) settles\n * this handle's {@link SolveHandle.result}, so any in-flight or later wait\n * stops polling and reflects that terminal state.\n */\n async cancel(options: { signal?: AbortSignal } = {}): Promise<Solve> {\n try {\n this.#solve = await this.#client.solves.cancel(this.id, options);\n } catch (err) {\n if (!(err instanceof ConflictError)) throw err;\n // Already terminal — report the real state rather than the 409.\n this.#solve = await this.#client.solves.retrieve(this.id, options);\n }\n if (!this.#terminal && isTerminal(this.#solve.status)) this.#cacheTerminal();\n return this.#solve;\n }\n\n /**\n * Build and memoize the terminal outcome from the current `#solve`. The\n * precondition is that `#solve` is terminal and `#terminal` is unset.\n */\n #cacheTerminal(): Promise<Solve> {\n const settled =\n this.#solve.status === \"solved\"\n ? Promise.resolve(this.#solve)\n : Promise.reject(new SolveFailedError(this.#solve));\n // Never let the memoized rejection surface as an unhandled rejection; real\n // callers read it explicitly through result().\n settled.catch(() => {});\n this.#terminal = settled;\n return settled;\n }\n\n async #poll(options: SolveHelperOptions): Promise<Solve> {\n const timeout = options.timeout ?? 180_000;\n const deadline = Date.now() + timeout;\n\n for (;;) {\n // cancel() (or a previous poll) may have already settled this handle.\n if (this.#terminal) return this.#terminal;\n if (isTerminal(this.#solve.status)) return this.#cacheTerminal();\n if (Date.now() >= deadline) {\n throw new TimeoutError(\n `Solve ${this.id} did not finish within ${timeout}ms (last status: ${this.#solve.status}).`,\n { solveId: this.id, solve: this.#solve },\n );\n }\n this.#solve = await this.#client.solves.retrieve(this.id, {\n wait: waitSeconds(deadline),\n signal: options.signal,\n });\n }\n }\n}\n\n/**\n * The `wait` value for the next long-poll: whole seconds until `deadline`,\n * clamped to the server's 1–90 window. The floor of 1 keeps the param valid,\n * so callers must decide whether the deadline has passed with the clock, not\n * with this return value.\n */\nfunction waitSeconds(deadline: number): number {\n const remaining = Math.ceil((deadline - Date.now()) / 1000);\n return Math.max(1, Math.min(MAX_WAIT_SECONDS, remaining));\n}\n\nfunction isAbort(err: unknown): boolean {\n return err instanceof Error && err.name === \"AbortError\";\n}\n\n/** The fields of a report, ready for the wire: a `Date` becomes an ISO string. */\nfunction toWireFields(fields: Omit<FeedbackReport, \"solve_id\">): Record<string, unknown> {\n const wire: Record<string, unknown> = { outcome: fields.outcome };\n if (fields.reason !== undefined) wire.reason = fields.reason;\n if (fields.context !== undefined) wire.context = fields.context;\n if (fields.reported_at !== undefined) {\n wire.reported_at =\n fields.reported_at instanceof Date ? fields.reported_at.toISOString() : fields.reported_at;\n }\n return wire;\n}\n\nfunction toWireReport(report: FeedbackReport): Record<string, unknown> {\n const { solve_id, ...fields } = report;\n return { solve_id, ...toWireFields(fields) };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/version.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ErrorCode, Solve } from \"./types.js\";\n\n/**\n * Base class for every error this library throws. Catch `NoneCapError` to\n * handle all of them, or catch a subclass to handle one kind.\n */\nexport class NoneCapError extends Error {\n /** Machine-readable error code from the API envelope, when there is one. */\n readonly code: ErrorCode | undefined;\n /** HTTP status, when the error came from a response. */\n readonly status: number | undefined;\n /** The request field that was rejected, for validation errors. */\n readonly param: string | null;\n /** The API's correlation id for this request (`X-Request-Id`); quote it to support. */\n readonly requestId: string | undefined;\n /** Seconds to wait before retrying, when the API sent `Retry-After`. */\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n requestId?: string;\n retryAfter?: number;\n } = {},\n ) {\n super(message);\n this.name = new.target.name;\n this.code = opts.code;\n this.status = opts.status;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId;\n this.retryAfter = opts.retryAfter;\n // Restore the prototype chain when compiled down to ES5-era targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — the API key is missing, malformed, or revoked. */\nexport class AuthenticationError extends NoneCapError {}\n\n/** 403 — the key is valid but not allowed to do this (scope or locked account). */\nexport class PermissionError extends NoneCapError {}\n\n/** 402 — the account is out of credits. */\nexport class InsufficientCreditsError extends NoneCapError {}\n\n/** 402 — this API key reached its own credit limit (the account may still have credits). */\nexport class KeyCreditLimitError extends InsufficientCreditsError {}\n\n/** 422 / 400 — the request was rejected. `param` names the offending field. */\nexport class ValidationError extends NoneCapError {}\n\n/** 413 — the request body exceeds the route's size limit. */\nexport class PayloadTooLargeError extends ValidationError {}\n\n/** 415 — a JSON route was called without `Content-Type: application/json`. */\nexport class UnsupportedMediaTypeError extends ValidationError {}\n\n/** 404 — no such resource. */\nexport class NotFoundError extends NoneCapError {}\n\n/** 409 — the solve is already in a terminal state (e.g. cancelling a finished solve). */\nexport class ConflictError extends NoneCapError {}\n\n/** 429 — back off and retry; `retryAfter` (seconds) is set when the API sent it. */\nexport class RateLimitError extends NoneCapError {}\n\n/** 429 — too many solves in flight for this account. Wait for one to finish. */\nexport class ConcurrencyLimitError extends RateLimitError {}\n\n/** 429 — hCaptcha is refusing challenges for this sitekey, so the submit was shed.\n * Wait `retryAfter` seconds; the message says whether a different proxy pool can help. */\nexport class SitekeyRateLimitedError extends RateLimitError {}\n\n/** 429 — nearly every recent solve through the proxy you supplied failed because the\n * proxy refused the connection, so submits through it are shed. Fix the proxy or\n * switch exit; `retryAfter` says when the next submit is let through to re-check it. */\nexport class ProxyUnavailableError extends RateLimitError {}\n\n/** 429 — your account has a submit rate cap on this sitekey and reached it for the\n * trailing minute, or your own-proxy sessions for this sitekey are at their limit.\n * Nothing was charged; wait `retryAfter` seconds. */\nexport class RateCappedError extends RateLimitError {}\n\n/** 422 — {@link NoneCap.recognize} produced no answer for these images, or the challenge\n * type is not supported. Nothing was charged. */\nexport class RecognitionFailedError extends NoneCapError {}\n\n/** 5xx, or a response that wasn't the expected shape. `requestId` is the id to quote. */\nexport class APIError extends NoneCapError {}\n\n/** 503 — new solves are paused for maintenance. Retry shortly. */\nexport class ServiceUnavailableError extends APIError {}\n\n/** The request never reached the API (DNS, TCP, TLS, timeout, offline). */\nexport class ConnectionError extends NoneCapError {}\n\n/**\n * Thrown by {@link NoneCap.solve} when a solve reaches a terminal state without\n * a token: `failed`, `expired`, or `cancelled`. The full solve is attached so\n * you can inspect `solve.error` and timings.\n */\nexport class SolveFailedError extends NoneCapError {\n readonly solve: Solve;\n\n constructor(solve: Solve) {\n const detail = solve.error ? `${solve.error.code}: ${solve.error.message}` : solve.status;\n super(`Solve ${solve.id} ${solve.status} (${detail})`, {\n code: undefined,\n status: undefined,\n });\n this.solve = solve;\n }\n\n /** `solve.error.code`, e.g. `proxy_error`; the status when no error object came back. */\n get solveCode(): string {\n return this.solve.error?.code ?? this.solve.status;\n }\n\n /** `solve.error.reason`, the typed sub-reason, or null. */\n get reason(): string | null {\n return this.solve.error?.reason ?? null;\n }\n\n /** Whether re-submitting the same request unchanged can succeed. */\n get retryable(): boolean {\n return this.solve.error?.retryable ?? false;\n }\n}\n\n/**\n * Thrown by {@link NoneCap.solve} (and {@link SolveHandle.result}) when the\n * client-side timeout elapses first. When the timeout came from waiting on a\n * solve, `solveId` and the last-known `solve` are attached so you can still\n * cancel the in-flight solve. They are `undefined` for transport-level timeouts.\n */\nexport class TimeoutError extends NoneCapError {\n /** The id of the in-flight solve, when the timeout came from a solve wait. */\n readonly solveId: string | undefined;\n /** The last-known solve state, so you can cancel it after a wait timed out. */\n readonly solve: Solve | undefined;\n\n constructor(\n message: string,\n opts: {\n code?: ErrorCode;\n status?: number;\n param?: string | null;\n solveId?: string;\n solve?: Solve;\n } = {},\n ) {\n super(message, opts);\n this.solveId = opts.solveId;\n this.solve = opts.solve;\n }\n}\n\n/** Map an API error envelope (plus HTTP status) to the right error subclass. */\nexport function errorFromResponse(\n status: number,\n code: ErrorCode | undefined,\n message: string,\n param: string | null,\n extra: { requestId?: string; retryAfter?: number } = {},\n): NoneCapError {\n const opts = { code, status, param, ...extra };\n switch (code) {\n case \"unauthorized\":\n return new AuthenticationError(message, opts);\n case \"forbidden\":\n case \"account_locked\":\n return new PermissionError(message, opts);\n case \"insufficient_credits\":\n return new InsufficientCreditsError(message, opts);\n case \"key_credit_limit_exceeded\":\n return new KeyCreditLimitError(message, opts);\n case \"invalid_request\":\n case \"validation_error\":\n case \"expired_window\":\n return new ValidationError(message, opts);\n case \"payload_too_large\":\n return new PayloadTooLargeError(message, opts);\n case \"unsupported_media_type\":\n return new UnsupportedMediaTypeError(message, opts);\n case \"not_found\":\n case \"not_eligible\":\n return new NotFoundError(message, opts);\n case \"conflict\":\n return new ConflictError(message, opts);\n case \"concurrency_limit_exceeded\":\n return new ConcurrencyLimitError(message, opts);\n case \"sitekey_rate_limited\":\n return new SitekeyRateLimitedError(message, opts);\n case \"proxy_unavailable\":\n return new ProxyUnavailableError(message, opts);\n case \"rate_capped\":\n return new RateCappedError(message, opts);\n case \"rate_limited\":\n case \"ext_daily_limit\":\n return new RateLimitError(message, opts);\n case \"recognition_failed\":\n return new RecognitionFailedError(message, opts);\n case \"maintenance\":\n return new ServiceUnavailableError(message, opts);\n default:\n return new APIError(message, opts);\n }\n}\n","/**\n * The published package version, sent as the `User-Agent` on every request.\n *\n * Hardcoded rather than imported from package.json: a JSON import would need\n * `resolveJsonModule` and would resolve differently under the ESM and CJS\n * builds. Bump it in the SAME commit as package.json: the drift check is the\n * `Version constant matches package.json` step in ci.yml and lives ONLY there,\n * so `npm test` and `tsc` both stay green on a mismatch (test/version.test.ts\n * asserts the User-Agent uses VERSION, never that VERSION is right).\n */\nexport const VERSION = \"0.10.0\";\n","import {\n APIError,\n ConflictError,\n ConnectionError,\n NoneCapError,\n SolveFailedError,\n TimeoutError,\n errorFromResponse,\n} from \"./errors.js\";\nimport type {\n Account,\n ErrorCode,\n Feedback,\n FeedbackBatch,\n FeedbackReport,\n RecognitionOutcome,\n RecognitionOutcomeResult,\n RecognizeAreaSelectParams,\n RecognizeAreaSelectResult,\n RecognizeBinaryParams,\n RecognizeBinaryResult,\n RecognizeParams,\n RecognizeResult,\n RecognizeTasklistAreaSelectResult,\n RecognizeTasklistBinaryResult,\n RecognizeTasklistDragDropResult,\n RecognizeTasklistParams,\n Solve,\n SolveCreateParams,\n SolveList,\n SolveListParams,\n SolveStatus,\n} from \"./types.js\";\n\nimport { VERSION } from \"./version.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.nonecap.com\";\nconst USER_AGENT = `nonecap-js/${VERSION}`;\n/** The API caps server-side long-poll at 90 seconds. */\nconst MAX_WAIT_SECONDS = 90;\n/** The API caps one `POST /v1/feedback` call at 500 items. */\nexport const FEEDBACK_BATCH_MAX = 500;\nconst TERMINAL: ReadonlySet<SolveStatus> = new Set([\n \"solved\",\n \"failed\",\n \"cancelled\",\n \"expired\",\n]);\n\n/** Is this a terminal solve status? */\nexport function isTerminal(status: SolveStatus): boolean {\n return TERMINAL.has(status);\n}\n\n/** A `fetch` implementation. Defaults to the global `fetch`. */\nexport type FetchLike = (\n input: string,\n init?: RequestInit,\n) => Promise<Response>;\n\n/** Options for constructing a {@link NoneCap} client. */\nexport interface NoneCapOptions {\n /** Your NoneCap API key. Find it at https://dashboard.nonecap.com. */\n apiKey: string;\n /** Override the API base URL. Defaults to https://api.nonecap.com. */\n baseURL?: string;\n /**\n * Per-request timeout in milliseconds for a single HTTP call. Defaults to\n * 100000 (just above the 90s server long-poll). Note this bounds one HTTP\n * round trip, not the whole {@link NoneCap.solve} wait — use the `timeout`\n * option on `solve()` for that.\n */\n timeout?: number;\n /** Inject a custom `fetch` (for testing, proxies, or non-standard runtimes). */\n fetch?: FetchLike;\n}\n\n/** Per-call options for the long-polling endpoints. */\nexport interface WaitOptions {\n /**\n * Hold the connection open up to this many seconds (1–90) waiting for the\n * solve to finish before responding. Omit to return immediately.\n */\n wait?: number;\n /** Abort the request. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solve} and {@link SolveHandle.result}. */\nexport interface SolveHelperOptions {\n /**\n * Give up after this many milliseconds and throw {@link TimeoutError}.\n * Defaults to 180000 (3 minutes).\n */\n timeout?: number;\n /** Abort waiting. */\n signal?: AbortSignal;\n}\n\n/** Options for {@link NoneCap.solves.start}. */\nexport interface SolveStartOptions {\n /** Abort the submission. */\n signal?: AbortSignal;\n}\n\ninterface RequestOptions {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n signal?: AbortSignal;\n /** Override the per-request timeout for this call (used by long polls). */\n timeout?: number;\n /** HTTP statuses to treat as success in addition to 2xx (e.g. 202). */\n expect?: number[];\n}\n\n/**\n * The NoneCap API client.\n *\n * ```ts\n * const nc = new NoneCap({ apiKey: process.env.NONECAP_KEY! });\n * const { token } = await nc.solve({ type: \"hcaptcha\", sitekey, url });\n * ```\n */\nexport class NoneCap {\n readonly #apiKey: string;\n readonly #baseURL: string;\n readonly #timeout: number;\n readonly #fetch: FetchLike;\n\n constructor(options: NoneCapOptions) {\n if (!options || !options.apiKey) {\n throw new NoneCapError(\n \"A NoneCap API key is required. Pass it as `new NoneCap({ apiKey })`.\",\n );\n }\n this.#apiKey = options.apiKey;\n this.#baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#timeout = options.timeout ?? 100_000;\n const f = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new NoneCapError(\n \"No `fetch` available. Use Node 18+, or pass a `fetch` in the client options.\",\n );\n }\n this.#fetch = f;\n }\n\n /** Operations on solves. */\n readonly solves = {\n /** Submit a solve. Pass `{ wait }` to hold the connection until it finishes. */\n create: (params: SolveCreateParams, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"POST\", \"/v1/solves\", {\n body: params,\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Fetch a solve by id. Pass `{ wait }` to long-poll until it finishes. */\n retrieve: (id: string, options: WaitOptions = {}): Promise<Solve> =>\n this.#request<Solve>(\"GET\", `/v1/solves/${encodeURIComponent(id)}`, {\n query: { wait: options.wait },\n signal: options.signal,\n timeout: this.#timeoutForWait(options.wait),\n expect: [202],\n }),\n\n /** Cancel a pending or in-flight solve. */\n cancel: (id: string, options: { signal?: AbortSignal } = {}): Promise<Solve> =>\n this.#request<Solve>(\"DELETE\", `/v1/solves/${encodeURIComponent(id)}`, {\n signal: options.signal,\n }),\n\n /**\n * Submit a solve and return a {@link SolveHandle} for it.\n *\n * Unlike {@link NoneCap.solve}, this returns as soon as the submission is\n * accepted, so `handle.id` is available immediately. Use the handle to\n * `cancel()` the solve or `await handle.result()` for the finished solve.\n *\n * ```ts\n * const handle = await nc.solves.start({ type: \"hcaptcha\", sitekey, url });\n * // ...later, e.g. on shutdown:\n * await handle.cancel();\n * // or wait for it:\n * const { token } = await handle.result();\n * ```\n */\n start: async (\n params: SolveCreateParams,\n options: SolveStartOptions = {},\n ): Promise<SolveHandle> => {\n const solve = await this.solves.create(params, { signal: options.signal });\n return new SolveHandle(this, solve);\n },\n\n /** Fetch one page of solves. */\n list: (params: SolveListParams = {}, options: { signal?: AbortSignal } = {}): Promise<SolveList> =>\n this.#request<SolveList>(\"GET\", \"/v1/solves\", {\n query: {\n limit: params.limit,\n starting_after: params.starting_after,\n status: params.status,\n type: params.type,\n },\n signal: options.signal,\n }),\n\n /**\n * Iterate every solve across pages, newest first.\n *\n * ```ts\n * for await (const solve of nc.solves.listAll()) { ... }\n * ```\n */\n listAll: (\n params: SolveListParams = {},\n options: { signal?: AbortSignal } = {},\n ): AsyncIterableIterator<Solve> => this.#listAll(params, options),\n };\n\n /**\n * Report what your downstream target did with the tokens we minted.\n *\n * Feedback is free, own-solves-only, and idempotent per solve id: reporting\n * the same solve again corrects the earlier verdict. Only `solved` solves can\n * be reported, and only within the API's reporting window (~30 days from the\n * solve; corrections to an already-reported solve are never re-gated by it).\n */\n readonly feedback = {\n /**\n * Report one solve's downstream outcome, returning the recorded feedback.\n *\n * Unlike {@link NoneCap.feedback.reportMany}, a rejected report throws:\n * {@link NotFoundError} if the solve isn't yours or never minted a token,\n * {@link ValidationError} if a field is wrong or the reporting window closed.\n *\n * ```ts\n * await nc.feedback.report({ solve_id: solve.id, outcome: \"rejected\", reason: \"...\" });\n * ```\n */\n report: (report: FeedbackReport, options: { signal?: AbortSignal } = {}): Promise<Feedback> => {\n const { solve_id, ...fields } = report;\n return this.#request<Feedback>(\n \"POST\",\n `/v1/solves/${encodeURIComponent(solve_id)}/feedback`,\n { body: toWireFields(fields), signal: options.signal },\n );\n },\n\n /**\n * Report many verdicts at once — the path to use at volume. Buffer verdicts\n * as you learn them and flush them here.\n *\n * The call succeeds even when individual items are rejected: each is\n * resolved on its own so one stale id never discards the rest. Check\n * `failed` rather than relying on a thrown error.\n *\n * More than {@link FEEDBACK_BATCH_MAX} reports are split across sequential\n * requests and merged into one result, in request order. An empty array is\n * a no-op that returns an empty batch without a request.\n *\n * ```ts\n * const batch = await nc.feedback.reportMany(buffer);\n * if (batch.failed) console.warn(batch.results.filter((r) => r.status === \"error\"));\n * ```\n */\n reportMany: async (\n reports: readonly FeedbackReport[],\n options: { signal?: AbortSignal } = {},\n ): Promise<FeedbackBatch> => {\n const merged: FeedbackBatch = {\n object: \"feedback_batch\",\n recorded: 0,\n updated: 0,\n unchanged: 0,\n failed: 0,\n results: [],\n };\n // Chunks are sent in order and the server upserts last-write-wins, so a\n // solve reported twice still ends at its last value. Duplicates split\n // across a chunk boundary each get written, though, so the earlier one\n // reports `recorded`/`updated` where a single request would say\n // `unchanged`.\n for (let i = 0; i < reports.length; i += FEEDBACK_BATCH_MAX) {\n const batch = await this.#request<FeedbackBatch>(\"POST\", \"/v1/feedback\", {\n body: { feedback: reports.slice(i, i + FEEDBACK_BATCH_MAX).map(toWireReport) },\n signal: options.signal,\n });\n merged.recorded += batch.recorded;\n merged.updated += batch.updated;\n merged.unchanged += batch.unchanged;\n merged.failed += batch.failed;\n merged.results.push(...batch.results);\n }\n return merged;\n },\n };\n\n /** Fetch your account, including the current credit balance. */\n me(options: { signal?: AbortSignal } = {}): Promise<Account> {\n return this.#request<Account>(\"GET\", \"/v1/me\", { signal: options.signal });\n }\n\n /**\n * Recognize a challenge's images: send the instruction and images, get the\n * answer back in the same response. No token, no polling.\n *\n * An answered call's charge is final. Throws {@link RecognitionFailedError}\n * when no answer came back (nothing is charged then), {@link ValidationError}\n * for a malformed request.\n *\n * ```ts\n * const { id, data } = await nc.recognize({\n * type: \"hcaptcha\",\n * task: \"Please click each image containing a bus\",\n * image_data: tiles, // base64\n * });\n * ```\n */\n recognize(params: RecognizeBinaryParams, options?: { signal?: AbortSignal }): Promise<RecognizeBinaryResult>;\n recognize(params: RecognizeAreaSelectParams, options?: { signal?: AbortSignal }): Promise<RecognizeAreaSelectResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_label_binary\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistBinaryResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_label_area_select\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistAreaSelectResult>;\n recognize(\n params: RecognizeTasklistParams<\"image_drag_drop\">,\n options?: { signal?: AbortSignal },\n ): Promise<RecognizeTasklistDragDropResult>;\n recognize(params: RecognizeParams, options?: { signal?: AbortSignal }): Promise<RecognizeResult>;\n recognize(params: RecognizeParams, options: { signal?: AbortSignal } = {}): Promise<RecognizeResult> {\n return this.#request<RecognizeResult>(\"POST\", \"/v1/recognize\", {\n body: params,\n signal: options.signal,\n });\n }\n\n /**\n * Report whether a {@link NoneCap.recognize} answer worked on the challenge.\n * Optional and free; it feeds NoneCap's accuracy stats and never refunds the\n * call. The first report for an id sticks: a repeat returns it unchanged.\n */\n reportRecognitionOutcome(\n id: string,\n result: RecognitionOutcome,\n options: { signal?: AbortSignal } = {},\n ): Promise<RecognitionOutcomeResult> {\n return this.#request<RecognitionOutcomeResult>(\"POST\", \"/v1/recognize/outcome\", {\n body: { id, result },\n signal: options.signal,\n });\n }\n\n /**\n * Submit a solve and wait for it to finish, returning the solved solve.\n *\n * Uses the server's long-poll under the hood and keeps polling until the\n * solve is terminal or `timeout` elapses. Throws {@link SolveFailedError} if\n * the solve fails/expires/is cancelled, or {@link TimeoutError} on timeout.\n *\n * This is sugar for `(await solves.start(params)).result(options)`. When you\n * need to cancel the solve while it runs, use {@link NoneCap.solves.start}\n * and keep the {@link SolveHandle}.\n */\n async solve(params: SolveCreateParams, options: SolveHelperOptions = {}): Promise<Solve> {\n const handle = await this.solves.start(params, { signal: options.signal });\n return handle.result(options);\n }\n\n // -- internals ------------------------------------------------------------\n\n #timeoutForWait(wait?: number): number | undefined {\n if (wait === undefined) return undefined;\n // Give the socket a margin beyond the server's long-poll window.\n return wait * 1000 + 15_000;\n }\n\n async *#listAll(\n params: SolveListParams,\n options: { signal?: AbortSignal },\n ): AsyncIterableIterator<Solve> {\n let cursor = params.starting_after;\n for (;;) {\n const page = await this.solves.list({ ...params, starting_after: cursor }, options);\n for (const solve of page.data) yield solve;\n if (!page.has_more || page.data.length === 0) return;\n cursor = page.data[page.data.length - 1]!.id;\n }\n }\n\n async #request<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const url = new URL(this.#baseURL + path);\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== \"\") url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n Accept: \"application/json\",\n // Browsers drop this as a forbidden header; on Node it identifies the SDK.\n \"User-Agent\": USER_AGENT,\n };\n let bodyInit: string | undefined;\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyInit = JSON.stringify(options.body);\n }\n\n const controller = new AbortController();\n const timeoutMs = options.timeout ?? this.#timeout;\n const timer = setTimeout(() => controller.abort(new TimeoutError(`Request timed out after ${timeoutMs}ms.`)), timeoutMs);\n const onAbort = () => controller.abort(options.signal?.reason);\n if (options.signal) {\n if (options.signal.aborted) onAbort();\n else options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n let res: Response;\n try {\n res = await this.#fetch(url.toString(), {\n method,\n headers,\n body: bodyInit,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof TimeoutError) throw err;\n if (isAbort(err)) {\n // A caller-supplied signal aborting surfaces as the caller's reason.\n if (options.signal?.aborted) throw options.signal.reason instanceof Error\n ? options.signal.reason\n : new NoneCapError(\"Request aborted.\");\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms.`);\n }\n throw new ConnectionError(\n `Could not reach the NoneCap API at ${this.#baseURL}: ${(err as Error).message}`,\n );\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n return this.#parse<T>(res, options.expect ?? []);\n }\n\n async #parse<T>(res: Response, expect: number[]): Promise<T> {\n const text = await res.text();\n let json: unknown;\n if (text) {\n try {\n json = JSON.parse(text);\n } catch {\n throw new APIError(\n `Unexpected non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n { status: res.status },\n );\n }\n }\n\n if (res.ok || expect.includes(res.status)) {\n return json as T;\n }\n\n const envelope = json as\n | { error?: { code?: ErrorCode; message?: string; param?: string | null; request_id?: string } }\n | undefined;\n const apiError = envelope?.error;\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw !== null && /^\\d+$/.test(retryAfterRaw) ? Number(retryAfterRaw) : undefined;\n throw errorFromResponse(\n res.status,\n apiError?.code,\n apiError?.message ?? `HTTP ${res.status}`,\n apiError?.param ?? null,\n { requestId: apiError?.request_id ?? res.headers.get(\"x-request-id\") ?? undefined, retryAfter },\n );\n }\n}\n\n/**\n * A handle on a started solve, returned by {@link NoneCap.solves.start}.\n *\n * The handle is the cancellable lifecycle object for one solve. It is a plain\n * object, not a promise: `await`ing it does nothing useful. Wait for the result\n * with {@link SolveHandle.result}, and cancel with {@link SolveHandle.cancel}.\n * You do not construct it yourself — `solves.start()` hands you one with `id`\n * already resolved.\n */\nexport class SolveHandle {\n /** The id of the started solve, available as soon as `start()` resolved. */\n readonly id: string;\n\n readonly #client: NoneCap;\n /** The latest solve state we have seen, from the create, polls, or cancel. */\n #solve: Solve;\n /**\n * The cached TERMINAL outcome: resolves to the solved solve, or rejects with\n * {@link SolveFailedError} if terminal-but-not-solved. Only ever set once the\n * solve actually reaches a terminal state, so it is safe to replay forever. A\n * timed-out wait does NOT settle this — it is retryable.\n */\n #terminal: Promise<Solve> | undefined;\n /** The poll currently in flight, shared by concurrent result() callers. */\n #inflight: Promise<Solve> | undefined;\n\n constructor(client: NoneCap, solve: Solve) {\n this.#client = client;\n this.#solve = solve;\n this.id = solve.id;\n }\n\n /** The last-known solve state for this handle. */\n get solve(): Solve {\n return this.#solve;\n }\n\n /**\n * Long-poll until the solve is terminal, returning the solved solve. Throws\n * {@link SolveFailedError} if it fails/expires/is cancelled, or\n * {@link TimeoutError} on timeout (with `solveId`/`solve` attached so you can\n * still {@link SolveHandle.cancel} it).\n *\n * Memoizes the *terminal* outcome: once the solve actually finishes, every\n * later call returns that same settled result. A {@link TimeoutError} is not\n * memoized — it just means this wait gave up, so a later call (e.g. with a\n * larger `timeout`) resumes polling. Concurrent calls share one in-flight\n * poll, so they never issue duplicate requests. The first caller's\n * `timeout`/`signal` drive the shared poll; a later call starts a fresh one.\n */\n result(options: SolveHelperOptions = {}): Promise<Solve> {\n if (this.#terminal) return this.#terminal;\n if (this.#inflight) return this.#inflight;\n const run = this.#poll(options).finally(() => {\n // Free the slot so a retry can re-poll after a timeout; a terminal\n // outcome is already memoized in #terminal and wins on the next call.\n if (this.#inflight === run) this.#inflight = undefined;\n });\n this.#inflight = run;\n return run;\n }\n\n /**\n * Cancel the solve. Cancelled solves are never charged, so this is for clean\n * shutdown / freeing slots / stopping early, not cost protection.\n *\n * If the solve already reached a terminal state the API answers 409; that is\n * not an error a caller cares about, so this swallows {@link ConflictError}\n * and returns the current solve state instead. A cancel that lands on a\n * terminal state (cancelled, or whatever the 409-swallow read back) settles\n * this handle's {@link SolveHandle.result}, so any in-flight or later wait\n * stops polling and reflects that terminal state.\n */\n async cancel(options: { signal?: AbortSignal } = {}): Promise<Solve> {\n try {\n this.#solve = await this.#client.solves.cancel(this.id, options);\n } catch (err) {\n if (!(err instanceof ConflictError)) throw err;\n // Already terminal — report the real state rather than the 409.\n this.#solve = await this.#client.solves.retrieve(this.id, options);\n }\n if (!this.#terminal && isTerminal(this.#solve.status)) this.#cacheTerminal();\n return this.#solve;\n }\n\n /**\n * Build and memoize the terminal outcome from the current `#solve`. The\n * precondition is that `#solve` is terminal and `#terminal` is unset.\n */\n #cacheTerminal(): Promise<Solve> {\n const settled =\n this.#solve.status === \"solved\"\n ? Promise.resolve(this.#solve)\n : Promise.reject(new SolveFailedError(this.#solve));\n // Never let the memoized rejection surface as an unhandled rejection; real\n // callers read it explicitly through result().\n settled.catch(() => {});\n this.#terminal = settled;\n return settled;\n }\n\n async #poll(options: SolveHelperOptions): Promise<Solve> {\n const timeout = options.timeout ?? 180_000;\n const deadline = Date.now() + timeout;\n\n for (;;) {\n // cancel() (or a previous poll) may have already settled this handle.\n if (this.#terminal) return this.#terminal;\n if (isTerminal(this.#solve.status)) return this.#cacheTerminal();\n if (Date.now() >= deadline) {\n throw new TimeoutError(\n `Solve ${this.id} did not finish within ${timeout}ms (last status: ${this.#solve.status}).`,\n { solveId: this.id, solve: this.#solve },\n );\n }\n this.#solve = await this.#client.solves.retrieve(this.id, {\n wait: waitSeconds(deadline),\n signal: options.signal,\n });\n }\n }\n}\n\n/**\n * The `wait` value for the next long-poll: whole seconds until `deadline`,\n * clamped to the server's 1–90 window. The floor of 1 keeps the param valid,\n * so callers must decide whether the deadline has passed with the clock, not\n * with this return value.\n */\nfunction waitSeconds(deadline: number): number {\n const remaining = Math.ceil((deadline - Date.now()) / 1000);\n return Math.max(1, Math.min(MAX_WAIT_SECONDS, remaining));\n}\n\nfunction isAbort(err: unknown): boolean {\n return err instanceof Error && err.name === \"AbortError\";\n}\n\n/** The fields of a report, ready for the wire: a `Date` becomes an ISO string. */\nfunction toWireFields(fields: Omit<FeedbackReport, \"solve_id\">): Record<string, unknown> {\n const wire: Record<string, unknown> = { outcome: fields.outcome };\n if (fields.reason !== undefined) wire.reason = fields.reason;\n if (fields.context !== undefined) wire.context = fields.context;\n if (fields.reported_at !== undefined) {\n wire.reported_at =\n fields.reported_at instanceof Date ? fields.reported_at.toISOString() : fields.reported_at;\n }\n return wire;\n}\n\nfunction toWireReport(report: FeedbackReport): Record<string, unknown> {\n const { solve_id, ...fields } = report;\n return { solve_id, ...toWireFields(fields) };\n}\n"]}
|