@hunt-labs/bytekit-sdk 0.2.0 → 0.2.2

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 ADDED
@@ -0,0 +1,91 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@hunt-labs/bytekit-sdk` are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ This file records only the delta between versions. For how to use the package
9
+ today, see [README.md](./README.md), which remains the authoritative usage guide.
10
+
11
+ ## [0.2.2] - 2026-07-16
12
+
13
+ ### Changed
14
+
15
+ - Re-release of 0.2.1. The 0.2.1 artifacts never reached npm — the prod publish's
16
+ `publish-sdk` step failed on a CI test-isolation flake (`cjs-require.test.ts`
17
+ rebuilding the shared `dist`), which is now fixed. No consumer-facing changes
18
+ beyond 0.2.1.
19
+
20
+ ## [0.2.1] - 2026-07-16
21
+
22
+ ### Changed
23
+
24
+ - Primary exports renamed `RapidCrawl`→`ByteKit`, `RapidCrawlError`→`ByteKitError`,
25
+ `RapidCrawlOptions`→`ByteKitOptions`. The old names remain as deprecated,
26
+ identity-preserving aliases (`RapidCrawl === ByteKit`), so existing imports keep
27
+ working. (#2421)
28
+
29
+ ### Fixed
30
+
31
+ - `request()` now returns `undefined` on `204 No Content` / empty-body responses
32
+ instead of throwing a JSON-parse error — `account.apiKeys.revoke()` now resolves
33
+ as its `Promise<void>` contract declares. (#2450)
34
+
35
+ ### Removed
36
+
37
+ - `client.recordings` (the `/v1/recordings` endpoint is permanently `410`
38
+ deactivated). (#2421)
39
+
40
+ ## [0.2.0] - 2026-07-15
41
+
42
+ This is a breaking release. Four runtime behavior changes affect code written
43
+ against 0.1.0 — read each one before upgrading.
44
+
45
+ ### Changed (breaking)
46
+
47
+ - **Default client-side timeout (120s).** Requests now abort after 120000 ms by
48
+ default (`DEFAULT_TIMEOUT_MS` in `src/client.ts`); 0.1.0 had no client-side
49
+ timeout and would hang indefinitely. A slow request now rejects with
50
+ `RapidCrawlConnectionError` carrying `code: 'timeout'`. Override per client via
51
+ `new RapidCrawl({ apiKey, timeoutMs })`.
52
+ - **Network failures throw `RapidCrawlConnectionError`.** Every `fetch()` rejection
53
+ is now wrapped by `toConnectionError()` and re-thrown as `RapidCrawlConnectionError`.
54
+ 0.1.0 surfaced undici's bare `TypeError: fetch failed`. Code that matched on a bare
55
+ `TypeError` to detect a network failure will no longer match — catch
56
+ `RapidCrawlConnectionError` instead.
57
+ - **Constructor throws on an empty `apiKey`.** `new RapidCrawl({ apiKey: '' })` (or a
58
+ missing key) now throws a `TypeError` immediately instead of silently sending
59
+ `Authorization: Bearer undefined`. Ensure `apiKey` is populated (e.g. from
60
+ `process.env.BYTEKIT_API_KEY`) before constructing the client.
61
+ - **Request-body types narrowed to the OpenAPI schema.** Request payloads are now
62
+ typed from spec-derived types generated from the OpenAPI schema
63
+ (`src/generated/api.d.ts`) rather than `Record<string, unknown>`. Payloads that
64
+ previously compiled by virtue of the loose index type may now be rejected by the
65
+ type checker; align them with the documented request shape.
66
+
67
+ ### Changed
68
+
69
+ - Package renamed to `@hunt-labs/bytekit-sdk` (the `@bytekit` npm scope was
70
+ unobtainable). The prior `rapidcrawl`/`@rapidcrawl/sdk` name remains installable at
71
+ its last version but is deprecated.
72
+ - Generated API types (`dist/generated/api.d.ts`) are now shipped in the tarball so
73
+ consumers get the typed request/response surface without regenerating from the spec.
74
+
75
+ ### Added
76
+
77
+ - Publish-ready packaging metadata: types-first `exports`, `engines`, `keywords`,
78
+ `homepage`, `bugs`, `README.md`, `LICENSE`, and an MIT `license` field.
79
+
80
+ ## [0.1.0] - 2026
81
+
82
+ ### Added
83
+
84
+ - Initial release of the ByteKit TypeScript SDK — a typed client for the ByteKit API
85
+ (scrape, screenshot, search, and related endpoints), published under the original
86
+ `@rapidcrawl/sdk` name.
87
+
88
+ [0.2.2]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
89
+ [0.2.1]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
90
+ [0.2.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
91
+ [0.1.0]: https://github.com/Hunt-Labs-Inc/ByteKit/tree/main/packages/sdk-typescript
package/README.md CHANGED
@@ -10,11 +10,14 @@ screenshots, sitemaps, page monitors, and web search.
10
10
  npm install @hunt-labs/bytekit-sdk
11
11
  ```
