{"version":3,"file":"wretch.min.js","sources":["../../src/constants.ts","../../src/utils.ts","../../src/config.ts","../../src/middleware.ts","../../src/resolver.ts","../../src/core.ts","../../src/index.ts"],"sourcesContent":["export const JSON_MIME = \"application/json\"\nexport const CONTENT_TYPE_HEADER = \"Content-Type\"\nexport const FETCH_ERROR = Symbol()","import { CONTENT_TYPE_HEADER } from \"./constants.js\"\n\nexport function extractContentType(headers: HeadersInit = {}): string | undefined {\n return Object.entries(headers).find(([k]) =>\n k.toLowerCase() === CONTENT_TYPE_HEADER.toLowerCase()\n )?.[1]\n}\n\nexport function isLikelyJsonMime(value: string): boolean {\n return /^application\\/.*json.*/.test(value)\n}\n\nexport const mix = function (one: object, two: object, mergeArrays: boolean = false) {\n return Object.entries(two).reduce((acc, [key, newValue]) => {\n const value = one[key]\n if (Array.isArray(value) && Array.isArray(newValue)) {\n acc[key] = mergeArrays ? [...value, ...newValue] : newValue\n } else if (typeof value === \"object\" && typeof newValue === \"object\") {\n acc[key] = mix(value, newValue, mergeArrays)\n } else {\n acc[key] = newValue\n }\n\n return acc\n }, { ...one })\n}\n","import { mix } from \"./utils.js\"\nimport type { Config } from \"./types.js\"\n\ndeclare const global\n\nconst config: Config = {\n // Default options\n options: {},\n // Error type\n errorType: \"text\",\n // Polyfills\n polyfills: {\n // fetch: null,\n // FormData: null,\n // URLSearchParams: null,\n // performance: null,\n // PerformanceObserver: null,\n // AbortController: null\n },\n polyfill(p: string, doThrow: boolean = true, instance: boolean = false, ...args: any[]) {\n const res = this.polyfills[p] ||\n (typeof self !== \"undefined\" ? self[p] : null) ||\n (typeof global !== \"undefined\" ? global[p] : null)\n if (doThrow && !res) throw new Error(p + \" is not defined\")\n return instance && res ? new res(...args) : res\n }\n}\n\n/**\n * Sets the default fetch options that will be stored internally when instantiating wretch objects.\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.options({ headers: { \"Accept\": \"application/json\" } });\n *\n * // The fetch request is sent with both headers.\n * wretch(\"...\", { headers: { \"X-Custom\": \"Header\" } }).get().res();\n * ```\n *\n * @param options Default options\n * @param replace If true, completely replaces the existing options instead of mixing in\n */\nexport function setOptions(options: object, replace = false) {\n config.options = replace ? options : mix(config.options, options)\n}\n\n/**\n * Sets the default polyfills that will be stored internally when instantiating wretch objects.\n * Useful for browserless environments like `node.js`.\n *\n * Needed for libraries like [fetch-ponyfill](https://github.com/qubyte/fetch-ponyfill).\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.polyfills({\n * fetch: require(\"node-fetch\"),\n * FormData: require(\"form-data\"),\n * URLSearchParams: require(\"url\").URLSearchParams,\n * });\n *\n * // Uses the above polyfills.\n * wretch(\"...\").get().res();\n * ```\n *\n * @param polyfills An object containing the polyfills\n * @param replace If true, replaces the current polyfills instead of mixing in\n */\nexport function setPolyfills(polyfills: object, replace = false) {\n config.polyfills = replace ? polyfills : mix(config.polyfills, polyfills)\n}\n\n/**\n * Sets the default method (text, json, …) used to parse the data contained in the response body in case of an HTTP error.\n * As with other static methods, it will affect wretch instances created after calling this function.\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.errorType(\"json\")\n *\n * wretch(\"http://server/which/returns/an/error/with/a/json/body\")\n * .get()\n * .res()\n * .catch(error => {\n * // error[errorType] (here, json) contains the parsed body\n * console.log(error.json)\n * })\n * ```\n *\n * If null, defaults to \"text\".\n */\nexport function setErrorType(errorType: string) {\n config.errorType = errorType\n}\n\nexport default config\n","import type { ConfiguredMiddleware, FetchLike } from \"./types.js\"\n\n/**\n * @private @internal\n */\nexport const middlewareHelper = (middlewares: ConfiguredMiddleware[]) => (fetchFunction: FetchLike): FetchLike => {\n return middlewares.reduceRight((acc, curr) => curr(acc), fetchFunction) || fetchFunction\n}\n","import { middlewareHelper } from \"./middleware.js\"\nimport { mix } from \"./utils.js\"\nimport type { Wretch, WretchResponse, WretchResponseChain, WretchError as WretchErrorType } from \"./types.js\"\nimport { FETCH_ERROR } from \"./constants.js\"\n\n/**\n * This class inheriting from Error is thrown when the fetch response is not \"ok\".\n * It extends Error and adds status, text and body fields.\n */\nexport class WretchError extends Error implements WretchErrorType {\n status: number\n response: WretchResponse\n text?: string\n json?: any\n}\n\nexport const resolver = (wretch: T & Wretch) => {\n const {\n _url: url,\n _options: opts,\n _config: config,\n _catchers: _catchers,\n _resolvers: resolvers,\n _middlewares: middlewares,\n _addons: addons\n } = wretch\n\n const catchers = new Map(_catchers)\n const finalOptions = mix(config.options, opts)\n addons.forEach(addon => addon.beforeRequest && addon.beforeRequest(wretch, finalOptions))\n // The generated fetch request\n const _fetchReq = middlewareHelper(middlewares)(config.polyfill(\"fetch\"))(url, finalOptions)\n // Throws on an http error\n const referenceError = new Error()\n const throwingPromise: Promise = _fetchReq\n .catch(error => {\n throw { __wrap: error }\n })\n .then(response => {\n if (!response.ok) {\n const err = new WretchError()\n // Enhance the error object\n err[\"cause\"] = referenceError\n err.stack = err.stack + \"\\nCAUSE: \" + referenceError.stack\n err.response = response\n if (response.type === \"opaque\") {\n throw err\n }\n return response[config.errorType]().then((body: string) => {\n err.message = body\n err[config.errorType] = body\n err[\"status\"] = response.status\n throw err\n })\n }\n return response\n })\n // Wraps the Promise in order to dispatch the error to a matching catcher\n const catchersWrapper = (promise: Promise): Promise => {\n return promise.catch(err => {\n const error = err.__wrap || err\n\n const catcher =\n err.__wrap && catchers.has(FETCH_ERROR) ? catchers.get(FETCH_ERROR) :\n (catchers.get(error.status) || catchers.get(error.name))\n\n if (catcher)\n return catcher(error, wretch)\n\n throw error\n })\n }\n // Enforces the proper promise type when a body parsing method is called.\n type BodyParser = (funName: string | null) => (cb?: (type: Type) => Result) => Promise>\n const bodyParser: BodyParser = funName => cb => funName ?\n // If a callback is provided, then callback with the body result otherwise return the parsed body itself.\n catchersWrapper(throwingPromise.then(_ => _ && _[funName]()).then(_ => cb ? cb(_) : _)) :\n // No body parsing method - return the response\n catchersWrapper(throwingPromise.then(_ => cb ? cb(_ as any) : _))\n\n const responseChain: WretchResponseChain = {\n _wretchReq: wretch,\n _fetchReq,\n res: bodyParser(null),\n json: bodyParser(\"json\"),\n blob: bodyParser(\"blob\"),\n formData: bodyParser(\"formData\"),\n arrayBuffer: bodyParser(\"arrayBuffer\"),\n text: bodyParser(\"text\"),\n error(errorId, cb) {\n catchers.set(errorId, cb)\n return this\n },\n badRequest(cb) { return this.error(400, cb) },\n unauthorized(cb) { return this.error(401, cb) },\n forbidden(cb) { return this.error(403, cb) },\n notFound(cb) { return this.error(404, cb) },\n timeout(cb) { return this.error(408, cb) },\n internalError(cb) { return this.error(500, cb) },\n fetchError(cb) { return this.error(FETCH_ERROR, cb) },\n }\n\n const enhancedResponseChain: R extends undefined ? Chain & WretchResponseChain : R = addons.reduce((chain, addon) => ({\n ...chain,\n ...(addon.resolver as any)\n }), responseChain)\n\n return resolvers.reduce((chain, r) => r(chain, wretch), enhancedResponseChain)\n}\n","import { mix, extractContentType, isLikelyJsonMime } from \"./utils.js\"\nimport { JSON_MIME, CONTENT_TYPE_HEADER } from \"./constants.js\"\nimport { resolver } from \"./resolver.js\"\nimport config from \"./config.js\"\nimport type { Wretch } from \"./types.js\"\n\nexport const core: Wretch = {\n _url: \"\",\n _options: {},\n _config: config,\n _catchers: new Map(),\n _resolvers: [],\n _deferred: [],\n _middlewares: [],\n _addons: [],\n addon(addon) {\n return { ...this, _addons: [...this._addons, addon], ...addon.wretch }\n },\n errorType(errorType: string) {\n return {\n ...this,\n _config: {\n ...this._config,\n errorType\n }\n }\n },\n polyfills(polyfills, replace = false) {\n return {\n ...this,\n _config: {\n ...this._config,\n polyfills: replace ? polyfills : mix(this._config.polyfills, polyfills)\n }\n }\n },\n url(_url, replace = false) {\n if (replace)\n return { ...this, _url }\n const split = this._url.split(\"?\")\n return {\n ...this,\n _url: split.length > 1 ?\n split[0] + _url + \"?\" + split[1] :\n this._url + _url\n }\n },\n options(options, replace = false) {\n return { ...this, _options: replace ? options : mix(this._options, options) }\n },\n headers(headerValues) {\n return { ...this, _options: mix(this._options, { headers: headerValues || {} }) }\n },\n accept(headerValue) {\n return this.headers({ Accept: headerValue })\n },\n content(headerValue) {\n return this.headers({ [CONTENT_TYPE_HEADER]: headerValue })\n },\n auth(headerValue) {\n return this.headers({ Authorization: headerValue })\n },\n catcher(errorId, catcher) {\n const newMap = new Map(this._catchers)\n newMap.set(errorId, catcher)\n return { ...this, _catchers: newMap }\n },\n resolve(resolver, clear: boolean = false) {\n return { ...this, _resolvers: clear ? [resolver] : [...this._resolvers, resolver] }\n },\n defer(callback, clear: boolean = false) {\n return {\n ...this,\n _deferred: clear ? [callback] : [...this._deferred, callback]\n }\n },\n middlewares(middlewares, clear = false) {\n return {\n ...this,\n _middlewares: clear ? middlewares : [...this._middlewares, ...middlewares]\n }\n },\n fetch(method: string = this._options.method, url = \"\", body = null) {\n let base = this.url(url).options({ method })\n // \"Jsonify\" the body if it is an object and if it is likely that the content type targets json.\n const contentType = extractContentType(base._options.headers)\n const jsonify = typeof body === \"object\" && (!base._options.headers || !contentType || isLikelyJsonMime(contentType))\n base =\n !body ? base :\n jsonify ? base.json(body, contentType) :\n base.body(body)\n return resolver(\n base\n ._deferred\n .reduce((acc: Wretch, curr) => curr(acc, acc._url, acc._options), base)\n )\n },\n get(url = \"\") {\n return this.fetch(\"GET\", url)\n },\n delete(url = \"\") {\n return this.fetch(\"DELETE\", url)\n },\n put(body, url = \"\") {\n return this.fetch(\"PUT\", url, body)\n },\n post(body, url = \"\") {\n return this.fetch(\"POST\", url, body)\n },\n patch(body, url = \"\") {\n return this.fetch(\"PATCH\", url, body)\n },\n head(url = \"\") {\n return this.fetch(\"HEAD\", url)\n },\n opts(url = \"\") {\n return this.fetch(\"OPTIONS\", url)\n },\n body(contents) {\n return { ...this, _options: { ...this._options, body: contents } }\n },\n json(jsObject, contentType) {\n const currentContentType = extractContentType(this._options.headers)\n return this.content(\n contentType ||\n isLikelyJsonMime(currentContentType) && currentContentType ||\n JSON_MIME\n ).body(JSON.stringify(jsObject))\n }\n}\n","import { setOptions, setErrorType, setPolyfills } from \"./config.js\"\nimport { core } from \"./core.js\"\nimport { WretchError } from \"./resolver.js\"\nimport type { Wretch } from \"./types.js\"\n\nexport type {\n Wretch,\n Config,\n ConfiguredMiddleware,\n FetchLike,\n Middleware,\n WretchResponseChain,\n WretchOptions,\n WretchError,\n WretchErrorCallback,\n WretchResponse,\n WretchDeferredCallback,\n WretchAddon\n} from \"./types.js\"\n\n/**\n * Creates a new wretch instance with a base url and base\n * [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch).\n *\n * ```ts\n * import wretch from \"wretch\"\n *\n * // Reusable instance\n * const w = wretch(\"https://domain.com\", { mode: \"cors\" })\n * ```\n *\n * @param _url The base url\n * @param _options The base fetch options\n * @returns A fresh wretch instance\n */\nfunction factory(_url = \"\", _options = {}): Wretch {\n return { ...core, _url, _options }\n}\n\nfactory[\"default\"] = factory\n/** {@inheritDoc setOptions} */\nfactory.options = setOptions\n/** {@inheritDoc setErrorType} */\nfactory.errorType = setErrorType\n/** {@inheritDoc setPolyfills} */\nfactory.polyfills = setPolyfills\nfactory.WretchError = WretchError\n\nexport default factory\n"],"names":["_a","Object","entries","headers","find","k","toLowerCase","isLikelyJsonMime","value","two","acc","key","newValue","one","Array","isArray","mergeArrays","config","options","errorType","polyfills","Error","p","instance","res","args","WretchError","resolver","wretch","finalOptions","mix","opts","addons","forEach","addon","beforeRequest","_fetchReq","middlewares","fetchFunction","reduceRight","curr","middlewareHelper","polyfill","url","referenceError","throwingPromise","error","ok","err","stack","response","type","then","body","message","bodyParser","cb","funName","_","catch","__wrap","catcher","catchers","has","FETCH_ERROR","get","status","name","responseChain","_wretchReq","formData","arrayBuffer","errorId","set","this","badRequest","unauthorized","notFound","timeout","internalError","fetchError","enhancedResponseChain","reduce","chain","resolvers","r","core","_catchers","Map","_deferred","_middlewares","_addons","_config","replace","_url","split","length","_options","headerValues","accept","Accept","headerValue","content","auth","Authorization","newMap","clear","_resolvers","defer","callback","fetch","method","base","contentType","extractContentType","jsonify","json","patch","head","contents","jsObject","currentContentType","JSON","stringify","factory"],"mappings":"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"}