### CHANGELOG ## [3.0.9](https://github.com/elbywan/wretch/compare/3.0.8...3.0.9) (2026-06-19) ### :art: Code improvement(s) * Narrow AbortAddon controller() return type to AbortController ([6a83061](https://github.com/elbywan/wretch/commit/6a83061)) ### :bug: Bug fix(es) * Fix .fetchError catching user errors ([9a8faad](https://github.com/elbywan/wretch/commit/9a8faad)), closes [#318](https://github.com/elbywan/wretch/issues/318) ## [3.0.8](https://github.com/elbywan/wretch/compare/3.0.7...3.0.8) (2026-05-23) ### :arrow_up: Version update(s) * Add min-release-age guard ([14185e9](https://github.com/elbywan/wretch/commit/14185e9)) * Upgrade dependencies ([56165dc](https://github.com/elbywan/wretch/commit/56165dc)) ### :bug: Bug fix(es) * Fix catcher return type inference ([f78f32a](https://github.com/elbywan/wretch/commit/f78f32a)), closes [#313](https://github.com/elbywan/wretch/issues/313) ### :white_check_mark: Test improvement(s) * Properly typecheck tests ([5af0e78](https://github.com/elbywan/wretch/commit/5af0e78)) ## [3.0.7](https://github.com/elbywan/wretch/compare/3.0.6...3.0.7) (2026-03-07) ### :arrow_up: Version update(s) * Bump fastify from 5.6.1 to 5.7.3 ([153cae9](https://github.com/elbywan/wretch/commit/153cae9)) * Bump lodash from 4.17.21 to 4.17.23 ([2355d02](https://github.com/elbywan/wretch/commit/2355d02)) * Bump qs from 6.14.0 to 6.14.2 ([02ca86e](https://github.com/elbywan/wretch/commit/02ca86e)) * Upgrade dependencies ([f677f28](https://github.com/elbywan/wretch/commit/f677f28)) ### :factory: New feature(s) * Allow multiple error ids on catchers ([dc93190](https://github.com/elbywan/wretch/commit/dc93190)) ## [3.0.6](https://github.com/elbywan/wretch/compare/3.0.5...3.0.6) (2025-12-12) ### :bug: Bug fix(es) * Add Self to return type ([e5582d6](https://github.com/elbywan/wretch/commit/e5582d6)) * Widen catcherFallback error type ([d0a3fbe](https://github.com/elbywan/wretch/commit/d0a3fbe)), closes [#290](https://github.com/elbywan/wretch/issues/290) ### :white_check_mark: Test improvement(s) * Add core snippet testing infrastructure ([fcea6f7](https://github.com/elbywan/wretch/commit/fcea6f7)) * Add directive system for snippet test control ([106e0d6](https://github.com/elbywan/wretch/commit/106e0d6)) * Add execution engine and test orchestration ([28f60a1](https://github.com/elbywan/wretch/commit/28f60a1)) * Add extensible plugin system with examples ([262a40d](https://github.com/elbywan/wretch/commit/262a40d)) * Integrate snippet testing framework and document usage ([9cdeb4c](https://github.com/elbywan/wretch/commit/9cdeb4c)) ## [3.0.5](https://github.com/elbywan/wretch/compare/3.0.4...3.0.5) (2025-11-27) ### :art: Code improvement(s) * Add progress option to customize the upload body size computation ([2cd547f](https://github.com/elbywan/wretch/commit/2cd547f)) ## [3.0.4](https://github.com/elbywan/wretch/compare/3.0.3...3.0.4) (2025-11-26) ### :arrow_up: Version update(s) * Bump glob ([49a5e53](https://github.com/elbywan/wretch/commit/49a5e53)) * Bump js-yaml from 4.1.0 to 4.1.1 ([43882e1](https://github.com/elbywan/wretch/commit/43882e1)) ### :bug: Bug fix(es) * Improve body size computation when tracking upload progress ([bfae158](https://github.com/elbywan/wretch/commit/bfae158)), closes [#284](https://github.com/elbywan/wretch/issues/284) ## [3.0.3](https://github.com/elbywan/wretch/compare/3.0.2...3.0.3) (2025-11-10) ### :bug: Bug fix(es) * Use body size when available to compute upload total bytes ([27c0443](https://github.com/elbywan/wretch/commit/27c0443)), closes [#278](https://github.com/elbywan/wretch/issues/278) ### :white_check_mark: Test improvement(s) * Migrate documentation examples from httpbun.org to htt ([df84f73](https://github.com/elbywan/wretch/commit/df84f73)) ## [3.0.2](https://github.com/elbywan/wretch/compare/3.0.1...3.0.2) (2025-10-24) ### :bug: Bug fix(es) * Clone the body before assigning to WretchError message ([5379037](https://github.com/elbywan/wretch/commit/5379037)), closes [#277](https://github.com/elbywan/wretch/issues/277) ## [3.0.1](https://github.com/elbywan/wretch/compare/3.0.0...3.0.1) (2025-10-21) ### :bug: Bug fix(es) * Fix malformed package.json key ([ddf3b4c](https://github.com/elbywan/wretch/commit/ddf3b4c)) ### :memo: Documentation update(s) * Fix typescript API links ([831598a](https://github.com/elbywan/wretch/commit/831598a)) # [3.0.0](https://github.com/elbywan/wretch/compare/2.11.1...3.0.0) (2025-10-19) ### :arrow_up: Version update(s) * Migrate to rolldown ([219f1ce](https://github.com/elbywan/wretch/commit/219f1ce)) * Upgrade packages ([da968b2](https://github.com/elbywan/wretch/commit/da968b2)) * Upgrade packages ([ae05a13](https://github.com/elbywan/wretch/commit/ae05a13)) ### :art: Code improvement(s) * Add automated npm publishing workflow ([745b8a0](https://github.com/elbywan/wretch/commit/745b8a0)) * Golf bytes ([b0316f1](https://github.com/elbywan/wretch/commit/b0316f1)) * Improve .customError typings ([6efdb24](https://github.com/elbywan/wretch/commit/6efdb24)) * Remove deno related docuentation and tests ([1ceac88](https://github.com/elbywan/wretch/commit/1ceac88)) * Remove global config and dead code ([bdb8134](https://github.com/elbywan/wretch/commit/bdb8134)) * Use proto to manage tools ([23f22e4](https://github.com/elbywan/wretch/commit/23f22e4)) ### :bug: Bug fix(es) * Fix custom error conflicting with catchers ([0486e49](https://github.com/elbywan/wretch/commit/0486e49)) ### :checkered_flag: Performance update(s) * Add bun tests ([df0e075](https://github.com/elbywan/wretch/commit/df0e075)) * Add deno tests ([c02f1e8](https://github.com/elbywan/wretch/commit/c02f1e8)) * Add workflow to test code snippets ([f036a71](https://github.com/elbywan/wretch/commit/f036a71)) * Improve mock server lifecycle ([68d1a0f](https://github.com/elbywan/wretch/commit/68d1a0f)) * Improve snippet testing ([299bd90](https://github.com/elbywan/wretch/commit/299bd90)) * Replace karma with web-test-runner ([5b4215c](https://github.com/elbywan/wretch/commit/5b4215c)) * Test all the documentation snippets and rework recipes ([a8ae915](https://github.com/elbywan/wretch/commit/a8ae915)) * Unify tests ([ab95d83](https://github.com/elbywan/wretch/commit/ab95d83)) ### :factory: New feature(s) * Accept multiple addons when calling .addon ([91c6024](https://github.com/elbywan/wretch/commit/91c6024)) * Add attempt argument to the onRetry callback ([0cfb31c](https://github.com/elbywan/wretch/commit/0cfb31c)) * Add request parameter to .customError transformer ([4347e4b](https://github.com/elbywan/wretch/commit/4347e4b)) * Upload progress support ([012b233](https://github.com/elbywan/wretch/commit/012b233)) ### :feature: undefined * Add .toFetch method ([aa8ef0a](https://github.com/elbywan/wretch/commit/aa8ef0a)) ### :fire: Breaking change(s) * Consolidate addon optional parameters into options objects ([dfe5860](https://github.com/elbywan/wretch/commit/dfe5860)) * Remove .errorType and introduce .customError ([fdf4371](https://github.com/elbywan/wretch/commit/fdf4371)) * Remove node <22 compatibility ([304c7ff](https://github.com/elbywan/wretch/commit/304c7ff)) * Remove static methods ([ff703f7](https://github.com/elbywan/wretch/commit/ff703f7)) * Skip retrying 4xx errors by default in retry middleware ([a63e471](https://github.com/elbywan/wretch/commit/a63e471)), closes [#176](https://github.com/elbywan/wretch/issues/176) ### :memo: Documentation update(s) * Add issue links to the recipes ([5aa7146](https://github.com/elbywan/wretch/commit/5aa7146)) * Improve documentation ([7f69396](https://github.com/elbywan/wretch/commit/7f69396)) * Init recipes ([37dccac](https://github.com/elbywan/wretch/commit/37dccac)) * Migration guide ([5faaceb](https://github.com/elbywan/wretch/commit/5faaceb)) * Niceify website ([64d7ade](https://github.com/elbywan/wretch/commit/64d7ade)) ### :white_check_mark: Test improvement(s) * Remove jest in favour of node:test ([bd0d3e1](https://github.com/elbywan/wretch/commit/bd0d3e1)) ## [2.11.1](https://github.com/elbywan/wretch/compare/2.11.0...2.11.1) (2025-10-19) ### :arrow_up: Version update(s) * Bump axios from 1.10.0 to 1.11.0 ([88e6554](https://github.com/elbywan/wretch/commit/88e6554)) * Bump axios from 1.7.7 to 1.10.0 ([2ccb6fa](https://github.com/elbywan/wretch/commit/2ccb6fa)) * Bump cookie, light-my-request and socket.io ([891b26e](https://github.com/elbywan/wretch/commit/891b26e)) * Bump form-data from 4.0.0 to 4.0.4 ([1b1bdac](https://github.com/elbywan/wretch/commit/1b1bdac)) * Bump serialize-javascript from 6.0.1 to 6.0.2 ([ae8918f](https://github.com/elbywan/wretch/commit/ae8918f)) * Bump tmp from 0.2.1 to 0.2.4 ([9355826](https://github.com/elbywan/wretch/commit/9355826)) ### :bug: Bug fix(es) * Ignore parsing errors in errorType('json') ([974e8fa](https://github.com/elbywan/wretch/commit/974e8fa)), closes [#266](https://github.com/elbywan/wretch/issues/266) ### :memo: Documentation update(s) * Better retry code snippets types ([6dbdedc](https://github.com/elbywan/wretch/commit/6dbdedc)), closes [#255](https://github.com/elbywan/wretch/issues/255) ### :white_check_mark: Test improvement(s) * Fix node22 delay middleware test ([0e0b30f](https://github.com/elbywan/wretch/commit/0e0b30f)) # [2.11.0](https://github.com/elbywan/wretch/compare/2.10.0...2.11.0) (2024-10-29) ### :arrow_up: Version update(s) * Bump body-parser from 1.20.0 to 1.20.3 ([598ce94](https://github.com/elbywan/wretch/commit/598ce94)) * Bump rollup from 4.5.0 to 4.22.4 ([75f9db7](https://github.com/elbywan/wretch/commit/75f9db7)) ### :factory: New feature(s) * Add partial typing for the wretch options ([e778f88](https://github.com/elbywan/wretch/commit/e778f88)), closes [#253](https://github.com/elbywan/wretch/issues/253) [#251](https://github.com/elbywan/wretch/issues/251) # [2.10.0](https://github.com/elbywan/wretch/compare/2.9.1...2.10.0) (2024-09-13) ### :arrow_up: Version update(s) * Bump axios from 1.6.2 to 1.7.7 ([4542c28](https://github.com/elbywan/wretch/commit/4542c28)) ### :art: Code improvement(s) * Expand eslint ignore list ([cdad424](https://github.com/elbywan/wretch/commit/cdad424)) * Properly build commonjs ([c7f00fc](https://github.com/elbywan/wretch/commit/c7f00fc)), closes [#247](https://github.com/elbywan/wretch/issues/247) ## [2.9.1](https://github.com/elbywan/wretch/compare/2.9.0...2.9.1) (2024-09-06) ### :arrow_up: Version update(s) * Bump braces from 3.0.2 to 3.0.3 ([a50cdf6](https://github.com/elbywan/wretch/commit/a50cdf6)) * Bump ws and socket.io ([c615396](https://github.com/elbywan/wretch/commit/c615396)) ### :art: Code improvement(s) * Enhance errorType and allow disabling it ([cfd45a9](https://github.com/elbywan/wretch/commit/cfd45a9)) * Replace tslint with eslint ([661865a](https://github.com/elbywan/wretch/commit/661865a)) * Replace URL.canParse with a try/catch block ([f6fc851](https://github.com/elbywan/wretch/commit/f6fc851)), closes [#244](https://github.com/elbywan/wretch/issues/244) ### :memo: Documentation update(s) * Regenerate api docs ([bc1f570](https://github.com/elbywan/wretch/commit/bc1f570)) * Replace bundlephobia badge with bundlejs ([b9f27a7](https://github.com/elbywan/wretch/commit/b9f27a7)) # [2.9.0](https://github.com/elbywan/wretch/compare/2.8.1...2.9.0) (2024-06-01) ### :arrow_up: Version update(s) * Bump follow-redirects from 1.15.4 to 1.15.6 ([6204bec](https://github.com/elbywan/wretch/commit/6204bec)) * Install firefox in the CI env ([c80ad35](https://github.com/elbywan/wretch/commit/c80ad35)) ### :bug: Bug fix(es) * Do not jasonify FormData instances ([4693837](https://github.com/elbywan/wretch/commit/4693837)), closes [#231](https://github.com/elbywan/wretch/issues/231) ### :factory: New feature(s) * Add BasicAuth addon ([ad5b591](https://github.com/elbywan/wretch/commit/ad5b591)) ## [2.8.1](https://github.com/elbywan/wretch/compare/2.8.0...2.8.1) (2024-03-07) ### :arrow_up: Version update(s) * Bump follow-redirects from 1.15.1 to 1.15.4 ([04fada6](https://github.com/elbywan/wretch/commit/04fada6)) ### :bug: Bug fix(es) * Fix error callback type missing addons extensions ([99a21a8](https://github.com/elbywan/wretch/commit/99a21a8)), closes [#222](https://github.com/elbywan/wretch/issues/222) # [2.8.0](https://github.com/elbywan/wretch/compare/2.7.1...2.8.0) (2023-12-30) ### :factory: New feature(s) * addon.resolver can now be a function ([0bf9aa8](https://github.com/elbywan/wretch/commit/0bf9aa8)), closes [#212](https://github.com/elbywan/wretch/issues/212) ## [2.7.1](https://github.com/elbywan/wretch/compare/2.7.0...2.7.1) (2023-11-19) ### :arrow_up: Version update(s) * Bump @babel/traverse from 7.19.4 to 7.23.2 ([922005e](https://github.com/elbywan/wretch/commit/922005e)) * Upgrade dependencies ([d774826](https://github.com/elbywan/wretch/commit/d774826)) ### :bug: Bug fix(es) * Fix passing Headers/entries array as an argument to headers() ([f32845a](https://github.com/elbywan/wretch/commit/f32845a)), closes [#205](https://github.com/elbywan/wretch/issues/205) # [2.7.0](https://github.com/elbywan/wretch/compare/2.6.0...2.7.0) (2023-09-12) ### :factory: New feature(s) * Support FileList objects in the form data addon ([3582809](https://github.com/elbywan/wretch/commit/3582809)), closes [#201](https://github.com/elbywan/wretch/issues/201) ### :memo: Documentation update(s) * Mention file names in the form data addon doc ([411fb09](https://github.com/elbywan/wretch/commit/411fb09)), closes [#197](https://github.com/elbywan/wretch/issues/197) # [2.6.0](https://github.com/elbywan/wretch/compare/2.5.2...2.6.0) (2023-06-28) ### :arrow_up: Version update(s) * Bump engine.io and socket.io ([3ef1738](https://github.com/elbywan/wretch/commit/3ef1738)) * Bump socket.io-parser from 4.2.2 to 4.2.3 ([b42aa0f](https://github.com/elbywan/wretch/commit/b42aa0f)) * Upgrade dependencies ([b183cf7](https://github.com/elbywan/wretch/commit/b183cf7)) ### :factory: New feature(s) * Add fallback catcher method ([46610cf](https://github.com/elbywan/wretch/commit/46610cf)), closes [#192](https://github.com/elbywan/wretch/issues/192) ### :memo: Documentation update(s) * Update node-fetch code snippet ([3b6ac7e](https://github.com/elbywan/wretch/commit/3b6ac7e)), closes [#179](https://github.com/elbywan/wretch/issues/179) ## [2.5.2](https://github.com/elbywan/wretch/compare/2.5.1...2.5.2) (2023-04-11) ### :bug: Bug fix(es) * Fix catcher and resolve callback argument type. ([76c295f](https://github.com/elbywan/wretch/commit/76c295f)), closes [#177](https://github.com/elbywan/wretch/issues/177) ### :memo: Documentation update(s) * Node.js 18 section wording ([b696b1c](https://github.com/elbywan/wretch/commit/b696b1c)) * Warn to use a custom until function to avoid retrying on 4xx error ([1812c73](https://github.com/elbywan/wretch/commit/1812c73)), closes [#176](https://github.com/elbywan/wretch/issues/176) ## [2.5.1](https://github.com/elbywan/wretch/compare/2.5.0...2.5.1) (2023-02-27) ### :bug: Bug fix(es) * Update resolver.ts - Add null verification to .get("Content-Type") ([a68a524](https://github.com/elbywan/wretch/commit/a68a524)) # [2.5.0](https://github.com/elbywan/wretch/compare/2.4.1...2.5.0) (2023-02-20) ### :arrow_up: Version update(s) * Bump @fastify/multipart from 7.3.0 to 7.4.1 ([e6074c9](https://github.com/elbywan/wretch/commit/e6074c9)) * Bump @sideway/formula from 3.0.0 to 3.0.1 ([8208646](https://github.com/elbywan/wretch/commit/8208646)) * Bump ua-parser-js from 0.7.31 to 0.7.33 ([1694fe6](https://github.com/elbywan/wretch/commit/1694fe6)) ### :factory: New feature(s) * Parse error type as json on proper content-type ([ea9adbf](https://github.com/elbywan/wretch/commit/ea9adbf)), closes [#171](https://github.com/elbywan/wretch/issues/171) ## [2.4.1](https://github.com/elbywan/wretch/compare/2.4.0...2.4.1) (2023-01-20) ### :bug: Bug fix(es) * Fix abort/progress addons state isolation issue ([2b3a659](https://github.com/elbywan/wretch/commit/2b3a659)) # [2.4.0](https://github.com/elbywan/wretch/compare/2.3.2...2.4.0) (2023-01-19) ### :factory: New feature(s) * Add skip argument to the retry middleware ([746f8c9](https://github.com/elbywan/wretch/commit/746f8c9)) ## [2.3.2](https://github.com/elbywan/wretch/compare/2.3.1...2.3.2) (2023-01-11) ### :bug: Bug fix(es) * Fix catcher priority ([d359bd7](https://github.com/elbywan/wretch/commit/d359bd7)), closes [#162](https://github.com/elbywan/wretch/issues/162) ## [2.3.1](https://github.com/elbywan/wretch/compare/2.3.0...2.3.1) (2023-01-07) ### :bug: Bug fix(es) * Fix middlewares and addons subpath exports ([bfd2542](https://github.com/elbywan/wretch/commit/bfd2542)), closes [#160](https://github.com/elbywan/wretch/issues/160) ### :memo: Documentation update(s) * Add limitations section to the readme ([ad0a102](https://github.com/elbywan/wretch/commit/ad0a102)), closes [#159](https://github.com/elbywan/wretch/issues/159) # [2.3.0](https://github.com/elbywan/wretch/compare/2.2.3...2.3.0) (2022-12-12) ### :factory: New feature(s) * Add url property to WretchError ([a1f6ac6](https://github.com/elbywan/wretch/commit/a1f6ac6)), closes [#157](https://github.com/elbywan/wretch/issues/157) ## [2.2.3](https://github.com/elbywan/wretch/compare/2.2.2...2.2.3) (2022-12-09) ### :bug: Bug fix(es) * Better error catching precedence ([107fc71](https://github.com/elbywan/wretch/commit/107fc71)), closes [#155](https://github.com/elbywan/wretch/issues/155) ## [2.2.2](https://github.com/elbywan/wretch/compare/2.2.1...2.2.2) (2022-12-03) ### :bug: Bug fix(es) * Fix compatibility issue between the perfs and progress addons ([b70e8cd](https://github.com/elbywan/wretch/commit/b70e8cd)) ## [2.2.1](https://github.com/elbywan/wretch/compare/2.2.0...2.2.1) (2022-12-03) ### :bug: Bug fix(es) * Add missing export for the progress addon ([ebb0577](https://github.com/elbywan/wretch/commit/ebb0577)) * Add missing progress addon rollup config ([bd6c89b](https://github.com/elbywan/wretch/commit/bd6c89b)) * Register the progress addon in the .all entry point ([b01e03d](https://github.com/elbywan/wretch/commit/b01e03d)) # [2.2.0](https://github.com/elbywan/wretch/compare/2.1.5...2.2.0) (2022-12-03) ### :arrow_up: Version update(s) * Bump dependencies including outdated rollup plugins ([bcbcdc5](https://github.com/elbywan/wretch/commit/bcbcdc5)) * Bump engine.io from 6.2.0 to 6.2.1 ([6a93854](https://github.com/elbywan/wretch/commit/6a93854)) * Bump fastify from 4.9.2 to 4.10.2 ([8ae9122](https://github.com/elbywan/wretch/commit/8ae9122)) ### :art: Code improvement(s) * Add a prepare script ([17b0a76](https://github.com/elbywan/wretch/commit/17b0a76)) ### :bug: Bug fix(es) * Fix a minor Wretch type issue in addons ([23ba7b1](https://github.com/elbywan/wretch/commit/23ba7b1)) ### :factory: New feature(s) * Add progress addon ([2bae524](https://github.com/elbywan/wretch/commit/2bae524)), closes [#154](https://github.com/elbywan/wretch/issues/154) ## [2.1.5](https://github.com/elbywan/wretch/compare/2.1.4...2.1.5) (2022-10-15) ### :arrow_up: Version update(s) * Bump dependencies ([6043c75](https://github.com/elbywan/wretch/commit/6043c75)) * Bump fastify from 4.3.0 to 4.8.1 ([130ccc2](https://github.com/elbywan/wretch/commit/130ccc2)) ### :bug: Bug fix(es) * Query addon should strip undefined values ([ce395b5](https://github.com/elbywan/wretch/commit/ce395b5)), closes [#148](https://github.com/elbywan/wretch/issues/148) ### :memo: Documentation update(s) * Add timeout code sample in the readme ([beb51c8](https://github.com/elbywan/wretch/commit/beb51c8)) * Fix outdated code comments ([d4c546d](https://github.com/elbywan/wretch/commit/d4c546d)) * Fix unpkg url in the readme ([07d4a00](https://github.com/elbywan/wretch/commit/07d4a00)) ## [2.1.4](https://github.com/elbywan/wretch/compare/2.1.3...2.1.4) (2022-09-28) ### :bug: Bug fix(es) * Relax the typechecker when using resolve within defer ([9e052c8](https://github.com/elbywan/wretch/commit/9e052c8)), closes [#146](https://github.com/elbywan/wretch/issues/146) ## [2.1.3](https://github.com/elbywan/wretch/compare/2.1.2...2.1.3) (2022-09-28) ### :bug: Bug fix(es) * Fix the retry middleware crashing on network errors ([95cbad5](https://github.com/elbywan/wretch/commit/95cbad5)), closes [#145](https://github.com/elbywan/wretch/issues/145) ## [2.1.2](https://github.com/elbywan/wretch/compare/2.1.1...2.1.2) (2022-09-27) ### :art: Code improvement(s) * Fix some linter warnings ([c1029c8](https://github.com/elbywan/wretch/commit/c1029c8)) ### :bug: Bug fix(es) * Fix type inconsistencies in the body parsers ([b7cae7e](https://github.com/elbywan/wretch/commit/b7cae7e)), closes [#143](https://github.com/elbywan/wretch/issues/143) ### :memo: Documentation update(s) * Fix throttling cache documentation link ([f66859d](https://github.com/elbywan/wretch/commit/f66859d)) ## [2.1.1](https://github.com/elbywan/wretch/compare/2.1.0...2.1.1) (2022-09-03) ### :bug: Bug fix(es) * Fix typo in function name #141 ([d82cfd5](https://github.com/elbywan/wretch/commit/d82cfd5)), closes [#141](https://github.com/elbywan/wretch/issues/141) # [2.1.0](https://github.com/elbywan/wretch/compare/2.0.4...2.1.0) (2022-09-03) ### :factory: New feature(s) * Add ability to resolve with latest response to the retry middle ([60a7453](https://github.com/elbywan/wretch/commit/60a7453)), closes [#141](https://github.com/elbywan/wretch/issues/141) ### :memo: Documentation update(s) * Remove outdated documentation entries for the retry middleware ([7a5620c](https://github.com/elbywan/wretch/commit/7a5620c)) ## [2.0.4](https://github.com/elbywan/wretch/compare/2.0.3...2.0.4) (2022-08-18) ### :art: Code improvement(s) * Harmonize WretchError types ([1981837](https://github.com/elbywan/wretch/commit/1981837)) ## [2.0.3](https://github.com/elbywan/wretch/compare/2.0.2...2.0.3) (2022-08-16) ### :art: Code improvement(s) * Export WretchError from the root index ([76f9096](https://github.com/elbywan/wretch/commit/76f9096)), closes [#79](https://github.com/elbywan/wretch/issues/79) ## [2.0.2](https://github.com/elbywan/wretch/compare/2.0.1...2.0.2) (2022-08-03) ### :bug: Bug fix(es) * Fix defer and resolve return types. ([0c59c6c](https://github.com/elbywan/wretch/commit/0c59c6c)), closes [#140](https://github.com/elbywan/wretch/issues/140) ## [2.0.1](https://github.com/elbywan/wretch/compare/2.0.0...2.0.1) (2022-08-02) ### :arrow_up: Version update(s) * Add unpkg field to map to the right bundle. ([ae87b64](https://github.com/elbywan/wretch/commit/ae87b64)) * Upgrade dependencies. ([b6a1258](https://github.com/elbywan/wretch/commit/b6a1258)) ### :memo: Documentation update(s) * Update cdn links. ([7571101](https://github.com/elbywan/wretch/commit/7571101)) # [2.0.0](https://github.com/elbywan/wretch/compare/2.0.0-next.1...2.0.0) (2022-08-01) # [2.0.0-next.1](https://github.com/elbywan/wretch/compare/1.7.10...2.0.0-next.1) (2022-07-08) ### :arrow_up: Version update(s) * Bump packages ([5302d04](https://github.com/elbywan/wretch/commit/5302d04)) ### :art: Code improvement(s) * Add editorconfig ([e81eaff](https://github.com/elbywan/wretch/commit/e81eaff)) * Improved packaging and bundling ([69c1e35](https://github.com/elbywan/wretch/commit/69c1e35)) ### :bug: Bug fix(es) * Fix the jest resolver ([3a1f7b8](https://github.com/elbywan/wretch/commit/3a1f7b8)) ### :docs: undefined * Update readme and website ([2eb24dc](https://github.com/elbywan/wretch/commit/2eb24dc)) ### :factory: New feature(s) * Add error cause ([9a0a387](https://github.com/elbywan/wretch/commit/9a0a387)), closes [#98](https://github.com/elbywan/wretch/issues/98) * Mark errors with a custom class ([211c902](https://github.com/elbywan/wretch/commit/211c902)), closes [#79](https://github.com/elbywan/wretch/issues/79) ### :fire: Breaking change(s) * Add url arg and harmonize replace/mixin arguments ([8e4d0aa](https://github.com/elbywan/wretch/commit/8e4d0aa)) * Complete refactoring ([c2f5035](https://github.com/elbywan/wretch/commit/c2f5035)) * Drop support on node < 14 ([1ff926c](https://github.com/elbywan/wretch/commit/1ff926c)) * Restore normal array behaviour for formdata and fix tests ([6879d48](https://github.com/elbywan/wretch/commit/6879d48)), closes [#119](https://github.com/elbywan/wretch/issues/119) ### :memo: Documentation update(s) * Additional improvements ([e79ff71](https://github.com/elbywan/wretch/commit/e79ff71)) * Autogenerate API documentation and split it from the main README ([c710a71](https://github.com/elbywan/wretch/commit/c710a71)) * Move svg asset and minor readme changes ([30de07c](https://github.com/elbywan/wretch/commit/30de07c)) * Regenerate api doc ([7ae5b57](https://github.com/elbywan/wretch/commit/7ae5b57)) * Small edits to the contributing file and renames scripts related t ([abec7f0](https://github.com/elbywan/wretch/commit/abec7f0)) * Update browserstack badge. ([91cad34](https://github.com/elbywan/wretch/commit/91cad34)) * Update bundle size ([1115d34](https://github.com/elbywan/wretch/commit/1115d34)) * Update companion website ([d6bb842](https://github.com/elbywan/wretch/commit/d6bb842)) * Update documentation ([15fd187](https://github.com/elbywan/wretch/commit/15fd187)) ### :white_check_mark: Test improvement(s) * Better tests coverage ([77e85dc](https://github.com/elbywan/wretch/commit/77e85dc)) * Fix resolvers test for node14 ([ca8b559](https://github.com/elbywan/wretch/commit/ca8b559)) * Fix test on node 18 (with polyfilled fetch) ([d3b7b00](https://github.com/elbywan/wretch/commit/d3b7b00)) * Replace restify with fastify for mock server ([9ee2cfc](https://github.com/elbywan/wretch/commit/9ee2cfc)) * Run lint on CI ([9b819d3](https://github.com/elbywan/wretch/commit/9b819d3)) * Test in multiple version of node in CI ([00d80a6](https://github.com/elbywan/wretch/commit/00d80a6)) ## [1.7.10](https://github.com/elbywan/wretch/compare/1.7.9...1.7.10) (2022-05-21) ### :arrow_up: Version update(s) * Bump minimist from 1.2.5 to 1.2.6 ([6365ad0](https://github.com/elbywan/wretch/commit/6365ad0)) * Bump moment from 2.24.0 to 2.29.2 ([26e3889](https://github.com/elbywan/wretch/commit/26e3889)) * Bump to npm 8 ([9d5758e](https://github.com/elbywan/wretch/commit/9d5758e)) ### :bug: Bug fix(es) * Ignore when the .perf promise throws ([33407ea](https://github.com/elbywan/wretch/commit/33407ea)), closes [#131](https://github.com/elbywan/wretch/issues/131) ### :memo: Documentation update(s) * Update performance api node.js polyfill. ([185420b](https://github.com/elbywan/wretch/commit/185420b)) ### :white_check_mark: Test improvement(s) * Migrate to github actions. ([4b93f43](https://github.com/elbywan/wretch/commit/4b93f43)) ## [1.7.9](https://github.com/elbywan/wretch/compare/1.7.8...1.7.9) (2022-02-05) ### :bug: Bug fix(es) * Body json serialization condition fix. ([1c90fa3](https://github.com/elbywan/wretch/commit/1c90fa3)), closes [#123](https://github.com/elbywan/wretch/issues/123) ## [1.7.8](https://github.com/elbywan/wretch/compare/1.7.7...1.7.8) (2022-01-30) ### :arrow_up: Version update(s) * Bump dependencies and npm audit. ([881d17a](https://github.com/elbywan/wretch/commit/881d17a)) ### :bug: Bug fix(es) * Fix error for opaque responses. ([bbb5912](https://github.com/elbywan/wretch/commit/bbb5912)), closes [#121](https://github.com/elbywan/wretch/issues/121) * Preserve exotic json content types when strigifying body. ([d51c17b](https://github.com/elbywan/wretch/commit/d51c17b)), closes [#122](https://github.com/elbywan/wretch/issues/122) ## [1.7.7](https://github.com/elbywan/wretch/compare/1.7.6...1.7.7) (2021-12-13) ### :bug: Bug fix(es) * Fix errorType argument type. ([5efd606](https://github.com/elbywan/wretch/commit/5efd606)), closes [#118](https://github.com/elbywan/wretch/issues/118) ### :memo: Documentation update(s) * Update outdated badges. ([f286481](https://github.com/elbywan/wretch/commit/f286481)) ## [1.7.6](https://github.com/elbywan/wretch/compare/1.7.5...1.7.6) (2021-08-06) ### :arrow_up: Version update(s) * Upgrade dependencies. ([f62f977](https://github.com/elbywan/wretch/commit/f62f977)) ### :bug: Bug fix(es) * Prevent appending an extra ?/& for empty query strings. #114 ([15464a8](https://github.com/elbywan/wretch/commit/15464a8)), closes [#114](https://github.com/elbywan/wretch/issues/114) ### :memo: Documentation update(s) * Update readme badges. ([b65878f](https://github.com/elbywan/wretch/commit/b65878f)) ## [1.7.5](https://github.com/elbywan/wretch/compare/1.7.4...1.7.5) (2021-06-30) ### :arrow_up: Version update(s) * Bump find-my-way from 2.2.1 to 2.2.5 ([687a999](https://github.com/elbywan/wretch/commit/687a999)) * Bump handlebars from 4.7.6 to 4.7.7 ([0cb2ac2](https://github.com/elbywan/wretch/commit/0cb2ac2)) * Bump hosted-git-info from 2.8.8 to 2.8.9 ([c862315](https://github.com/elbywan/wretch/commit/c862315)) * Bump ini from 1.3.5 to 1.3.7 ([79fd31f](https://github.com/elbywan/wretch/commit/79fd31f)) * Bump lodash from 4.17.19 to 4.17.21 ([fe66a14](https://github.com/elbywan/wretch/commit/fe66a14)) * Bump node-notifier from 8.0.0 to 8.0.1 ([43cd685](https://github.com/elbywan/wretch/commit/43cd685)) * Bump ws from 7.3.1 to 7.4.6 ([d0f89f1](https://github.com/elbywan/wretch/commit/d0f89f1)) * Bump y18n from 4.0.0 to 4.0.1 ([6d0fbdc](https://github.com/elbywan/wretch/commit/6d0fbdc)) * Upgrade dependencies. ([805fade](https://github.com/elbywan/wretch/commit/805fade)) ### :bug: Bug fix(es) * Take into account the options argument headers when stringifying bo ([23484fd](https://github.com/elbywan/wretch/commit/23484fd)), closes [#75](https://github.com/elbywan/wretch/issues/75) ### :memo: Documentation update(s) * Update readme import section ([5970e6d](https://github.com/elbywan/wretch/commit/5970e6d)) ## [1.7.4](https://github.com/elbywan/wretch/compare/1.7.3...1.7.4) (2020-10-14) ### :bug: Bug fix(es) * Fix post with overloaded json content-type charset. ([af48887](https://github.com/elbywan/wretch/commit/af48887)) ### :memo: Documentation update(s) * Update package size approximation. ([2399419](https://github.com/elbywan/wretch/commit/2399419)) ## [1.7.3](https://github.com/elbywan/wretch/compare/1.7.2...1.7.3) (2020-10-12) ### :arrow_up: Version update(s) * Bump lodash from 4.17.14 to 4.17.19 ([c5c255f](https://github.com/elbywan/wretch/commit/c5c255f)) * Bump node-fetch from 2.6.0 to 2.6.1 ([d536ba5](https://github.com/elbywan/wretch/commit/d536ba5)) * Upgrade dependencies ([0bb3235](https://github.com/elbywan/wretch/commit/0bb3235)) ### :bug: Bug fix(es) * Allow custom charset with json body. ([52d2caa](https://github.com/elbywan/wretch/commit/52d2caa)), closes [#90](https://github.com/elbywan/wretch/issues/90) ### :memo: Documentation update(s) * Fix readme arry typo. ([b465a4f](https://github.com/elbywan/wretch/commit/b465a4f)) * Fix readme bad chars. ([12b7231](https://github.com/elbywan/wretch/commit/12b7231)) * Mention Deno in the readme. ([b52847a](https://github.com/elbywan/wretch/commit/b52847a)) ## [1.7.2](https://github.com/elbywan/wretch/compare/1.7.1...1.7.2) (2020-04-13) ### :arrow_up: Version update(s) * Bump acorn from 6.4.0 to 6.4.1 ([24bc906](https://github.com/elbywan/wretch/commit/24bc906)) * Upgrade dependencies ([76b32fd](https://github.com/elbywan/wretch/commit/76b32fd)) ### :bug: Bug fix(es) * Prevent overriding content-type when passing body in http methods. ([f6f9302](https://github.com/elbywan/wretch/commit/f6f9302)), closes [#75](https://github.com/elbywan/wretch/issues/75) ## [1.7.1](https://github.com/elbywan/wretch/compare/1.7.0...1.7.1) (2020-01-25) ### :bug: Bug fix(es) * Fix crash on nested null formdata value. #68 ([9c1adf0](https://github.com/elbywan/wretch/commit/9c1adf0)), closes [#68](https://github.com/elbywan/wretch/issues/68) ### :memo: Documentation update(s) * Update broken readme link. ([e115c63](https://github.com/elbywan/wretch/commit/e115c63)) # [1.7.0](https://github.com/elbywan/wretch/compare/1.6.0...1.7.0) (2020-01-25) ### :arrow_up: Version update(s) * Upgrade packages ([a68d94e](https://github.com/elbywan/wretch/commit/a68d94e)) ### :factory: New feature(s) * Support nested objects in formData. #68 ([90d9555](https://github.com/elbywan/wretch/commit/90d9555)), closes [#68](https://github.com/elbywan/wretch/issues/68) # [1.6.0](https://github.com/elbywan/wretch/compare/1.5.5...1.6.0) (2019-11-27) ### :factory: New feature(s) * Add esm bundle. #63 ([9655b46](https://github.com/elbywan/wretch/commit/9655b46)), closes [#63](https://github.com/elbywan/wretch/issues/63) * Add fetch error catcher. #62 ([96a147c](https://github.com/elbywan/wretch/commit/96a147c)), closes [#62](https://github.com/elbywan/wretch/issues/62) ## [1.5.5](https://github.com/elbywan/wretch/compare/1.5.4...1.5.5) (2019-10-15) ### :arrow_up: Version update(s) * Upgrade packages ([05c0b9e](https://github.com/elbywan/wretch/commit/05c0b9e)) ### :bug: Bug fix(es) * Fix handling falsey values for body callback and payload. ([2d99a4f](https://github.com/elbywan/wretch/commit/2d99a4f)), closes [#58](https://github.com/elbywan/wretch/issues/58) ### :memo: Documentation update(s) * Update readme browserstack badge. ([eddfd91](https://github.com/elbywan/wretch/commit/eddfd91)) ### :white_check_mark: Test improvement(s) * Restore latest browserstack matrix and add an exceptio ([ef09fd8](https://github.com/elbywan/wretch/commit/ef09fd8)) * Use macos firefox on browserstack ([e51048e](https://github.com/elbywan/wretch/commit/e51048e)) ## [1.5.4](https://github.com/elbywan/wretch/compare/1.5.3...1.5.4) (2019-07-16) ### :arrow_up: Version update(s) * Upgrade packages to fix vulnerabilities. ([dced4c1](https://github.com/elbywan/wretch/commit/dced4c1)) ### :memo: Documentation update(s) * Fix readme opts link ([5595ef7](https://github.com/elbywan/wretch/commit/5595ef7)) ### :white_check_mark: Test improvement(s) * Add missing browser test ([2f5498c](https://github.com/elbywan/wretch/commit/2f5498c)) * Add missing browser tests ([9bd7e4f](https://github.com/elbywan/wretch/commit/9bd7e4f)) * Fix browserstack browser & os matrix. ([451ef23](https://github.com/elbywan/wretch/commit/451ef23)) ## [1.5.3](https://github.com/elbywan/wretch/compare/1.5.2...1.5.3) (2019-07-11) ### :arrow_up: Version update(s) * Upgrade dependencies ([5e77291](https://github.com/elbywan/wretch/commit/5e77291)) ### :bug: Bug fix(es) * Preserve headers on null/undefined argument ([9e3fe0a](https://github.com/elbywan/wretch/commit/9e3fe0a)), closes [#52](https://github.com/elbywan/wretch/issues/52) ## [1.5.2](https://github.com/elbywan/wretch/compare/1.5.1...1.5.2) (2019-04-28) ### :bug: Bug fix(es) * Clear pending timeout when request resolves / fails ([687570b](https://github.com/elbywan/wretch/commit/687570b)), closes [#50](https://github.com/elbywan/wretch/issues/50) ### :memo: Documentation update(s) * Add 1.5.1 changelog ([fd4386c](https://github.com/elbywan/wretch/commit/fd4386c)) * Fix .catcher documentation typo. ([2b98d6b](https://github.com/elbywan/wretch/commit/2b98d6b)) * Remove bad usage of .error in the readme ([a5209d0](https://github.com/elbywan/wretch/commit/a5209d0)) ## [1.5.1](https://github.com/elbywan/wretch/compare/1.5.0...1.5.1) (2019-03-17) ### :arrow_up: Version update(s) * Upgrade rollup dep ([d890b8a](https://github.com/elbywan/wretch/commit/d890b8a)) ### :bug: Bug fix(es) * Fix mutating catchers propagation to cloned wretchers ([d207027](https://github.com/elbywan/wretch/commit/d207027)), closes [#44](https://github.com/elbywan/wretch/issues/44) ### :memo: Documentation update(s) * Add the concept of middleware context to the readme. ([50a78c5](https://github.com/elbywan/wretch/commit/50a78c5)) * Change package kb size displayed in the html ([b3ebb78](https://github.com/elbywan/wretch/commit/b3ebb78)) ### :white_check_mark: Test improvement(s) * CI build on node.js LTS ([90290ab](https://github.com/elbywan/wretch/commit/90290ab)) * Test form-data with streams. ([92af63a](https://github.com/elbywan/wretch/commit/92af63a)) # [1.5.0](https://github.com/elbywan/wretch/compare/1.4.2...1.5.0) (2019-02-23) ### :arrow_up: Version update(s) * Upgrade dependencies and fix package version in lock file ([b17d10a](https://github.com/elbywan/wretch/commit/b17d10a)) * Upgrade jest and rollup ([0573f7a](https://github.com/elbywan/wretch/commit/0573f7a)) ### :art: Code improvement(s) * Add inline source maps ([03ca27e](https://github.com/elbywan/wretch/commit/03ca27e)) ### :factory: New feature(s) * Add a replay() method. ([5af4ecc](https://github.com/elbywan/wretch/commit/5af4ecc)), closes [#35](https://github.com/elbywan/wretch/issues/35) ### :memo: Documentation update(s) * More details about the response types in the readme ([270fe16](https://github.com/elbywan/wretch/commit/270fe16)) ## [1.4.2](https://github.com/elbywan/wretch/compare/1.4.1...1.4.2) (2018-10-21) ### :arrow_up: Version update(s) * Upgrade packages ([268565d](https://github.com/elbywan/wretch/commit/268565d)) ### :art: Code improvement(s) * Export typedefs at the root level ([d2bcb13](https://github.com/elbywan/wretch/commit/d2bcb13)) ### :memo: Documentation update(s) * Fix readme typo ([78b7a2b](https://github.com/elbywan/wretch/commit/78b7a2b)) * Update .query documentation ([03c5cbe](https://github.com/elbywan/wretch/commit/03c5cbe)) ### :white_check_mark: Test improvement(s) * Improve performance timings test coverage ([c4db506](https://github.com/elbywan/wretch/commit/c4db506)) ## [1.4.1](https://github.com/elbywan/wretch/compare/1.4.0...1.4.1) (2018-08-13) ### :arrow_up: Version update(s) * 1.4.1 tag ([429fd8d](https://github.com/elbywan/wretch/commit/429fd8d)) * Upgrade devDeps ([0a6c223](https://github.com/elbywan/wretch/commit/0a6c223)) ### :art: Code improvement(s) * Improve typedefs ([232c063](https://github.com/elbywan/wretch/commit/232c063)) ### :bug: Bug fix(es) * Add default errorType to response object ([c134efa](https://github.com/elbywan/wretch/commit/c134efa)) ### :white_check_mark: Test improvement(s) * Improve unit tests to check default error type ([3f1bb4b](https://github.com/elbywan/wretch/commit/3f1bb4b)), closes [#c134](https://github.com/elbywan/wretch/issues/c134) * Prevent running browserstack on PRs ([c350060](https://github.com/elbywan/wretch/commit/c350060)) # [1.4.0](https://github.com/elbywan/wretch/compare/1.3.1...1.4.0) (2018-07-10) ### :arrow_up: Version update(s) * 1.4.0 tag ([27acc8e](https://github.com/elbywan/wretch/commit/27acc8e)) ### :fire: Breaking change(s) * Make .formUrl encode arrays in a standard way ([f04c9af](https://github.com/elbywan/wretch/commit/f04c9af)), closes [#26](https://github.com/elbywan/wretch/issues/26) ## [1.3.1](https://github.com/elbywan/wretch/compare/1.3.0...1.3.1) (2018-06-12) ### :arrow_up: Version update(s) * 1.3.1 tag ([f162e0e](https://github.com/elbywan/wretch/commit/f162e0e)) ### :art: Code improvement(s) * Launch the mock server aside of the test file. ([35c5a4e](https://github.com/elbywan/wretch/commit/35c5a4e)) ### :memo: Documentation update(s) * Add bundlephobia badge. ([0399a65](https://github.com/elbywan/wretch/commit/0399a65)) * Add paypal badge ([cd98e4d](https://github.com/elbywan/wretch/commit/cd98e4d)) * Fix broken readme links. ([75f767d](https://github.com/elbywan/wretch/commit/75f767d)) * Mention browserstack in the readme. ([2f6ad8e](https://github.com/elbywan/wretch/commit/2f6ad8e)) * Update readme package version ([04f75ce](https://github.com/elbywan/wretch/commit/04f75ce)) # [1.3.0](https://github.com/elbywan/wretch/compare/1.2.0...1.3.0) (2018-06-09) ### :arrow_up: Version update(s) * 1.3.0 tag ([ff05dfc](https://github.com/elbywan/wretch/commit/ff05dfc)) ### :bug: Bug fix(es) * Fix .url call when the url contains query parameters ([e68764f](https://github.com/elbywan/wretch/commit/e68764f)) ### :factory: New feature(s) * Add deferred callback chain. ([10ddfe5](https://github.com/elbywan/wretch/commit/10ddfe5)) ### :fire: Breaking change(s) * Add body argument shorthand to the http methods. ([103cde3](https://github.com/elbywan/wretch/commit/103cde3)) ### :memo: Documentation update(s) * Mention the wretch-middlewares package in the readme ([880c02c](https://github.com/elbywan/wretch/commit/880c02c)) * Update .query anchor ([b2670d9](https://github.com/elbywan/wretch/commit/b2670d9)) # [1.2.0](https://github.com/elbywan/wretch/compare/1.1.2...1.2.0) (2018-05-24) ### :arrow_up: Version update(s) * 1.2.0 tag ([3f067df](https://github.com/elbywan/wretch/commit/3f067df)) ### :factory: New feature(s) * Accept string argument in .query() #20 ([b53cca3](https://github.com/elbywan/wretch/commit/b53cca3)), closes [#20](https://github.com/elbywan/wretch/issues/20) ### :fire: Breaking change(s) * Make .query() chainable #20 ([1a6a7c8](https://github.com/elbywan/wretch/commit/1a6a7c8)), closes [#20](https://github.com/elbywan/wretch/issues/20) ### :white_check_mark: Test improvement(s) * Add more node.js versions used by the travis CI ([7d6d779](https://github.com/elbywan/wretch/commit/7d6d779)) * Fixes for node.js v10 ([0dcba96](https://github.com/elbywan/wretch/commit/0dcba96)) ## [1.1.2](https://github.com/elbywan/wretch/compare/1.1.1...1.1.2) (2018-03-07) ### :arrow_up: Version update(s) * 1.1.2 tag ([f4e9ffe](https://github.com/elbywan/wretch/commit/f4e9ffe)) ### :art: Code improvement(s) * Relaxed Response & Options types ([16c0b97](https://github.com/elbywan/wretch/commit/16c0b97)) ### :white_check_mark: Test improvement(s) * Update tests with a working abortController polyfill ([171ac48](https://github.com/elbywan/wretch/commit/171ac48)) ## [1.1.1](https://github.com/elbywan/wretch/compare/1.1.0...1.1.1) (2018-01-08) ### :arrow_up: Version update(s) * 1.1.1 tag ([efc67a4](https://github.com/elbywan/wretch/commit/efc67a4)) ### :art: Code improvement(s) * Remove typo ([7883219](https://github.com/elbywan/wretch/commit/7883219)) ### :factory: New feature(s) * Pass the original request to the catchers/resolvers callback ([1e4d3a4](https://github.com/elbywan/wretch/commit/1e4d3a4)) ### :memo: Documentation update(s) * Update middleware and intro ([09b0dc1](https://github.com/elbywan/wretch/commit/09b0dc1)) # [1.1.0](https://github.com/elbywan/wretch/compare/1.0.0...1.1.0) (2017-11-17) ### :arrow_up: Version update(s) * 1.1.0 tag ([75e0c68](https://github.com/elbywan/wretch/commit/75e0c68)) ### :art: Code improvement(s) * Comply with the commonjs typescript transpilation (#10) ([6931ff6](https://github.com/elbywan/wretch/commit/6931ff6)), closes [#10](https://github.com/elbywan/wretch/issues/10) * Refactor method function call ([cf07316](https://github.com/elbywan/wretch/commit/cf07316)) * Remove irregular whitespace ([7bc2990](https://github.com/elbywan/wretch/commit/7bc2990)) ### :bug: Bug fix(es) * Fix es6 const generated by rollup typescript helpers ([6791721](https://github.com/elbywan/wretch/commit/6791721)), closes [#11](https://github.com/elbywan/wretch/issues/11) ### :factory: New feature(s) * Add middlewares helper. (#12) ([b9c6a65](https://github.com/elbywan/wretch/commit/b9c6a65)), closes [#12](https://github.com/elbywan/wretch/issues/12) ### :memo: Documentation update(s) * Adding middlewares code samples (#12). ([b43cb1b](https://github.com/elbywan/wretch/commit/b43cb1b)), closes [#12](https://github.com/elbywan/wretch/issues/12) * Update npm badge color ([0eae7bb](https://github.com/elbywan/wretch/commit/0eae7bb)) * Update readme top message and remove experimental flag for abortin ([e449b46](https://github.com/elbywan/wretch/commit/e449b46)) # [1.0.0](https://github.com/elbywan/wretch/compare/0.3.1...1.0.0) (2017-10-20) ### :arrow_up: Version update(s) * 1.0.0 tag ([63b7d2b](https://github.com/elbywan/wretch/commit/63b7d2b)) ### :art: Code improvement(s) * Widen resolver return type ([6e2b299](https://github.com/elbywan/wretch/commit/6e2b299)) ### :factory: New feature(s) * Add auth method to set the Authorization header. ([1694396](https://github.com/elbywan/wretch/commit/1694396)) * Add early resolvers with the resolve function ([481803b](https://github.com/elbywan/wretch/commit/481803b)) * Add HEAD and OPTIONS http methods. ([3c30844](https://github.com/elbywan/wretch/commit/3c30844)) ### :memo: Documentation update(s) * Add homepage usage section, tagboxes and footer ([fd3bcf7](https://github.com/elbywan/wretch/commit/fd3bcf7)) * Bypass jekyll ([22c957c](https://github.com/elbywan/wretch/commit/22c957c)) * Fix readme typo ([9d1b4c6](https://github.com/elbywan/wretch/commit/9d1b4c6)) * Readme modifications : fix method links, simplify polyfills, add h ([e37ea0b](https://github.com/elbywan/wretch/commit/e37ea0b)) ### :white_check_mark: Test improvement(s) * Migrate from mocha to jest ([f67bd84](https://github.com/elbywan/wretch/commit/f67bd84)) ## [0.3.1](https://github.com/elbywan/wretch/compare/0.3.0...0.3.1) (2017-10-09) ### :arrow_up: Version update(s) * 0.3.1 tag ([ccca2dc](https://github.com/elbywan/wretch/commit/ccca2dc)) ### :memo: Documentation update(s) * Add homepage in package.json ([c78a5dd](https://github.com/elbywan/wretch/commit/c78a5dd)) # [0.3.0](https://github.com/elbywan/wretch/compare/0.2.4...0.3.0) (2017-10-09) ### :arrow_up: Version update(s) * 0.3.0 tag ([a9450c1](https://github.com/elbywan/wretch/commit/a9450c1)) ### :art: Code improvement(s) * Add polyfill getter method ([ca49cfc](https://github.com/elbywan/wretch/commit/ca49cfc)) * Can now catch on error name ([2a0f7e9](https://github.com/elbywan/wretch/commit/2a0f7e9)) ### :checkered_flag: Performance update(s) * Refactor perfs() to improve robustness and performance ([7b2b27c](https://github.com/elbywan/wretch/commit/7b2b27c)) ### :factory: New feature(s) * Abortable requests ([c5888fe](https://github.com/elbywan/wretch/commit/c5888fe)), closes [#7](https://github.com/elbywan/wretch/issues/7) * Add formUrl body type ([64f6c3e](https://github.com/elbywan/wretch/commit/64f6c3e)), closes [#9](https://github.com/elbywan/wretch/issues/9) ### :fire: Breaking change(s) * The .options function now mixin by default ([47b4630](https://github.com/elbywan/wretch/commit/47b4630)) * Remove .baseUrl and change .url behaviour ([5142b02](https://github.com/elbywan/wretch/commit/5142b02)), closes [#8](https://github.com/elbywan/wretch/issues/8) ### :memo: Documentation update(s) * Add methods indexes and clarify some point in the readme ([54dae1c](https://github.com/elbywan/wretch/commit/54dae1c)) * Add minimalist companion website. ([10f2197](https://github.com/elbywan/wretch/commit/10f2197)) * Add readme announcement. ([d87a57d](https://github.com/elbywan/wretch/commit/d87a57d)) * Fix readme typo ([85852a6](https://github.com/elbywan/wretch/commit/85852a6)) * Fixed readme usage layout ([7f8ea0f](https://github.com/elbywan/wretch/commit/7f8ea0f)) * Update readme ([7881e2c](https://github.com/elbywan/wretch/commit/7881e2c)) ## [0.2.4](https://github.com/elbywan/wretch/compare/0.2.3...0.2.4) (2017-10-06) ### :arrow_up: Version update(s) * 0.2.4 tag ([879e14a](https://github.com/elbywan/wretch/commit/879e14a)) ### :bug: Bug fix(es) * Fix perfs() concurrency issues ([79f86ce](https://github.com/elbywan/wretch/commit/79f86ce)) ## [0.2.3](https://github.com/elbywan/wretch/compare/0.2.2...0.2.3) (2017-10-06) ### :arrow_up: Version update(s) * 0.2.3 tag ([cce504c](https://github.com/elbywan/wretch/commit/cce504c)) ### :art: Code improvement(s) * Add module field in package.json ([90431ff](https://github.com/elbywan/wretch/commit/90431ff)) * Add node.js partial support to the perf function ([0045672](https://github.com/elbywan/wretch/commit/0045672)) * Hide the changelog preset beneath a scripts folder + rewrite ([696503c](https://github.com/elbywan/wretch/commit/696503c)) ### :factory: New feature(s) * Highly experimental perfs function. ([6fa1d29](https://github.com/elbywan/wretch/commit/6fa1d29)) ### :memo: Documentation update(s) * Correct errorType typo ([e058b7a](https://github.com/elbywan/wretch/commit/e058b7a)) * Fix contributing typo ([d12e29c](https://github.com/elbywan/wretch/commit/d12e29c)) * Perfs() documentation ([6c90e15](https://github.com/elbywan/wretch/commit/6c90e15)) * Readme : image cdn and shorten unpkg link ([8eac8c9](https://github.com/elbywan/wretch/commit/8eac8c9)) ### :white_check_mark: Test improvement(s) * Write perfs() tests ([3a14499](https://github.com/elbywan/wretch/commit/3a14499)) ## [0.2.2](https://github.com/elbywan/wretch/compare/0.2.1...0.2.2) (2017-10-04) ### :arrow_up: Version update(s) * 0.2.2 tag ([0883134](https://github.com/elbywan/wretch/commit/0883134)) ### :art: Code improvement(s) * Moves polyfills to the config object ([2820e34](https://github.com/elbywan/wretch/commit/2820e34)) ### :factory: New feature(s) * Allow non-global fetch & FormData ([112b9cc](https://github.com/elbywan/wretch/commit/112b9cc)) ## [0.2.1](https://github.com/elbywan/wretch/compare/0.2.0...0.2.1) (2017-10-03) ### :arrow_up: Version update(s) * 0.2.1 tag ([d13e8ad](https://github.com/elbywan/wretch/commit/d13e8ad)) ### :art: Code improvement(s) * Add custom changelog preset ([023a73c](https://github.com/elbywan/wretch/commit/023a73c)) * change changelog format to atom ([970bf7b](https://github.com/elbywan/wretch/commit/970bf7b)) ### :bug: Bug fix(es) * Fix baseUrl not mixing in options ([5c90df4](https://github.com/elbywan/wretch/commit/5c90df4)) ### :memo: Documentation update(s) * Add badges ([d29c96d](https://github.com/elbywan/wretch/commit/d29c96d)) * Regenerate changelog ([c14ede7](https://github.com/elbywan/wretch/commit/c14ede7)) * Update contributing guidelines ([b96022d](https://github.com/elbywan/wretch/commit/b96022d)) # [0.2.0](https://github.com/elbywan/wretch/compare/0.1.5...0.2.0) (2017-10-03) ### :arrow_up: Version update(s) * 0.2.0 tag ([d903c48](https://github.com/elbywan/wretch/commit/d903c48)) ### :fire: Breaking change(s) * :art: Replace mixdefaults with a mixin flag. ([c497f6e](https://github.com/elbywan/wretch/commit/c497f6e)) ### :memo: Documentation update(s) * Create CONTRIBUTING.md ([c79578a](https://github.com/elbywan/wretch/commit/c79578a)) * Update readme with unpkg ([1131755](https://github.com/elbywan/wretch/commit/1131755)) * Update README.md ([b8f3cc8](https://github.com/elbywan/wretch/commit/b8f3cc8)) ## [0.1.5](https://github.com/elbywan/wretch/compare/0.1.4...0.1.5) (2017-10-03) ### :arrow_up: Version update(s) * 0.1.5 tag ([6551424](https://github.com/elbywan/wretch/commit/6551424)) ### :art: Code improvement(s) * Update changelog ([7717052](https://github.com/elbywan/wretch/commit/7717052)) ### :checkered_flag: Performance update(s) * Use a Map instead of an Array for catchers ([dba8e63](https://github.com/elbywan/wretch/commit/dba8e63)) ## [0.1.4](https://github.com/elbywan/wretch/compare/0.1.3...0.1.4) (2017-10-03) ### :art: Code improvement(s) * Better changelog ([d4ae365](https://github.com/elbywan/wretch/commit/d4ae365)) ### :checkered_flag: Performance update(s) * [mix] small perf improvements ([fb319eb](https://github.com/elbywan/wretch/commit/fb319eb)) ### :factory: New feature(s) * Add changelog ([457852d](https://github.com/elbywan/wretch/commit/457852d)) * Add global catchers with the catcher method ([04b5cb9](https://github.com/elbywan/wretch/commit/04b5cb9)) ### :memo: Documentation update(s) * Fix typos ([ad0d612](https://github.com/elbywan/wretch/commit/ad0d612)) * Fix typos ([6b074dc](https://github.com/elbywan/wretch/commit/6b074dc)) * Update README.md ([ff48732](https://github.com/elbywan/wretch/commit/ff48732)) ## [0.1.3](https://github.com/elbywan/wretch/compare/0.1.2...0.1.3) (2017-10-03) ### :arrow_up: Version update(s) * 0.1.3 tag ([c8ad85e](https://github.com/elbywan/wretch/commit/c8ad85e)) * Update deps ([aec23f0](https://github.com/elbywan/wretch/commit/aec23f0)) ### :art: Code improvement(s) * Add gitattributes ([45329a4](https://github.com/elbywan/wretch/commit/45329a4)) * Add tslint ([0078004](https://github.com/elbywan/wretch/commit/0078004)) * Code split ([d3e725a](https://github.com/elbywan/wretch/commit/d3e725a)) * Update .gitattributes ([52eebb1](https://github.com/elbywan/wretch/commit/52eebb1)) ### :bug: Bug fix(es) * Fix typos in mergeArrays ([966cbeb](https://github.com/elbywan/wretch/commit/966cbeb)) ### :factory: New feature(s) * Add headers/content/body methods and better options type. ([3c9c10e](https://github.com/elbywan/wretch/commit/3c9c10e)) ### :memo: Documentation update(s) * Clearer README ([4579bb6](https://github.com/elbywan/wretch/commit/4579bb6)) * Update README.md ([743b7d5](https://github.com/elbywan/wretch/commit/743b7d5)) * Update README.md ([11094dd](https://github.com/elbywan/wretch/commit/11094dd)) * Update README.md ([9bc38dd](https://github.com/elbywan/wretch/commit/9bc38dd)) ## [0.1.2](https://github.com/elbywan/wretch/compare/0.1.1...0.1.2) (2017-10-03) ### :arrow_up: Version update(s) * 0.1.2 tag ([eb3a094](https://github.com/elbywan/wretch/commit/eb3a094)) ### :art: Code improvement(s) * Correct types ([f6aeb64](https://github.com/elbywan/wretch/commit/f6aeb64)) * Improve typescript definitions ([b8d4e96](https://github.com/elbywan/wretch/commit/b8d4e96)) ### :factory: New feature(s) * Add baseUrl ([a0107c9](https://github.com/elbywan/wretch/commit/a0107c9)), closes [#2](https://github.com/elbywan/wretch/issues/2) ### :memo: Documentation update(s) * Readme update ([e2e3522](https://github.com/elbywan/wretch/commit/e2e3522)) * Readme update ([3cb3b23](https://github.com/elbywan/wretch/commit/3cb3b23)) * Typo fix ([6a06919](https://github.com/elbywan/wretch/commit/6a06919)) * Update README.md ([ae0c9c0](https://github.com/elbywan/wretch/commit/ae0c9c0)) ## [0.1.1](https://github.com/elbywan/wretch/compare/0.1.0...0.1.1) (2017-10-03) ### :arrow_up: Version update(s) * 0.1.1 tag ([f054836](https://github.com/elbywan/wretch/commit/f054836)) ### :art: Code improvement(s) * Correct optional callbacks in declaration files ([0b37983](https://github.com/elbywan/wretch/commit/0b37983)) # [0.1.0](https://github.com/elbywan/wretch/compare/0.0.1...0.1.0) (2017-10-03) ### :arrow_up: Version update(s) * 0.1.0 tag ([2d161d6](https://github.com/elbywan/wretch/commit/2d161d6)) ### :art: Code improvement(s) * Add coverage ([517ee5d](https://github.com/elbywan/wretch/commit/517ee5d)) * Move from webpack to rollup and restore source maps ([6515d7a](https://github.com/elbywan/wretch/commit/6515d7a)) ### :fire: Breaking change(s) * Remove source maps ([338f080](https://github.com/elbywan/wretch/commit/338f080)) ### :memo: Documentation update(s) * Add documentation ([5cae7f3](https://github.com/elbywan/wretch/commit/5cae7f3)) ### :white_check_mark: Test improvement(s) * Improve coverage ([5b10a93](https://github.com/elbywan/wretch/commit/5b10a93)) ## [0.0.1](https://github.com/elbywan/wretch/compare/ac4ae15...0.0.1) (2017-10-03) ### :arrow_up: Version update(s) * 0.0.1 tag ([4d6eeed](https://github.com/elbywan/wretch/commit/4d6eeed)) ### :factory: New feature(s) * init ([ac4ae15](https://github.com/elbywan/wretch/commit/ac4ae15)) --- ### CONTRIBUTING # Contributing πŸŽ‰ Thank you for wishing to collaborate to the wretch library! **Ideas, feedback and help are more than welcome.** ## How to ### 1 - Clone the project ```bash git clone https://github.com/elbywan/wretch cd wretch ``` ### 2 - Setup toolchain This project uses [proto](https://moonrepo.dev/proto) to manage tool versions (Node.js, npm, Deno, Bun). Install proto: ```bash # macOS/Linux curl -fsSL https://moonrepo.dev/install/proto.sh | bash # Windows irm https://moonrepo.dev/install/proto.ps1 | iex ``` Then install the required tools: ```bash proto use ``` ### 3 - Install dependencies ```bash npm install ``` ### 4 - Change the code as you see fit ### 5 - Lint, Build and Test ```bash npm start # To run browser specs npm run test:browser # same as the ci npm run test:browser:watch # in watch mode ``` The code **must** pass the linter and specs. If you add a new functionality, please write some tests! If a linter rule which is not already set in the `.eslintrc.js` file is bothering you, feel free to propose a change. ### 6 - Commit & Pull request If the modification is related to an existing issue, please mention the number in the commit message. (for instance: `closes #10`) Also in order to generate a nice changelog file, please begin your commit message with an emoji corresponding to the change: - :fire: `:fire:` -> breaking change - :bug: `:bug:` -> bug fix - :factory: `:factory:` -> new feature - :art: `:art:` -> code improvement - :checkered_flag: `:checkered_flag:` -> performance update - :white_check_mark: `:white_check_mark:` -> test improvement - :memo: `:memo:` -> documentation update - :arrow_up: `:arrow_up:` -> package update Furthermore, starting the actual message content with an upper case and using the present tense and imperative mood would be great. And last but not least, always rebase your branch on top of the origin/master branch! --- ### README

