// Type definitions for http-errors 1.8
// Project: https://github.com/jshttp/http-errors
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
//                 BendingBender <https://github.com/BendingBender>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3

export = createHttpError;

declare const createHttpError: createHttpError.CreateHttpError & createHttpError.NamedConstructors & {
    isHttpError: createHttpError.IsHttpError
};

declare namespace createHttpError {
    interface HttpError<N extends number = number> extends Error {
        status: N;
        statusCode: N;
        expose: boolean;
        headers?: {
            [key: string]: string;
        } | undefined;
        [key: string]: any;
    }

    type UnknownError = Error | string | number | { [key: string]: any };

    type HttpErrorConstructor<N extends number = number> = new (msg?: string) => HttpError<N>;

    type CreateHttpError = <N extends UnknownError>(arg: N, ...rest: UnknownError[]) => HttpError<N extends number ? N : number>;

    type IsHttpError = (error: unknown) => error is HttpError;

    type NamedConstructors = {
        [code: string]: HttpErrorConstructor;
        HttpError: HttpErrorConstructor;
    }
    & Record<'BadRequest' | '400', HttpErrorConstructor<400>>
    & Record<'Unauthorized' | '401', HttpErrorConstructor<401>>
    & Record<'PaymentRequired' | '402', HttpErrorConstructor<402>>
    & Record<'Forbidden' | '403', HttpErrorConstructor<403>>
    & Record<'NotFound' | '404', HttpErrorConstructor<404>>
    & Record<'MethodNotAllowed' | '405', HttpErrorConstructor<405>>
    & Record<'NotAcceptable' | '406', HttpErrorConstructor<406>>
    & Record<'ProxyAuthenticationRequired' | '407', HttpErrorConstructor<407>>
    & Record<'RequestTimeout' | '408', HttpErrorConstructor<408>>
    & Record<'Conflict' | '409', HttpErrorConstructor<409>>
    & Record<'Gone' | '410', HttpErrorConstructor<410>>
    & Record<'LengthRequired' | '411', HttpErrorConstructor<411>>
    & Record<'PreconditionFailed' | '412', HttpErrorConstructor<412>>
    & Record<'PayloadTooLarge' | '413', HttpErrorConstructor<413>>
    & Record<'URITooLong' | '414', HttpErrorConstructor<414>>
    & Record<'UnsupportedMediaType' | '415', HttpErrorConstructor<415>>
    & Record<'RangeNotSatisfiable' | '416', HttpErrorConstructor<416>>
    & Record<'ExpectationFailed' | '417', HttpErrorConstructor<417>>
    & Record<'ImATeapot' | '418', HttpErrorConstructor<418>>
    & Record<'MisdirectedRequest' | '421', HttpErrorConstructor<421>>
    & Record<'UnprocessableEntity' | '422', HttpErrorConstructor<422>>
    & Record<'Locked' | '423', HttpErrorConstructor<423>>
    & Record<'FailedDependency' | '424', HttpErrorConstructor<424>>
    & Record<'UnorderedCollection' | '425', HttpErrorConstructor<425>>
    & Record<'UpgradeRequired' | '426', HttpErrorConstructor<426>>
    & Record<'PreconditionRequired' | '428', HttpErrorConstructor<428>>
    & Record<'TooManyRequests' | '429', HttpErrorConstructor<429>>
    & Record<'RequestHeaderFieldsTooLarge' | '431', HttpErrorConstructor<431>>
    & Record<'UnavailableForLegalReasons' | '451', HttpErrorConstructor<451>>
    & Record<'InternalServerError' | '500', HttpErrorConstructor<500>>
    & Record<'NotImplemented' | '501', HttpErrorConstructor<501>>
    & Record<'BadGateway' | '502', HttpErrorConstructor<502>>
    & Record<'ServiceUnavailable' | '503', HttpErrorConstructor<500>>
    & Record<'GatewayTimeout' | '504', HttpErrorConstructor<504>>
    & Record<'HTTPVersionNotSupported' | '505', HttpErrorConstructor<505>>
    & Record<'VariantAlsoNegotiates' | '506', HttpErrorConstructor<506>>
    & Record<'InsufficientStorage' | '507', HttpErrorConstructor<507>>
    & Record<'LoopDetected' | '508', HttpErrorConstructor<508>>
    & Record<'BandwidthLimitExceeded' | '509', HttpErrorConstructor<509>>
    & Record<'NotExtended' | '510', HttpErrorConstructor<510>>
    & Record<'NetworkAuthenticationRequire' | '511', HttpErrorConstructor<511>>
    ;
}
