UNPKG

10.1 kBTypeScriptView Raw
1import type { LiteralUnion, Required } from './common.js';
2import type { Hooks } from './hooks.js';
3import type { RetryOptions } from './retry.js';
4export type SearchParamsInit = string | string[][] | Record<string, string> | URLSearchParams | undefined;
5export type SearchParamsOption = SearchParamsInit | Record<string, string | number | boolean> | Array<Array<string | number | boolean>>;
6export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'head' | 'delete';
7export type Input = string | URL | Request;
8export type DownloadProgress = {
9 percent: number;
10 transferredBytes: number;
11 /**
12 Note: If it's not possible to retrieve the body size, it will be `0`.
13 */
14 totalBytes: number;
15};
16export type KyHeadersInit = NonNullable<RequestInit['headers']> | Record<string, string | undefined>;
17/**
18Custom Ky options
19*/
20export type KyOptions = {
21 /**
22 Shortcut for sending JSON. Use this instead of the `body` option.
23
24 Accepts any plain object or value, which will be `JSON.stringify()`'d and sent in the body with the correct header set.
25 */
26 json?: unknown;
27 /**
28 User-defined JSON-parsing function.
29
30 Use-cases:
31 1. Parse JSON via the [`bourne` package](https://github.com/hapijs/bourne) to protect from prototype pollution.
32 2. Parse JSON with [`reviver` option of `JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
33
34 @default JSON.parse()
35
36 @example
37 ```
38 import ky from 'ky';
39 import bourne from '@hapijs/bourne';
40
41 const json = await ky('https://example.com', {
42 parseJson: text => bourne(text)
43 }).json();
44 ```
45 */
46 parseJson?: (text: string) => unknown;
47 /**
48 User-defined JSON-stringifying function.
49
50 Use-cases:
51 1. Stringify JSON with a custom `replacer` function.
52
53 @default JSON.stringify()
54
55 @example
56 ```
57 import ky from 'ky';
58 import {DateTime} from 'luxon';
59
60 const json = await ky('https://example.com', {
61 stringifyJson: data => JSON.stringify(data, (key, value) => {
62 if (key.endsWith('_at')) {
63 return DateTime.fromISO(value).toSeconds();
64 }
65
66 return value;
67 })
68 }).json();
69 ```
70 */
71 stringifyJson?: (data: unknown) => string;
72 /**
73 Search parameters to include in the request URL. Setting this will override all existing search parameters in the input URL.
74
75 Accepts any value supported by [`URLSearchParams()`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams).
76 */
77 searchParams?: SearchParamsOption;
78 /**
79 A prefix to prepend to the `input` URL when making the request. It can be any valid URL, either relative or absolute. A trailing slash `/` is optional and will be added automatically, if needed, when it is joined with `input`. Only takes effect when `input` is a string. The `input` argument cannot start with a slash `/` when using this option.
80
81 Useful when used with [`ky.extend()`](#kyextenddefaultoptions) to create niche-specific Ky-instances.
82
83 Notes:
84 - After `prefixUrl` and `input` are joined, the result is resolved against the [base URL](https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI) of the page (if any).
85 - Leading slashes in `input` are disallowed when using this option to enforce consistency and avoid confusion about how the `input` URL is handled, given that `input` will not follow the normal URL resolution rules when `prefixUrl` is being used, which changes the meaning of a leading slash.
86
87 @example
88 ```
89 import ky from 'ky';
90
91 // On https://example.com
92
93 const response = await ky('unicorn', {prefixUrl: '/api'});
94 //=> 'https://example.com/api/unicorn'
95
96 const response = await ky('unicorn', {prefixUrl: 'https://cats.com'});
97 //=> 'https://cats.com/unicorn'
98 ```
99 */
100 prefixUrl?: URL | string;
101 /**
102 An object representing `limit`, `methods`, `statusCodes`, `afterStatusCodes`, and `maxRetryAfter` fields for maximum retry count, allowed methods, allowed status codes, status codes allowed to use the [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time, and maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time.
103
104 If `retry` is a number, it will be used as `limit` and other defaults will remain in place.
105
106 If the response provides an HTTP status contained in `afterStatusCodes`, Ky will wait until the date or timeout given in the [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header has passed to retry the request. If `Retry-After` is missing, the non-standard [`RateLimit-Reset`](https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-02.html#section-3.3) header is used in its place as a fallback. If the provided status code is not in the list, the [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header will be ignored.
107
108 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.
109
110 By default, delays between retries are calculated with the function `0.3 * (2 ** (attemptCount - 1)) * 1000`, where `attemptCount` is the attempt number (starts from 1), however this can be changed by passing a `delay` function.
111
112 Retries are not triggered following a timeout.
113
114 @example
115 ```
116 import ky from 'ky';
117
118 const json = await ky('https://example.com', {
119 retry: {
120 limit: 10,
121 methods: ['get'],
122 statusCodes: [413]
123 }
124 }).json();
125 ```
126 */
127 retry?: RetryOptions | number;
128 /**
129 Timeout in milliseconds for getting a response, including any retries. Can not be greater than 2147483647.
130 If set to `false`, there will be no timeout.
131
132 @default 10000
133 */
134 timeout?: number | false;
135 /**
136 Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
137 */
138 hooks?: Hooks;
139 /**
140 Throw an `HTTPError` when, after following redirects, the response has a non-2xx status code. To also throw for redirects instead of following them, set the [`redirect`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) option to `'manual'`.
141
142 Setting this to `false` may be useful if you are checking for resource availability and are expecting error responses.
143
144 Note: If `false`, error responses are considered successful and the request will not be retried.
145
146 @default true
147 */
148 throwHttpErrors?: boolean;
149 /**
150 Download progress event handler.
151
152 @param chunk - Note: It's empty for the first call.
153
154 @example
155 ```
156 import ky from 'ky';
157
158 const response = await ky('https://example.com', {
159 onDownloadProgress: (progress, chunk) => {
160 // Example output:
161 // `0% - 0 of 1271 bytes`
162 // `100% - 1271 of 1271 bytes`
163 console.log(`${progress.percent * 100}% - ${progress.transferredBytes} of ${progress.totalBytes} bytes`);
164 }
165 });
166 ```
167 */
168 onDownloadProgress?: (progress: DownloadProgress, chunk: Uint8Array) => void;
169 /**
170 User-defined `fetch` function.
171 Has to be fully compatible with the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) standard.
172
173 Use-cases:
174 1. Use custom `fetch` implementations like [`isomorphic-unfetch`](https://www.npmjs.com/package/isomorphic-unfetch).
175 2. Use the `fetch` wrapper function provided by some frameworks that use server-side rendering (SSR).
176
177 @default fetch
178
179 @example
180 ```
181 import ky from 'ky';
182 import fetch from 'isomorphic-unfetch';
183
184 const json = await ky('https://example.com', {fetch}).json();
185 ```
186 */
187 fetch?: (input: Input, init?: RequestInit) => Promise<Response>;
188};
189/**
190Each key from KyOptions is present and set to `true`.
191
192This type is used for identifying and working with the known keys in KyOptions.
193*/
194export type KyOptionsRegistry = {
195 [K in keyof KyOptions]-?: true;
196};
197/**
198Options are the same as `window.fetch`, except for the KyOptions
199*/
200export interface Options extends KyOptions, Omit<RequestInit, 'headers'> {
201 /**
202 HTTP method used to make the request.
203
204 Internally, the standard methods (`GET`, `POST`, `PUT`, `PATCH`, `HEAD` and `DELETE`) are uppercased in order to avoid server errors due to case sensitivity.
205 */
206 method?: LiteralUnion<HttpMethod, string>;
207 /**
208 HTTP headers used to make the request.
209
210 You can pass a `Headers` instance or a plain object.
211
212 You can remove a header with `.extend()` by passing the header with an `undefined` value.
213
214 @example
215 ```
216 import ky from 'ky';
217
218 const url = 'https://sindresorhus.com';
219
220 const original = ky.create({
221 headers: {
222 rainbow: 'rainbow',
223 unicorn: 'unicorn'
224 }
225 });
226
227 const extended = original.extend({
228 headers: {
229 rainbow: undefined
230 }
231 });
232
233 const response = await extended(url).json();
234
235 console.log('rainbow' in response);
236 //=> false
237
238 console.log('unicorn' in response);
239 //=> true
240 ```
241 */
242 headers?: KyHeadersInit;
243}
244export type InternalOptions = Required<Omit<Options, 'hooks' | 'retry'>, 'fetch' | 'prefixUrl' | 'timeout'> & {
245 headers: Required<Headers>;
246 hooks: Required<Hooks>;
247 retry: Required<RetryOptions>;
248 prefixUrl: string;
249};
250/**
251Normalized options passed to the `fetch` call and the `beforeRequest` hooks.
252*/
253export interface NormalizedOptions extends RequestInit {
254 method: NonNullable<RequestInit['method']>;
255 credentials?: NonNullable<RequestInit['credentials']>;
256 retry: RetryOptions;
257 prefixUrl: string;
258 onDownloadProgress: Options['onDownloadProgress'];
259}
260export type { RetryOptions } from './retry.js';