@hunt-labs/bytekit-cli 0.5.0 → 0.6.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 +109 -0
- package/README.md +28 -6
- package/dist/client.d.ts +111 -5
- package/dist/client.js +232 -27
- package/dist/commands/bulk.js +22 -4
- package/dist/commands/fetch.js +75 -16
- package/dist/commands/monitors.js +26 -2
- package/dist/commands/scrape.js +24 -5
- package/dist/commands/screenshots.js +45 -1
- package/dist/commands/sitemap.js +24 -1
- package/dist/lib/download-artifact.d.ts +30 -1
- package/dist/lib/download-artifact.js +89 -5
- package/dist/lib/url-lines.d.ts +46 -8
- package/dist/lib/url-lines.js +58 -19
- package/dist/output.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,8 +8,113 @@ 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
|
+
## [Unreleased]
|
|
12
|
+
|
|
13
|
+
## [0.6.0] - 2026-07-29
|
|
14
|
+
|
|
15
|
+
### Breaking
|
|
16
|
+
|
|
17
|
+
- **`screenshots create --async` now exits `2` in human mode instead of `0`.** The queued 202 is
|
|
18
|
+
not a completed capture — there is no artifact yet — and every other queued path in the CLI
|
|
19
|
+
already signalled that with exit code `2` (`scrape create --async`). A script that relied on
|
|
20
|
+
exit `0` to mean "the screenshot is ready" was reading a false success; under `set -e` such a
|
|
21
|
+
script now stops at the queue step, which is the intended correction. The envelope itself is
|
|
22
|
+
unchanged and still printed. Two carve-outs: **`--json` keeps exit `0`** (the envelope is a
|
|
23
|
+
complete machine-readable payload — identical to `scrape create --async --json`), and
|
|
24
|
+
`--async -o <file>` also exits `2` while still writing no file (it prints the queued envelope
|
|
25
|
+
and skips the download, as before). Poll with `bytekit screenshots get <id>`.
|
|
26
|
+
- **A `--file` per-item key outside a bulk endpoint's own strict schema now fails the whole
|
|
27
|
+
create with a `422`** instead of silently succeeding with that key ignored. In 0.5.x, `--file`
|
|
28
|
+
never read anything but `url` from a JSON line — every other key was dropped client-side
|
|
29
|
+
before the request was ever built. As of 0.6.0 those keys ride to the server (`items` on
|
|
30
|
+
`bulk create` / `scrape bulk create`; inside `urls` on `fetch bulk create`), and `/v1/bulk` /
|
|
31
|
+
`/v1/scrape/bulk` reject any key their `.strict()` per-item schema doesn't recognize. A file
|
|
32
|
+
that worked in 0.5.x purely because its extra keys were quietly discarded may now `422` — see
|
|
33
|
+
each command's `--file` help for the keys actually honored on that endpoint.
|
|
34
|
+
- **`fetch bulk create --file` per-item keys outside `url`/`format`/`country`/`cache_ttl` now
|
|
35
|
+
fail the whole create with a `422`** instead of silently succeeding with that key ignored.
|
|
36
|
+
`/v1/fetch/bulk`'s per-item override schema (inside `urls[]`) is now `.strict()` on the
|
|
37
|
+
gateway (issue #2648), matching the `/v1/bulk` / `/v1/scrape/bulk` posture above. The
|
|
38
|
+
`--file` help text for `fetch bulk create` is now uniform with `bulk create` /
|
|
39
|
+
`scrape bulk create` and no longer enumerates keys — this entry is where the honored set
|
|
40
|
+
(`url`, `format`, `country`, `cache_ttl`) is documented instead.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- **Per-item bulk configuration on all three bulk creates** (`bulk create`, `scrape bulk create`,
|
|
45
|
+
`fetch bulk create`). A `--file` line may now be a JSON object carrying `url` plus per-item
|
|
46
|
+
fields instead of only a bare URL; such a file is sent as `items` on `/v1/bulk` and
|
|
47
|
+
`/v1/scrape/bulk`, and as a heterogeneous `urls` array on `/v1/fetch/bulk` (which has no
|
|
48
|
+
`items` property). A line whose only key is `url` still normalizes to a bare URL string, so a
|
|
49
|
+
file of url-only lines produces a byte-identical request to before. A JSON line with a missing
|
|
50
|
+
or non-string `url` is now rejected locally with a usage error (exit `1`) instead of being sent
|
|
51
|
+
to the server as a URL. (See Breaking, above, for the per-item strict-schema behavior change
|
|
52
|
+
this enables.)
|
|
53
|
+
- `--defaults`, `--webhook-secret` and `--metadata` on all three bulk creates, plus `--custom` on
|
|
54
|
+
`scrape bulk create` only (`/v1/bulk` and `/v1/fetch/bulk` have no top-level `custom`, so the
|
|
55
|
+
flag would be rejected or stripped there). `--defaults` is forwarded verbatim; the server owns
|
|
56
|
+
precedence and unknown-key handling.
|
|
57
|
+
- The full markdown-tuning surface on `fetch create`: `--markdown-query`, `--markdown-links`,
|
|
58
|
+
`--markdown-images`, `--with-links-summary`, `--with-images-summary`, `--markdown-compact`,
|
|
59
|
+
`--markdown-filter-images`, `--markdown-include-media`, `--markdown-include-warnings`,
|
|
60
|
+
`--markdown-include-stats`, and `--custom`.
|
|
61
|
+
- Webhook delivery and processing flags on `sitemap create`: `--webhook-url`, `--webhook-secret`,
|
|
62
|
+
`--cache-ttl`, `--compact`, `--process`, `--metadata`. Webhook-driven sitemap crawls were
|
|
63
|
+
previously unreachable from the shell.
|
|
64
|
+
- `--headers`, `--cookies` and `--metadata` on `screenshots create`.
|
|
65
|
+
- `--metadata` on `monitors create`, and `--metadata` + `--url` on `monitors update`. `--type`
|
|
66
|
+
remains deliberately absent from `update` — it is immutable server-side.
|
|
67
|
+
|
|
68
|
+
## [0.5.1] - 2026-07-28
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- **Corrects the scope of the 0.5.0 "stalled body" fix claim.** `screenshots create`/`get -o`
|
|
73
|
+
downloads the `image_url` artifact bytes with a bare `globalThis.fetch` call
|
|
74
|
+
(`lib/download-artifact.ts`) that sat entirely outside the transport seam `sendWithRetry` owns —
|
|
75
|
+
no abort signal, no connection-error taxonomy. The 0.5.0 entry below ("The per-attempt request
|
|
76
|
+
timeout now covers the response body read... a server that answered with headers and then
|
|
77
|
+
stalled its body... hung the CLI forever", #2546) reads as if it covered every response body; it
|
|
78
|
+
only ever covered API-call bodies read through the JSON/raw transports. A stalled artifact host
|
|
79
|
+
(headers, then a body that never completes) still hung the CLI indefinitely until now. The
|
|
80
|
+
download path now shares the same per-attempt abort budget and `ByteKitConnectionError` timeout
|
|
81
|
+
taxonomy as the API transport (`createAttemptBudget` / `toConnectionError`, exported from
|
|
82
|
+
`client.ts` — no second timeout implementation), with the same 120 s per-attempt default and no
|
|
83
|
+
retry (artifact GETs are not the API's 429 domain). Partial-file policy: the response is
|
|
84
|
+
buffered fully in memory before any write, so an aborted download never leaves a
|
|
85
|
+
partial/truncated file at the `-o` destination. **User-visible consequence:** a legitimately
|
|
86
|
+
slow (but not stalled) large artifact download now hard-fails after 120 s instead of waiting
|
|
87
|
+
indefinitely, and there is currently no CLI flag to raise that budget for a single command.
|
|
88
|
+
(#2587)
|
|
89
|
+
- While in the file: the 429-retry path left its (unread) response body undrained before sleeping
|
|
90
|
+
and retrying — undici cannot reclaim the underlying socket for connection-pool reuse until a body
|
|
91
|
+
is fully read. The body is now drained with `response.text()` on that path, bounded by its own
|
|
92
|
+
short (2 s) cap independent of the 120 s per-attempt budget, so a 429 whose body stalls can no
|
|
93
|
+
longer delay the retry by anywhere near the full attempt budget (or, with the budget disabled,
|
|
94
|
+
forever). **Correction to an intermediate `Unreleased` draft of this same fix:** that draft's cap
|
|
95
|
+
only bounded how long the _retry_ waited — it resolved on schedule but never touched the
|
|
96
|
+
abandoned `response.text()` call itself, which kept reading against a live socket indefinitely.
|
|
97
|
+
Because every CLI success path exits via a soft `process.exitCode` (#2544) rather than
|
|
98
|
+
`process.exit()`, that orphaned read kept the whole process alive forever — strictly worse than
|
|
99
|
+
having no drain at all, and on the exact class of hang this ticket exists to eliminate. The cap
|
|
100
|
+
now also **aborts** the request when it fires, so the abandoned read is actually torn down, not
|
|
101
|
+
merely ignored; this holds even when the per-attempt timeout itself is disabled
|
|
102
|
+
(`timeoutMs <= 0`). **User-visible consequence:** a 429 with a stalled body still costs the retry
|
|
103
|
+
at most ~2 s, exactly as before, but the CLI process now reliably exits afterward instead of
|
|
104
|
+
hanging forever regardless of that visible latency. The same discard-drain on the
|
|
105
|
+
artifact-download's non-2xx path is removed outright rather than capped: that path throws
|
|
106
|
+
straight into `process.exit(1)`, so there is no subsequent request in the process for a reclaimed
|
|
107
|
+
socket to serve, and the drain there bought nothing. (#2587)
|
|
108
|
+
|
|
11
109
|
## [0.5.0] - 2026-07-24
|
|
12
110
|
|
|
111
|
+
### Note
|
|
112
|
+
|
|
113
|
+
- The `0.3.1` and `0.4.0` versions below document real, tagged changes but were
|
|
114
|
+
never published to npm — the registry's version history jumps straight from
|
|
115
|
+
`0.3.0` to `0.5.0`. Don't go looking for those tarballs; the changes they
|
|
116
|
+
describe ship for the first time in this release.
|
|
117
|
+
|
|
13
118
|
### Added
|
|
14
119
|
|
|
15
120
|
- Surface parity round 2 (#2545): every `x-sdk-scope: v0.1` endpoint the SDK
|
|
@@ -236,7 +341,11 @@ Additive, lower-risk release — no breaking changes to existing commands.
|
|
|
236
341
|
- Initial release of the ByteKit CLI, wrapping the ByteKit SDK as shell
|
|
237
342
|
subcommands, published under the original `rapidcrawl-cli` name.
|
|
238
343
|
|
|
344
|
+
[Unreleased]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
345
|
+
[0.5.1]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
346
|
+
[0.5.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
239
347
|
[0.4.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
348
|
+
[0.3.1]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
240
349
|
[0.3.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
241
350
|
[0.2.2]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
|
242
351
|
[0.2.1]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/cli
|
package/README.md
CHANGED
|
@@ -182,6 +182,11 @@ Both verbs accept `--country <cc>`, `--timeout-ms <n>`, and `--cache-ttl <ttl>`
|
|
|
182
182
|
bytekit search "ai web scraping" --limit 10 --country us
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
+
`search` also accepts `--type <type>` (`web` (default), `news`, or `images`),
|
|
186
|
+
`--language <code>` (two-letter language code, e.g. `en`, `fr`), and
|
|
187
|
+
`--date-range <window>` (recency filter: `any` (default), `hour`, `day`,
|
|
188
|
+
`week`, `month`, `year`). Each flag is omitted from the request when absent.
|
|
189
|
+
|
|
185
190
|
### `screenshots` — capture a page
|
|
186
191
|
|
|
187
192
|
```bash
|
|
@@ -232,7 +237,7 @@ bytekit monitors create --url https://example.com/pricing --interval-type daily
|
|
|
232
237
|
bytekit monitors list --limit 25 --status active
|
|
233
238
|
bytekit monitors update mon_123abc --status paused # pause
|
|
234
239
|
bytekit monitors update mon_123abc --status active # resume
|
|
235
|
-
bytekit monitors captures list mon_123abc
|
|
240
|
+
bytekit monitors captures list mon_123abc --limit 25
|
|
236
241
|
bytekit monitors delete mon_123abc
|
|
237
242
|
```
|
|
238
243
|
|
|
@@ -240,6 +245,10 @@ bytekit monitors delete mon_123abc
|
|
|
240
245
|
(`active`, `processing`, `paused`, `cancelled`, `suspended`) as query filters,
|
|
241
246
|
each omitted when absent.
|
|
242
247
|
|
|
248
|
+
`monitors captures list <id>` accepts `--limit <n>` and `--cursor <cursor>` to
|
|
249
|
+
page through a monitor's capture history — pass the response's `next_cursor`
|
|
250
|
+
back as `--cursor` to fetch the next page. Both flags are omitted when absent.
|
|
251
|
+
|
|
243
252
|
`monitors update` gains `--status` (`active` | `paused` — pause and resume from
|
|
244
253
|
the shell), `--change-threshold <pct>` (accepts a float), `--notify-on`
|
|
245
254
|
(`change`, `every`), `--webhook-secret <secret>`, and three JSON-object flags:
|
|
@@ -294,11 +303,24 @@ omitted when absent. `retry <id>` requeues a failed or exhausted delivery.
|
|
|
294
303
|
|
|
295
304
|
## Exit codes
|
|
296
305
|
|
|
297
|
-
| Code | Meaning
|
|
298
|
-
| ---- |
|
|
299
|
-
| `0` | Success.
|
|
300
|
-
| `1` | Usage error, or an API/connection error.
|
|
301
|
-
| `2` | The
|
|
306
|
+
| Code | Meaning |
|
|
307
|
+
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
308
|
+
| `0` | Success. |
|
|
309
|
+
| `1` | Usage error, or an API/connection error. |
|
|
310
|
+
| `2` | The job was accepted but is still **queued**, so there is no content body or artifact to emit. Applies to `scrape create --async` with `--raw` or a bare `-o` (which writes the bare `sc_` id to stdout) and in human mode, and to `screenshots create --async` in human mode (including with `-o`, which deliberately writes no file). Not a failure: the job was accepted and billed. Poll it with `bytekit scrape get <id>` / `bytekit screenshots get <id>`. **`--json` keeps exit `0` in both cases** — the queued envelope is a complete machine-readable payload. |
|
|
311
|
+
|
|
312
|
+
The stderr message for exit code `1` has two shapes, depending on where the
|
|
313
|
+
error originates:
|
|
314
|
+
|
|
315
|
+
- **App-level errors** (a rejected API call, a connection failure, a missing
|
|
316
|
+
key) are always prefixed `Error: ` (uppercase) — e.g.
|
|
317
|
+
`Error: API key required. Pass --key or set BYTEKIT_API_KEY.`
|
|
318
|
+
- **Commander-level usage errors** (an unknown command, a missing required
|
|
319
|
+
argument, an unrecognized flag) come from the `commander` library itself and
|
|
320
|
+
use its own lowercase `error: ` prefix — e.g. `error: unknown command 'bogus'`.
|
|
321
|
+
|
|
322
|
+
Scripts that grep stderr for a failure reason should match case-insensitively,
|
|
323
|
+
or handle both prefixes.
|
|
302
324
|
|
|
303
325
|
Code `2` is deliberately distinct from both `0` and `1` so a script can branch
|
|
304
326
|
on "queued" without parsing stderr:
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ByteKit } from '@hunt-labs/bytekit-sdk';
|
|
1
|
+
import { ByteKit, ByteKitConnectionError } from '@hunt-labs/bytekit-sdk';
|
|
2
2
|
export interface GlobalOptions {
|
|
3
3
|
key?: string | undefined;
|
|
4
4
|
baseUrl?: string | undefined;
|
|
@@ -22,6 +22,24 @@ export declare const MIN_RETRY_AFTER_MS = 1000;
|
|
|
22
22
|
export declare const MAX_RETRY_AFTER_MS = 60000;
|
|
23
23
|
/** Exactly one retry. A second 429 is terminal — no loop. */
|
|
24
24
|
export declare const MAX_RETRIES = 1;
|
|
25
|
+
/**
|
|
26
|
+
* Cap on a best-effort, discard-only body drain (#2587 cr2-1). Independent of the per-attempt
|
|
27
|
+
* abort budget: the 429 drain below (`response.text().catch(() => {})`) exists ONLY so undici can
|
|
28
|
+
* return the socket to the connection pool — nothing downstream reads the drained bytes — but
|
|
29
|
+
* binding that read to the FULL per-attempt budget (120 s default, or, under `timeoutMs <= 0`,
|
|
30
|
+
* to no bound at all) let a stalled 429 body burn the whole budget, or hang forever, before a
|
|
31
|
+
* retry that needs nothing from that body. Short enough that a legitimately stalled 429 body costs
|
|
32
|
+
* the retry very little wall-clock time.
|
|
33
|
+
*
|
|
34
|
+
* #2587 cr3-2: past this cap, the read is not merely abandoned — {@link drainBestEffort} actively
|
|
35
|
+
* ABORTS its underlying request. Resolving the race without aborting anything (the earlier
|
|
36
|
+
* cr2-1 shape) let the retry proceed on schedule while the abandoned `response.text()` kept
|
|
37
|
+
* reading against a live socket forever, which — because the CLI exits via a soft
|
|
38
|
+
* `process.exitCode` (#2544) rather than `process.exit()` — kept the whole process alive
|
|
39
|
+
* indefinitely. `.catch`-guarding the read only made it safe to abandon the RESULT; it never made
|
|
40
|
+
* abandoning the underlying READ safe.
|
|
41
|
+
*/
|
|
42
|
+
export declare const DRAIN_TIMEOUT_MS = 2000;
|
|
25
43
|
/**
|
|
26
44
|
* Default CLIENT-SIDE abort budget for a single fetch attempt, in ms.
|
|
27
45
|
*
|
|
@@ -33,6 +51,49 @@ export declare const MAX_RETRIES = 1;
|
|
|
33
51
|
* exists.
|
|
34
52
|
*/
|
|
35
53
|
export declare const DEFAULT_TIMEOUT_MS = 120000;
|
|
54
|
+
/**
|
|
55
|
+
* A per-attempt abort budget: an `AbortController`, optionally fired by a `setTimeout`.
|
|
56
|
+
*
|
|
57
|
+
* The budget spans the WHOLE attempt — time-to-headers **and** the response body read (#2546).
|
|
58
|
+
* Arming it only until headers arrive left `response.text()` / `response.arrayBuffer()` unbounded,
|
|
59
|
+
* so a server that answered with headers and then stalled its body hung the CLI forever.
|
|
60
|
+
*
|
|
61
|
+
* The controller ALWAYS exists, even when `ms <= 0` — only its own timeout timer is conditional
|
|
62
|
+
* on `ms > 0`. `sendWithRetry`'s 429-drain cap ({@link DRAIN_TIMEOUT_MS}, via the returned
|
|
63
|
+
* `abort()`) needs a live controller to tear down an abandoned body read regardless of whether the
|
|
64
|
+
* OVERALL per-attempt budget is enabled — `ms <= 0` must still mean "no full-attempt timeout", not
|
|
65
|
+
* "no controller to abort a stalled drain with" (#2587 cr3-2: the earlier drain fix abandoned the
|
|
66
|
+
* read entirely rather than aborting it, so the socket — and the event loop — stayed alive
|
|
67
|
+
* indefinitely, worse than the pre-fix baseline it replaced).
|
|
68
|
+
*
|
|
69
|
+
* Deliberately NOT `AbortSignal.timeout` (which the SDK prefers): that schedules on a timer the
|
|
70
|
+
* test runner's fake timers cannot advance, so the transport's timeout would be untestable under
|
|
71
|
+
* `vi.useFakeTimers()`. CLI requests are short-lived and single-shot, so the GC advantage
|
|
72
|
+
* `AbortSignal.timeout` buys the long-running SDK does not apply here. The timer is `unref`'d so a
|
|
73
|
+
* pending budget never keeps the process alive, and `cleanup()` clears it on every exit path.
|
|
74
|
+
*
|
|
75
|
+
* Exported so `lib/download-artifact.ts` can reuse the same budget for the artifact-download path
|
|
76
|
+
* (#2587) rather than growing a second timeout implementation — that path sits entirely outside
|
|
77
|
+
* `sendWithRetry` (it is not a JSON/raw API call), so it would otherwise never inherit this bound.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createAttemptBudget(ms: number): {
|
|
80
|
+
signal: AbortSignal;
|
|
81
|
+
cleanup: () => void;
|
|
82
|
+
abort: (reason: unknown) => void;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Map a `fetch` or body-read rejection (no usable HTTP payload was produced) onto the SDK's
|
|
86
|
+
* `ByteKitConnectionError` taxonomy, so a CLI failure carries the same `{name, code, cause}` a
|
|
87
|
+
* direct SDK call would.
|
|
88
|
+
*
|
|
89
|
+
* `timedOut` is true when this attempt's own budget fired the abort, which is the reliable
|
|
90
|
+
* discriminator (undici rejects with the signal's reason — or a wrapper carrying it, see
|
|
91
|
+
* {@link abortNameOf} — whose `name` we also inspect as a fallback for a caller-style AbortError).
|
|
92
|
+
*
|
|
93
|
+
* Exported so `lib/download-artifact.ts` reuses the same taxonomy for the artifact-download path
|
|
94
|
+
* (#2587) instead of hand-rolling a second error mapping.
|
|
95
|
+
*/
|
|
96
|
+
export declare function toConnectionError(err: unknown, method: string, path: string, timedOut: boolean): ByteKitConnectionError;
|
|
36
97
|
/**
|
|
37
98
|
* Parse a `Retry-After` header into a clamped millisecond delay.
|
|
38
99
|
*
|
|
@@ -48,6 +109,18 @@ export declare function parseRetryAfterMs(raw: string | null): number;
|
|
|
48
109
|
* property of the client (see {@link buildClient}) routes all JSON commands through it from one
|
|
49
110
|
* seam. `/v1/fetch` does NOT ride this transport — it rides `requestRaw` (see
|
|
50
111
|
* {@link createRetryingRequestRaw}); `/v1/fetch/bulk` is a JSON job envelope and does.
|
|
112
|
+
*
|
|
113
|
+
* DECISION (#2586 dod-4): the 4th `RequestOptions` parameter of the SDK's contract is accepted
|
|
114
|
+
* here — so the signature matches `ByteKit['request']` exactly, closing the gap where a caller-typo
|
|
115
|
+
* of a 5th positional argument would silently no-op instead of a compile error — but deliberately
|
|
116
|
+
* NOT forwarded into `sendWithRetry`. Two reasons: (1) no CLI command constructs a `RequestOptions`
|
|
117
|
+
* today (no `--timeout` flag exists yet, and `signal` has no CLI-level source), so the parameter is
|
|
118
|
+
* always `undefined` in practice; (2) the CLI already owns a per-attempt abort budget with its own
|
|
119
|
+
* semantics (`createAttemptBudget`, `timeoutMs` above) that would need explicit composition with a
|
|
120
|
+
* caller `signal` to honor `RequestOptions` correctly (the SDK's `composeSignals`) — inventing that
|
|
121
|
+
* unexercised composition here, with no caller able to reach it, would be undertested surface for no
|
|
122
|
+
* present behavior change. If a future CLI flag needs per-call overrides, wire it through
|
|
123
|
+
* `sendWithRetry`'s `timeoutMs` (already per-attempt) at that point, with its own tests.
|
|
51
124
|
*/
|
|
52
125
|
export declare function createRetryingRequest(apiKey: string, baseUrl: string, timeoutMs?: number): ByteKit['request'];
|
|
53
126
|
/**
|
|
@@ -62,8 +135,32 @@ export declare function createRetryingRequest(apiKey: string, baseUrl: string, t
|
|
|
62
135
|
* so `FetchResource` builds an ordinary `FetchResult` from it and the CLI never forks fetch
|
|
63
136
|
* handling away from the SDK. `bytes` is byte-exact (binary-safe); `body` is the best-effort UTF-8
|
|
64
137
|
* decode, matching the SDK's own semantics.
|
|
138
|
+
*
|
|
139
|
+
* The 4th `RequestOptions` parameter is accepted but not forwarded — see the DECISION note on
|
|
140
|
+
* {@link createRetryingRequest}, which applies here verbatim. `FetchResource.create`/`get` DO thread
|
|
141
|
+
* a `requestOptions` argument through to this seam (unlike every other resource), but no CLI `fetch`
|
|
142
|
+
* command constructs one today (no `--timeout` flag), so it is still always `undefined` in practice.
|
|
65
143
|
*/
|
|
66
144
|
export declare function createRetryingRequestRaw(apiKey: string, baseUrl: string, timeoutMs?: number): ByteKit['requestRaw'];
|
|
145
|
+
/**
|
|
146
|
+
* Build the CLI's header-carrying JSON transport: the SDK's `requestWithResponse` contract
|
|
147
|
+
* (`{data, headers, status}`, #2547), plus the same bounded 429 retry every other CLI transport
|
|
148
|
+
* gets.
|
|
149
|
+
*
|
|
150
|
+
* Unused by any CLI command today — `screenshots.createWithResponse` / `getWithResponse` and
|
|
151
|
+
* `sitemap.getWithResponse` all exist on the SDK surface but no command builds on them yet. It is
|
|
152
|
+
* still installed (see {@link buildClient}) rather than left un-overridden: the transport-coverage
|
|
153
|
+
* contract test (#2586 dod-3) derives its method list from the real SDK prototype, and leaving a
|
|
154
|
+
* transport method un-overridden is exactly how #2535 shipped broken — the first command that DOES
|
|
155
|
+
* call a `*WithResponse` resource method must not silently ride the bare SDK transport and skip the
|
|
156
|
+
* CLI's retry/timeout/error taxonomy.
|
|
157
|
+
*
|
|
158
|
+
* Same body-read shape as {@link createRetryingRequest} (204/empty → `undefined`, `JSON.parse`
|
|
159
|
+
* otherwise), with `headers` and `status` threaded through from the successful response alongside
|
|
160
|
+
* the parsed `data`. The 4th `RequestOptions` parameter is accepted but not forwarded — see the
|
|
161
|
+
* DECISION note on {@link createRetryingRequest}.
|
|
162
|
+
*/
|
|
163
|
+
export declare function createRetryingRequestWithResponse(apiKey: string, baseUrl: string, timeoutMs?: number): ByteKit['requestWithResponse'];
|
|
67
164
|
/**
|
|
68
165
|
* Build an authenticated SDK client from global CLI options.
|
|
69
166
|
*
|
|
@@ -72,9 +169,18 @@ export declare function createRetryingRequestRaw(apiKey: string, baseUrl: string
|
|
|
72
169
|
* baseUrl: --base-url flag → BYTEKIT_BASE_URL → DEFAULT_BASE_URL.
|
|
73
170
|
* Exits with a descriptive error when no key is available.
|
|
74
171
|
*
|
|
75
|
-
* The returned client's `request` AND `
|
|
76
|
-
* every command inherits the 429 retry — JSON commands via `request`, the
|
|
77
|
-
* commands via `requestRaw
|
|
78
|
-
*
|
|
172
|
+
* The returned client's `request`, `requestRaw`, AND `requestWithResponse` are all replaced by the
|
|
173
|
+
* retrying transports, so every command inherits the 429 retry — JSON commands via `request`, the
|
|
174
|
+
* `/v1/fetch` content commands via `requestRaw`, and the header-carrying `*WithResponse` surface via
|
|
175
|
+
* `requestWithResponse`. Overriding only `request` is the #2535 defect: the SDK's fetch resource
|
|
176
|
+
* rides `requestRaw`, so fetch bypassed the retry and the CLI's error taxonomy entirely; leaving
|
|
177
|
+
* `requestWithResponse` un-overridden is the same class of defect (#2586) — it is unused by any CLI
|
|
178
|
+
* command TODAY, but a future command built on `screenshots.createWithResponse` /
|
|
179
|
+
* `sitemap.getWithResponse` would otherwise silently ride the bare SDK transport.
|
|
180
|
+
*
|
|
181
|
+
* `baseUrl` is normalized ONCE, here, before it reaches either the SDK constructor or the CLI's own
|
|
182
|
+
* transport builders below — the CLI's transports build their request URL from this local variable
|
|
183
|
+
* directly (they do not call the SDK's own normalized `send()`), so a trailing-slash flag would
|
|
184
|
+
* otherwise double-slash every request the CLI makes (#2586).
|
|
79
185
|
*/
|
|
80
186
|
export declare function buildClient(opts: GlobalOptions): ByteKit;
|