"use strict";
/*
 * @adonisjs/validator
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
const utils_1 = require("../utils");
/**
 * String schema type
 */
function string(options, rules) {
    if (!rules && Array.isArray(options)) {
        rules = options;
        options = {};
    }
    return (0, utils_1.getLiteralType)('string', false, false, options, rules || []);
}
string.optional = function optionalString(options, rules) {
    if (!rules && Array.isArray(options)) {
        rules = options;
        options = {};
    }
    return (0, utils_1.getLiteralType)('string', true, false, options, rules || []);
};
string.nullable = function nullableString(options, rules) {
    if (!rules && Array.isArray(options)) {
        rules = options;
        options = {};
    }
    return (0, utils_1.getLiteralType)('string', false, true, options, rules || []);
};
string.nullableAndOptional = function nullableAndOptionalString(options, rules) {
    if (!rules && Array.isArray(options)) {
        rules = options;
        options = {};
    }
    return (0, utils_1.getLiteralType)('string', true, true, options, rules || []);
};
/**
 * Boolean schema type
 */
function boolean(rules) {
    return (0, utils_1.getLiteralType)('boolean', false, false, undefined, rules || []);
}
boolean.optional = function optionalBoolean(rules) {
    return (0, utils_1.getLiteralType)('boolean', true, false, undefined, rules || []);
};
boolean.nullable = function nullableBoolean(rules) {
    return (0, utils_1.getLiteralType)('boolean', false, true, undefined, rules || []);
};
boolean.nullableAndOptional = function nullableAndOptionalBoolean(rules) {
    return (0, utils_1.getLiteralType)('boolean', true, true, undefined, rules || []);
};
/**
 * Number schema type
 */
function number(rules) {
    return (0, utils_1.getLiteralType)('number', false, false, undefined, rules || []);
}
number.optional = function optionalNumber(rules) {
    return (0, utils_1.getLiteralType)('number', true, false, undefined, rules || []);
};
number.nullable = function nullableNumber(rules) {
    return (0, utils_1.getLiteralType)('number', false, true, undefined, rules || []);
};
number.nullableAndOptional = function nullableAndOptionalNumber(rules) {
    return (0, utils_1.getLiteralType)('number', true, true, undefined, rules || []);
};
/**
 * bigint schema type
 */
function bigint(rules) {
    return (0, utils_1.getLiteralType)('bigint', false, false, undefined, rules || []);
}
bigint.optional = function optionalBigInt(rules) {
    return (0, utils_1.getLiteralType)('bigint', true, false, undefined, rules || []);
};
bigint.nullable = function nullableBigInt(rules) {
    return (0, utils_1.getLiteralType)('bigint', false, true, undefined, rules || []);
};
bigint.nullableAndOptional = function nullableAndOptionalBigInt(rules) {
    return (0, utils_1.getLiteralType)('bigint', true, true, undefined, rules || []);
};
/**
 * Date schema type
 */
function date(options, rules) {
    return (0, utils_1.getLiteralType)('date', false, false, options, rules || []);
}
date.optional = function optionalDate(options, rules) {
    return (0, utils_1.getLiteralType)('date', true, false, options, rules || []);
};
date.nullable = function nullableDate(options, rules) {
    return (0, utils_1.getLiteralType)('date', false, true, options, rules || []);
};
date.nullableAndOptional = function nullableAndOptionalDate(options, rules) {
    return (0, utils_1.getLiteralType)('date', true, true, options, rules || []);
};
/**
 * Object schema type
 */