12
12
 
13
- > **ESM-only.** This package ships as ESM (`"type": "module"`) and has no
14
- > CommonJS build. Use it from an ESM project (`"type": "module"` in your
15
- > `package.json`, or a `.mjs` entrypoint), or load it from CommonJS with a
16
- > dynamic `await import('@hunt-labs/bytekit-sdk')`. A top-level
17
- > `require('@hunt-labs/bytekit-sdk')` will not work.
13
+ > **ESM-only.** This package ships a single ESM build (`"type": "module"`) with
14
+ > no separate CommonJS bundle. Use it from an ESM project (`"type": "module"` in
15
+ > your `package.json`, or a `.mjs` entrypoint). From CommonJS you can either load
16
+ > it with a dynamic `await import('@hunt-labs/bytekit-sdk')`, or — on **Node
17
+ > ≥20.19 / ≥22.12**, which resolve `require()` of ESM — call a top-level
18
+ > `require('@hunt-labs/bytekit-sdk')` directly (the package's `exports` map
19
+ > carries a `default` condition for exactly this). On older Node, a top-level
20
+ > `require()` throws `ERR_REQUIRE_ESM`; use the dynamic `import()` there.
18
21
 
19
22
  Requires Node.js 18+ (the client uses the global `fetch`).
20
23
 
@@ -142,9 +145,6 @@ const account = await client.account.get();
142
145
  const keys = await client.account.apiKeys.list();
