import { AxiosError, AxiosResponse } from 'axios' export type HttpStatusName = keyof typeof httpStatusCode export type HttpStatus = typeof httpStatusCode[HttpStatusName] export type HttpStatusRange = keyof typeof httpStatusCodeRange type HttpStatusResponse = { is: (status: HttpStatusName) => boolean, isInRange: (statusRange: HttpStatusRange) => boolean, } function isAxiosResponse(value: unknown): value is AxiosResponse { const response = value as AxiosResponse return typeof response.status === 'number' } function isAxiosError(value: unknown): value is AxiosError { const error = value as AxiosError return isAxiosResponse(error.response) } function getStatusCode(value: unknown): number { if (typeof value === 'number') { return value } if (isAxiosResponse(value)) { return value.status } if (isAxiosError(value)) { return getStatusCode(value.response) } return 0 } export function httpStatus(value: unknown): HttpStatusResponse { const status = getStatusCode(value) return { is: (statusName: HttpStatusName) => httpStatusCode[statusName] === status, isInRange: (statusRange: HttpStatusRange) => httpStatusCodeRange[statusRange].includes(status), } } export const httpStatusCode = { Continue: 100, SwitchingProtocols: 101, Processing: 102, OK: 200, Created: 201, Accepted: 202, NonAuthoritativeInformation: 203, NoContent: 204, ResetContent: 205, PartialContent: 206, MultiStatus: 207, MultipleChoices: 300, MovedPermanently: 301, MovedTemporarily: 302, SeeOther: 303, NotModified: 304, UseProxy: 305, TemporaryRedirect: 307, PermanentRedirect: 308, BadRequest: 400, Unauthorized: 401, PaymentRequired: 402, Forbidden: 403, NotFound: 404, MethodNotAllowed: 405, NotAcceptable: 406, ProxyAuthenticationRequired: 407, RequestTimeout: 408, Conflict: 409, Gone: 410, LengthRequired: 411, PreconditionFailed: 412, RequestEntityTooLarge: 413, RequestURITooLong: 414, UnsupportedMediaType: 415, RequestedRangeNotSatisfiable: 416, ExpectationFailed: 417, ImATeapot: 418, InsufficientSpaceOnResource: 419, MethodFailure: 420, MisdirectedRequest: 421, UnprocessableEntity: 422, Locked: 423, FailedDependency: 424, PreconditionRequired: 428, TooManyRequests: 429, RequestHeaderFieldsTooLarge: 431, UnavailableForLegalReasons: 451, InternalServerError: 500, NotImplemented: 501, BadGateway: 502, ServiceUnavailable: 503, GatewayTimeout: 504, HTTPVersionNotSupported: 505, InsufficientStorage: 507, NetworkAuthenticationRequired: 511, } export const httpStatusCodeRange = { informational: [ httpStatusCode.Continue, httpStatusCode.SwitchingProtocols, httpStatusCode.Processing, ], successful: [ httpStatusCode.OK, httpStatusCode.Created, httpStatusCode.Accepted, httpStatusCode.NonAuthoritativeInformation, httpStatusCode.NoContent, httpStatusCode.ResetContent, httpStatusCode.PartialContent, httpStatusCode.MultiStatus, ], redirection: [ httpStatusCode.MultipleChoices, httpStatusCode.MovedPermanently, httpStatusCode.MovedTemporarily, httpStatusCode.SeeOther, httpStatusCode.NotModified, httpStatusCode.UseProxy, httpStatusCode.TemporaryRedirect, httpStatusCode.PermanentRedirect, ], clientError: [ httpStatusCode.BadRequest, httpStatusCode.Unauthorized, httpStatusCode.PaymentRequired, httpStatusCode.Forbidden, httpStatusCode.NotFound, httpStatusCode.MethodNotAllowed, httpStatusCode.NotAcceptable, httpStatusCode.ProxyAuthenticationRequired, httpStatusCode.RequestTimeout, httpStatusCode.Conflict, httpStatusCode.Gone, httpStatusCode.LengthRequired, httpStatusCode.PreconditionFailed, httpStatusCode.RequestEntityTooLarge, httpStatusCode.RequestURITooLong, httpStatusCode.UnsupportedMediaType, httpStatusCode.RequestedRangeNotSatisfiable, httpStatusCode.ExpectationFailed, httpStatusCode.ImATeapot, httpStatusCode.InsufficientSpaceOnResource, httpStatusCode.MethodFailure, httpStatusCode.MisdirectedRequest, httpStatusCode.UnprocessableEntity, httpStatusCode.Locked, httpStatusCode.FailedDependency, httpStatusCode.PreconditionRequired, httpStatusCode.TooManyRequests, httpStatusCode.RequestHeaderFieldsTooLarge, httpStatusCode.UnavailableForLegalReasons, ], serverError: [ httpStatusCode.InternalServerError, httpStatusCode.NotImplemented, httpStatusCode.BadGateway, httpStatusCode.ServiceUnavailable, httpStatusCode.GatewayTimeout, httpStatusCode.HTTPVersionNotSupported, httpStatusCode.InsufficientStorage, httpStatusCode.NetworkAuthenticationRequired, ], }