| 'use strict'; | ||
| const destr = require('destr'); | ||
| const ufo = require('ufo'); | ||
| function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } | ||
| const destr__default = /*#__PURE__*/_interopDefaultCompat(destr); | ||
| class FetchError extends Error { | ||
| constructor(message, opts) { | ||
| super(message, opts); | ||
| this.name = "FetchError"; | ||
| if (opts?.cause && !this.cause) { | ||
| this.cause = opts.cause; | ||
| } | ||
| } | ||
| } | ||
| function createFetchError(ctx) { | ||
| const errorMessage = ctx.error?.message || ctx.error?.toString() || ""; | ||
| const method = ctx.request?.method || ctx.options?.method || "GET"; | ||
| const url = ctx.request?.url || String(ctx.request) || "/"; | ||
| const requestStr = `[${method}] ${JSON.stringify(url)}`; | ||
| const statusStr = ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"; | ||
| const message = `${requestStr}: ${statusStr}${errorMessage ? ` ${errorMessage}` : ""}`; | ||
| const fetchError = new FetchError( | ||
| message, | ||
| ctx.error ? { cause: ctx.error } : void 0 | ||
| ); | ||
| for (const key of ["request", "options", "response"]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx[key]; | ||
| } | ||
| }); | ||
| } | ||
| for (const [key, refKey] of [ | ||
| ["data", "_data"], | ||
| ["status", "status"], | ||
| ["statusCode", "status"], | ||
| ["statusText", "statusText"], | ||
| ["statusMessage", "statusText"] | ||
| ]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx.response && ctx.response[refKey]; | ||
| } | ||
| }); | ||
| } | ||
| return fetchError; | ||
| } | ||
| const payloadMethods = new Set( | ||
| Object.freeze(["PATCH", "POST", "PUT", "DELETE"]) | ||
| ); | ||
| function isPayloadMethod(method = "GET") { | ||
| return payloadMethods.has(method.toUpperCase()); | ||
| } | ||
| function isJSONSerializable(value) { | ||
| if (value === void 0) { | ||
| return false; | ||
| } | ||
| const t = typeof value; | ||
| if (t === "string" || t === "number" || t === "boolean" || t === null) { | ||
| return true; | ||
| } | ||
| if (t !== "object") { | ||
| return false; | ||
| } | ||
| if (Array.isArray(value)) { | ||
| return true; | ||
| } | ||
| if (value.buffer) { | ||
| return false; | ||
| } | ||
| if (value instanceof FormData || value instanceof URLSearchParams) { | ||
| return false; | ||
| } | ||
| return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function"; | ||
| } | ||
| const textTypes = /* @__PURE__ */ new Set([ | ||
| "image/svg", | ||
| "application/xml", | ||
| "application/xhtml", | ||
| "application/html" | ||
| ]); | ||
| const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; | ||
| function detectResponseType(_contentType = "") { | ||
| if (!_contentType) { | ||
| return "json"; | ||
| } | ||
| const contentType = _contentType.split(";").shift() || ""; | ||
| if (JSON_RE.test(contentType)) { | ||
| return "json"; | ||
| } | ||
| if (contentType === "text/event-stream") { | ||
| return "stream"; | ||
| } | ||
| if (textTypes.has(contentType) || contentType.startsWith("text/")) { | ||
| return "text"; | ||
| } | ||
| return "blob"; | ||
| } | ||
| function resolveFetchOptions(request, input, defaults, Headers) { | ||
| const headers = mergeHeaders( | ||
| input?.headers ?? request?.headers, | ||
| defaults?.headers, | ||
| Headers | ||
| ); | ||
| let query; | ||
| if (defaults?.query || defaults?.params || input?.params || input?.query) { | ||
| query = { | ||
| ...defaults?.params, | ||
| ...defaults?.query, | ||
| ...input?.params, | ||
| ...input?.query | ||
| }; | ||
| } | ||
| return { | ||
| ...defaults, | ||
| ...input, | ||
| query, | ||
| params: query, | ||
| headers | ||
| }; | ||
| } | ||
| function mergeHeaders(input, defaults, Headers) { | ||
| if (!defaults) { | ||
| return new Headers(input); | ||
| } | ||
| const headers = new Headers(defaults); | ||
| if (input) { | ||
| for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) { | ||
| headers.set(key, value); | ||
| } | ||
| } | ||
| return headers; | ||
| } | ||
| async function callHooks(context, hooks) { | ||
| if (hooks) { | ||
| if (Array.isArray(hooks)) { | ||
| for (const hook of hooks) { | ||
| await hook(context); | ||
| } | ||
| } else { | ||
| await hooks(context); | ||
| } | ||
| } | ||
| } | ||
| const retryStatusCodes = /* @__PURE__ */ new Set([ | ||
| 408, | ||
| // Request Timeout | ||
| 409, | ||
| // Conflict | ||
| 425, | ||
| // Too Early (Experimental) | ||
| 429, | ||
| // Too Many Requests | ||
| 500, | ||
| // Internal Server Error | ||
| 502, | ||
| // Bad Gateway | ||
| 503, | ||
| // Service Unavailable | ||
| 504 | ||
| // Gateway Timeout | ||
| ]); | ||
| const nullBodyResponses = /* @__PURE__ */ new Set([101, 204, 205, 304]); | ||
| function createFetch(globalOptions = {}) { | ||
| const { | ||
| fetch = globalThis.fetch, | ||
| Headers = globalThis.Headers, | ||
| AbortController = globalThis.AbortController | ||
| } = globalOptions; | ||
| async function onError(context) { | ||
| const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false; | ||
| if (context.options.retry !== false && !isAbort) { | ||
| let retries; | ||
| if (typeof context.options.retry === "number") { | ||
| retries = context.options.retry; | ||
| } else { | ||
| retries = isPayloadMethod(context.options.method) ? 0 : 1; | ||
| } | ||
| const responseCode = context.response && context.response.status || 500; | ||
| if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) { | ||
| const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0; | ||
| if (retryDelay > 0) { | ||
| await new Promise((resolve) => setTimeout(resolve, retryDelay)); | ||
| } | ||
| return $fetchRaw(context.request, { | ||
| ...context.options, | ||
| retry: retries - 1 | ||
| }); | ||
| } | ||
| } | ||
| const error = createFetchError(context); | ||
| if (Error.captureStackTrace) { | ||
| Error.captureStackTrace(error, $fetchRaw); | ||
| } | ||
| throw error; | ||
| } | ||
| const $fetchRaw = async function $fetchRaw2(_request, _options = {}) { | ||
| const context = { | ||
| request: _request, | ||
| options: resolveFetchOptions( | ||
| _request, | ||
| _options, | ||
| globalOptions.defaults, | ||
| Headers | ||
| ), | ||
| response: void 0, | ||
| error: void 0 | ||
| }; | ||
| if (context.options.method) { | ||
| context.options.method = context.options.method.toUpperCase(); | ||
| } | ||
| if (context.options.onRequest) { | ||
| await callHooks(context, context.options.onRequest); | ||
| if (!(context.options.headers instanceof Headers)) { | ||
| context.options.headers = new Headers( | ||
| context.options.headers || {} | ||
| /* compat */ | ||
| ); | ||
| } | ||
| } | ||
| if (typeof context.request === "string") { | ||
| if (context.options.baseURL) { | ||
| context.request = ufo.withBase(context.request, context.options.baseURL); | ||
| } | ||
| if (context.options.query) { | ||
| context.request = ufo.withQuery(context.request, context.options.query); | ||
| delete context.options.query; | ||
| } | ||
| if ("query" in context.options) { | ||
| delete context.options.query; | ||
| } | ||
| if ("params" in context.options) { | ||
| delete context.options.params; | ||
| } | ||
| } | ||
| if (context.options.body && isPayloadMethod(context.options.method)) { | ||
| if (isJSONSerializable(context.options.body)) { | ||
| const contentType = context.options.headers.get("content-type"); | ||
| if (typeof context.options.body !== "string") { | ||
| context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams( | ||
| context.options.body | ||
| ).toString() : JSON.stringify(context.options.body); | ||
| } | ||
| if (!contentType) { | ||
| context.options.headers.set("content-type", "application/json"); | ||
| } | ||
| if (!context.options.headers.has("accept")) { | ||
| context.options.headers.set("accept", "application/json"); | ||
| } | ||
| } else if ( | ||
| // ReadableStream Body | ||
| "pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || // Node.js Stream Body | ||
| typeof context.options.body.pipe === "function" | ||
| ) { | ||
| if (!("duplex" in context.options)) { | ||
| context.options.duplex = "half"; | ||
| } | ||
| } | ||
| } | ||
| let abortTimeout; | ||
| if (!context.options.signal && context.options.timeout) { | ||
| const controller = new AbortController(); | ||
| abortTimeout = setTimeout(() => { | ||
| const error = new Error( | ||
| "[TimeoutError]: The operation was aborted due to timeout" | ||
| ); | ||
| error.name = "TimeoutError"; | ||
| error.code = 23; | ||
| controller.abort(error); | ||
| }, context.options.timeout); | ||
| context.options.signal = controller.signal; | ||
| } | ||
| try { | ||
| context.response = await fetch( | ||
| context.request, | ||
| context.options | ||
| ); | ||
| } catch (error) { | ||
| context.error = error; | ||
| if (context.options.onRequestError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onRequestError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } finally { | ||
| if (abortTimeout) { | ||
| clearTimeout(abortTimeout); | ||
| } | ||
| } | ||
| const hasBody = (context.response.body || // https://github.com/unjs/ofetch/issues/324 | ||
| // https://github.com/unjs/ofetch/issues/294 | ||
| // https://github.com/JakeChampion/fetch/issues/1454 | ||
| context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD"; | ||
| if (hasBody) { | ||
| const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || ""); | ||
| switch (responseType) { | ||
| case "json": { | ||
| const data = await context.response.text(); | ||
| const parseFunction = context.options.parseResponse || destr__default; | ||
| context.response._data = parseFunction(data); | ||
| break; | ||
| } | ||
| case "stream": { | ||
| context.response._data = context.response.body || context.response._bodyInit; | ||
| break; | ||
| } | ||
| default: { | ||
| context.response._data = await context.response[responseType](); | ||
| } | ||
| } | ||
| } | ||
| if (context.options.onResponse) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponse | ||
| ); | ||
| } | ||
| if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) { | ||
| if (context.options.onResponseError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponseError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } | ||
| return context.response; | ||
| }; | ||
| const $fetch = async function $fetch2(request, options) { | ||
| const r = await $fetchRaw(request, options); | ||
| return r._data; | ||
| }; | ||
| $fetch.raw = $fetchRaw; | ||
| $fetch.native = (...args) => fetch(...args); | ||
| $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({ | ||
| ...globalOptions, | ||
| ...customGlobalOptions, | ||
| defaults: { | ||
| ...globalOptions.defaults, | ||
| ...customGlobalOptions.defaults, | ||
| ...defaultOptions | ||
| } | ||
| }); | ||
| return $fetch; | ||
| } | ||
| exports.FetchError = FetchError; | ||
| exports.createFetch = createFetch; | ||
| exports.createFetchError = createFetchError; |
| import destr from 'destr'; | ||
| import { withBase, withQuery } from 'ufo'; | ||
| class FetchError extends Error { | ||
| constructor(message, opts) { | ||
| super(message, opts); | ||
| this.name = "FetchError"; | ||
| if (opts?.cause && !this.cause) { | ||
| this.cause = opts.cause; | ||
| } | ||
| } | ||
| } | ||
| function createFetchError(ctx) { | ||
| const errorMessage = ctx.error?.message || ctx.error?.toString() || ""; | ||
| const method = ctx.request?.method || ctx.options?.method || "GET"; | ||
| const url = ctx.request?.url || String(ctx.request) || "/"; | ||
| const requestStr = `[${method}] ${JSON.stringify(url)}`; | ||
| const statusStr = ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"; | ||
| const message = `${requestStr}: ${statusStr}${errorMessage ? ` ${errorMessage}` : ""}`; | ||
| const fetchError = new FetchError( | ||
| message, | ||
| ctx.error ? { cause: ctx.error } : void 0 | ||
| ); | ||
| for (const key of ["request", "options", "response"]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx[key]; | ||
| } | ||
| }); | ||
| } | ||
| for (const [key, refKey] of [ | ||
| ["data", "_data"], | ||
| ["status", "status"], | ||
| ["statusCode", "status"], | ||
| ["statusText", "statusText"], | ||
| ["statusMessage", "statusText"] | ||
| ]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx.response && ctx.response[refKey]; | ||
| } | ||
| }); | ||
| } | ||
| return fetchError; | ||
| } | ||
| const payloadMethods = new Set( | ||
| Object.freeze(["PATCH", "POST", "PUT", "DELETE"]) | ||
| ); | ||
| function isPayloadMethod(method = "GET") { | ||
| return payloadMethods.has(method.toUpperCase()); | ||
| } | ||
| function isJSONSerializable(value) { | ||
| if (value === void 0) { | ||
| return false; | ||
| } | ||
| const t = typeof value; | ||
| if (t === "string" || t === "number" || t === "boolean" || t === null) { | ||
| return true; | ||
| } | ||
| if (t !== "object") { | ||
| return false; | ||
| } | ||
| if (Array.isArray(value)) { | ||
| return true; | ||
| } | ||
| if (value.buffer) { | ||
| return false; | ||
| } | ||
| if (value instanceof FormData || value instanceof URLSearchParams) { | ||
| return false; | ||
| } | ||
| return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function"; | ||
| } | ||
| const textTypes = /* @__PURE__ */ new Set([ | ||
| "image/svg", | ||
| "application/xml", | ||
| "application/xhtml", | ||
| "application/html" | ||
| ]); | ||
| const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; | ||
| function detectResponseType(_contentType = "") { | ||
| if (!_contentType) { | ||
| return "json"; | ||
| } | ||
| const contentType = _contentType.split(";").shift() || ""; | ||
| if (JSON_RE.test(contentType)) { | ||
| return "json"; | ||
| } | ||
| if (contentType === "text/event-stream") { | ||
| return "stream"; | ||
| } | ||
| if (textTypes.has(contentType) || contentType.startsWith("text/")) { | ||
| return "text"; | ||
| } | ||
| return "blob"; | ||
| } | ||
| function resolveFetchOptions(request, input, defaults, Headers) { | ||
| const headers = mergeHeaders( | ||
| input?.headers ?? request?.headers, | ||
| defaults?.headers, | ||
| Headers | ||
| ); | ||
| let query; | ||
| if (defaults?.query || defaults?.params || input?.params || input?.query) { | ||
| query = { | ||
| ...defaults?.params, | ||
| ...defaults?.query, | ||
| ...input?.params, | ||
| ...input?.query | ||
| }; | ||
| } | ||
| return { | ||
| ...defaults, | ||
| ...input, | ||
| query, | ||
| params: query, | ||
| headers | ||
| }; | ||
| } | ||
| function mergeHeaders(input, defaults, Headers) { | ||
| if (!defaults) { | ||
| return new Headers(input); | ||
| } | ||
| const headers = new Headers(defaults); | ||
| if (input) { | ||
| for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) { | ||
| headers.set(key, value); | ||
| } | ||
| } | ||
| return headers; | ||
| } | ||
| async function callHooks(context, hooks) { | ||
| if (hooks) { | ||
| if (Array.isArray(hooks)) { | ||
| for (const hook of hooks) { | ||
| await hook(context); | ||
| } | ||
| } else { | ||
| await hooks(context); | ||
| } | ||
| } | ||
| } | ||
| const retryStatusCodes = /* @__PURE__ */ new Set([ | ||
| 408, | ||
| // Request Timeout | ||
| 409, | ||
| // Conflict | ||
| 425, | ||
| // Too Early (Experimental) | ||
| 429, | ||
| // Too Many Requests | ||
| 500, | ||
| // Internal Server Error | ||
| 502, | ||
| // Bad Gateway | ||
| 503, | ||
| // Service Unavailable | ||
| 504 | ||
| // Gateway Timeout | ||
| ]); | ||
| const nullBodyResponses = /* @__PURE__ */ new Set([101, 204, 205, 304]); | ||
| function createFetch(globalOptions = {}) { | ||
| const { | ||
| fetch = globalThis.fetch, | ||
| Headers = globalThis.Headers, | ||
| AbortController = globalThis.AbortController | ||
| } = globalOptions; | ||
| async function onError(context) { | ||
| const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false; | ||
| if (context.options.retry !== false && !isAbort) { | ||
| let retries; | ||
| if (typeof context.options.retry === "number") { | ||
| retries = context.options.retry; | ||
| } else { | ||
| retries = isPayloadMethod(context.options.method) ? 0 : 1; | ||
| } | ||
| const responseCode = context.response && context.response.status || 500; | ||
| if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) { | ||
| const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0; | ||
| if (retryDelay > 0) { | ||
| await new Promise((resolve) => setTimeout(resolve, retryDelay)); | ||
| } | ||
| return $fetchRaw(context.request, { | ||
| ...context.options, | ||
| retry: retries - 1 | ||
| }); | ||
| } | ||
| } | ||
| const error = createFetchError(context); | ||
| if (Error.captureStackTrace) { | ||
| Error.captureStackTrace(error, $fetchRaw); | ||
| } | ||
| throw error; | ||
| } | ||
| const $fetchRaw = async function $fetchRaw2(_request, _options = {}) { | ||
| const context = { | ||
| request: _request, | ||
| options: resolveFetchOptions( | ||
| _request, | ||
| _options, | ||
| globalOptions.defaults, | ||
| Headers | ||
| ), | ||
| response: void 0, | ||
| error: void 0 | ||
| }; | ||
| if (context.options.method) { | ||
| context.options.method = context.options.method.toUpperCase(); | ||
| } | ||
| if (context.options.onRequest) { | ||
| await callHooks(context, context.options.onRequest); | ||
| if (!(context.options.headers instanceof Headers)) { | ||
| context.options.headers = new Headers( | ||
| context.options.headers || {} | ||
| /* compat */ | ||
| ); | ||
| } | ||
| } | ||
| if (typeof context.request === "string") { | ||
| if (context.options.baseURL) { | ||
| context.request = withBase(context.request, context.options.baseURL); | ||
| } | ||
| if (context.options.query) { | ||
| context.request = withQuery(context.request, context.options.query); | ||
| delete context.options.query; | ||
| } | ||
| if ("query" in context.options) { | ||
| delete context.options.query; | ||
| } | ||
| if ("params" in context.options) { | ||
| delete context.options.params; | ||
| } | ||
| } | ||
| if (context.options.body && isPayloadMethod(context.options.method)) { | ||
| if (isJSONSerializable(context.options.body)) { | ||
| const contentType = context.options.headers.get("content-type"); | ||
| if (typeof context.options.body !== "string") { | ||
| context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams( | ||
| context.options.body | ||
| ).toString() : JSON.stringify(context.options.body); | ||
| } | ||
| if (!contentType) { | ||
| context.options.headers.set("content-type", "application/json"); | ||
| } | ||
| if (!context.options.headers.has("accept")) { | ||
| context.options.headers.set("accept", "application/json"); | ||
| } | ||
| } else if ( | ||
| // ReadableStream Body | ||
| "pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || // Node.js Stream Body | ||
| typeof context.options.body.pipe === "function" | ||
| ) { | ||
| if (!("duplex" in context.options)) { | ||
| context.options.duplex = "half"; | ||
| } | ||
| } | ||
| } | ||
| let abortTimeout; | ||
| if (!context.options.signal && context.options.timeout) { | ||
| const controller = new AbortController(); | ||
| abortTimeout = setTimeout(() => { | ||
| const error = new Error( | ||
| "[TimeoutError]: The operation was aborted due to timeout" | ||
| ); | ||
| error.name = "TimeoutError"; | ||
| error.code = 23; | ||
| controller.abort(error); | ||
| }, context.options.timeout); | ||
| context.options.signal = controller.signal; | ||
| } | ||
| try { | ||
| context.response = await fetch( | ||
| context.request, | ||
| context.options | ||
| ); | ||
| } catch (error) { | ||
| context.error = error; | ||
| if (context.options.onRequestError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onRequestError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } finally { | ||
| if (abortTimeout) { | ||
| clearTimeout(abortTimeout); | ||
| } | ||
| } | ||
| const hasBody = (context.response.body || // https://github.com/unjs/ofetch/issues/324 | ||
| // https://github.com/unjs/ofetch/issues/294 | ||
| // https://github.com/JakeChampion/fetch/issues/1454 | ||
| context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD"; | ||
| if (hasBody) { | ||
| const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || ""); | ||
| switch (responseType) { | ||
| case "json": { | ||
| const data = await context.response.text(); | ||
| const parseFunction = context.options.parseResponse || destr; | ||
| context.response._data = parseFunction(data); | ||
| break; | ||
| } | ||
| case "stream": { | ||
| context.response._data = context.response.body || context.response._bodyInit; | ||
| break; | ||
| } | ||
| default: { | ||
| context.response._data = await context.response[responseType](); | ||
| } | ||
| } | ||
| } | ||
| if (context.options.onResponse) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponse | ||
| ); | ||
| } | ||
| if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) { | ||
| if (context.options.onResponseError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponseError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } | ||
| return context.response; | ||
| }; | ||
| const $fetch = async function $fetch2(request, options) { | ||
| const r = await $fetchRaw(request, options); | ||
| return r._data; | ||
| }; | ||
| $fetch.raw = $fetchRaw; | ||
| $fetch.native = (...args) => fetch(...args); | ||
| $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({ | ||
| ...globalOptions, | ||
| ...customGlobalOptions, | ||
| defaults: { | ||
| ...globalOptions.defaults, | ||
| ...customGlobalOptions.defaults, | ||
| ...defaultOptions | ||
| } | ||
| }); | ||
| return $fetch; | ||
| } | ||
| export { FetchError as F, createFetchError as a, createFetch as c }; |
+1
-1
| 'use strict'; | ||
| const fetch$1 = require('./shared/ofetch.-9wI71OD.cjs'); | ||
| const fetch$1 = require('./shared/ofetch.BBShr9Pz.cjs'); | ||
| require('destr'); | ||
@@ -5,0 +5,0 @@ require('ufo'); |
+2
-2
@@ -1,3 +0,3 @@ | ||
| import { c as createFetch } from './shared/ofetch.DCGFE0NK.mjs'; | ||
| export { F as FetchError, a as createFetchError } from './shared/ofetch.DCGFE0NK.mjs'; | ||
| import { c as createFetch } from './shared/ofetch.CWycOUEr.mjs'; | ||
| export { F as FetchError, a as createFetchError } from './shared/ofetch.CWycOUEr.mjs'; | ||
| import 'destr'; | ||
@@ -4,0 +4,0 @@ import 'ufo'; |
+1
-1
@@ -6,3 +6,3 @@ 'use strict'; | ||
| const nodeFetch = require('node-fetch-native'); | ||
| const fetch$1 = require('./shared/ofetch.-9wI71OD.cjs'); | ||
| const fetch$1 = require('./shared/ofetch.BBShr9Pz.cjs'); | ||
| require('destr'); | ||
@@ -9,0 +9,0 @@ require('ufo'); |
+2
-2
| import http from 'node:http'; | ||
| import https from 'node:https'; | ||
| import nodeFetch, { AbortController as AbortController$1, Headers as Headers$1 } from 'node-fetch-native'; | ||
| import { c as createFetch } from './shared/ofetch.DCGFE0NK.mjs'; | ||
| export { F as FetchError, a as createFetchError } from './shared/ofetch.DCGFE0NK.mjs'; | ||
| import { c as createFetch } from './shared/ofetch.CWycOUEr.mjs'; | ||
| export { F as FetchError, a as createFetchError } from './shared/ofetch.CWycOUEr.mjs'; | ||
| import 'destr'; | ||
@@ -7,0 +7,0 @@ import 'ufo'; |
+2
-2
| { | ||
| "name": "ofetch", | ||
| "version": "1.5.0", | ||
| "version": "1.5.1", | ||
| "description": "A better fetch API. Works on node, browser and workers.", | ||
@@ -69,3 +69,3 @@ "repository": "unjs/ofetch", | ||
| "play": "jiti playground/index.ts", | ||
| "release": "pnpm test && changelogen --release && npm publish && git push --follow-tags", | ||
| "release": "pnpm test && changelogen --release --publish", | ||
| "test": "pnpm lint && vitest run --coverage" | ||
@@ -72,0 +72,0 @@ }, |
| 'use strict'; | ||
| const destr = require('destr'); | ||
| const ufo = require('ufo'); | ||
| function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } | ||
| const destr__default = /*#__PURE__*/_interopDefaultCompat(destr); | ||
| class FetchError extends Error { | ||
| constructor(message, opts) { | ||
| super(message, opts); | ||
| this.name = "FetchError"; | ||
| if (opts?.cause && !this.cause) { | ||
| this.cause = opts.cause; | ||
| } | ||
| } | ||
| } | ||
| function createFetchError(ctx) { | ||
| const errorMessage = ctx.error?.message || ctx.error?.toString() || ""; | ||
| const method = ctx.request?.method || ctx.options?.method || "GET"; | ||
| const url = ctx.request?.url || String(ctx.request) || "/"; | ||
| const requestStr = `[${method}] ${JSON.stringify(url)}`; | ||
| const statusStr = ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"; | ||
| const message = `${requestStr}: ${statusStr}${errorMessage ? ` ${errorMessage}` : ""}`; | ||
| const fetchError = new FetchError( | ||
| message, | ||
| ctx.error ? { cause: ctx.error } : void 0 | ||
| ); | ||
| for (const key of ["request", "options", "response"]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx[key]; | ||
| } | ||
| }); | ||
| } | ||
| for (const [key, refKey] of [ | ||
| ["data", "_data"], | ||
| ["status", "status"], | ||
| ["statusCode", "status"], | ||
| ["statusText", "statusText"], | ||
| ["statusMessage", "statusText"] | ||
| ]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx.response && ctx.response[refKey]; | ||
| } | ||
| }); | ||
| } | ||
| return fetchError; | ||
| } | ||
| const payloadMethods = new Set( | ||
| Object.freeze(["PATCH", "POST", "PUT", "DELETE"]) | ||
| ); | ||
| function isPayloadMethod(method = "GET") { | ||
| return payloadMethods.has(method.toUpperCase()); | ||
| } | ||
| function isJSONSerializable(value) { | ||
| if (value === void 0) { | ||
| return false; | ||
| } | ||
| const t = typeof value; | ||
| if (t === "string" || t === "number" || t === "boolean" || t === null) { | ||
| return true; | ||
| } | ||
| if (t !== "object") { | ||
| return false; | ||
| } | ||
| if (Array.isArray(value)) { | ||
| return true; | ||
| } | ||
| if (value.buffer) { | ||
| return false; | ||
| } | ||
| if (value instanceof FormData || value instanceof URLSearchParams) { | ||
| return false; | ||
| } | ||
| return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function"; | ||
| } | ||
| const textTypes = /* @__PURE__ */ new Set([ | ||
| "image/svg", | ||
| "application/xml", | ||
| "application/xhtml", | ||
| "application/html" | ||
| ]); | ||
| const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; | ||
| function detectResponseType(_contentType = "") { | ||
| if (!_contentType) { | ||
| return "json"; | ||
| } | ||
| const contentType = _contentType.split(";").shift() || ""; | ||
| if (JSON_RE.test(contentType)) { | ||
| return "json"; | ||
| } | ||
| if (contentType === "text/event-stream") { | ||
| return "stream"; | ||
| } | ||
| if (textTypes.has(contentType) || contentType.startsWith("text/")) { | ||
| return "text"; | ||
| } | ||
| return "blob"; | ||
| } | ||
| function resolveFetchOptions(request, input, defaults, Headers) { | ||
| const headers = mergeHeaders( | ||
| input?.headers ?? request?.headers, | ||
| defaults?.headers, | ||
| Headers | ||
| ); | ||
| let query; | ||
| if (defaults?.query || defaults?.params || input?.params || input?.query) { | ||
| query = { | ||
| ...defaults?.params, | ||
| ...defaults?.query, | ||
| ...input?.params, | ||
| ...input?.query | ||
| }; | ||
| } | ||
| return { | ||
| ...defaults, | ||
| ...input, | ||
| query, | ||
| params: query, | ||
| headers | ||
| }; | ||
| } | ||
| function mergeHeaders(input, defaults, Headers) { | ||
| if (!defaults) { | ||
| return new Headers(input); | ||
| } | ||
| const headers = new Headers(defaults); | ||
| if (input) { | ||
| for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) { | ||
| headers.set(key, value); | ||
| } | ||
| } | ||
| return headers; | ||
| } | ||
| async function callHooks(context, hooks) { | ||
| if (hooks) { | ||
| if (Array.isArray(hooks)) { | ||
| for (const hook of hooks) { | ||
| await hook(context); | ||
| } | ||
| } else { | ||
| await hooks(context); | ||
| } | ||
| } | ||
| } | ||
| const retryStatusCodes = /* @__PURE__ */ new Set([ | ||
| 408, | ||
| // Request Timeout | ||
| 409, | ||
| // Conflict | ||
| 425, | ||
| // Too Early (Experimental) | ||
| 429, | ||
| // Too Many Requests | ||
| 500, | ||
| // Internal Server Error | ||
| 502, | ||
| // Bad Gateway | ||
| 503, | ||
| // Service Unavailable | ||
| 504 | ||
| // Gateway Timeout | ||
| ]); | ||
| const nullBodyResponses = /* @__PURE__ */ new Set([101, 204, 205, 304]); | ||
| function createFetch(globalOptions = {}) { | ||
| const { | ||
| fetch = globalThis.fetch, | ||
| Headers = globalThis.Headers, | ||
| AbortController = globalThis.AbortController | ||
| } = globalOptions; | ||
| async function onError(context) { | ||
| const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false; | ||
| if (context.options.retry !== false && !isAbort) { | ||
| let retries; | ||
| if (typeof context.options.retry === "number") { | ||
| retries = context.options.retry; | ||
| } else { | ||
| retries = isPayloadMethod(context.options.method) ? 0 : 1; | ||
| } | ||
| const responseCode = context.response && context.response.status || 500; | ||
| if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) { | ||
| const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0; | ||
| if (retryDelay > 0) { | ||
| await new Promise((resolve) => setTimeout(resolve, retryDelay)); | ||
| } | ||
| return $fetchRaw(context.request, { | ||
| ...context.options, | ||
| retry: retries - 1 | ||
| }); | ||
| } | ||
| } | ||
| const error = createFetchError(context); | ||
| if (Error.captureStackTrace) { | ||
| Error.captureStackTrace(error, $fetchRaw); | ||
| } | ||
| throw error; | ||
| } | ||
| const $fetchRaw = async function $fetchRaw2(_request, _options = {}) { | ||
| const context = { | ||
| request: _request, | ||
| options: resolveFetchOptions( | ||
| _request, | ||
| _options, | ||
| globalOptions.defaults, | ||
| Headers | ||
| ), | ||
| response: void 0, | ||
| error: void 0 | ||
| }; | ||
| if (context.options.method) { | ||
| context.options.method = context.options.method.toUpperCase(); | ||
| } | ||
| if (context.options.onRequest) { | ||
| await callHooks(context, context.options.onRequest); | ||
| } | ||
| if (typeof context.request === "string") { | ||
| if (context.options.baseURL) { | ||
| context.request = ufo.withBase(context.request, context.options.baseURL); | ||
| } | ||
| if (context.options.query) { | ||
| context.request = ufo.withQuery(context.request, context.options.query); | ||
| delete context.options.query; | ||
| } | ||
| if ("query" in context.options) { | ||
| delete context.options.query; | ||
| } | ||
| if ("params" in context.options) { | ||
| delete context.options.params; | ||
| } | ||
| } | ||
| if (context.options.body && isPayloadMethod(context.options.method)) { | ||
| if (isJSONSerializable(context.options.body)) { | ||
| const contentType = context.options.headers.get("content-type"); | ||
| if (typeof context.options.body !== "string") { | ||
| context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams( | ||
| context.options.body | ||
| ).toString() : JSON.stringify(context.options.body); | ||
| } | ||
| context.options.headers = new Headers(context.options.headers || {}); | ||
| if (!contentType) { | ||
| context.options.headers.set("content-type", "application/json"); | ||
| } | ||
| if (!context.options.headers.has("accept")) { | ||
| context.options.headers.set("accept", "application/json"); | ||
| } | ||
| } else if ( | ||
| // ReadableStream Body | ||
| "pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || // Node.js Stream Body | ||
| typeof context.options.body.pipe === "function" | ||
| ) { | ||
| if (!("duplex" in context.options)) { | ||
| context.options.duplex = "half"; | ||
| } | ||
| } | ||
| } | ||
| let abortTimeout; | ||
| if (!context.options.signal && context.options.timeout) { | ||
| const controller = new AbortController(); | ||
| abortTimeout = setTimeout(() => { | ||
| const error = new Error( | ||
| "[TimeoutError]: The operation was aborted due to timeout" | ||
| ); | ||
| error.name = "TimeoutError"; | ||
| error.code = 23; | ||
| controller.abort(error); | ||
| }, context.options.timeout); | ||
| context.options.signal = controller.signal; | ||
| } | ||
| try { | ||
| context.response = await fetch( | ||
| context.request, | ||
| context.options | ||
| ); | ||
| } catch (error) { | ||
| context.error = error; | ||
| if (context.options.onRequestError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onRequestError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } finally { | ||
| if (abortTimeout) { | ||
| clearTimeout(abortTimeout); | ||
| } | ||
| } | ||
| const hasBody = (context.response.body || // https://github.com/unjs/ofetch/issues/324 | ||
| // https://github.com/unjs/ofetch/issues/294 | ||
| // https://github.com/JakeChampion/fetch/issues/1454 | ||
| context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD"; | ||
| if (hasBody) { | ||
| const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || ""); | ||
| switch (responseType) { | ||
| case "json": { | ||
| const data = await context.response.text(); | ||
| const parseFunction = context.options.parseResponse || destr__default; | ||
| context.response._data = parseFunction(data); | ||
| break; | ||
| } | ||
| case "stream": { | ||
| context.response._data = context.response.body || context.response._bodyInit; | ||
| break; | ||
| } | ||
| default: { | ||
| context.response._data = await context.response[responseType](); | ||
| } | ||
| } | ||
| } | ||
| if (context.options.onResponse) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponse | ||
| ); | ||
| } | ||
| if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) { | ||
| if (context.options.onResponseError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponseError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } | ||
| return context.response; | ||
| }; | ||
| const $fetch = async function $fetch2(request, options) { | ||
| const r = await $fetchRaw(request, options); | ||
| return r._data; | ||
| }; | ||
| $fetch.raw = $fetchRaw; | ||
| $fetch.native = (...args) => fetch(...args); | ||
| $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({ | ||
| ...globalOptions, | ||
| ...customGlobalOptions, | ||
| defaults: { | ||
| ...globalOptions.defaults, | ||
| ...customGlobalOptions.defaults, | ||
| ...defaultOptions | ||
| } | ||
| }); | ||
| return $fetch; | ||
| } | ||
| exports.FetchError = FetchError; | ||
| exports.createFetch = createFetch; | ||
| exports.createFetchError = createFetchError; |
| import destr from 'destr'; | ||
| import { withBase, withQuery } from 'ufo'; | ||
| class FetchError extends Error { | ||
| constructor(message, opts) { | ||
| super(message, opts); | ||
| this.name = "FetchError"; | ||
| if (opts?.cause && !this.cause) { | ||
| this.cause = opts.cause; | ||
| } | ||
| } | ||
| } | ||
| function createFetchError(ctx) { | ||
| const errorMessage = ctx.error?.message || ctx.error?.toString() || ""; | ||
| const method = ctx.request?.method || ctx.options?.method || "GET"; | ||
| const url = ctx.request?.url || String(ctx.request) || "/"; | ||
| const requestStr = `[${method}] ${JSON.stringify(url)}`; | ||
| const statusStr = ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"; | ||
| const message = `${requestStr}: ${statusStr}${errorMessage ? ` ${errorMessage}` : ""}`; | ||
| const fetchError = new FetchError( | ||
| message, | ||
| ctx.error ? { cause: ctx.error } : void 0 | ||
| ); | ||
| for (const key of ["request", "options", "response"]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx[key]; | ||
| } | ||
| }); | ||
| } | ||
| for (const [key, refKey] of [ | ||
| ["data", "_data"], | ||
| ["status", "status"], | ||
| ["statusCode", "status"], | ||
| ["statusText", "statusText"], | ||
| ["statusMessage", "statusText"] | ||
| ]) { | ||
| Object.defineProperty(fetchError, key, { | ||
| get() { | ||
| return ctx.response && ctx.response[refKey]; | ||
| } | ||
| }); | ||
| } | ||
| return fetchError; | ||
| } | ||
| const payloadMethods = new Set( | ||
| Object.freeze(["PATCH", "POST", "PUT", "DELETE"]) | ||
| ); | ||
| function isPayloadMethod(method = "GET") { | ||
| return payloadMethods.has(method.toUpperCase()); | ||
| } | ||
| function isJSONSerializable(value) { | ||
| if (value === void 0) { | ||
| return false; | ||
| } | ||
| const t = typeof value; | ||
| if (t === "string" || t === "number" || t === "boolean" || t === null) { | ||
| return true; | ||
| } | ||
| if (t !== "object") { | ||
| return false; | ||
| } | ||
| if (Array.isArray(value)) { | ||
| return true; | ||
| } | ||
| if (value.buffer) { | ||
| return false; | ||
| } | ||
| if (value instanceof FormData || value instanceof URLSearchParams) { | ||
| return false; | ||
| } | ||
| return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function"; | ||
| } | ||
| const textTypes = /* @__PURE__ */ new Set([ | ||
| "image/svg", | ||
| "application/xml", | ||
| "application/xhtml", | ||
| "application/html" | ||
| ]); | ||
| const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; | ||
| function detectResponseType(_contentType = "") { | ||
| if (!_contentType) { | ||
| return "json"; | ||
| } | ||
| const contentType = _contentType.split(";").shift() || ""; | ||
| if (JSON_RE.test(contentType)) { | ||
| return "json"; | ||
| } | ||
| if (contentType === "text/event-stream") { | ||
| return "stream"; | ||
| } | ||
| if (textTypes.has(contentType) || contentType.startsWith("text/")) { | ||
| return "text"; | ||
| } | ||
| return "blob"; | ||
| } | ||
| function resolveFetchOptions(request, input, defaults, Headers) { | ||
| const headers = mergeHeaders( | ||
| input?.headers ?? request?.headers, | ||
| defaults?.headers, | ||
| Headers | ||
| ); | ||
| let query; | ||
| if (defaults?.query || defaults?.params || input?.params || input?.query) { | ||
| query = { | ||
| ...defaults?.params, | ||
| ...defaults?.query, | ||
| ...input?.params, | ||
| ...input?.query | ||
| }; | ||
| } | ||
| return { | ||
| ...defaults, | ||
| ...input, | ||
| query, | ||
| params: query, | ||
| headers | ||
| }; | ||
| } | ||
| function mergeHeaders(input, defaults, Headers) { | ||
| if (!defaults) { | ||
| return new Headers(input); | ||
| } | ||
| const headers = new Headers(defaults); | ||
| if (input) { | ||
| for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers(input)) { | ||
| headers.set(key, value); | ||
| } | ||
| } | ||
| return headers; | ||
| } | ||
| async function callHooks(context, hooks) { | ||
| if (hooks) { | ||
| if (Array.isArray(hooks)) { | ||
| for (const hook of hooks) { | ||
| await hook(context); | ||
| } | ||
| } else { | ||
| await hooks(context); | ||
| } | ||
| } | ||
| } | ||
| const retryStatusCodes = /* @__PURE__ */ new Set([ | ||
| 408, | ||
| // Request Timeout | ||
| 409, | ||
| // Conflict | ||
| 425, | ||
| // Too Early (Experimental) | ||
| 429, | ||
| // Too Many Requests | ||
| 500, | ||
| // Internal Server Error | ||
| 502, | ||
| // Bad Gateway | ||
| 503, | ||
| // Service Unavailable | ||
| 504 | ||
| // Gateway Timeout | ||
| ]); | ||
| const nullBodyResponses = /* @__PURE__ */ new Set([101, 204, 205, 304]); | ||
| function createFetch(globalOptions = {}) { | ||
| const { | ||
| fetch = globalThis.fetch, | ||
| Headers = globalThis.Headers, | ||
| AbortController = globalThis.AbortController | ||
| } = globalOptions; | ||
| async function onError(context) { | ||
| const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false; | ||
| if (context.options.retry !== false && !isAbort) { | ||
| let retries; | ||
| if (typeof context.options.retry === "number") { | ||
| retries = context.options.retry; | ||
| } else { | ||
| retries = isPayloadMethod(context.options.method) ? 0 : 1; | ||
| } | ||
| const responseCode = context.response && context.response.status || 500; | ||
| if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) { | ||
| const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0; | ||
| if (retryDelay > 0) { | ||
| await new Promise((resolve) => setTimeout(resolve, retryDelay)); | ||
| } | ||
| return $fetchRaw(context.request, { | ||
| ...context.options, | ||
| retry: retries - 1 | ||
| }); | ||
| } | ||
| } | ||
| const error = createFetchError(context); | ||
| if (Error.captureStackTrace) { | ||
| Error.captureStackTrace(error, $fetchRaw); | ||
| } | ||
| throw error; | ||
| } | ||
| const $fetchRaw = async function $fetchRaw2(_request, _options = {}) { | ||
| const context = { | ||
| request: _request, | ||
| options: resolveFetchOptions( | ||
| _request, | ||
| _options, | ||
| globalOptions.defaults, | ||
| Headers | ||
| ), | ||
| response: void 0, | ||
| error: void 0 | ||
| }; | ||
| if (context.options.method) { | ||
| context.options.method = context.options.method.toUpperCase(); | ||
| } | ||
| if (context.options.onRequest) { | ||
| await callHooks(context, context.options.onRequest); | ||
| } | ||
| if (typeof context.request === "string") { | ||
| if (context.options.baseURL) { | ||
| context.request = withBase(context.request, context.options.baseURL); | ||
| } | ||
| if (context.options.query) { | ||
| context.request = withQuery(context.request, context.options.query); | ||
| delete context.options.query; | ||
| } | ||
| if ("query" in context.options) { | ||
| delete context.options.query; | ||
| } | ||
| if ("params" in context.options) { | ||
| delete context.options.params; | ||
| } | ||
| } | ||
| if (context.options.body && isPayloadMethod(context.options.method)) { | ||
| if (isJSONSerializable(context.options.body)) { | ||
| const contentType = context.options.headers.get("content-type"); | ||
| if (typeof context.options.body !== "string") { | ||
| context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams( | ||
| context.options.body | ||
| ).toString() : JSON.stringify(context.options.body); | ||
| } | ||
| context.options.headers = new Headers(context.options.headers || {}); | ||
| if (!contentType) { | ||
| context.options.headers.set("content-type", "application/json"); | ||
| } | ||
| if (!context.options.headers.has("accept")) { | ||
| context.options.headers.set("accept", "application/json"); | ||
| } | ||
| } else if ( | ||
| // ReadableStream Body | ||
| "pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || // Node.js Stream Body | ||
| typeof context.options.body.pipe === "function" | ||
| ) { | ||
| if (!("duplex" in context.options)) { | ||
| context.options.duplex = "half"; | ||
| } | ||
| } | ||
| } | ||
| let abortTimeout; | ||
| if (!context.options.signal && context.options.timeout) { | ||
| const controller = new AbortController(); | ||
| abortTimeout = setTimeout(() => { | ||
| const error = new Error( | ||
| "[TimeoutError]: The operation was aborted due to timeout" | ||
| ); | ||
| error.name = "TimeoutError"; | ||
| error.code = 23; | ||
| controller.abort(error); | ||
| }, context.options.timeout); | ||
| context.options.signal = controller.signal; | ||
| } | ||
| try { | ||
| context.response = await fetch( | ||
| context.request, | ||
| context.options | ||
| ); | ||
| } catch (error) { | ||
| context.error = error; | ||
| if (context.options.onRequestError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onRequestError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } finally { | ||
| if (abortTimeout) { | ||
| clearTimeout(abortTimeout); | ||
| } | ||
| } | ||
| const hasBody = (context.response.body || // https://github.com/unjs/ofetch/issues/324 | ||
| // https://github.com/unjs/ofetch/issues/294 | ||
| // https://github.com/JakeChampion/fetch/issues/1454 | ||
| context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD"; | ||
| if (hasBody) { | ||
| const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || ""); | ||
| switch (responseType) { | ||
| case "json": { | ||
| const data = await context.response.text(); | ||
| const parseFunction = context.options.parseResponse || destr; | ||
| context.response._data = parseFunction(data); | ||
| break; | ||
| } | ||
| case "stream": { | ||
| context.response._data = context.response.body || context.response._bodyInit; | ||
| break; | ||
| } | ||
| default: { | ||
| context.response._data = await context.response[responseType](); | ||
| } | ||
| } | ||
| } | ||
| if (context.options.onResponse) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponse | ||
| ); | ||
| } | ||
| if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) { | ||
| if (context.options.onResponseError) { | ||
| await callHooks( | ||
| context, | ||
| context.options.onResponseError | ||
| ); | ||
| } | ||
| return await onError(context); | ||
| } | ||
| return context.response; | ||
| }; | ||
| const $fetch = async function $fetch2(request, options) { | ||
| const r = await $fetchRaw(request, options); | ||
| return r._data; | ||
| }; | ||
| $fetch.raw = $fetchRaw; | ||
| $fetch.native = (...args) => fetch(...args); | ||
| $fetch.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({ | ||
| ...globalOptions, | ||
| ...customGlobalOptions, | ||
| defaults: { | ||
| ...globalOptions.defaults, | ||
| ...customGlobalOptions.defaults, | ||
| ...defaultOptions | ||
| } | ||
| }); | ||
| return $fetch; | ||
| } | ||
| export { FetchError as F, createFetchError as a, createFetch as c }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
63925
0.3%969
1.04%