var Result;
(function (Result) {
    function is(value) {
        return (typeof value == "object" &&
            typeof value.status == "number" &&
            (value.header == undefined ||
                (typeof value.header == "object" && (value.header.eTag == undefined || typeof value.header.eTag == "string"))));
    }
    Result.is = is;
    function hasBody(value) {
        return typeof value == "object" && typeof value.status == "number" && value.body != undefined && value.body != null;
    }
    Result.hasBody = hasBody;
    function getBody(value, fallback) {
        return hasBody(value) ? value.body : fallback;
    }
    Result.getBody = getBody;
})(Result || (Result = {}));

var Error;
(function (Error) {
    function is(value) {
        return typeof value == "object" && typeof value.type == "string" && Result.is(value) && value.status >= 400;
    }
    Error.is = is;
})(Error || (Error = {}));

var Flaw;
(function (Flaw) {
    function is(value) {
        return (typeof value == "object" &&
            (value.property == undefined || typeof value.property == "string") &&
            typeof value.type == "string" &&
            (value.flaws == undefined || (Array.isArray(value.flaws) && value.flaws.every(Flaw.is))) &&
            (value.condition == undefined || typeof value.condition == "string"));
    }
    Flaw.is = is;
})(Flaw || (Flaw = {}));

function created(body) {
    return { status: 201, body };
}
(function (created) {
    function is(value) {
        return typeof value == "object" && value.body && Result.is(value) && value.status == 201;
    }
    created.is = is;
})(created || (created = {}));

function noContent() {
    return { status: 204 };
}
(function (noContent) {
    function is(value) {
        return Result.is(value) && value.status == 204;
    }
    noContent.is = is;
})(noContent || (noContent = {}));

function ok(body, eTag) {
    return { status: 200, body, header: { eTag } };
}
(function (ok) {
    function is(value) {
        return typeof value == "object" && value.body && Result.is(value) && value.status == 200;
    }
    ok.is = is;
})(ok || (ok = {}));

function permanent(location) {
    return { status: 301, location };
}
(function (permanent) {
    function is(value) {
        return Result.is(value) && value.status == 301;
    }
    permanent.is = is;
})(permanent || (permanent = {}));

function found(location) {
    return { status: 302, location };
}
(function (found) {
    function is(value) {
        return Result.is(value) && value.status == 302;
    }
    found.is = is;
})(found || (found = {}));

function notModified(eTag) {
    return { status: 304, header: { eTag: eTag } };
}
(function (notModified) {
    function is(value) {
        return (typeof value == "object" &&
            Result.is(value) &&
            value.status == 304 &&
            typeof value.header == "object" &&
            typeof value.header.eTag == "string");
    }
    notModified.is = is;
})(notModified || (notModified = {}));

function flawedContent(content) {
    return { status: 400, type: "flawed content", content };
}
(function (flawedContent) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "flawed content";
    }
    flawedContent.is = is;
})(flawedContent || (flawedContent = {}));

function invalidContent(type, description, details) {
    return { status: 400, type: "invalid content", content: { type, description, details } };
}
(function (invalidContent) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "invalid content";
    }
    invalidContent.is = is;
})(invalidContent || (invalidContent = {}));

function invalidPathArgument(pattern, name, type, description) {
    return { status: 400, type: "invalid path argument", pattern, argument: { name, type, description } };
}
(function (invalidPathArgument) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "invalid path argument";
    }
    invalidPathArgument.is = is;
})(invalidPathArgument || (invalidPathArgument = {}));

function invalidQueryArgument(name, type, description) {
    return { status: 400, type: "invalid query argument", argument: { name, type, description } };
}
(function (invalidQueryArgument) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "invalid query argument";
    }
    invalidQueryArgument.is = is;
})(invalidQueryArgument || (invalidQueryArgument = {}));

function malformedContent(property, type, description, details) {
    return { status: 400, type: "malformed content", content: { property, type, description, details } };
}
(function (malformedContent) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "malformed content";
    }
    malformedContent.is = is;
})(malformedContent || (malformedContent = {}));

