diff --git a/src/createClient.ts b/src/createClient.ts index 3a9dd6f..8e1fe35 100644 --- a/src/createClient.ts +++ b/src/createClient.ts @@ -11,7 +11,6 @@ import { DecoratedResponse, DecoratedResponsePromise, Modifiers, - SoFetchRequestInit, } from "@/types"; import { callbackStore, mergeHeaders } from "@/utils"; @@ -53,14 +52,14 @@ export const createClient = (options: ClientOptions = {}): Client => { }; const _createMethod = (methodInit: RequestInit) => { - return (info: RequestInfo, init: SoFetchRequestInit = {}) => { + return (info: RequestInfo, init?: RequestInit & { json?: unknown }) => { const result = (async (): Promise => { /** * Combine the incoming RequestInit with the default RequestInit * and set "content-type" header to "application/json" by * default if JSON is passed as the request body. */ - const { json, ...requestInit } = init; + const { json, ...requestInit } = init ?? {}; const combinedRequestInit: RequestInit = { ...methodInit, ...requestInit, @@ -211,6 +210,10 @@ export const createClient = (options: ClientOptions = {}): Client => { }; return { + request: _createMethod({ + ...options.defaults?.request, + }), + get: _createMethod({ method: "GET", ...options.defaults?.get, diff --git a/src/types.ts b/src/types.ts index 25e1059..4e3162f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,10 +5,6 @@ import { NetworkError, } from "./errors"; -export type SoFetchRequestInit = Omit & { - json?: unknown; -}; - export type Callbacks = { onRequestStart: (details: { request: Request }) => Promise | void; onSuccessResponse: (details: { @@ -79,12 +75,20 @@ export type DecoratedResponsePromise = Omit< }; export type Client = { + /** + * Perform an HTTP request using any HTTP method (defaults to GET) + */ + request: ( + input: RequestInfo, + init?: RequestInit & { json?: unknown } + ) => DecoratedResponsePromise; + /** * Perform a HTTP GET request */ get: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -92,7 +96,7 @@ export type Client = { */ put: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -100,7 +104,7 @@ export type Client = { */ post: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -108,7 +112,7 @@ export type Client = { */ patch: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -116,7 +120,7 @@ export type Client = { */ delete: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -124,7 +128,7 @@ export type Client = { */ options: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; /** @@ -132,7 +136,7 @@ export type Client = { */ head: ( input: RequestInfo, - init?: SoFetchRequestInit + init?: Omit & { json?: unknown } ) => DecoratedResponsePromise; callbacks: { @@ -152,6 +156,7 @@ export type Client = { export type ClientOptions = { defaults?: { + request: RequestInit; get: Omit; put: Omit; post: Omit; diff --git a/test/f.test.ts b/test/f.test.ts index 1d3f85b..b1118e6 100644 --- a/test/f.test.ts +++ b/test/f.test.ts @@ -22,6 +22,30 @@ const mockConsoleError = () => { const HOST = "http://that-is-so-fetch.com"; +describe("f.request()", () => { + test("When no method is specified it performs a GET request and returns a response", async () => { + nock(HOST) + .get("/api/user") + .reply(200, { firstName: "Shane", lastName: "MacGowan", age: 65 }); + + const response = await f.request(HOST + "/api/user"); + expect(response).toBeInstanceOf(Response); + expect(response.status).toBe(200); + expect(response.statusText).toBe("OK"); + }); + + test("You can provide an HTTP method", async () => { + nock(HOST) + .put("/api/user") + .reply(200, { firstName: "Shane", lastName: "MacGowan", age: 65 }); + + const response = await f.request(HOST + "/api/user", { method: "put" }); + expect(response).toBeInstanceOf(Response); + expect(response.status).toBe(200); + expect(response.statusText).toBe("OK"); + }); +}); + describe("f.get()", () => { test("It performs a GET request and returns a response", async () => { nock(HOST)