boolean-prop.js

import { compose, curryN, prop, isNil, when, always } from 'ramda';
import yn from 'yn';

/**
 * `yn` wrapper that forces all `undefined` values to be `null` to accommodate the fact that
 * latest `yn` version treats unrecognized values as `undefined` instead of `null`. In order to keep
 * retro-compatibility we force those values to be `null`.
 *
 * @example
 *   boolify('y'); // -> true
 *   boolify('abomasum'); // -> null
 *   boolify('NO'); // -> false
 *
 * @private
 * @see https://github.com/sindresorhus/yn#readme
 * @param {*} value that should be converted.
 * @returns {boolean?}
 */
const boolify = compose(when(isNil, always(null)), yn);

/**
 * Shorthand function to extract a property from an object and convert it to a boolean.
 * Parsing of values to boolean follows `yn` logic.
 *
 * @example
 *  booleanProp('foo', { foo: 'y' }); // -> true
 *  booleanProp('foo', { foo: 0 }); // -> false
 *
 * @function
 * @see https://github.com/sindresorhus/yn#readme
 * @see https://ramdajs.com/docs/#prop
 * @param {string} propName Name of the property to extract.
 * @param {object} obj Source of the extracted property
 * @returns {boolean} The value of `obj` at `propName` as a boolean.
 */
export const booleanProp = curryN(2, compose(boolify, prop));

/**
 * Shorthand function to extract a property from an object and convert it to a `Boolean`.
 * If boolean conversion would return `null` or `undefined`, it returns `defaultValue`, instead.
 *
 * @example
 *  booleanPropOr(true, 'foo', { bar: 42 }); // -> true
 *  booleanPropOr(false, 'foo', { foo: 'y' }); // -> true
 *
 * @function
 * @see https://github.com/sindresorhus/yn#readme
 * @see https://ramdajs.com/docs/#propOr
 * @param {*} defaultValue The value to return if `propName` does not exist in `obj`
 *  or is nil.
 *  @param {string} propName Name of the property to extract.
 * @param {object} obj Source of the extracted property.
 * @returns {*} The value of `obj` at `propName` as a boolean or `defaultValue`.
 */
export const booleanPropOr = curryN(3, (defaultValue, propName, obj) => {
  const value = booleanProp(propName, obj);
  return isNil(value) ? defaultValue : value;
});