const methods = ["GET", "POST", "DELETE", "HEAD", "PATCH", "PUT", "OPTIONS", "TRACE", "CONNECT"];
function methodNotAllowed(...allow) {
    return { status: 405, type: "method not allowed", header: { allow } };
}
(function (methodNotAllowed) {
    function is(value) {
        return (typeof value == "object" &&
            value.status == 405 &&
            value.type == "method not allowed" &&
            typeof value.header == "object" &&
            Array.isArray(value.header.allow) &&
            value.header.allow.every((m) => methods.some(m)) &&
            Error.is(value));
    }
    methodNotAllowed.is = is;
})(methodNotAllowed || (methodNotAllowed = {}));

function missingProperty(property, type, description) {
    return {
        status: 400,
        type: "missing property",
        content: typeof description == "string" ? { property, type, description } : Object.assign({ property, type }, description),
    };
}
(function (missingProperty) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "missing property";
    }
    missingProperty.is = is;
})(missingProperty || (missingProperty = {}));

function missingQueryArgument(name, type, description) {
    return { status: 400, type: "missing query argument", argument: { name, type, description } };
}
(function (missingQueryArgument) {
    function is(value) {
        return Error.is(value) && value.status == 400 && value.type == "missing query argument";
    }
    missingQueryArgument.is = is;
})(missingQueryArgument || (missingQueryArgument = {}));

function notFound() {
    return { status: 404, type: "not found" };
}
(function (notFound) {
    function is(value) {
        return Error.is(value) && value.status == 404 && value.type == "not found";
    }
    notFound.is = is;
})(notFound || (notFound = {}));

function unauthorized() {
    return { status: 401, type: "not authorized" };
}
(function (unauthorized) {
    function is(value) {
        return Error.is(value) && value.status == 401 && value.type == "not authorized";
    }
    unauthorized.is = is;
})(unauthorized || (unauthorized = {}));

function backendFailure(backend, details, reference) {
    if (backend != "string" && details == undefined && reference == undefined) {
        details = backend;
        backend = "unknown";
    }
    return { status: 502, type: "backend failure", backend, details, reference };
}
(function (backendFailure) {
    function is(value) {
        return (Error.is(value) &&
            value.status == 502 &&
            value.type == "backend failure" &&
            typeof value.backend == "string");
    }
    backendFailure.is = is;
})(backendFailure || (backendFailure = {}));

function backendTimeout() {
    return { status: 504, type: "backend timeout" };
}
(function (backendTimeout) {
    function is(value) {
        return Error.is(value) && value.status == 504 && value.type == "backend timeout";
    }
    backendTimeout.is = is;
})(backendTimeout || (backendTimeout = {}));

function databaseFailure(details) {
    return { status: 502, type: "database failure", details };
}
(function (databaseFailure) {
    function is(value) {
        return Error.is(value) && value.status == 502 && value.type == "database failure";
    }
    databaseFailure.is = is;
})(databaseFailure || (databaseFailure = {}));

function databaseTimeout() {
    return { status: 504, type: "database timeout" };
}
(function (databaseTimeout) {
    function is(value) {
        return Error.is(value) && value.status == 504 && value.type == "database timeout";
    }
    databaseTimeout.is = is;
})(databaseTimeout || (databaseTimeout = {}));

function missconfigured(key, description) {
    return { status: 503, type: "missing configuration", key, description };
}
(function (missconfigured) {
    function is(value) {
        return Error.is(value) && value.status == 503 && value.type == "missing configuration";
    }
    missconfigured.is = is;
})(missconfigured || (missconfigured = {}));

function unavailable() {
    return { status: 503, type: "service unavailable" };
}
(function (unavailable) {
    function is(value) {
        return Error.is(value) && value.status == 503 && value.type == "service unavailable";
    }
    unavailable.is = is;
})(unavailable || (unavailable = {}));

function unknown(error) {
    return { status: 500, type: "unknown error", error };
}
(function (unknown) {
    function is(value) {
        return Error.is(value) && value.status == 500 && value.type == "unknown error";
    }
    unknown.is = is;
})(unknown || (unknown = {}));

export { Error as E, backendFailure as b, invalidContent as i, unauthorized as u };
