Comparing version 1.3.0 to 1.4.0
@@ -7,11 +7,20 @@ export const supportsRequestStreams = (() => { | ||
if (supportsReadableStream && supportsRequest) { | ||
hasContentType = new globalThis.Request('https://empty.invalid', { | ||
body: new globalThis.ReadableStream(), | ||
method: 'POST', | ||
// @ts-expect-error - Types are outdated. | ||
get duplex() { | ||
duplexAccessed = true; | ||
return 'half'; | ||
}, | ||
}).headers.has('Content-Type'); | ||
try { | ||
hasContentType = new globalThis.Request('https://empty.invalid', { | ||
body: new globalThis.ReadableStream(), | ||
method: 'POST', | ||
// @ts-expect-error - Types are outdated. | ||
get duplex() { | ||
duplexAccessed = true; | ||
return 'half'; | ||
}, | ||
}).headers.has('Content-Type'); | ||
} | ||
catch (error) { | ||
// QQBrowser on iOS throws "unsupported BodyInit type" error (see issue #581) | ||
if (error instanceof Error && error.message === 'unsupported BodyInit type') { | ||
return false; | ||
} | ||
throw error; | ||
} | ||
} | ||
@@ -18,0 +27,0 @@ return duplexAccessed && !hasContentType; |
@@ -154,2 +154,6 @@ import { HTTPError } from '../errors/HTTPError.js'; | ||
} | ||
if (this._options.json !== undefined) { | ||
this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json); | ||
this._options.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json'); | ||
} | ||
this.request = new globalThis.Request(this._input, this._options); | ||
@@ -172,7 +176,2 @@ if (this._options.searchParams) { | ||
} | ||
if (this._options.json !== undefined) { | ||
this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json); | ||
this.request.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json'); | ||
this.request = new globalThis.Request(this.request, { body: this._options.body }); | ||
} | ||
} | ||
@@ -188,13 +187,8 @@ _calculateRetryDelay(error) { | ||
if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) { | ||
let after = Number(retryAfter); | ||
let after = Number(retryAfter) * 1000; | ||
if (Number.isNaN(after)) { | ||
after = Date.parse(retryAfter) - Date.now(); | ||
} | ||
else { | ||
after *= 1000; | ||
} | ||
if (this._options.retry.maxRetryAfter !== undefined && after > this._options.retry.maxRetryAfter) { | ||
return 0; | ||
} | ||
return after; | ||
const max = this._options.retry.maxRetryAfter ?? after; | ||
return after < max ? after : max; | ||
} | ||
@@ -255,6 +249,9 @@ if (error.response.status === 413) { | ||
const nonRequestOptions = findUnknownOptions(this.request, this._options); | ||
// Cloning is done here to prepare in advance for retries | ||
const mainRequest = this.request; | ||
this.request = mainRequest.clone(); | ||
if (this._options.timeout === false) { | ||
return this._options.fetch(this.request.clone(), nonRequestOptions); | ||
return this._options.fetch(mainRequest, nonRequestOptions); | ||
} | ||
return timeout(this.request.clone(), nonRequestOptions, this.abortController, this._options); | ||
return timeout(mainRequest, nonRequestOptions, this.abortController, this._options); | ||
} | ||
@@ -261,0 +258,0 @@ /* istanbul ignore next */ |
@@ -8,3 +8,3 @@ // eslint-lint-disable-next-line @typescript-eslint/naming-convention | ||
const reason = status ? `status code ${status}` : 'an unknown error'; | ||
super(`Request failed with ${reason}`); | ||
super(`Request failed with ${reason}: ${request.method} ${request.url}`); | ||
Object.defineProperty(this, "response", { | ||
@@ -11,0 +11,0 @@ enumerable: true, |
export class TimeoutError extends Error { | ||
constructor(request) { | ||
super('Request timed out'); | ||
super(`Request timed out: ${request.method} ${request.url}`); | ||
Object.defineProperty(this, "request", { | ||
@@ -5,0 +5,0 @@ enumerable: true, |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" resolution-mode="require"/> | ||
type UndiciHeadersInit = string[][] | Record<string, string | readonly string[]> | Headers; | ||
@@ -3,0 +2,0 @@ type UndiciBodyInit = ArrayBuffer | AsyncIterable<Uint8Array> | Blob | FormData | Iterable<Uint8Array> | NodeJS.ArrayBufferView | URLSearchParams | null | string; |
{ | ||
"name": "ky", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "Tiny and elegant HTTP client based on the browser Fetch API", | ||
@@ -25,3 +25,3 @@ "license": "MIT", | ||
"scripts": { | ||
"test": "xo && npm run build && ava --timeout=10m --serial", | ||
"test": "xo && npm run build && ava", | ||
"debug": "PWDEBUG=1 ava --timeout=2m", | ||
@@ -28,0 +28,0 @@ "release": "np", |
@@ -223,3 +223,3 @@ <div align="center"> | ||
If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`. If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request. | ||
If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`. If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will use `maxRetryAfter`. | ||
@@ -226,0 +226,0 @@ The `backoffLimit` option is the upper limit of the delay per retry in milliseconds. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
150072
1174