From 5326a3ee4bc91451d911c7b42070ab18fea06a23 Mon Sep 17 00:00:00 2001 From: Hadrian de Oliveira Date: Sat, 20 May 2023 01:48:32 +0000 Subject: [PATCH 1/2] Add custom fetch option --- README.md | 1 + src/index.test.ts | 14 ++++++++++++++ src/index.ts | 10 +++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0f94bf7..2e315f5 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ createClient(options); | Name | Type | Description | | :-------------- | :------: | :--------------------------------------------------------------------------------------------------------------------------------------- | | `baseUrl` | `string` | Prefix all fetch URLs with this option (e.g. `"https://myapi.dev/v1/"`). | +| `fetch` | `fetch` | Fetch function used for requests (defaults to `globalThis.fetch`) | | (Fetch options) | | Any valid fetch option (`headers`, `mode`, `cache`, `signal` …) ([docs](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options)) | ## 🎯 Project Goals diff --git a/src/index.test.ts b/src/index.test.ts index f968b5e..db516b0 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -180,6 +180,20 @@ describe('client', () => { }) ); }); + + it('accepts a custom fetch function', async () => { + const data = { works: true }; + const client = createClient({ + fetch: async () => + Promise.resolve({ + headers: new Headers(), + json: async () => data, + status: 200, + ok: true, + } as Response), + }); + expect((await client.get('/', {})).data).toBe(data); + }); }); describe('get()', () => { diff --git a/src/index.ts b/src/index.ts index 6373e92..a448038 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,8 @@ const DEFAULT_HEADERS = { interface ClientOptions extends RequestInit { /** set the common root URL for all API requests */ baseUrl?: string; + /** custom fetch (defaults to globalThis.fetch) */ + fetch?: typeof fetch; } export interface BaseParams { params?: { query?: Record }; @@ -51,17 +53,19 @@ export type FetchResponse = | { data: T extends { responses: any } ? NonNullable, JSONLike>> : unknown; error?: never; response: Response } | { data?: never; error: T extends { responses: any } ? NonNullable, JSONLike>> : unknown; response: Response }; -export default function createClient(options?: ClientOptions) { +export default function createClient(clientOptions: ClientOptions = {}) { + const { fetch = globalThis.fetch, ...options } = clientOptions; + const defaultHeaders = new Headers({ ...DEFAULT_HEADERS, - ...(options?.headers ?? {}), + ...(options.headers ?? {}), }); async function coreFetch

(url: P, fetchOptions: FetchOptions): Promise> { const { headers, body: requestBody, params = {}, querySerializer = (q: QuerySerializer) => new URLSearchParams(q as any).toString(), ...init } = fetchOptions || {}; // URL - let finalURL = `${options?.baseUrl ?? ''}${url as string}`; + let finalURL = `${options.baseUrl ?? ''}${url as string}`; if ((params as any).path) { for (const [k, v] of Object.entries((params as any).path)) finalURL = finalURL.replace(`{${k}}`, encodeURIComponent(String(v))); } From 58270bbbf2ccede92b455c16f2c9a376bc0f81a7 Mon Sep 17 00:00:00 2001 From: Hadrian de Oliveira Date: Sat, 20 May 2023 02:01:42 +0000 Subject: [PATCH 2/2] Fix test request path --- src/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.test.ts b/src/index.test.ts index db516b0..615ccfa 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -192,7 +192,7 @@ describe('client', () => { ok: true, } as Response), }); - expect((await client.get('/', {})).data).toBe(data); + expect((await client.get('/self', {})).data).toBe(data); }); });