From 53ec6fc397e731859d99476265ddf1891d2a0522 Mon Sep 17 00:00:00 2001 From: LautaroPetaccio Date: Wed, 24 Jun 2026 14:44:16 -0300 Subject: [PATCH] feat: accept the native fetch directly as the HTTPProvider fetch option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FetchFunction declared `mode?: string`, which made the global native fetch non-assignable to it (native `RequestInit` types `mode` as `RequestMode`, and `string` is not assignable to `RequestMode`), forcing callers to cast with `fetch as unknown as FetchFunction`. HTTPProvider never sets `mode`, so dropping it lets the global native fetch — the same WHATWG signature on web and server — as well as native-fetch components (e.g. @dcl/fetch-component) and node-fetch be passed to `options.fetch` with no cast. Type-only change: the emitted JS is unchanged, and existing callers (including those still passing node-fetch) keep compiling. Adds compile-time assertions and regenerates the API report and docs. --- docs/eth-connect.fetchfunction.md | 1 - report/eth-connect.api.md | 1 - src/providers/HTTPProvider.ts | 6 +++++- test/HTTPProvider.spec.ts | 24 +++++++++++++++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/eth-connect.fetchfunction.md b/docs/eth-connect.fetchfunction.md index b4c43e44..83045df9 100644 --- a/docs/eth-connect.fetchfunction.md +++ b/docs/eth-connect.fetchfunction.md @@ -10,7 +10,6 @@ export type FetchFunction = (url: string, params: { body?: any; method?: string; - mode?: string; headers?: any; }) => Promise; ``` diff --git a/report/eth-connect.api.md b/report/eth-connect.api.md index eb06a378..6c1a9b4e 100644 --- a/report/eth-connect.api.md +++ b/report/eth-connect.api.md @@ -880,7 +880,6 @@ export function extractTypeName(name: string): string; export type FetchFunction = (url: string, params: { body?: any; method?: string; - mode?: string; headers?: any; }) => Promise; diff --git a/src/providers/HTTPProvider.ts b/src/providers/HTTPProvider.ts index 3472f1cf..dcf10662 100644 --- a/src/providers/HTTPProvider.ts +++ b/src/providers/HTTPProvider.ts @@ -1,12 +1,16 @@ import { RPCMessage, Callback, toRPC } from './common' export { RPCMessage, Callback } from './common' +// Structurally compatible with the global native `fetch` (the same WHATWG signature on web +// and server) as well as native-fetch components (e.g. @dcl/fetch-component) and node-fetch, +// so callers can pass any of them directly without a cast. Only the fields HTTPProvider sets +// are listed; a previous `mode?: string` was dropped because it is unused here and made the +// native fetch's `RequestInit` (`mode?: RequestMode`) non-assignable to this type. export type FetchFunction = ( url: string, params: { body?: any method?: string - mode?: string headers?: any } ) => Promise diff --git a/test/HTTPProvider.spec.ts b/test/HTTPProvider.spec.ts index e5cf52b0..4215bac2 100644 --- a/test/HTTPProvider.spec.ts +++ b/test/HTTPProvider.spec.ts @@ -1,4 +1,4 @@ -import { HTTPProvider } from '../src/providers/HTTPProvider' +import { HTTPProvider, HTTPProviderOptions } from '../src/providers/HTTPProvider' type SendResult = { err: Error | null; result: any } @@ -110,3 +110,25 @@ describe('when sending an async request through the HTTPProvider', () => { }) }) }) + +describe('when configuring the fetch option', () => { + describe('and the global native fetch is supplied', () => { + it('should be accepted without a cast', () => { + // This compiles only if the global native fetch (same WHATWG signature on web and + // server) is assignable to the fetch option — the point of this change. + const options: HTTPProviderOptions = { fetch: globalThis.fetch } + + expect(typeof options.fetch).toBe('function') + }) + }) + + describe('and a native-fetch component is supplied', () => { + it('should be accepted without a cast', () => { + // Mirrors the shape of native-fetch components such as @dcl/fetch-component. + const fetchComponent: (url: string, init?: RequestInit) => Promise = globalThis.fetch + const options: HTTPProviderOptions = { fetch: fetchComponent } + + expect(typeof options.fetch).toBe('function') + }) + }) +})