/**
* @module helpers/jrh_validate
* @author jesse reichler <mouser@donationcoder.com>
* @copyright 6/27/19
* @description
* Collection of helper functions for validating data
*/
"use strict";
//---------------------------------------------------------------------------
/**
* Validate a string. Just check that it's non-blank if so requested.
*
* @param {obj} jrResult - existing JrResult objec to push errors into
* @param {string} keyname - name of the property we are validating, used only for error generation
* @param {string} str - the value we are validating
* @param {boolean} flagRequired - if true, it will be an error if value is blank
* @returns validated string or undefined if invalid (with JrResult containing error)
*/
function validateString(jrResult, keyname, str, flagRequired) {
if (!str) {
if (!flagRequired) {
return str;
}
jrResult.pushFieldError(keyname, keyname + " cannot be left blank");
return undefined;
}
// anything else is good for now
return str;
}
/**
* Validate a name. This code currently just calls validateString.
*
* @param {obj} jrResult - existing JrResult objec to push errors into
* @param {string} keyname - name of the property we are validating, used only for error generation
* @param {string} str - the value we are validating
* @param {boolean} flagRequired - if true, it will be an error if value is blank
* @returns validated string or undefined if invalid (with JrResult containing error)
*/
function validateRealName(jrResult, keyname, str, flagRequired) {
return validateString(jrResult, keyname, str, flagRequired);
}
/**
* Validate a true|false value.
*
* @param {obj} jrResult - existing JrResult objec to push errors into
* @param {string} keyname - name of the property we are validating, used only for error generation
* @param {boolean} val - the value we are validating
* @param {boolean} flagRequired - if true, it will be an error if value is undefined or null
* @returns true or false, or undefined if invalid (with JrResult containing error)
*/
function validateTrueFalse(jrResult, keyname, val, flagRequired) {
if (val) {
return true;
}
if (flagRequired && (val === undefined || val === null)) {
jrResult.pushFieldError(keyname, keyname + " cannot be left blank");
return undefined;
}
return false;
}
/**
* Validate a number.
*
* @param {obj} jrResult - existing JrResult objec to push errors into
* @param {string} keyname - name of the property we are validating, used only for error generation
* @param {int} val - the value we are validating
* @param {boolean} flagRequired - if true, it will be an error if value is undefined or null
* @returns integer value, or undefined if invalid (with JrResult containing error)
*/
function validateInteger(jrResult, keyname, val, flagRequired) {
// check for missing
if (val === undefined || val === null) {
if (flagRequired) {
jrResult.pushFieldError(keyname, keyname + " cannot be left blank");
return undefined;
}
return 0;
}
const num = parseInt(val, 10);
if (Number.isNaN(num)) {
jrResult.pushFieldError(keyname, keyname + " must be a valid integer value");
return null;
}
return num;
}
/**
* Validate a number in a [min,max] range
*
* @param {obj} jrResult - existing JrResult objec to push errors into
* @param {string} keyname - name of the property we are validating, used only for error generation
* @param {int} val - the value we are validating
* @param {int} min - minimum value considered valid
* @param {int} max - maximum value considered valid
* @param {boolean} flagRequired - if true, it will be an error if value is undefined or null
* @returns integer value, or undefined if invalid (with JrResult containing error)
*/
function validateIntegerRange(jrResult, keyname, val, min, max, flagRequired) {
// check for missing
if (val === undefined || val === null) {
if (flagRequired) {
jrResult.pushFieldError(keyname, keyname + " cannot be left blank");
return undefined;
}
return undefined;
}
const num = parseInt(val, 10);
if (Number.isNaN(num)) {
jrResult.pushFieldError(keyname, keyname + " must be a valid integer value");
return null;
}
if (num < min || num > max) {
jrResult.pushFieldError(keyname, keyname + " must be an integer in the range [%d,%d]".format(min, max));
return null;
}
return num;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
/**
* Validates an object to yield proper json, or a json string, which is converted to a json object
*
* @param {*} jrResult
* @param {*} keyname
* @param {*} val
* @param {*} flagRequired
* @returns a json object or sets error in jrResult
*/
function validateJsonObjOrStringToObj(jrResult, keyname, val, flagRequired) {
const oval = val;
if (val === "" || val === null || val === undefined) {
if (!flagRequired) {
if (val === "") {
// we need to return null not undefined
return null;
}
return undefined;
}
jrResult.pushFieldError(keyname, keyname + " cannot be left blank");
return oval;
}
// test to see if we can conver it
if (typeof val === "string") {
try {
val = val.trim();
if (val.length === 0 || val[0] !== "{") {
jrResult.pushFieldError(keyname, keyname + " is not a valid json object string (must start with { bracket).");
return oval;
}
val = JSON.parse(val);
// success, just drop down and return the converted string
} catch (e) {
jrResult.pushFieldError(keyname, keyname + " is not a valid json string: " + e.toString());
return oval;
}
} else {
// it's not a string, so make it a json string to see if its valid
try {
const valAsString = JSON.stringify(val);
// check that its not simple value
if (valAsString.length === 0 || valAsString[0] !== "{") {
jrResult.pushFieldError(keyname, keyname + " is not a valid json object (must start with { bracket).");
return oval;
}
// success, just drop down and return the original string
} catch (e) {
jrResult.pushFieldError(keyname, keyname + " is not a valid json strinifyable object: " + e.toString());
return oval;
}
}
// anything else is good for now
return val;
}
//---------------------------------------------------------------------------
module.exports = {
validateString,
validateRealName,
validateTrueFalse,
validateInteger,
validateIntegerRange,
validateJsonObjOrStringToObj,
};