143
146
  ```
144
147
 
145
- > `client.recordings.*` targets the `/v1/recordings` endpoints, which are
146
- > deactivated server-side and return HTTP 410.
147
-
148
148
  ## Error handling
149
149
 
150
150
  Any 4xx/5xx response throws a `RapidCrawlError` carrying the HTTP status and
package/dist/client.d.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import { ScrapeResource } from './resources/scrape.js';
2
2
  import { ScreenshotsResource } from './resources/screenshots.js';
3
- import { RecordingsResource } from './resources/recordings.js';
4
3
  import { BulkResource } from './resources/bulk.js';
5
4
  import { FetchResource } from './resources/fetch.js';
6
5
  import { MonitorsResource } from './resources/monitors.js';
7
6
  import { SitemapResource } from './resources/sitemap.js';
8
7
  import { SearchResource } from './resources/search.js';
9
8
  import { AccountResource } from './resources/account.js';
10
- export interface RapidCrawlOptions {
9
+ export interface ByteKitOptions {
11
10
  apiKey: string;
12
11
  baseUrl?: string;
13
12
  /**
@@ -42,38 +41,37 @@ export interface RequestOptions {
42
41
  /** Why a request never produced an HTTP response. */
43
42
  export type ConnectionErrorCode = 'timeout' | 'aborted' | 'connection';
44
43
  /** Thrown when the API responds with a 4xx or 5xx status code. */
45
- export declare class RapidCrawlError extends Error {
44
+ export declare class ByteKitError extends Error {
46
45
  readonly status: number;
47
46
  readonly code: string;
48
47
  constructor(status: number, code: string, message: string);
49
48
  }
50
49
  /**
51
50
  * Thrown when the request never produced an HTTP response at all — DNS, socket, TLS,
52
- * a client-side timeout, or a caller-initiated abort. Distinct from `RapidCrawlError`,
51
+ * a client-side timeout, or a caller-initiated abort. Distinct from `ByteKitError`,
53
52
  * which always carries a real HTTP status: catch both to cover every failure.
54
53
  *
55
54
  * The original failure is preserved on `.cause`.
56
55
  */
57
- export declare class RapidCrawlConnectionError extends Error {
56
+ export declare class ByteKitConnectionError extends Error {
58
57
  readonly code: ConnectionErrorCode;
59
58
  constructor(code: ConnectionErrorCode, message: string, options?: {
60
59
  cause?: unknown;
61
60
  });
62
61
  }
63
- export declare class RapidCrawl {
62
+ export declare class ByteKit {
64
63
  private readonly apiKey;
65
64
  private readonly baseUrl;
66
65
  private readonly defaultTimeoutMs;
67
66
  readonly scrape: ScrapeResource;
68
67
  readonly screenshots: ScreenshotsResource;
69
- readonly recordings: RecordingsResource;
70
68
  readonly bulk: BulkResource;
71
69
  readonly fetch: FetchResource;
72
70
  readonly monitors: MonitorsResource;
73
71
  readonly sitemap: SitemapResource;
74
72
  readonly search: SearchResource;
75
73
  readonly account: AccountResource;
76
- constructor(options: RapidCrawlOptions);
74
+ constructor(options: ByteKitOptions);
77
75
  /**
78
76
  * Resolve the abort budget for one request from the caller's options and the
79
77
  * constructor default. Precedence:
@@ -89,11 +87,13 @@ export declare class RapidCrawl {
89
87
  */
90
88
  private resolveSignal;
91
89
  /**
92
- * Make an authenticated JSON request to the RapidCrawl API.
90
+ * Make an authenticated JSON request to the ByteKit API.
93
91
  *
94
- * Throws `RapidCrawlError` on 4xx/5xx responses, and `RapidCrawlConnectionError`
92
+ * Throws `ByteKitError` on 4xx/5xx responses, and `ByteKitConnectionError`
95
93
  * when no HTTP response was produced at all (DNS/socket/TLS failure, client-side
96
94
  * timeout, or caller abort).
97
95
  */
98
96
  request<T>(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<T>;
99
97
  }
98
+ export { ByteKit as RapidCrawl, ByteKitError as RapidCrawlError, ByteKitConnectionError as RapidCrawlConnectionError, };
99
+ export type { ByteKitOptions as RapidCrawlOptions };
package/dist/client.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ScrapeResource } from './resources/scrape.js';
2
2
  import { ScreenshotsResource } from './resources/screenshots.js';
3
- import { RecordingsResource } from './resources/recordings.js';
4
3
  import { BulkResource } from './resources/bulk.js';
5
4
  import { FetchResource } from './resources/fetch.js';
6
5
  import { MonitorsResource } from './resources/monitors.js';
@@ -17,28 +16,28 @@ const DEFAULT_BASE_URL = 'https://api.bytekit.com';
17
16
  */
18
17
  const DEFAULT_TIMEOUT_MS = 120_000;
19
18
  /** Thrown when the API responds with a 4xx or 5xx status code. */
20
- export class RapidCrawlError extends Error {
19
+ export class ByteKitError extends Error {
21
20
  status;
22
21
  code;
23
22
  constructor(status, code, message) {
24
23
  super(message);
25
- this.name = 'RapidCrawlError';
24
+ this.name = 'ByteKitError';
26
25
  this.status = status;
27
26
  this.code = code;
28
27
  }
29
28
  }
30
29
  /**
31
30
  * Thrown when the request never produced an HTTP response at all — DNS, socket, TLS,
32
- * a client-side timeout, or a caller-initiated abort. Distinct from `RapidCrawlError`,
31
+ * a client-side timeout, or a caller-initiated abort. Distinct from `ByteKitError`,
33
32
  * which always carries a real HTTP status: catch both to cover every failure.
34
33
  *
35
34
  * The original failure is preserved on `.cause`.
36
35
  */
37
- export class RapidCrawlConnectionError extends Error {
36
+ export class ByteKitConnectionError extends Error {
38
37
  code;
39
38
  constructor(code, message, options) {
40
39
  super(message, options);
41
- this.name = 'RapidCrawlConnectionError';
40
+ this.name = 'ByteKitConnectionError';
42
41
  this.code = code;
43
42
  }
44
43
  }
@@ -52,7 +51,7 @@ function validateTimeout(value, optionName) {
52
51
  if (value === undefined)
53
52
  return undefined;
54
53
  if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
55
- throw new TypeError(`RapidCrawl: ${optionName} must be a non-negative finite number (got ${describe(value)})`);
54
+ throw new TypeError(`ByteKit: ${optionName} must be a non-negative finite number (got ${describe(value)})`);
56
55
  }
57
56
  return value;
58
57
  }
@@ -69,7 +68,7 @@ function describe(value) {
69
68
  }
70
69
  /** The abort reason used by the `setTimeout` fallback; named so it maps to `code: 'timeout'`. */
71
70
  function timeoutReason(ms) {
72
- const reason = new Error(`RapidCrawl: request timed out after ${ms}ms`);
71
+ const reason = new Error(`ByteKit: request timed out after ${ms}ms`);
73
72
  reason.name = 'TimeoutError';
74
73
  return reason;
75
74
  }
@@ -147,17 +146,16 @@ function toConnectionError(err, method, url, timeoutSignal) {
147
146
  : code === 'aborted'
148
147
  ? 'request aborted by the caller'
149
148
  : 'connection failed before a response was received';
150
- return new RapidCrawlConnectionError(code, `RapidCrawl: ${method} ${url} — ${detail}`, {
149
+ return new ByteKitConnectionError(code, `ByteKit: ${method} ${url} — ${detail}`, {
151
150
  cause: err,
152
151
  });
153
152
  }
154
- export class RapidCrawl {
153
+ export class ByteKit {
155
154
  apiKey;
156
155
  baseUrl;
157
156
  defaultTimeoutMs;
158
157
  scrape;
159
158
  screenshots;
160
- recordings;
161
159
  bulk;
162
160
  fetch;
163
161
  monitors;
@@ -166,14 +164,13 @@ export class RapidCrawl {
166
164
  account;
167
165
  constructor(options) {
168
166
  if (!options?.apiKey) {
169
- throw new TypeError('RapidCrawl: `apiKey` is required — got an empty value. Pass options.apiKey (e.g. from process.env.BYTEKIT_API_KEY).');
167
+ throw new TypeError('ByteKit: `apiKey` is required — got an empty value. Pass options.apiKey (e.g. from process.env.BYTEKIT_API_KEY).');
170
168
  }
171
169
  this.apiKey = options.apiKey;
172
170
  this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
173
171
  this.defaultTimeoutMs = validateTimeout(options.timeoutMs, '"timeoutMs"') ?? DEFAULT_TIMEOUT_MS;
174
172
  this.scrape = new ScrapeResource(this);
175
173
  this.screenshots = new ScreenshotsResource(this);
176
- this.recordings = new RecordingsResource(this);
177
174
  this.bulk = new BulkResource(this);
178
175
  this.fetch = new FetchResource(this);
179
176
  this.monitors = new MonitorsResource(this);
@@ -218,9 +215,9 @@ export class RapidCrawl {
218
215
  };
219
216
  }
220
217
  /**
221
- * Make an authenticated JSON request to the RapidCrawl API.
218
+ * Make an authenticated JSON request to the ByteKit API.
222
219
  *
223
- * Throws `RapidCrawlError` on 4xx/5xx responses, and `RapidCrawlConnectionError`
220
+ * Throws `ByteKitError` on 4xx/5xx responses, and `ByteKitConnectionError`
224
221
  * when no HTTP response was produced at all (DNS/socket/TLS failure, client-side
225
222
  * timeout, or caller abort).
226
223
  */
@@ -264,8 +261,32 @@ export class RapidCrawl {
264
261
  catch {
265
262
  // leave defaults
266
263
  }
267
- throw new RapidCrawlError(response.status, code, message);
264
+ throw new ByteKitError(response.status, code, message);
268
265
  }
269
- return response.json();
266
+ // A 204 No Content has an empty body, and a genuinely empty body can arrive on
267
+ // other success codes too (defensive). Calling response.json() on an empty body
268
+ // rejects with a SyntaxError — which is how a successful revoke() (DELETE → 204)
269
+ // used to throw instead of resolving. Read the body once as text and short-circuit
270
+ // to `undefined` when it is empty; a JSON-bearing response (scrape.create,
271
+ // apiKeys.create/get, …) still parses and returns unchanged.
272
+ if (response.status === 204) {
273
+ return undefined;
274
+ }
275
+ const text = await response.text();
276
+ if (text.trim().length === 0) {
277
+ return undefined;
278
+ }
279
+ return JSON.parse(text);
270
280
  }
271
281
  }
282
+ // ---------------------------------------------------------------------------
283
+ // Deprecated RapidCrawl* aliases (#2421).
284
+ //
285
+ // The public surface renamed from RapidCrawl to ByteKit. These aliases point at
286
+ // the SAME implementations (identity preserved: `RapidCrawl === ByteKit`), so an
287
+ // existing consumer's `instanceof` / error-shape contract keeps holding for one
288
+ // minor version. Exported here — not only from index.ts — so the SDK's own
289
+ // resource files can keep importing the legacy type name from './client.js'
290
+ // without churn. Re-exported (with @deprecated JSDoc) from index.ts.
291
+ // ---------------------------------------------------------------------------
292
+ export { ByteKit as RapidCrawl, ByteKitError as RapidCrawlError, ByteKitConnectionError as RapidCrawlConnectionError, };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
+ export { ByteKit, ByteKitError, ByteKitConnectionError } from './client.js';
2
+ export type { ByteKitOptions, RequestOptions, ConnectionErrorCode } from './client.js';
3
+ /** @deprecated Renamed to ByteKit / ByteKitError / ByteKitConnectionError — kept as aliases for one minor version. */
1
4
  export { RapidCrawl, RapidCrawlError, RapidCrawlConnectionError } from './client.js';
2
- export type { RapidCrawlOptions, RequestOptions, ConnectionErrorCode } from './client.js';
5
+ /** @deprecated Renamed to ByteKitOptions — kept as an alias for one minor version. */
6
+ export type { RapidCrawlOptions } from './client.js';
3
7
  export { V01_METHODS } from './allowlist.js';
4
8
  export type { V01Method } from './allowlist.js';
5
9
  export type { ScrapeId, ScreenshotId, RecordingId, BulkId, MonitorId, SitemapId, ApiKeyId, SearchType, SearchDateRange, SearchOpts, SearchResult, SearchResultImage, SearchResponse, } from './types.js';
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
+ export { ByteKit, ByteKitError, ByteKitConnectionError } from './client.js';
2
+ /** @deprecated Renamed to ByteKit / ByteKitError / ByteKitConnectionError — kept as aliases for one minor version. */
1
3
  export { RapidCrawl, RapidCrawlError, RapidCrawlConnectionError } from './client.js';
2
4
  export { V01_METHODS } from './allowlist.js';
@@ -63,10 +63,9 @@ declare class ApiKeysResource {
63
63
  * declares `content?: never`, so there is no JSON arm to derive a payload
64
64
  * from — hence `Promise<void>`.
65
65
  *
66
- * KNOWN DRIFT: `client.request()` calls `response.json()` unconditionally,
67
- * which throws on the gateway's empty 204 body — so this method currently
68
- * rejects at runtime. The fix belongs in `client.ts` (tracked separately);
69
- * typing it here states the intended contract rather than encoding the bug.
66
+ * `client.request()` short-circuits an empty body (204 or any empty response)
67
+ * to `undefined` before it would parse the body as JSON (#2450), so this
68
+ * method resolves cleanly on the gateway's empty 204 body.
70
69
  */
71
70
  revoke(id: ApiKeyId): Promise<void>;
72
71
  /** POST /v1/account/api-keys/{id}/reveal — reveal the plaintext API key value */
@@ -43,10 +43,9 @@ class ApiKeysResource {
43
43
  * declares `content?: never`, so there is no JSON arm to derive a payload
44
44
  * from — hence `Promise<void>`.
45
45
  *
46
- * KNOWN DRIFT: `client.request()` calls `response.json()` unconditionally,
47
- * which throws on the gateway's empty 204 body — so this method currently
48
- * rejects at runtime. The fix belongs in `client.ts` (tracked separately);
49
- * typing it here states the intended contract rather than encoding the bug.
46
+ * `client.request()` short-circuits an empty body (204 or any empty response)
47
+ * to `undefined` before it would parse the body as JSON (#2450), so this
48
+ * method resolves cleanly on the gateway's empty 204 body.
50
49
  */
51
50
  revoke(id) {
52
51
  return this.client.request('DELETE', `/v1/account/api-keys/${id}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunt-labs/bytekit-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Official TypeScript SDK for the ByteKit API",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,14 +22,9 @@
