@hunt-labs/bytekit-sdk 0.2.2 → 0.4.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/CHANGELOG.md +117 -0
- package/README.md +80 -10
- package/dist/allowlist.d.ts +1 -1
- package/dist/allowlist.js +7 -0
- package/dist/client.d.ts +100 -6
- package/dist/client.js +202 -49
- package/dist/generated/api.d.ts +17 -7
- package/dist/index.d.ts +9 -7
- package/dist/index.js +0 -2
- package/dist/resources/account.d.ts +16 -11
- package/dist/resources/account.js +20 -15
- package/dist/resources/bulk.d.ts +24 -8
- package/dist/resources/bulk.js +14 -9
- package/dist/resources/fetch.d.ts +127 -10
- package/dist/resources/fetch.js +67 -19
- package/dist/resources/monitors.d.ts +69 -11
- package/dist/resources/monitors.js +27 -14
- package/dist/resources/query-string.d.ts +10 -0
- package/dist/resources/query-string.js +20 -0
- package/dist/resources/scrape.d.ts +48 -9
- package/dist/resources/scrape.js +10 -5
- package/dist/resources/screenshots.d.ts +42 -5
- package/dist/resources/screenshots.js +44 -5
- package/dist/resources/search.d.ts +9 -4
- package/dist/resources/search.js +8 -3
- package/dist/resources/sitemap.d.ts +41 -5
- package/dist/resources/sitemap.js +23 -5
- package/dist/resources/usage.d.ts +36 -0
- package/dist/resources/usage.js +30 -0
- package/dist/resources/webhooks.d.ts +25 -0
- package/dist/resources/webhooks.js +20 -0
- package/dist/types.d.ts +7 -4
- package/dist/types.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,122 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
This file records only the delta between versions. For how to use the package
|
|
9
9
|
today, see [README.md](./README.md), which remains the authoritative usage guide.
|
|
10
10
|
|
|
11
|
+
## [0.4.0] - 2026-07-24
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `RequestOptions` (per-call `requestTimeoutMs` + caller `signal`) is now accepted by
|
|
16
|
+
**every** resource method, not just `scrape.create` / `scrape.get`. It is always a
|
|
17
|
+
trailing optional parameter — on `screenshots.create` it is the third positional, after
|
|
18
|
+
`params` — so every existing call site compiles and serializes byte-identically. Per-call
|
|
19
|
+
options continue to beat the constructor's `timeoutMs` default; omitting them leaves the
|
|
20
|
+
constructor default in force exactly as before. (#2547)
|
|
21
|
+
- `ApiResponse<T>` (`{ data, headers, status }`), a generic `client.requestWithResponse<T>()`
|
|
22
|
+
transport, and three typed siblings — `sitemap.getWithResponse`,
|
|
23
|
+
`screenshots.createWithResponse`, `screenshots.getWithResponse` — make the documented
|
|
24
|
+
`X-Raw-Bytes`, `X-Billable-Bytes`, `X-Billing-Multiplier` and `X-Screenshot-*` response
|
|
25
|
+
headers reachable. This surface is purely **additive**: it issues the identical request
|
|
26
|
+
with the identical options as the base method, and no existing return type changes.
|
|
27
|
+
(#2547)
|
|
28
|
+
- `MonitorStatus` and `ScrapeCookie` are exported from the package entrypoint. (#2547)
|
|
29
|
+
|
|
30
|
+
### Changed (**BREAKING** at compile time)
|
|
31
|
+
|
|
32
|
+
- `ScrapeOpts.cookies` is now `ScrapeCookie[]`, derived from the spec's `Cookie` schema
|
|
33
|
+
(`name` and `value` required; `domain`, `path`, `secure`, `httpOnly` optional), instead of
|
|
34
|
+
an open bag of untyped records. A cookie missing `name` used to compile and fail as a 422
|
|
35
|
+
on the wire; it is a compile error now. Serialization is unchanged. (#2547)
|
|
36
|
+
- `ListMonitorsParams.status` is now the spec enum
|
|
37
|
+
(`'active' | 'processing' | 'paused' | 'cancelled' | 'suspended'`), derived from the
|
|
38
|
+
generated `listMonitors` query type, instead of `string`. A typo like `'activee'` used to
|
|
39
|
+
compile and 422; it is a compile error now. The serialized query string is unchanged.
|
|
40
|
+
(#2547)
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- `timeoutMs` / `requestTimeoutMs` (and a caller-supplied `signal`) now cover the
|
|
45
|
+
**response body read**, not just the time to first byte of headers. The abort budget was
|
|
46
|
+
armed for `fetch` and cleared the moment headers arrived, after which `request()`'s
|
|
47
|
+
`response.text()`, `requestRaw()`'s `response.arrayBuffer()`, and the error-body
|
|
48
|
+
`response.json()` on a non-2xx all read the body unbounded — so a server that answered
|
|
49
|
+
with headers and then stalled its body hung the caller forever. A mid-body abort now
|
|
50
|
+
surfaces as `ByteKitConnectionError` with `code: 'timeout'` (budget) or `'aborted'`
|
|
51
|
+
(caller signal) instead of a bare `TypeError: terminated`.
|
|
52
|
+
|
|
53
|
+
The default is **unchanged at 120 s**, and the precedence table for
|
|
54
|
+
`signal` / `requestTimeoutMs` / `timeoutMs` is untouched. One consequence worth planning
|
|
55
|
+
for: a legitimately large body (a multi-MB `/v1/fetch` document) now counts against that
|
|
56
|
+
same budget, where previously only the wait for headers did. (#2546)
|
|
57
|
+
|
|
58
|
+
- The README's webhook-retry sample used an invalid delivery id prefix (`whd_`) that its own
|
|
59
|
+
branded type rejects. The sample is corrected, and a new test compiles every TypeScript
|
|
60
|
+
sample in the README against the SDK's sources so a non-compiling sample can no longer
|
|
61
|
+
ship. (#2547)
|
|
62
|
+
|
|
63
|
+
### Fixed (**BREAKING** at compile time)
|
|
64
|
+
|
|
65
|
+
- `fetch.get` no longer accepts the eleven markdown-tuning options (`markdown_mode`,
|
|
66
|
+
`markdown_query`, `markdown_links`, `markdown_images`, `with_links_summary`,
|
|
67
|
+
`with_images_summary`, `markdown_compact`, `markdown_filter_images`,
|
|
68
|
+
`markdown_include_media`, `markdown_include_warnings`, `markdown_include_stats`).
|
|
69
|
+
The spec's `GET /v1/fetch` declares only `url`, `format`, `country`, `timeout_ms`
|
|
70
|
+
and `cache_ttl`, so those options were silently dropped by the query builder — a
|
|
71
|
+
caller asking for `markdown_mode: 'llm'` compiled and received default article-mode
|
|
72
|
+
markdown. They are now compile errors instead of silent no-ops; use `fetch.create`
|
|
73
|
+
(POST), which accepts and serializes all of them unchanged. `FetchGetOpts` is now
|
|
74
|
+
derived from the generated `getFetch` query type, so future spec drift fails
|
|
75
|
+
`tsc --noEmit` rather than reaching production. (#2539)
|
|
76
|
+
|
|
77
|
+
## [0.3.0] - 2026-07-21
|
|
78
|
+
|
|
79
|
+
### Removed (**BREAKING**)
|
|
80
|
+
|
|
81
|
+
- The deprecated `RapidCrawl`, `RapidCrawlError`, and `RapidCrawlConnectionError`
|
|
82
|
+
exports and the `RapidCrawlOptions` type alias (kept as a one-minor-version
|
|
83
|
+
bridge in #2421) are removed. Import the `ByteKit*` names instead. (#2473)
|
|
84
|
+
- The `RecordingId` type export is removed. Recordings are deactivated
|
|
85
|
+
(`/v1/recordings` returns 410), so the branded id had no reachable use.
|
|
86
|
+
Breaking in theory only — unused in practice. (#2481)
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- `fetch.create` / `fetch.get` no longer throw a bare `SyntaxError` on every
|
|
91
|
+
non-JSON body. `/v1/fetch` returns the fetched content AS the response body
|
|
92
|
+
(metadata in `X-Fetch-*` headers), but both methods routed through the
|
|
93
|
+
JSON-parsing transport. They now use a raw-capable transport and resolve to a
|
|
94
|
+
typed `FetchResult` — raw `body`, byte-exact `bytes`, plus `id`,
|
|
95
|
+
`creditsCharged`, `cache`, `custom`, `contentType`, and `headers` parsed from
|
|
96
|
+
the `X-Fetch-*` metadata. (#2466)
|
|
97
|
+
- A trailing slash on the constructor `baseUrl` (e.g. `"https://api.bytekit.com/"`)
|
|
98
|
+
no longer produces double-slash request URLs — it is normalized once, preserving
|
|
99
|
+
a path-carrying baseUrl. (#2481)
|
|
100
|
+
- `SearchResult.date` is now optional (`string | null | undefined`): `images`
|
|
101
|
+
search results omit the field entirely. (#2481)
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
|
|
105
|
+
- New `usage` resource (`get`, `daily`, `byEndpoint` — `GET /v1/usage`,
|
|
106
|
+
`/v1/usage/daily`, `/v1/usage/by-endpoint`) and `webhooks` resource (`list`,
|
|
107
|
+
`retry` — `GET /v1/webhook-deliveries`, `POST /v1/webhook-deliveries/{id}/retry`),
|
|
108
|
+
with their request/response types exported. (#2471)
|
|
109
|
+
- `ScrapeOpts` and `FetchOpts` now cover the full documented request field set
|
|
110
|
+
(10 previously missing `ScrapeRequest` fields; 11 markdown-tuning
|
|
111
|
+
`FetchRequest` fields), plus the `'text'` markdown-links mode. A compile-time
|
|
112
|
+
drift guard keeps them aligned with the generated OpenAPI schema. (#2475)
|
|
113
|
+
- `monitors`, `sitemap`, `bulk`, and `fetch.bulk` methods are now fully typed from
|
|
114
|
+
the generated OpenAPI `operations` (previously `Record<string, unknown>` in /
|
|
115
|
+
`Promise<unknown>` out); their request/response types are re-exported. (#2481)
|
|
116
|
+
- `monitors.list` accepts typed query params and returns a typed response
|
|
117
|
+
(`ListMonitorsParams` / `ListMonitorsResponse`, both exported). (#2480)
|
|
118
|
+
|
|
119
|
+
### Changed (**BREAKING**)
|
|
120
|
+
|
|
121
|
+
- `fetch.get` now rejects a `custom` option at compile time: `GET /v1/fetch` has
|
|
122
|
+
no `custom` query param, so the value was silently dropped before. Use
|
|
123
|
+
`fetch.create` (POST) to echo a `custom` payload. (#2481)
|
|
124
|
+
- `FetchOpts.format` is narrowed from `string` to the spec union
|
|
125
|
+
`'markdown' | 'html'`; off-spec values now fail to compile. (#2475)
|
|
126
|
+
|
|
11
127
|
## [0.2.2] - 2026-07-16
|
|
12
128
|
|
|
13
129
|
### Changed
|
|
@@ -85,6 +201,7 @@ against 0.1.0 — read each one before upgrading.
|
|
|
85
201
|
(scrape, screenshot, search, and related endpoints), published under the original
|
|
86
202
|
`@rapidcrawl/sdk` name.
|
|
87
203
|
|
|
204
|
+
[0.3.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
|
|
88
205
|
[0.2.2]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
|
|
89
206
|
[0.2.1]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
|
|
90
207
|
[0.2.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
|
package/README.md
CHANGED
|
@@ -27,16 +27,15 @@ Create an API key at [app.bytekit.com](https://app.bytekit.com) (keys are
|
|
|
27
27
|
prefixed `sk_live_`) and pass it to the client constructor:
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
|
-
import {
|
|
30
|
+
import { ByteKit } from '@hunt-labs/bytekit-sdk';
|
|
31
31
|
|
|
32
|
-
const client = new
|
|
32
|
+
const client = new ByteKit({ apiKey: process.env.BYTEKIT_API_KEY! }); // sk_live_...
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
The key is sent as `Authorization: Bearer <apiKey>` on every request. Keep it
|
|
36
36
|
server-side — it is not safe to ship in a browser bundle.
|
|
37
37
|
|
|
38
|
-
>
|
|
39
|
-
> previous product name). It is the SDK's only entrypoint class.
|
|
38
|
+
> `ByteKit` is the SDK's only entrypoint class.
|
|
40
39
|
|
|
41
40
|
## Base-URL override
|
|
42
41
|
|
|
@@ -44,7 +43,7 @@ Requests go to `https://api.bytekit.com` by default. Point the client at
|
|
|
44
43
|
staging, a local gateway, or a proxy with the `baseUrl` option:
|
|
45
44
|
|
|
46
45
|
```ts
|
|
47
|
-
const client = new
|
|
46
|
+
const client = new ByteKit({
|
|
48
47
|
apiKey: process.env.BYTEKIT_API_KEY!,
|
|
49
48
|
baseUrl: 'https://api-stg.bytekit.com', // default: https://api.bytekit.com
|
|
50
49
|
});
|
|
@@ -69,8 +68,27 @@ const scrape = await client.scrape.get('sc_123abc');
|
|
|
69
68
|
|
|
70
69
|
### Raw fetch (unprocessed response body)
|
|
71
70
|
|
|
71
|
+
`/v1/fetch` returns the fetched content **as the body**, with metadata in
|
|
72
|
+
`X-Fetch-*` response headers. `fetch.create` / `fetch.get` resolve a
|
|
73
|
+
`FetchResult` — `body` is the raw content string (a JSON-serving upstream
|
|
74
|
+
comes back as the raw JSON string, never a parsed object), and the named
|
|
75
|
+
fields decode the metadata headers. `body` is UTF-8-decoded, so for true
|
|
76
|
+
binary content (images, PDFs, etc. — `/v1/fetch` supports raw passthrough)
|
|
77
|
+
use `bytes` instead, which is byte-for-byte identical to the wire content:
|
|
78
|
+
|
|
72
79
|
```ts
|
|
73
|
-
const
|
|
80
|
+
const res = await client.fetch.create({ url: 'https://example.com' });
|
|
81
|
+
|
|
82
|
+
console.log(res.body); // raw content (e.g. "<!doctype html>…") — UTF-8 decoded
|
|
83
|
+
console.log(res.bytes); // Uint8Array — byte-exact, safe for binary content
|
|
84
|
+
console.log(res.id); // X-Fetch-ID, e.g. "ft_0123abcd…"
|
|
85
|
+
console.log(res.creditsCharged); // X-Fetch-Credits-Charged, as a number
|
|
86
|
+
console.log(res.cache); // "hit" | "miss" | "bypass"
|
|
87
|
+
console.log(res.custom); // base64 X-Fetch-Custom echo, or null
|
|
88
|
+
console.log(res.contentType); // response Content-Type, e.g. "text/html"
|
|
89
|
+
|
|
90
|
+
// Anything not surfaced as a named field is on res.headers:
|
|
91
|
+
console.log(res.headers.get('X-Fetch-Waf-Vendor'));
|
|
74
92
|
```
|
|
75
93
|
|
|
76
94
|
### Web search
|
|
@@ -124,7 +142,10 @@ await client.bulk.screenshots.list('bulk_123abc');
|
|
|
124
142
|
```ts
|
|
125
143
|
const monitor = await client.monitors.create({
|
|
126
144
|
url: 'https://example.com/pricing',
|
|
145
|
+
type: 'screenshot',
|
|
127
146
|
interval_type: 'daily',
|
|
147
|
+
change_threshold: 5,
|
|
148
|
+
notify_on: 'change',
|
|
128
149
|
webhook_url: 'https://your.app/hooks/bytekit',
|
|
129
150
|
});
|
|
130
151
|
await client.monitors.list();
|
|
@@ -134,7 +155,17 @@ await client.monitors.delete('mon_123abc');
|
|
|
134
155
|
### Sitemap crawl
|
|
135
156
|
|
|
136
157
|
```ts
|
|
137
|
-
|
|
158
|
+
// `url` is the only required field — every other option can be omitted.
|
|
159
|
+
const minimal = await client.sitemap.create({ url: 'https://example.com' });
|
|
160
|
+
|
|
161
|
+
const crawl = await client.sitemap.create({
|
|
162
|
+
url: 'https://example.com',
|
|
163
|
+
strategy: 'standard',
|
|
164
|
+
max_depth: 2,
|
|
165
|
+
max_urls: 5000,
|
|
166
|
+
cache_ttl: '30d',
|
|
167
|
+
compact: false,
|
|
168
|
+
});
|
|
138
169
|
const sitemap = await client.sitemap.get('sm_123abc');
|
|
139
170
|
```
|
|
140
171
|
|
|
@@ -143,20 +174,59 @@ const sitemap = await client.sitemap.get('sm_123abc');
|
|
|
143
174
|
```ts
|
|
144
175
|
const account = await client.account.get();
|
|
145
176
|
const keys = await client.account.apiKeys.list();
|
|
177
|
+
|
|
178
|
+
// Usage (Bearer API key auth)
|
|
179
|
+
const usage = await client.usage.get();
|
|
180
|
+
const daily = await client.usage.daily({ from: '2026-01-01', to: '2026-01-31' });
|
|
181
|
+
const byEndpoint = await client.usage.byEndpoint();
|
|
182
|
+
|
|
183
|
+
// Webhook deliveries
|
|
184
|
+
const deliveries = await client.webhooks.list();
|
|
185
|
+
await client.webhooks.retry('wh_123abc');
|
|
146
186
|
```
|
|
147
187
|
|
|
188
|
+
> **Note:** `client.account.*` (including `client.account.apiKeys.*`) targets the
|
|
189
|
+
> `/v1/account/*` endpoints, which authenticate with a Clerk dashboard session —
|
|
190
|
+
> **not** a Bearer API key. Calling them with an API-key client will fail auth.
|
|
191
|
+
> They remain on the SDK surface for dashboard/session consumers and are marked
|
|
192
|
+
> `x-sdk-scope: internal` in the spec, so they are intentionally excluded from the
|
|
193
|
+
> v0.1 Bearer-key parity guarantee.
|
|
194
|
+
|
|
195
|
+
### Response headers
|
|
196
|
+
|
|
197
|
+
The API carries billing and capture metadata in `X-*` response headers alongside the
|
|
198
|
+
JSON body — `X-Raw-Bytes`, `X-Billable-Bytes`, `X-Billing-Multiplier`, and the
|
|
199
|
+
`X-Screenshot-*` family. Every resource method returns just the parsed body, so use a
|
|
200
|
+
`*WithResponse` sibling when you also need the headers:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
const { data, headers, status } = await client.sitemap.getWithResponse('sm_123abc');
|
|
204
|
+
|
|
205
|
+
console.log(data.status); // exactly what sitemap.get('sm_123abc') resolves to
|
|
206
|
+
console.log(headers.get('X-Raw-Bytes')); // e.g. "12345"
|
|
207
|
+
console.log(status); // 200
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`client.screenshots.createWithResponse()` and `client.screenshots.getWithResponse()`
|
|
211
|
+
work the same way. Any other endpoint's headers are reachable through the generic
|
|
212
|
+
transport, `client.requestWithResponse('GET', '/v1/scrape/sc_123abc')`.
|
|
213
|
+
|
|
214
|
+
These siblings are purely additive: they issue the identical request and accept the
|
|
215
|
+
identical options as their base methods, and `data` is exactly what the base method
|
|
216
|
+
resolves to — no existing return type changes.
|
|
217
|
+
|
|
148
218
|
## Error handling
|
|
149
219
|
|
|
150
|
-
Any 4xx/5xx response throws a `
|
|
220
|
+
Any 4xx/5xx response throws a `ByteKitError` carrying the HTTP status and
|
|
151
221
|
the API's error code:
|
|
152
222
|
|
|
153
223
|
```ts
|
|
154
|
-
import {
|
|
224
|
+
import { ByteKit, ByteKitError } from '@hunt-labs/bytekit-sdk';
|
|
155
225
|
|
|
156
226
|
try {
|
|
157
227
|
await client.scrape.create({ url: 'https://example.com' });
|
|
158
228
|
} catch (err) {
|
|
159
|
-
if (err instanceof
|
|
229
|
+
if (err instanceof ByteKitError) {
|
|
160
230
|
console.error(err.status, err.code, err.message);
|
|
161
231
|
}
|
|
162
232
|
}
|
package/dist/allowlist.d.ts
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
*
|
|
9
9
|
* To add a method: annotate the operation in the spec first, then add it here.
|
|
10
10
|
*/
|
|
11
|
-
export declare const V01_METHODS: readonly ["scrape.create", "scrape.get", "screenshots.create", "screenshots.get", "bulk.create", "bulk.get", "bulk.cancel", "bulk.screenshots.list", "scrape.bulk.create", "scrape.bulk.get", "fetch.create", "fetch.get", "fetch.bulk.create", "fetch.bulk.get", "monitors.create", "monitors.list", "monitors.get", "monitors.update", "monitors.delete", "monitors.captures.list", "sitemap.create", "sitemap.get", "search.query", "account.get"];
|
|
11
|
+
export declare const V01_METHODS: readonly ["scrape.create", "scrape.get", "screenshots.create", "screenshots.get", "bulk.create", "bulk.get", "bulk.cancel", "bulk.screenshots.list", "scrape.bulk.create", "scrape.bulk.get", "fetch.create", "fetch.get", "fetch.bulk.create", "fetch.bulk.get", "monitors.create", "monitors.list", "monitors.get", "monitors.update", "monitors.delete", "monitors.captures.list", "sitemap.create", "sitemap.get", "search.query", "account.get", "usage.get", "usage.daily", "usage.byEndpoint", "webhooks.list", "webhooks.retry"];
|
|
12
12
|
export type V01Method = (typeof V01_METHODS)[number];
|
package/dist/allowlist.js
CHANGED
|
@@ -34,4 +34,11 @@ export const V01_METHODS = [
|
|
|
34
34
|
'sitemap.get',
|
|
35
35
|
'search.query',
|
|
36
36
|
'account.get',
|
|
37
|
+
// usage + webhook-delivery ops — resource surface shipped in #2471, brought
|
|
38
|
+
// under the parity guard in #2476.
|
|
39
|
+
'usage.get',
|
|
40
|
+
'usage.daily',
|
|
41
|
+
'usage.byEndpoint',
|
|
42
|
+
'webhooks.list',
|
|
43
|
+
'webhooks.retry',
|
|
37
44
|
];
|
package/dist/client.d.ts
CHANGED
|
@@ -6,12 +6,16 @@ import { MonitorsResource } from './resources/monitors.js';
|
|
|
6
6
|
import { SitemapResource } from './resources/sitemap.js';
|
|
7
7
|
import { SearchResource } from './resources/search.js';
|
|
8
8
|
import { AccountResource } from './resources/account.js';
|
|
9
|
+
import { UsageResource } from './resources/usage.js';
|
|
10
|
+
import { WebhooksResource } from './resources/webhooks.js';
|
|
9
11
|
export interface ByteKitOptions {
|
|
10
12
|
apiKey: string;
|
|
11
13
|
baseUrl?: string;
|
|
12
14
|
/**
|
|
13
15
|
* Default CLIENT-SIDE request timeout in ms — the abort budget for the whole HTTP
|
|
14
|
-
* round-trip made by this SDK
|
|
16
|
+
* round-trip made by this SDK, covering time-to-headers **and** the response body
|
|
17
|
+
* read (so a large legitimate body counts against it too). `0` disables the SDK-side
|
|
18
|
+
* timeout. Default 120000.
|
|
15
19
|
*
|
|
16
20
|
* NOT the same thing as `ScrapeOpts.timeout_ms`, which is the SERVER-side budget the
|
|
17
21
|
* gateway applies to the scrape itself. Override per call with
|
|
@@ -24,12 +28,14 @@ export interface RequestOptions {
|
|
|
24
28
|
/**
|
|
25
29
|
* Caller-owned abort signal. When supplied WITHOUT a per-call `requestTimeoutMs`, it
|
|
26
30
|
* fully replaces the constructor timeout — supply `requestTimeoutMs` alongside it to
|
|
27
|
-
* keep a bound (the request then aborts on whichever fires first).
|
|
31
|
+
* keep a bound (the request then aborts on whichever fires first). Firing it aborts an
|
|
32
|
+
* in-flight response body read as well, not only the wait for headers.
|
|
28
33
|
*/
|
|
29
34
|
signal?: AbortSignal;
|
|
30
35
|
/**
|
|
31
|
-
* Per-call CLIENT-SIDE abort budget in ms
|
|
32
|
-
* `0` disables the SDK-side timeout for
|
|
36
|
+
* Per-call CLIENT-SIDE abort budget in ms, covering headers **and** the response body
|
|
37
|
+
* read. Wins over the constructor's `timeoutMs`. `0` disables the SDK-side timeout for
|
|
38
|
+
* this call.
|
|
33
39
|
*
|
|
34
40
|
* Deliberately NOT named `timeoutMs`: it rides on the same call as `ScrapeOpts.timeout_ms`
|
|
35
41
|
* (the SERVER-side scrape budget), and the two mean different things —
|
|
@@ -38,6 +44,29 @@ export interface RequestOptions {
|
|
|
38
44
|
*/
|
|
39
45
|
requestTimeoutMs?: number;
|
|
40
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* A JSON response together with its transport metadata (#2547).
|
|
49
|
+
*
|
|
50
|
+
* Returned by {@link ByteKit.requestWithResponse} and by the `*WithResponse` sibling
|
|
51
|
+
* methods. `data` is exactly what the corresponding base method resolves to, so a caller
|
|
52
|
+
* can migrate from `x = await r.get(id)` to `{ data: x, headers } = await
|
|
53
|
+
* r.getWithResponse(id)` with no change to how `x` is used.
|
|
54
|
+
*
|
|
55
|
+
* This is an ADDITIVE surface: it never changes the return type, the request bytes, or the
|
|
56
|
+
* abort semantics of any existing method.
|
|
57
|
+
*/
|
|
58
|
+
export interface ApiResponse<T> {
|
|
59
|
+
/** The parsed JSON body — identical to what the base method returns. `undefined` on 204/empty. */
|
|
60
|
+
data: T;
|
|
61
|
+
/**
|
|
62
|
+
* The full RESPONSE headers, e.g. `X-Raw-Bytes`, `X-Billable-Bytes`,
|
|
63
|
+
* `X-Billing-Multiplier`. The `Authorization` header lives on the REQUEST and is never
|
|
64
|
+
* reachable here.
|
|
65
|
+
*/
|
|
66
|
+
headers: Headers;
|
|
67
|
+
/** The HTTP status code of the successful response (2xx; non-2xx already threw). */
|
|
68
|
+
status: number;
|
|
69
|
+
}
|
|
41
70
|
/** Why a request never produced an HTTP response. */
|
|
42
71
|
export type ConnectionErrorCode = 'timeout' | 'aborted' | 'connection';
|
|
43
72
|
/** Thrown when the API responds with a 4xx or 5xx status code. */
|
|
@@ -71,6 +100,8 @@ export declare class ByteKit {
|
|
|
71
100
|
readonly sitemap: SitemapResource;
|
|
72
101
|
readonly search: SearchResource;
|
|
73
102
|
readonly account: AccountResource;
|
|
103
|
+
readonly usage: UsageResource;
|
|
104
|
+
readonly webhooks: WebhooksResource;
|
|
74
105
|
constructor(options: ByteKitOptions);
|
|
75
106
|
/**
|
|
76
107
|
* Resolve the abort budget for one request from the caller's options and the
|
|
@@ -86,6 +117,31 @@ export declare class ByteKit {
|
|
|
86
117
|
* A timeout of `0` (either level) means "no SDK-side timeout".
|
|
87
118
|
*/
|
|
88
119
|
private resolveSignal;
|
|
120
|
+
/**
|
|
121
|
+
* Perform the authenticated round-trip and return whatever the caller's `readBody`
|
|
122
|
+
* continuation makes of the successful response, having already thrown for the two
|
|
123
|
+
* non-body failure modes:
|
|
124
|
+
*
|
|
125
|
+
* - `ByteKitConnectionError` when no HTTP response was produced at all
|
|
126
|
+
* (DNS/socket/TLS failure, client-side timeout, or caller abort) — including one
|
|
127
|
+
* that fires while the body is streaming.
|
|
128
|
+
* - `ByteKitError` on any 4xx/5xx, carrying the API's `code`/`message`.
|
|
129
|
+
*
|
|
130
|
+
* The body is read through a continuation each caller supplies — JSON text for
|
|
131
|
+
* `request()`, raw bytes for `requestRaw()`. This is the single place that owns auth,
|
|
132
|
+
* the abort budget, and the error taxonomy; the two public transports differ only in
|
|
133
|
+
* how they read a successful body.
|
|
134
|
+
*
|
|
135
|
+
* The abort budget spans headers **and** body (#2546). Returning the `Response` used to
|
|
136
|
+
* end the guarded region at the headers boundary, leaving `response.text()` /
|
|
137
|
+
* `response.arrayBuffer()` — and the `!response.ok` branch's `response.json()` —
|
|
138
|
+
* unbounded: a server that sent headers and then stalled its body hung the caller
|
|
139
|
+
* forever. `readBody` must therefore ONLY consume the stream; `JSON.parse` and
|
|
140
|
+
* `TextDecoder` run in the callers, outside the guard, so a malformed body still
|
|
141
|
+
* surfaces its own parse error rather than being remapped to a connection error.
|
|
142
|
+
* `cleanup()` still runs exactly once per call, now after the body completes.
|
|
143
|
+
*/
|
|
144
|
+
private send;
|
|
89
145
|
/**
|
|
90
146
|
* Make an authenticated JSON request to the ByteKit API.
|
|
91
147
|
*
|
|
@@ -94,6 +150,44 @@ export declare class ByteKit {
|
|
|
94
150
|
* timeout, or caller abort).
|
|
95
151
|
*/
|
|
96
152
|
request<T>(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
153
|
+
/**
|
|
154
|
+
* Make an authenticated request whose response body IS the content, not a JSON
|
|
155
|
+
* envelope — the `/v1/fetch` contract, where metadata rides in `X-Fetch-*`
|
|
156
|
+
* response headers.
|
|
157
|
+
*
|
|
158
|
+
* Returns BOTH a UTF-8-decoded string AND the raw, byte-for-byte body, plus the
|
|
159
|
+
* response `Headers` and status, WITHOUT ever calling `JSON.parse`. This is
|
|
160
|
+
* deliberately a separate transport from `request()`: the generic JSON parse
|
|
161
|
+
* there is shared by every other resource and must not change (#2466).
|
|
162
|
+
*
|
|
163
|
+
* `/v1/fetch` supports true binary passthrough (images, PDFs, etc.) as a
|
|
164
|
+
* first-class mode, and UTF-8 decoding a non-UTF-8 byte stream is lossy — any
|
|
165
|
+
* invalid byte sequence gets silently replaced with U+FFFD. Reading the body
|
|
166
|
+
* once via `arrayBuffer()` lets both forms be derived from the same bytes: `bytes`
|
|
167
|
+
* is always byte-exact, `body` is a best-effort string for callers who know the
|
|
168
|
+
* content is text.
|
|
169
|
+
*/
|
|
170
|
+
requestRaw(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<{
|
|
171
|
+
body: string;
|
|
172
|
+
bytes: Uint8Array;
|
|
173
|
+
headers: Headers;
|
|
174
|
+
status: number;
|
|
175
|
+
}>;
|
|
176
|
+
/**
|
|
177
|
+
* Make an authenticated JSON request and return the parsed body TOGETHER WITH the
|
|
178
|
+
* response headers and status (#2547).
|
|
179
|
+
*
|
|
180
|
+
* Identical to {@link ByteKit.request} in every observable respect — same method, path,
|
|
181
|
+
* body, `RequestOptions` precedence, error taxonomy, and empty-body handling (both drain
|
|
182
|
+
* the body through {@link readSuccessText} and parse it through {@link parseJsonBody}). It
|
|
183
|
+
* differs only in what it returns, so nothing about an existing call changes by switching
|
|
184
|
+
* to it.
|
|
185
|
+
*
|
|
186
|
+
* Use it to read the documented `X-*` metadata the API emits alongside a JSON envelope —
|
|
187
|
+
* `X-Raw-Bytes`, `X-Billable-Bytes`, `X-Billing-Multiplier`, the `X-Screenshot-*` family
|
|
188
|
+
* — for any endpoint. `sitemap.getWithResponse`, `screenshots.createWithResponse` and
|
|
189
|
+
* `screenshots.getWithResponse` are typed shorthands over this for the endpoints whose
|
|
190
|
+
* headers are documented in the API reference.
|
|
191
|
+
*/
|
|
192
|
+
requestWithResponse<T>(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<ApiResponse<T>>;
|
|
97
193
|
}
|
|
98
|
-
export { ByteKit as RapidCrawl, ByteKitError as RapidCrawlError, ByteKitConnectionError as RapidCrawlConnectionError, };
|
|
99
|
-
export type { ByteKitOptions as RapidCrawlOptions };
|