wretch-logo

Wretch

github-badge npm-badge npm-downloads-badge Coverage Status license-badge

A tiny (~1.8KB g-zipped) wrapper built around fetch with an intuitive syntax.

f[ETCH] [WR]apper

##### Wretch 3.0 is now live πŸŽ‰ ! Check out the [Migration Guide](MIGRATION_V2_V3.md) for upgrading from v2, and please have a look at the [releases](https://github.com/elbywan/wretch/releases) and the [changelog](https://github.com/elbywan/wretch/blob/master/CHANGELOG.md) after each update for new features and breaking changes. ##### And if you like the library please consider becoming a [sponsor](https://github.com/sponsors/elbywan) ❀️. # Features #### `wretch` is a small wrapper around [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) designed to simplify the way to perform network requests and handle responses. - πŸͺΆ **Small** - core is less than 1.8KB g-zipped - πŸ’‘ **Intuitive** - lean API, handles errors, headers and (de)serialization - 🧊 **Immutable** - every call creates a cloned instance that can then be reused safely - πŸ”Œ **Modular** - plug addons to add new features, and middlewares to intercept requests - 🧩 **Isomorphic** - compatible with modern browsers, Node.js 22+, Deno and Bun - 🦺 **Type safe** - strongly typed, written in TypeScript - βœ… **Proven** - fully covered by unit tests and widely used - πŸ’“ **Maintained** - alive and well for many years # Table of Contents - [**Quick Start**](#quick-start) - [**Motivation**](#motivation) - [**Installation**](#installation) - [**Compatibility**](#compatibility) - [**Usage**](#usage) - [**Recipes**](#recipes) - [**Api**](#api-) - [**Addons**](#addons) - [**Middlewares**](#middlewares) - [**Migration Guides**](#migration-guides) - [**License**](#license) # Quick Start ```bash # 1️⃣ Install npm i wretch ``` ```javascript // 2️⃣ Import and create a reusable API client import wretch from "wretch" const api = wretch("https://jsonplaceholder.typicode.com") .options({ mode: "cors" }) // 3️⃣ Make requests with automatic JSON handling const post = await api.get("/posts/1").json() console.log(post.title) // 4️⃣ POST with automatic serialization const created = await api .post({ title: "New Post", body: "Content", userId: 1 }, "/posts") .json() // 5️⃣ Handle errors elegantly await api .get("/posts/999") .notFound(() => console.log("Post not found!")) .json() // 6️⃣ Different response types const text = await api.get("/posts/1").text() // Raw text const response = await api.get("/posts/1").res() // Raw Response object const blob = await api.get("/photos/1").blob() // Binary data ``` # Motivation #### Because having to write a second callback to process a response body feels awkward. Fetch needs a second callback to process the response body. ```javascript fetch("https://jsonplaceholder.typicode.com/posts/1") .then(response => response.json()) .then(json => { //Do stuff with the parsed json }); ``` Wretch does it for you. ```javascript // Use .res for the raw response, .text for raw text, .json for json, .blob for a blob … wretch("https://jsonplaceholder.typicode.com/posts/1") .get() .json(json => { // Do stuff with the parsed json return json }); ``` #### Because manually checking and throwing every request error code is tedious. Fetch won't reject on HTTP error status. ```javascript fetch("https://jsonplaceholder.typicode.com/posts/1") .then(response => { if(!response.ok) { if(response.status === 404) throw new Error("Not found") else if(response.status === 401) throw new Error("Unauthorized") else if(response.status === 418) throw new Error("I'm a teapot !") else throw new Error("Other error") } else {/* … */} }) .then(data => {/* … */}) .catch(error => { /* … */ }) ``` Wretch throws when the response is not successful and contains helper methods to handle common codes. ```javascript wretch("https://jsonplaceholder.typicode.com/posts/1") .get() .notFound(error => { /* … */ }) .unauthorized(error => { /* … */ }) .error(418, error => { /* … */ }) .res(response => {/* … */ }) .catch(error => { /* uncaught errors */ }) ``` #### Because sending a json object should be easy. With fetch you have to set the header, the method and the body manually. ```javascript fetch("https://jsonplaceholder.typicode.com/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "hello": "world" }) }).then(response => {/* … */}) // Omitting the data retrieval and error management parts… ``` With wretch, you have shorthands at your disposal. ```javascript wretch("https://jsonplaceholder.typicode.com/posts") .post({ "hello": "world" }) .res(response => { /* … */ }) ``` #### Because configuration should not rhyme with repetition. A Wretch object is immutable which means that you can reuse previous instances safely. ```javascript const token = "MY_SECRET_TOKEN" // Cross origin authenticated requests on an external API const externalApi = wretch("https://jsonplaceholder.typicode.com") // Base url // Authorization header .auth(`Bearer ${token}`) // Cors fetch options .options({ credentials: "include", mode: "cors" }) // Handle 403 errors .resolve((w) => w.forbidden(error => { /* Handle all 403 errors */ })); // Fetch a resource const resource = await externalApi // Add a custom header for this request .headers({ "If-Unmodified-Since": "Wed, 21 Oct 2015 07:28:00 GMT" }) .get("/posts/1") .json(() => {/* do something with the resource */}); // Post a resource externalApi .url("/posts") .post({ "Shiny new": "resource object" }) .json(() => {/* do something with the created resource */}); ``` # Installation ## Package Manager ```sh npm i wretch # or yarn/pnpm add wretch ``` ## <script> tag The package contains multiple bundles depending on the format and feature set located under the `/dist/bundle` folder.
Bundle variants
> πŸ’‘ If you pick the core bundle, then to plug addons you must import them separately from `/dist/bundle/addons/[addonName].min.js` | Feature set | File Name | | ------------------ | ------------------- | | Core features only | `wretch.min.js` | | Core + all addons | `wretch.all.min.js` | | Format | Extension | | -------- | ---------- | | ESM | `.min.mjs` | | CommonJS | `.min.cjs` | | UMD | `.min.js` |
```html ``` # Compatibility ## Browsers `wretch@^3` is compatible with modern browsers only. For older browsers please use `wretch@^1`. ## Node.js Wretch is compatible with and tested in _Node.js >= 22_. For older Node.js versions, please use `wretch@^2`. Node.js 22+ includes native fetch support and all required Web APIs (FormData, URLSearchParams, AbortController, etc.) out of the box, so no polyfills are needed. ## Deno Works with [Deno](https://deno.land/) out of the box. ```bash deno add npm:wretch ``` ```ts import wretch from "wretch"; const text = await wretch("https://httpbingo.org").get("/status/200").text(); console.log(text); // -> { "code": 200, "description": "OK" } ``` ## Bun Works with [Bun](https://bun.sh/) out of the box. ```bash bun add wretch ``` ```ts import wretch from "wretch"; const text = await wretch("https://httpbingo.org").get("/status/200").text(); console.log(text); // -> { "code": 200, "description": "OK" } ``` # Usage ## Import ```typescript // ECMAScript modules import wretch from "wretch" // CommonJS const wretch = require("wretch") // Global variable (script tag) window.wretch ``` ## Common Use Cases ```javascript // 🌐 REST API Client const api = wretch("https://jsonplaceholder.typicode.com") .auth("Bearer token") .resolve(r => r.json()) const users = await api.get("/users") const user = await api.post({ name: "John" }, "/users") users ``` ```javascript // πŸ“€ File Upload with Progress import ProgressAddon from "wretch/addons/progress" import FormDataAddon from "wretch/addons/formData" await wretch("https://httpbingo.org/post") .addon([FormDataAddon, ProgressAddon()]) .formData({ file: file }) .post() .progress((loaded, total) => console.log(`${(loaded/total*100).toFixed()}%`)) .json() ``` ```javascript // πŸ”„ Auto-retry on Network Failure import { retry } from "wretch/middlewares" const resilientApi = wretch() .middlewares([retry({ maxAttempts: 3, retryOnNetworkError: true })]) ``` ```typescript // 🎯 Type-safe TypeScript interface User { id: number; name: string; email: string } const user = await wretch("https://jsonplaceholder.typicode.com") .get("/users/1") .json() // Fully typed! user ``` ```javascript // πŸ” Automatic Token Refresh const api = wretch("https://httpbingo.org/basic-auth/user/pass") .addon(BasicAuthAddon) .resolve(w => w.unauthorized(async (error, req) => { const newToken = await refreshToken() return req .basicAuth("user", "pass") .unauthorized(e => { console.log("Still unauthorized after token refresh"); throw e }) .fetch() .json() })) ``` ## Custom Fetch Implementation You can provide a custom fetch implementation using the `.fetchPolyfill()` method. This is useful for for a variety of use cases including mocking, adding logging, timing, or other custom behavior to all requests made through a wretch instance. ```js import wretch from "wretch" // Per-instance custom fetch const api = wretch("https://jsonplaceholder.typicode.com") .fetchPolyfill((url, opts) => { console.log('Fetching:', url) console.time(url) return fetch(url, opts).finally(() => { console.timeEnd(url) }) }) await api.get("/posts").json() ``` ### [toFetch() - Fetch Adapter πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#tofetch) Converts a wretch instance into a fetch-like function, preserving all configuration (middlewares, catchers, headers, etc.). Useful for integrating wretch with libraries that expect a fetch signature. ```js const myFetch = wretch("https://jsonplaceholder.typicode.com") .auth("Bearer token") .catcher(401, (err) => console.log("Unauthorized")) .toFetch() // Use like regular fetch const response = await myFetch("/users", { method: "GET" }) response ``` ```js // Pass to libraries expecting fetch import { createClient } from "@apollo/client" const client = createClient({ fetch: wretch().auth("Bearer token").toFetch() }) ``` ## Chaining **A high level overview of the successive steps that can be chained to perform a request and parse the result.** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Request Chain β”‚ β”‚ β”‚ β”‚ wretch(url) ──> .helper() ──> .body() ──> .httpMethod() β”‚ β”‚ ↓ ↓ ↓ β”‚ β”‚ .headers() .json() .get() β”‚ β”‚ .auth() .body() .post() β”‚ β”‚ .options() .put() β”‚ β”‚ .delete() β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ [ fetch() is called ] ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Response Chain β”‚ β”‚ β”‚ β”‚ .catcher() ──> .responseType() ──> Promise ──> .then()/.catch()β”‚ β”‚ ↓ ↓ β”‚ β”‚ .notFound() .json() β”‚ β”‚ .unauthorized() .text() β”‚ β”‚ .error() .blob() β”‚ β”‚ .res() β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Step-by-step breakdown:** ```ts // First, instantiate wretch wretch(baseUrl, baseOptions) ``` _The "request" chain starts here._ ```ts // Optional - A set of helper methods to set the default options, set accept header, change the current url… .() // Optional - Serialize an object to json or FormData formats and sets the body & header field if needed .() // Required - Sends the get/put/post/delete/patch request. .() ``` _The "response" chain starts here._ _Fetch is called after the request chain ends and before the response chain starts._
_The request is on the fly and now it is time to chain catchers and finally call a response type handler._ ```ts // Optional - You can chain error handlers here .() // Required - Specify the data type you need, which will be parsed and handed to you .() // >> Ends the response chain. ``` _From this point on, wretch returns a standard Promise._ ```ts .then(…) .catch(…) ``` ### Concrete Example Here's how the chaining works in practice: ```js await wretch("https://api.example.com") // Base URL .headers({ "X-Api-Key": "secret" }) // Helper method .query({ limit: 10 }) // Helper method .json({ name: "Alice", role: "admin" }) // Body type .post("/users") // HTTP method (starts request) .badRequest(err => console.log("Invalid")) // Catcher .unauthorized(err => console.log("No auth")) // Catcher .json(user => console.log(user)) // Response type ``` # Recipes Looking for common patterns and solutions? Check out the **[Recipes Guide](RECIPES.md)** for practical examples covering: - **Error Handling** - Parsing error response bodies, custom error types, global handlers - **TypeScript Patterns** - Typing precomposed instances, reusable catchers - **File Uploads** - Progress tracking, FormData handling - **Query Strings** - Filtering undefined values - **Request Control** - Combining timeouts with AbortControllers, aborting on errors - **Advanced Patterns** - Token refresh & replay, schema validation, async polling # [API πŸ”—](https://elbywan.github.io/wretch/api/) > πŸ’‘ The API documentation is now autogenerated and hosted separately, click the links access it. ### [Factory Method πŸ”—](https://elbywan.github.io/wretch/api/functions/index.default) The default export is a factory function used to instantiate wretch. ```js import wretch from "wretch" const api = wretch("http://domain.com/", { cache: "default" }) ``` ### [Helper Methods πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#accept) Helper Methods are used to configure the request and program actions. **Available methods:** [`.url()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#url) Β· [`.options()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#options) Β· [`.headers()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#headers) Β· [`.auth()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#auth) Β· [`.accept()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#accept) Β· [`.content()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#content) Β· [`.signal()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#signal) Β· [`.toFetch()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#tofetch) Β· [`.fetchPolyfill()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#fetchpolyfill) Β· [`.catcher()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#catcher) Β· [`.catcherFallback()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#catcherfallback) Β· [`.customError()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#customerror) Β· [`.defer()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#defer) Β· [`.resolve()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#resolve) Β· [`.middlewares()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#middlewares) Β· [`.addon()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#addon) Β· [`.polyfills()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#polyfills) ```js let api = wretch("http://domain.com/") api = api .url("/posts/1") .headers({ "Cache-Control": "no-cache" }) .content("text/html") ``` ### [Body Types πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#body) Specify a body type if uploading data. Can also be added through the HTTP Method argument. **Available methods:** [`.body()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#body) Β· [`.json()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#json) ```js let api = wretch("http://domain.com/") api = api.body("
") api ``` ### [HTTP Methods πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#delete) Sets the HTTP method and sends the request. Calling an HTTP method ends the request chain and returns a response chain. You can pass optional url and body arguments to these methods. **Available methods:** [`.get()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#get) Β· [`.post()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#post) Β· [`.put()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#put) Β· [`.patch()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#patch) Β· [`.delete()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#delete) Β· [`.head()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#head) Β· [`.opts()`](https://elbywan.github.io/wretch/api/interfaces/index.Wretch#opts) ```js const api = wretch("http://jsonplaceholder.typicode.com") // These shorthands: api.get("/posts"); api.post({ json: "body" }, "/posts"); // Are equivalent to: api.url("/posts").get(); api.json({ json: "body" }).url("/posts").post(); ``` **NOTE:** if the body argument is an `Object` it is assumed that it is a JSON payload and it will have the same behaviour as calling `.json(body)` unless the `Content-Type` header has been set to something else beforehand. ### [Catchers πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#badRequest) Catchers are optional, but if none are provided an error will still be thrown for http error codes and it will be up to you to catch it. **Available methods:** [`.badRequest()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#badrequest) Β· [`.unauthorized()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#unauthorized) Β· [`.forbidden()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#forbidden) Β· [`.notFound()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#notfound) Β· [`.timeout()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#timeout) Β· [`.internalError()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#internalerror) Β· [`.error()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#error) Β· [`.fetchError()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#fetcherror) ```js wretch("http://domain.com/resource") .get() .badRequest((err) => console.log(err.status)) .unauthorized((err) => console.log(err.status)) .forbidden((err) => console.log(err.status)) .notFound((err) => console.log(err.status)) .timeout((err) => console.log(err.status)) .internalError((err) => console.log(err.status)) .error(418, (err) => console.log(err.status)) .fetchError((err) => console.log(err)) .res(); ``` The error passed to catchers is enhanced with additional properties. ```ts type WretchError = Error & { status: number; response: WretchResponse; url: string; }; ``` By default, `error.message` is set to the response body text (or `statusText` if body parsing fails). #### Request Replay The original request is passed along the error and can be used in order to perform an additional request. ```js await wretch("https://httpbingo.org/basic-auth/user/pass") .addon(BasicAuthAddon) .basicAuth("user", "wrongpass") .get() .unauthorized(async (error, req) => { // Renew credentials const password = await wretch("https://httpbingo.org/base64/decode/cGFzcw==").get().text(); // Replay the original request with new credentials return req .basicAuth("user", password) .fetch() .unauthorized((err) => { throw err }) .json(); }) .json() // The promise chain is preserved as expected // ".then" will be performed on the result of the original request // or the replayed one (if a 401 error was thrown) .then(() => { /* … */ }); ``` #### Multiple Error Codes You can catch multiple error codes with a single handler by passing an array: ```js // Catch multiple codes at once const api = wretch("https://httpbingo.org").catcher([401, 403], err => { console.log("Authentication/authorization error:", err.status) }); // The catchers will handle all specified codes await api.get("/bearer").json() ``` ### [Response Types πŸ”—](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#arrayBuffer) Setting the final response body type ends the chain and returns a regular promise. All these methods accept an optional callback, and will return a Promise resolved with either the return value of the provided callback or the expected type. **Available methods:** [`.res()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#res) Β· [`.json()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#json) Β· [`.text()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#text) Β· [`.blob()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#blob) Β· [`.arrayBuffer()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#arraybuffer) Β· [`.formData()`](https://elbywan.github.io/wretch/api/interfaces/index.WretchResponseChain#formdata) ```js const ENDPOINT = "https://jsonplaceholder.typicode.com/posts/1" // Without a callback wretch(ENDPOINT) .get() .json() .then(json => { /* the json argument is the parsed json of the response body */ }) // Without a callback using await const json = await wretch(ENDPOINT).get().json() // With a callback the value returned is passed to the Promise wretch(ENDPOINT).get().json(json => "Hello world!").then(console.log) // => Hello world! ``` _If an error is caught by catchers, the response type handler will not be called._ # Addons Addons are separate pieces of code that you can import and plug into `wretch` to add new features. ```js import FormDataAddon from "wretch/addons/formData" import QueryStringAddon from "wretch/addons/queryString" // Add both addons const w = wretch().addon([FormDataAddon, QueryStringAddon]) // Additional features are now available w.formData({ hello: "world" }).query({ check: true }) ``` Typescript should also be fully supported and will provide completions. https://user-images.githubusercontent.com/3428394/182319457-504a0856-abdd-4c1d-bd04-df5a061e515d.mov ### [QueryString πŸ”—](https://elbywan.github.io/wretch/api/interfaces/addons_queryString.QueryStringAddon) Used to construct and append the query string part of the URL from an object. ```js import QueryStringAddon from "wretch/addons/queryString" let w = wretch("http://example.com").addon(QueryStringAddon); // url is http://example.com w = w.query({ a: 1, b: 2 }); // url is now http://example.com?a=1&b=2 w = w.query({ c: 3, d: [4, 5] }); // url is now http://example.com?a=1&b=2c=3&d=4&d=5 w = w.query("five&six&seven=eight"); // url is now http://example.com?a=1&b=2c=3&d=4&d=5&five&six&seven=eight w = w.query({ reset: true }, { replace: true }); // url is now http://example.com?reset=true ``` ### [FormData πŸ”—](https://elbywan.github.io/wretch/api/interfaces/addons_formData.FormDataAddon) Adds a helper method to serialize a `multipart/form-data` body from an object. ```js import FormDataAddon from "wretch/addons/formData" const form = { duck: "Muscovy", duckProperties: { beak: { color: "yellow", }, legs: 2, }, ignored: { key: 0, }, }; // Will append the following keys to the FormData payload: // "duck", "duckProperties[beak][color]", "duckProperties[legs]" wretch("https://httpbingo.org/post").addon(FormDataAddon).formData(form, { recursive: ["ignored"] }).post(); ``` ### [FormUrl πŸ”—](https://elbywan.github.io/wretch/api/interfaces/addons_formUrl.FormUrlAddon) Adds a method to serialize a `application/x-www-form-urlencoded` body from an object. ```js import FormUrlAddon from "wretch/addons/formUrl" const form = { a: 1, b: { c: 2 } }; const alreadyEncodedForm = "a=1&b=%7B%22c%22%3A2%7D"; // Automatically sets the content-type header to "application/x-www-form-urlencoded" wretch("https://httpbingo.org/post").addon(FormUrlAddon).formUrl(form).post(); wretch("https://httpbingo.org/post").addon(FormUrlAddon).formUrl(alreadyEncodedForm).post(); ``` ### [Abort πŸ”—](https://elbywan.github.io/wretch/api/variables/addons.abortAddon) Adds the ability to abort requests and set timeouts using AbortController and signals under the hood. ```js import AbortAddon from "wretch/addons/abort" ``` Use cases : ```js const [c, w] = wretch("https://httpbingo.org/get") .addon(AbortAddon()) .get() .onAbort((_) => console.log("Aborted !")) .controller(); w.text((_) => console.log("should never be called")); c.abort(); // Or : const controller = new AbortController(); wretch("https://httpbingo.org/get") .addon(AbortAddon()) .signal(controller) .get() .onAbort((_) => console.log("Aborted !")) .text((_) => console.log("should never be called")); controller.abort(); ``` ```js await wretch("https://httpbingo.org/delay/2") .addon(AbortAddon()) .get() // 1 second timeout .setTimeout(1000) .onAbort(_ => { console.log("Request timed out") }) .json(_ => { console.log("Response received in time") }) ``` ### [BasicAuth πŸ”—](https://elbywan.github.io/wretch/api/interfaces/addons_basicAuth.BasicAuthAddon) Adds the ability to set the `Authorization` header for the [basic authentication scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme) without the need to manually encode the username/password. Also, allows using URLs with `wretch` that contain credentials, which would otherwise throw an error. ```js import BasicAuthAddon from "wretch/addons/basicAuth" const user = "user" const pass = "pass" // Automatically sets the Authorization header to "Basic " + wretch("https://httpbingo.org/get") .addon(BasicAuthAddon) .basicAuth(user, pass) .get() // Allows using URLs with credentials in them wretch(`https://${user}:${pass}@httpbingo.org/basic-auth/${user}/${pass}`) .addon(BasicAuthAddon) .get() ``` ### [Progress πŸ”—](https://elbywan.github.io/wretch/api/interfaces/addons_progress.ProgressResolver) Adds the ability to monitor progress when downloading or uploading. _Compatible with all platforms implementing the [TransformStream WebAPI](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream#browser_compatibility)._ **Download progress:** ```js import ProgressAddon from "wretch/addons/progress" await wretch("https://httpbingo.org/bytes/5000") .addon(ProgressAddon()) .get() // Called with the number of bytes loaded and the total number of bytes to load .progress((loaded, total) => { console.log(`Download: ${(loaded / total * 100).toFixed(0)}%`) }) .blob() ``` **Upload progress:** ```js import ProgressAddon from "wretch/addons/progress" import FormDataAddon from "wretch/addons/formData" const formData = new FormData() formData.append('file', file) wretch("https://httpbingo.org/post") .addon([ProgressAddon(), FormDataAddon]) .onUpload((loaded, total) => { console.log(`Upload: ${(loaded / total * 100).toFixed(0)}%`) }) .post(formData) .res() ``` > **Note for browsers:** Upload progress requires HTTPS (HTTP/2) in Chrome/Chromium and doesn't work in Firefox due to streaming limitations. Works fully in Node.js. ### [Performance πŸ”—](https://elbywan.github.io/wretch/api/variables/addons.perfsAddon) Adds the ability to measure requests using the Performance Timings API. Uses the Performance API (browsers & Node.js) to expose timings related to the underlying request. > πŸ’‘ Make sure to follow the additional instructions in the documentation to setup Node.js if necessary. # Middlewares Middlewares are functions that can intercept requests before being processed by Fetch. Wretch includes a helper to help replicate the [middleware](http://expressjs.com/en/guide/using-middleware.html) style. ```js import wretch from "wretch" import { retry, dedupe } from "wretch/middlewares" const w = wretch().middlewares([retry(), dedupe()]) ``` > πŸ’‘ The following middlewares were previously provided by the [`wretch-middlewares`](https://github.com/elbywan/wretch-middlewares/) package. ### [Retry πŸ”—](https://elbywan.github.io/wretch/api/types/middlewares_retry.RetryMiddleware) **Retries a request multiple times in case of an error (or until a custom condition is true).** > **πŸ’‘ By default, the request will be retried only for server errors (5xx) and other non-successful responses, but not for client errors (4xx).** > > ```js > // To retry on all non-2xx responses (including 4xx): > until: (response, error) => !!response && response.ok > ``` ```js import wretch from 'wretch' import { retry } from 'wretch/middlewares' wretch().middlewares([ retry({ /* Options - defaults below */ delayTimer: 500, delayRamp: (delay, nbOfAttempts) => delay * nbOfAttempts, maxAttempts: 10, until: (response, error) => !!response && (response.ok || (response.status >= 400 && response.status < 500)), onRetry: undefined, retryOnNetworkError: false, resolveWithLatestResponse: false }) ]) // You can also return a Promise, which is useful if you want to inspect the body: wretch().middlewares([ retry({ until: response => response?.clone().json().then(body => body.field === 'something' ) || false }) ]) ``` ### [Dedupe πŸ”—](https://elbywan.github.io/wretch/api/types/middlewares_dedupe.DedupeMiddleware) **Prevents having multiple identical requests on the fly at the same time.** ```js import wretch from 'wretch' import { dedupe } from 'wretch/middlewares' wretch().middlewares([ dedupe({ /* Options - defaults below */ skip: (url, opts) => opts.skipDedupe || opts.method !== 'GET', key: (url, opts) => opts.method + '@' + url, resolver: response => response.clone() }) ]) ``` ### [Throttling Cache πŸ”—](https://elbywan.github.io/wretch/api/types/middlewares_throttlingCache.ThrottlingCacheMiddleware) **A throttling cache which stores and serves server responses for a certain amount of time.** ```js import wretch from 'wretch' import { throttlingCache } from 'wretch/middlewares' wretch().middlewares([ throttlingCache({ /* Options - defaults below */ throttle: 1000, skip: (url, opts) => opts.skipCache || opts.method !== 'GET', key: (url, opts) => opts.method + '@' + url, clear: (url, opts) => false, invalidate: (url, opts) => null, condition: response => response.ok, flagResponseOnCacheHit: '__cached' }) ]) ``` ### [Delay πŸ”—](https://elbywan.github.io/wretch/api/types/middlewares_delay.DelayMiddleware) **Delays the request by a specific amount of time.** ```js import wretch from 'wretch' import { delay } from 'wretch/middlewares' wretch().middlewares([ delay(1000) ]) ``` ## Writing a Middleware Basically a Middleware is a function having the following signature : ```ts // A middleware accepts options and returns a configured version type Middleware = (options?: { [key: string]: any }) => ConfiguredMiddleware; // A configured middleware (with options curried) type ConfiguredMiddleware = (next: FetchLike) => FetchLike; // A "fetch like" function, accepting an url and fetch options and returning a response promise type FetchLike = ( url: string, opts: WretchOptions, ) => Promise; ``` ### Context If you need to manipulate data within your middleware and expose it for later consumption, a solution could be to pass a named property to the wretch options (_suggested name: `context`_). Your middleware can then take advantage of that by mutating the object reference. ```js const contextMiddleware = (next) => (url, opts) => { if (opts.context) { // Mutate "context" opts.context.property = "anything"; } return next(url, opts); }; // Provide the reference to a "context" object const context = {}; const res = await wretch("https://httpbingo.org/get") // Pass "context" by reference as an option .options({ context }) .middlewares([contextMiddleware]) .get() .res(); console.log(context.property); // prints "anything" ``` ### Advanced examples
 πŸ‘€ Show me the code