22
22
  }
23
23
  },
24
24
  "files": [
25
- "dist"
25
+ "dist",
26
+ "CHANGELOG.md"
26
27
  ],
27
- "devDependencies": {
28
- "openapi-typescript": "7.13.0",
29
- "tsx": "*",
30
- "typescript": "^5.4.5",
31
- "vitest": "^1.6.0"
32
- },
33
28
  "engines": {
34
29
  "node": ">=18"
35
30
  },
@@ -49,10 +44,11 @@
49
44
  ],
50
45
  "homepage": "https://bytekit.com/docs",
51
46
  "bugs": {
52
- "email": "support@bytekit.com"
47
+ "email": "support@bytekit.com",
48
+ "url": "https://bytekit.com/contact"
53
49
  },
54
50
  "scripts": {
55
- "build": "rm -rf dist tsconfig.tsbuildinfo && tsc && mkdir -p dist/generated && cp src/generated/api.d.ts dist/generated/api.d.ts",
51
+ "build": "rm -rf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json && mkdir -p dist/generated && cp src/generated/api.d.ts dist/generated/api.d.ts",
56
52
  "gen:types": "openapi-typescript ../../docs/api/openapi.yaml -o src/generated/api.d.ts",
57
53
  "gen:types-check": "pnpm gen:types && git diff --exit-code src/generated/api.d.ts",
58
54
  "generate:docs": "tsx scripts/generate-docs.ts",
@@ -1,10 +0,0 @@
1
- import type { RapidCrawl } from '../client.js';
2
- import type { RecordingId } from '../types.js';
3
- export declare class RecordingsResource {
4
- private readonly client;
5
- constructor(client: RapidCrawl);
6
- /** POST /v1/recordings — start a recording */
7
- create(opts: Record<string, unknown>): Promise<unknown>;
8
- /** GET /v1/recordings/{id} — poll a recording by ID */
9
- get(id: RecordingId): Promise<unknown>;
10
- }
@@ -1,14 +0,0 @@
1
- export class RecordingsResource {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- /** POST /v1/recordings — start a recording */
7
- create(opts) {
8
- return this.client.request('POST', '/v1/recordings', opts);
9
- }
10
- /** GET /v1/recordings/{id} — poll a recording by ID */
11
- get(id) {
12
- return this.client.request('GET', `/v1/recordings/${id}`);
13
- }
14
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * A `fetch` mock that never settles until the request's own signal aborts.
3
- *
4
- * Shared between `client.test.ts` and `resources/__tests__/scrape.test.ts` (#2424 code review
5
- * cr-3) — both suites need a `fetch` stand-in that hangs forever except for reacting to the
6
- * abort signal the SDK attaches, so timeout/abort-ordering tests can assert on elapsed time and
7
- * error code without a real network call.
8
- */
9
- export declare function signalAwareNeverResolver(): (url: string, init: RequestInit) => Promise<Response>;
@@ -1,25 +0,0 @@
1
- // Test-only fixture, compiled like any other `src` file (not excluded from the tsc build):
2
- // excluding it broke ESLint's typed-lint project-service resolution (it requires every linted
3
- // file to be part of the tsconfig `include` set). The tradeoff is a small compiled fixture
4
- // landing in `dist/test-helpers/` alongside the package's real exports — negligible, and no
5
- // consumer imports it (it's not re-exported from `index.ts`).
6
- /**
7
- * A `fetch` mock that never settles until the request's own signal aborts.
8
- *
9
- * Shared between `client.test.ts` and `resources/__tests__/scrape.test.ts` (#2424 code review
10
- * cr-3) — both suites need a `fetch` stand-in that hangs forever except for reacting to the
11
- * abort signal the SDK attaches, so timeout/abort-ordering tests can assert on elapsed time and
12
- * error code without a real network call.
13
- */
14
- export function signalAwareNeverResolver() {
15
- return (_url, init) => new Promise((_resolve, reject) => {
16
- const signal = init.signal;
17
- if (!signal)
18
- return; // hangs — only used by tests that always pass a signal
19
- if (signal.aborted) {
20
- reject(signal.reason);
21
- return;
22
- }
23
- signal.addEventListener('abort', () => reject(signal.reason));
24
- });
25
- }