function object(rules) {
    return {
        members(schema) {
            return (0, utils_1.getObjectType)(false, false, Object.keys(schema).reduce((result, field) => {
                result[field] = schema[field].getTree();
                return result;
            }, {}), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getObjectType)(false, false, null, rules || []);
        },
    };
}
object.optional = function optionalObject(rules) {
    return {
        members(schema) {
            return (0, utils_1.getObjectType)(true, false, Object.keys(schema).reduce((result, field) => {
                result[field] = schema[field].getTree();
                return result;
            }, {}), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getObjectType)(true, false, null, rules || []);
        },
    };
};
object.nullable = function nullableObject(rules) {
    return {
        members(schema) {
            return (0, utils_1.getObjectType)(false, true, Object.keys(schema).reduce((result, field) => {
                result[field] = schema[field].getTree();
                return result;
            }, {}), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getObjectType)(false, true, null, rules || []);
        },
    };
};
object.nullableAndOptional = function nullableAndOptionalObject(rules) {
    return {
        members(schema) {
            return (0, utils_1.getObjectType)(true, true, Object.keys(schema).reduce((result, field) => {
                result[field] = schema[field].getTree();
                return result;
            }, {}), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getObjectType)(true, true, null, rules || []);
        },
    };
};
/**
 * Array schema type
 */
function array(rules) {
    return {
        members(schema) {
            return (0, utils_1.getArrayType)(false, false, schema.getTree(), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getArrayType)(false, false, null, rules || []);
        },
    };
}
array.optional = function optionalArray(rules) {
    return {
        members(schema) {
            return (0, utils_1.getArrayType)(true, false, schema.getTree(), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getArrayType)(true, false, null, rules || []);
        },
    };
};
array.nullable = function nullableArray(rules) {
    return {
        members(schema) {
            return (0, utils_1.getArrayType)(false, true, schema.getTree(), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getArrayType)(false, true, null, rules || []);
        },
    };
};
array.nullableAndOptional = function nullableAndOptionalArray(rules) {
    return {
        members(schema) {
            return (0, utils_1.getArrayType)(true, true, schema.getTree(), rules || []);
        },
        anyMembers() {
            return (0, utils_1.getArrayType)(true, true, null, rules || []);
        },
    };
};
/**
 * Enum schema type
 */
function oneOf(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enum', false, false, enumOptions, rules || []);
}
oneOf.optional = function optionalEnum(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enum', true, false, enumOptions, rules || []);
};
oneOf.nullable = function nullableEnum(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enum', false, true, enumOptions, rules || []);
};
oneOf.nullableAndOptional = function nullableAndOptionalEnum(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enum', true, true, enumOptions, rules || []);
};
/**
 * Enum set schema type
 */
function enumSet(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enumSet', false, false, enumOptions, rules || []);
}
enumSet.optional = function optionalEnumSet(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enumSet', true, false, enumOptions, rules || []);
};
enumSet.nullable = function nullableEnumSet(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enumSet', false, true, enumOptions, rules || []);
};
enumSet.nullableAndOptional = function nullableAndOptionalEnumSet(enumOptions, rules) {
    return (0, utils_1.getLiteralType)('enumSet', true, true, enumOptions, rules || []);
};
/**
 * File schema type
 */
function file(options, rules) {
    return (0, utils_1.getLiteralType)('file', false, false, options, rules || []);
}
file.optional = function optionalFile(options, rules) {
    return (0, utils_1.getLiteralType)('file', true, false, options, rules || []);
};
file.nullable = function nullableFile(options, rules) {
    return (0, utils_1.getLiteralType)('file', false, true, options, rules || []);
};
file.nullableAndOptional = function nullableAndOptionalFile(options, rules) {
    return (0, utils_1.getLiteralType)('file', true, true, options, rules || []);
};
/**
 * Define refs, which are resolved at runtime vs the compile time
 */
function refs(schemaRefs) {
    return Object.keys(schemaRefs).reduce((result, key) => {
        result[key] = {
            __$isRef: true,
            value: schemaRefs[key],
            key: key,
        };
        return result;
    }, {});
}
/**
 * List of available schema methods. One can add custom types by
 * using the extend method
 */
exports.schema = {
    string,
    boolean,
    number,
    bigint,
    date,
    object,
    array,
    enum: oneOf,
    enumSet: enumSet,
    file,
    refs,
    /**
     * Create a new schema compiled schema tree
     */
    create(tree) {
        return {
            props: {},
            tree: Object.keys(tree).reduce((result, field) => {
                result[field] = tree[field].getTree();
                return result;
            }, {}),
        };
    },
};
