"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMappingPropValidator = exports.HtmlElement = exports.deprecatedType = exports.deprecated = void 0;
/**
 * Функции объявленные в этом файле используются в сторонних либах для валидации propTypes в рантайме,
 * т.к. компоненты библиотеки могут использоваться в js, где нет проверок типов Typescript
 */
/**
 * Добавляет к type-checker для propType валидации метод isRequired
 *
 * @param validate оригинальный метод для валидации
 */
function createChainableTypeChecker(validate) {
    function checkType(isRequired, props, propName, componentName, location) {
        // eslint-disable-next-line no-param-reassign
        componentName = componentName || '';
        if (props[propName] === null || props[propName] === undefined) {
            if (isRequired) {
                return new Error("Required prop `" + propName + "` was not specified in `" + componentName + "`.");
            }
            return null;
        }
        return validate(props, propName, componentName, location);
    }
    var chainedCheckType = checkType.bind(null, false);
    chainedCheckType.isRequired = checkType.bind(null, true);
    return chainedCheckType;
}
/**
 * Проверяет, является ли заданный prop инстансом HTMLElement
 *
 * @param props пропы компонента
 * @param propName имя пропса для валидации
 * @param componentName имя компонента
 */
function propTypeIsHtmlElement(props, propName, componentName) {
    if (!(props[propName] instanceof (typeof HTMLElement === 'undefined' ? {} : HTMLElement))) {
        return new Error("Invalid prop `" + propName + "` supplied to `" + componentName + "`.\n            Expected valid HTMLElement object, " + typeof props[propName] + " given.");
    }
    return null;
}
/**
 * Враппер для prop-type валидаторов, позволяющий помечать prop как устаревший, сохраняя проверку типа
 *
 * @param propType оригинальный propType валидатор
 * @param message дополнительное сообщение
 */
function deprecated(propType, message) {
    var warned = false;
    return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        var props = args[0], propName = args[1], componentName = args[2];
        var prop = props[propName];
        if (prop !== undefined && prop !== null && !warned) {
            warned = true;
            if (process.env.NODE_ENV !== 'production') {
                // eslint-disable-next-line no-console
                console.warn("Property '" + propName + "' of '" + componentName + "' is deprecated. " + message);
            }
        }
        return propType.call.apply(propType, __spreadArrays([this], args));
    };
}
exports.deprecated = deprecated;
/**
 * Враппер для prop-type валидатора, позволяющий пометить один из типов как устаревший.
 * В случае, если заданный prop будет соответствовать старому валидатору, но не будет
 * соответствовать новому - пользователь будет об этом предупрежден
 *
 * @param oldType валидатор для старого типа.
 * @param newType валидатор для нового типа.
 * @param message дополнительное сообщение
 */
function deprecatedType(oldType, newType, message) {
    var warned = false;
    return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        var propName = args[1], componentName = args[2];
        var oldResult = oldType.call.apply(oldType, __spreadArrays([this], args));
        var newResult = newType.call.apply(newType, __spreadArrays([this], args));
        if (process.env.NODE_ENV !== 'production' && !oldResult && !warned && newResult) {
            warned = true;
            // eslint-disable-next-line no-console
            console.warn("Given type of '" + propName + "' of '" + componentName + "' is deprecated. " + message);
        }
        return newResult;
    };
}
exports.deprecatedType = deprecatedType;
/**
 * Готовый prop-type валидатор для проверки, что значение переданное в проп является HtmlElement
 */
exports.HtmlElement = createChainableTypeChecker(propTypeIsHtmlElement);
/**
 * Проверяет что значение пропса из заданного множества
 *
 * @param validationMapping множество допустимых значений пропса
 * @param controllingPropName имя контролируемого пропса
 */
function createMappingPropValidator(validationMapping, controllingPropName) {
    return function validateProp(props, propName, componentName) {
        var controllingPropValue = props[controllingPropName];
        var controlledPropValue = props[propName];
        var propsDefined = controllingPropValue && controlledPropValue;
        var availableOptions = validationMapping[controllingPropValue];
        if (!propsDefined || !Array.isArray(availableOptions)) {
            return null;
        }
        var isValidProp = availableOptions.indexOf(props[propName]) !== -1;
        if (!isValidProp) {
            return new Error("Invalid prop '" + propName + "' supplied to " + componentName + ".\n                Expected one of " + availableOptions + " for prop '" + controllingPropName + "' equal to " + controllingPropValue);
        }
        return null;
    };
}
exports.createMappingPropValidator = createMappingPropValidator;

//# sourceMappingURL=prop-types.js.map
