From d43960e702c420be0b64d3b367d6e78add0712b5 Mon Sep 17 00:00:00 2001 From: Julien Elbaz Date: Tue, 29 Oct 2024 08:54:22 +0100 Subject: [PATCH] :factory: Add partial typing for the wretch options Solves #253 and #251 --- src/index.cts | 4 ++-- src/index.ts | 4 ++-- src/types.ts | 2 +- src/utils.ts | 5 +++-- test/deno/wretch_test.ts | 10 +++++----- test/node/middlewares/retry.spec.ts | 12 ++++++------ 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/index.cts b/src/index.cts index b76d642..b193d8e 100644 --- a/src/index.cts +++ b/src/index.cts @@ -1,3 +1,3 @@ -import factory from "./index.js"; +import factory from "./index.js" -module.exports = factory.default; +module.exports = factory.default diff --git a/src/index.ts b/src/index.ts index 7ab175d..6cb767a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { setOptions, setErrorType, setPolyfills } from "./config.js" import { core } from "./core.js" import { WretchError } from "./resolver.js" -import type { Wretch } from "./types.js" +import type { Wretch, WretchOptions } from "./types.js" export type { Wretch, @@ -33,7 +33,7 @@ export type { * @param _options The base fetch options * @returns A fresh wretch instance */ -function factory(_url = "", _options = {}): Wretch { +function factory(_url = "", _options: WretchOptions = {}): Wretch { return { ...core, _url, _options } } diff --git a/src/types.ts b/src/types.ts index e5914a6..da7fa33 100644 --- a/src/types.ts +++ b/src/types.ts @@ -761,7 +761,7 @@ export type Config = { /** * Fetch Request options with additional properties. */ -export type WretchOptions = Record +export type WretchOptions = Record & RequestInit /** * An Error enhanced with status, text and body. */ diff --git a/src/utils.ts b/src/utils.ts index ba7b4c8..094e2bc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,8 @@ import { CONTENT_TYPE_HEADER } from "./constants.js" -export function extractContentType(headers: Record = {}): string | undefined { - return Object.entries(headers).find(([k]) => +export function extractContentType(headers: HeadersInit = {}): string | undefined { + const normalizedHeaders = headers instanceof Array ? Object.fromEntries(headers) : headers + return Object.entries(normalizedHeaders).find(([k]) => k.toLowerCase() === CONTENT_TYPE_HEADER.toLowerCase() )?.[1] } diff --git a/test/deno/wretch_test.ts b/test/deno/wretch_test.ts index cd2c09f..b4b0bab 100644 --- a/test/deno/wretch_test.ts +++ b/test/deno/wretch_test.ts @@ -1,12 +1,12 @@ import { assertEquals, fail -} from "https://deno.land/std@0.147.0/testing/asserts.ts" +} from "jsr:@std/assert" import { beforeAll, describe, it, -} from "https://deno.land/std@0.147.0/testing/bdd.ts" +} from "jsr:@std/testing/bdd" import wretchFn from "../../dist/bundle/wretch.min.mjs" import BasicAuthAddon from "../../dist/bundle/addons/basicAuth.min.mjs" @@ -15,7 +15,7 @@ import FormDataAddon from "../../dist/bundle/addons/formData.min.mjs" import QueryAddon from "../../dist/bundle/addons/queryString.min.mjs" import AbortAddon from "../../dist/bundle/addons/abort.min.mjs" // import PerfsAddon from "../../dist/bundle/addons/perfs.min.mjs" -import type { Wretch, WretchResponseChain, WretchResponse, Middleware } from "../../dist/types.d.ts" +import type { Wretch, WretchResponseChain, WretchResponse, Middleware, WretchError } from "../../dist/types.d.ts" declare type factory = { (_url?: string, _options?: object): Wretch; @@ -117,7 +117,7 @@ describe("Wretch", function () { } // Ensure that the charset is preserved. const headerWithCharset = "application/json; charset=utf-16" - assertEquals((wretch()).content(headerWithCharset).json({})._options.headers["Content-Type"], headerWithCharset) + assertEquals((wretch()).content(headerWithCharset).json({})._options.headers?.["Content-Type" as keyof HeadersInit], headerWithCharset) }) it("should perform an url encoded form data round trip", async function () { @@ -395,7 +395,7 @@ describe("Wretch", function () { await wretch(_URL + "/basicauth") .get() .res(_ => fail("Authenticated route should not respond without credentials.")) - } catch (e) { + } catch (e: any) { assertEquals(e.status, 401) } }) diff --git a/test/node/middlewares/retry.spec.ts b/test/node/middlewares/retry.spec.ts index e609c7f..2e52949 100644 --- a/test/node/middlewares/retry.spec.ts +++ b/test/node/middlewares/retry.spec.ts @@ -99,7 +99,7 @@ export default describe("Retry Middleware", () => { true ) .options({ a: 1 }) - await expect(w.get("/retry").res()).rejects.toThrowError( + await expect(w.get("/retry").res()).rejects.toThrow( "Number of attempts exceeded." ) expect(counter).toEqual(10) @@ -114,17 +114,17 @@ export default describe("Retry Middleware", () => { delayTimer: 1, onRetry() { counter++ - return { url: `/${counter}`, options: { method: counter } } + return { url: `/${counter}`, options: { method: `${counter}` } } }, }), ], true ) - await expect(w.options({ a: 0 }).get("/0").res()).rejects.toThrowError( + await expect(w.options({ a: 0 }).get("/0").res()).rejects.toThrow( "Number of attempts exceeded." ) logs.forEach((log, index) => { - expect(log).toMatchObject([`/${index}`, index === 0 ? "GET" : index]) + expect(log).toMatchObject([`/${index}`, index === 0 ? "GET" : `${index}`]) }) }) @@ -161,10 +161,10 @@ export default describe("Retry Middleware", () => { true ) - await expect(wThrow.get("/retry").res()).rejects.toThrowError( + await expect(wThrow.get("/retry").res()).rejects.toThrow( "Network Error" ) - await expect(wRetry.get("/retry").res()).rejects.toThrowError( + await expect(wRetry.get("/retry").res()).rejects.toThrow( "Network Error" ) expect(counter).toBe(10)