Skip to content

feat: add standard Fetch API compatible interface#24

Open
Lqm1 wants to merge 4 commits into
lexiforest:mainfrom
Lqm1:feature/fetch-compatible-api
Open

feat: add standard Fetch API compatible interface#24
Lqm1 wants to merge 4 commits into
lexiforest:mainfrom
Lqm1:feature/fetch-compatible-api

Conversation

@Lqm1

@Lqm1 Lqm1 commented Jun 26, 2026

Copy link
Copy Markdown

Summary

Proposal-oriented PR adding a standard Fetch API compatible fetch() on top of impers' HTTP engine, so impers can be plugged in as a custom fetch for clients TypeScript devs already use (ky, axios, etc.) while keeping impers' browser impersonation / HTTP/2-3 fingerprinting.

Why

ky and axios accept a custom fetch:

import ky from "ky";
import { fetch as impersFetch } from "impers";

const api = ky.create({ fetch: impersFetch });
await api("https://tls.browserleaks.com/json", { impersonate: "chrome124" } as never);

Users keep familiar ergonomics and transparently gain fingerprint spoofing. Even standalone, a Fetch-compatible interface is something TypeScript users expect.

Changes

  • src/http/fetch.tsfetch(input, init?): string | URL | Request input, standard RequestInit, returns a real global Response (.status/.ok/.headers/.text()/.json()/.arrayBuffer()/.clone()/bodyUsed). Network/SSL/timeout/abort errors → TypeError with original error in cause (Fetch semantics); 4xx/5xx returned, not rejected. redirect: follow|manual|error honored, maxRedirects defaults to 20. impers extensions via ImpersRequestInit; fresh Session per call (no cookie/state leakage, shared connection pool).
  • src/public.ts — exports fetch + ImpersRequestInit.
  • tests/fetch.test.ts — GET/POST, body types, Request input, redirects, errors, body semantics, impers extensions.
  • examples/fetch-api.ts — runnable sample.
  • tsconfig.jsontarget ES2020ES2022 (required for new TypeError(msg, { cause })).

Limitations

Inherited from the public Response constructor: response.url/.redirected/.type are not populated. Unsupported RequestInit fields silently ignored: credentials, mode, integrity, keepalive, window, duplex, referrerPolicy, referrer.

Test plan

  • npm test
  • npm run lint
  • npm run build

Notes for review

  1. Shadowing the global fetch vs. named-only export?
  2. ImpersRequestInit extensions flat on RequestInit vs. an impers sub-object?

Lqm1 added 4 commits June 27, 2026 02:09
The new `fetch()` function wraps impers' HTTP engine with a standard Fetch API
interface, supporting `RequestInit` and impers-specific extensions like
`impersonate`, `params`, `proxy`, `auth`, `timeout`, and more. Includes shared
session management, an example file, and comprehensive tests.
…quest

Each `fetch()` call now creates a new `Session` instance and closes it after
the request completes, preventing cookies and headers from leaking across
standalone calls. The underlying CurlMulti connection pool remains shared
via `getSharedMulti()`.

- Remove `shared-session.ts` module and inline its logic into `public.ts`
- Delete the `getFetchSession()` helper from `fetch.ts`
- Add test verifying cookies are not persisted between `fetch()` calls
…cause

Remove the `typeErrorWithCause` helper and use the standard `TypeError` constructor
with the `cause` option directly. This simplifies the code and aligns with modern
JavaScript error handling patterns.

To support the `cause` option, the TypeScript compilation target is bumped from
ES2020 to ES2022 in `tsconfig.json`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant