"use strict"; const defaultValue = require("default-value"); const escapeStringRegexp = require("escape-string-regexp"); const isString = require("@validatem/is-string"); const matchesFormat = require("@validatem/matches-format"); const wrapError = require("@validatem/wrap-error"); function replaceAll(string, search, replace) { let regex = new RegExp(escapeStringRegexp(search), "g"); return string.replace(regex, replace); } function generateRequirementsList(requirements) { return Object.entries(requirements) .filter(([ _key, value ]) => value === true) .map(([ key, _value]) => key); } module.exports = function makeIsNumericValidator(options = {}) { let decimalSeparator = defaultValue(options.decimalSeparator, "."); let groupSeparator = defaultValue(options.groupSeparator, ","); let allowDecimal = defaultValue(options.allowDecimal, false); let allowGroups = defaultValue(options.allowGroups, false); let allowNegative = defaultValue(options.allowNegative, false); let parse = defaultValue(options.parse, false); function parseNumber(value, context) { // Automatically avoid parsing if `ignoreResult` has been used if (context.parseIntoResult !== false) { let strippedValue = (allowGroups) ? replaceAll(value, groupSeparator, "") : value; let normalizedValue = (decimalSeparator !== ".") ? replaceAll(strippedValue, decimalSeparator, ".") : strippedValue; if (allowDecimal) { return parseFloat(normalizedValue); } else { return parseInt(normalizedValue); } } } let integerPartRegex = (allowGroups) ? `\\d+(${escapeStringRegexp(groupSeparator)}\\d+)*` : "\\d+"; let negativePrefixRegex = (allowNegative) ? "-?" : ""; let fractionalPartRegex = (allowDecimal) ? `(${escapeStringRegexp(decimalSeparator)}\\d+)?` : ""; let parser = (parse) ? parseNumber : undefined; let requirements = generateRequirementsList({ "whole": !allowDecimal, "positive": !allowNegative, "ungrouped": !allowGroups }); let requirementsString = (requirements.length > 0) ? `string representing a ${requirements.join(", ")} number` : "numeric string"; return wrapError(`Must be a ${requirementsString}`, [ isString, matchesFormat(new RegExp(`^${negativePrefixRegex}${integerPartRegex}${fractionalPartRegex}$`)), parser ]); };