ky
Version:
Tiny and elegant HTTP client based on the Fetch API
53 lines • 3.21 kB
JavaScript
/*! MIT License © Sindre Sorhus */
import { Ky } from './core/Ky.js';
import { requestMethods, getSupportedResponseTypes, stop, retry, } from './core/constants.js';
import { cloneDeep, validateAndMerge } from './utils/merge.js';
// Errors while setting up the request, such as invalid options or a throwing `init` hook, reject the returned promise instead of throwing, the same way `fetch()` reports them, so callers only have one error channel to handle.
const createRequest = (input, getOptions) => {
try {
return Ky.create(input, getOptions());
}
catch (error) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- A hook can throw any value, and it must be preserved exactly.
const result = Promise.reject(error);
// Matches `Ky.create()`, which only exposes `.bytes()` when the environment implements it.
for (const type of getSupportedResponseTypes()) {
// Returning the same promise marks it as handled, so a body method call does not also report an unhandled rejection.
result[type] = async () => result;
}
return result;
}
};
const createInstance = (defaults) => {
// eslint-disable-next-line @typescript-eslint/promise-function-async
const ky = (input, options) => createRequest(input, () => validateAndMerge(defaults, options));
for (const method of requestMethods) {
// eslint-disable-next-line @typescript-eslint/promise-function-async
ky[method] = (input, options) => createRequest(input, () => validateAndMerge(defaults, options, { method }));
}
ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
ky.extend = (newDefaults) => {
if (typeof newDefaults === 'function') {
// Pass a copy so mutations inside the callback cannot leak into this instance's defaults. Deep, because options like `context` are merged shallowly, so a nested value would still point at the parent's object. Non-plain values such as a `FormData` body are shared, the same way the `hooks.init` copies share them.
newDefaults = newDefaults(validateAndMerge(cloneDeep(defaults)));
}
return createInstance(validateAndMerge(defaults, newDefaults));
};
ky.stop = stop;
ky.retry = retry;
return ky;
};
const ky = createInstance();
export default ky;
export { KyError } from './errors/KyError.js';
export { HTTPError } from './errors/HTTPError.js';
export { SchemaValidationError } from './errors/SchemaValidationError.js';
export { NetworkError } from './errors/NetworkError.js';
export { TimeoutError } from './errors/TimeoutError.js';
export { ResponseSizeError } from './errors/ResponseSizeError.js';
export { ForceRetryError } from './errors/ForceRetryError.js';
export { isKyError, isHTTPError, isNetworkError, isTimeoutError, isResponseSizeError, isForceRetryError, } from './utils/type-guards.js';
export { replaceOption } from './utils/merge.js';
// Intentionally not exporting this for now as it's just an implementation detail and we don't want to commit to a certain API yet at least.
// export {NonError} from './errors/NonError.js';
//# sourceMappingURL=index.js.map