``` /* Detailed source-code truncated for AI context efficiency. */ ```
# Limitations ## [Cloudflare Workers](https://workers.cloudflare.com/) It seems like using `wretch` in a Cloudflare Worker environment is not possible out of the box, as the Cloudflare `Response` implementation does not implement the [`type`](https://developer.mozilla.org/en-US/docs/Web/API/Response/type) property and throws an error when trying to access it. #### Please check the issue [#159](https://github.com/elbywan/wretch/issues/159) for more information. ### Workaround The following middleware should fix the issue (thanks @jimmed πŸ™‡): ```js wretch().middlewares([ (next) => async (url, opts) => { const response = await next(url, opts); try { Reflect.get(response, "type", response); } catch (error) { Object.defineProperty(response, "type", { get: () => "default", }); } return response; }, ]) ``` ## Headers Case Sensitivity The [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object from the Fetch API uses the [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class to store headers under the hood. This class is case-insensitive, meaning that setting both will actually appends the value to the same key: ```js const headers = new Headers(); headers.append("Accept", "application/json"); headers.append("accept", "application/json"); headers.forEach((value, key) => console.log(key, value)); // prints: accept application/json, application/json ``` When using `wretch`, please be mindful of this limitation and avoid setting the same header multiple times with a different case: ```js wretch("https://httpbingo.org/post") .headers({ "content-type": "application/json" }) // .json is a shortcut for .headers("Content-Type": "application/json").post().json() .json({ foo: "bar" }) // Wretch stores the headers inside a plain javascript object and will not deduplicate them. // Later on when fetch builds the Headers object the content type header will be set twice // and its value will be "application/json, application/json". // Ultimately this is certainly not what you want. ``` #### Please check the issue [#80](https://github.com/elbywan/wretch/issues/80) for more information. ### Workaround You can use the following middleware to deduplicate headers (thanks @jimmed πŸ™‡): ```js export const manipulateHeaders = callback => next => (url, { headers, ...opts }) => { const nextHeaders = callback(new Headers(headers)) return next(url, { ...opts, headers: nextHeaders }) } export const dedupeHeaders = (dedupeHeaderLogic = {}) => { const deduperMap = new Map( Object.entries(dedupeHeaderLogic).map(([k, v]) => [k.toLowerCase(), v]), ) const dedupe = key => deduperMap.get(key.toLowerCase()) ?? (values => new Set(values)) return manipulateHeaders((headers) => { Object.entries(headers.raw()).forEach(([key, values]) => { const deduped = Array.from(dedupe(key)(values)) headers.delete(key) deduped.forEach((value, index) => headers[index ? 'append' : 'set'](key.toLowerCase(), value), ) }) return headers }) } // By default, it will deduplicate identical values for a given header. This can be used as follows: wretch().middlewares([dedupeHeaders()]) // If there is a specific header for which the defaults cause problems, then you can provide a callback to handle deduplication yourself: wretch().middlewares([ dedupeHeaders({ Accept: (values) => values.filter(v => v !== '*/*') }) ]) ``` # Migration Guides Comprehensive migration guides are available for upgrading between major versions: - **[Migration Guide: v2 to v3](MIGRATION_V2_V3.md)** - **[Migration Guide: v1 to v2](MIGRATION_V1_V2.md)** # License MIT ---