'use strict'
/**
* exists will return true when `propertyName` is a property of `obj`, else false is returned.
* You can also check for the existence of a property contained in a nested object by chaining
* the properties. Simply use a dot notation in the `propertyName` to specify the chain.
*
* @param {Object} obj `Object` to check
* @param {String} propertyName the name of the property to be checked for.
* @returns {Boolean} Returns true if `propertyName` is a property of `obj`.
* @example
* const ub = require('@nuskin/uncle-buck')
*
* let obj = { a: 1, b: { c: 0}}
* ub.exists(obj,'a') //returns true
* ub.exists(obj,'b.c') // returns true
*/
function exists(obj, propertyName) {
let properties = (propertyName || '').split('.')
while(properties.length){
let pname = properties.shift()
if(isObject(obj)){
if(properties.length){
return exists(obj[pname], properties.join('.'))
} else {
return Object.prototype.hasOwnProperty.call(obj, pname)
}
}
}
return false
}
/**
* isBoolean tests if `variable` is of type Boolean
*
* @param {*} variable value to test
* @returns {Boolean} Returns true if `variable` is a boolean
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.isBoolean(false) // returns true
*/
function isBoolean(variable) {
return typeof variable === 'boolean'
}
/**
* isString tests if `variable` is a String
*
* @param {*} variable value to test
* @returns {Boolean} Returns true if `variable` is a String
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.isString('my string') // returns true
*/
function isString(variable) {
return typeof variable === 'string'
}
/**
* isJSON tests if `str` is valid JSON.
*
* @param {String} str String to test
* @returns {Boolean} Returns true if string is valid JSON
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.isJSON('{"abc":true}') // returns true
* ub.isJSON('{"abc":true') // returns false
* ub.isJSON({"abc":true}) // returns false
*/
function isJSON(str) {
try {
if(isString(str)){
return (JSON.parse(str) && !!str)
} else {
return false
}
} catch (e) {
return false
}
}
/**
* isNull tests if `n` is `null` or `undefined`.
*
* @param {*} n value to test
* @returns {Boolean} Returns true if the value is `null` or `undefined`
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.isNull(null) // returns true
* ub.isNull(undefined) // returns true
* ub.isNull({}) // returns false
*/
function isNull(n) {
return n == null
}
/**
* isObject tests if `variable` is an object
*
* @param {*} variable value to test
* @returns {Boolean} Returns true if `variable` is an object
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.isObject('{"abc":true}') // returns false
* ub.isObject({"abc":true}) // returns true
*/
function isObject(variable) {
let rv = !isNull(variable)
if(rv){
rv = typeof variable === 'object' && !Array.isArray(variable)
}
return rv
}
/**
* nvl lets you replace null or undefined with a value of your choice. If `n` is
* null or undefined, * then nvl returns `val`. If `n` is not null or undefined,
* then nvl returns `n`.
*
* @param {*} n - The value you want to test for null or undefined
* @param (*) val - The value you want returned when `n` is null or undefined
* @returns {*} Returns `val` when `n` is null or undefined
* @example
* const ub = require('@nuskin/uncle-buck')
*
* ub.nvl(null,0) // returns 0
* ub.nvl('mystring','yourstring') // returns 'mystring'
*/
function nvl(n, val) {
if (isNull(n)) {
return val
}
return n
}
/**
* sleep will suspend execution for an interval amount of time that is set in
* milliseconds. The default is 1 second.
*
* @param {Number} ms The number of milliseconds to sleep for
* @example
* const { sleep } = require('@nuskin/uncle-buck')
* const myfunc = async () => {
* await sleep(2000) // sleep for 2 seconds
* // do something
* }
*
* myfunc()
*/
function sleep(ms = 1000) {
return new Promise(resolve => setTimeout(resolve, ms))
}
/**
* stringToJSON will convert a JSON string to a JavaScript object and return it. If
* `value` is already a JavaScript object, the object is simply returned. An error is thrown
* if `value` is not parseable or a JavaScript object.
* @param {*} value The value to evaluate
* @throws {Error} Thrown if `value` is not a valid JSON string or a JavaScript object.
* @returns {object} The JavaScript object parsed from the JSON string.
* @example
* const { stringToJSON } = require('@nuskin/uncle-buck')
* const jsonStr = JSON.stringify({ a: 1, b: '2', c: null })
* const obj = stringToJSON(jsonStr)
*
* console.log(obj)
*/
const stringToJSON = (value) => {
if (isJSON(value)) {
value = JSON.parse(value)
} else if (!isObject(value)) {
throw new Error(`Input is not a JSON string or a JavaScript object; received type: ${typeof value}`)
}
return value
}
module.exports = {
exists,
isBoolean,
isJSON,
isNull,
isObject,
isString,
nvl,
sleep,
stringToJSON
}