"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.nullIfEmpty = exports.omit = exports.pluck = exports.removeKeysWithNullishValues = exports.objectStringToNumber = exports.replaceObjectRawKeys = exports.arrayToObject = void 0;

var _toNumber = require("./to-number");

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/**
 * Takes an array of objects with a shared key and returns an object keyed by idPropName
 *
 * @param {array} arrayOfObjects Array of objects
 * @param {string} idPropName=id The keyname to use as the key in the resulting object
 * @returns {object} Keyed by idPropName
 */
const arrayToObject = (arrayOfObjects, idPropName = 'id') => arrayOfObjects.reduce((result, item) => {
  result[item[idPropName]] = item;
  return result;
}, {});
/**
 * Takes an object of simple keys/values and returns a corresponding new object.
 * If there are any keys in the original object whose name end with "_raw" the
 * returned object will have a corresponding key (without the _raw suffix) but
 * with its value always converted into a JS number. If it cannot be converted
 * to a number the value will be zero. This way, you can always do math with the result
 *
 * @param {any} obj
 * @returns {object} Updated object
 */


exports.arrayToObject = arrayToObject;

const replaceObjectRawKeys = obj => {
  const extraValues = {};

  for (const key in obj) {
    if (key.endsWith('_raw')) {
      extraValues[key.replace('_raw', '')] = (0, _toNumber.toNumber)(obj[key]);
    }
  }

  return _objectSpread(_objectSpread({}, obj), extraValues);
};
/**
 * When given an object of objects returns a new object where each "value
 * object" has been processed through `replaceObjectRawKeys`
 *
 * @param {object} obj
 * @returns {object}
 */


exports.replaceObjectRawKeys = replaceObjectRawKeys;

const objectStringToNumber = obj => {
  const result = {};

  for (const key in obj) {
    result[key] = replaceObjectRawKeys(obj[key]);
  }

  return result;
};
/**
 * Returns a new object where any keys whose values are == null are removed
 *
 * @param {object} obj
 * @returns {object} New object with nullish values removed
 */


exports.objectStringToNumber = objectStringToNumber;

const removeKeysWithNullishValues = obj => {
  const result = {};

  for (const key in obj) {
    const value = obj[key];

    if (value != null) {
      result[key] = value;
    }
  }

  return result;
};
/**
 * Construct new object with keys you care about from another object.
 *
 * @param {object} obj
 * @param {string[]} keys Array of keys to include in new object
 * @returns New object with only the keys specified in the second parameter
 */


exports.removeKeysWithNullishValues = removeKeysWithNullishValues;

const pluck = (obj, keys) => keys.reduce((result, key) => {
  if (obj.hasOwnProperty(key)) {
    result[key] = obj[key];
  }

  return result;
}, {});
/**
 * Construct a new object without keys specified in second argument
 *
 * @param {object} obj Starting object
 * @param {string[]} keysToSkip Keys you don't want in the resulting object
 */


exports.pluck = pluck;

const omit = (obj, keysToSkip = []) => {
  const copy = Object.assign({}, obj);
  keysToSkip.forEach(key => {
    delete copy[key];
  });
  return copy;
};
/**
 * Returns item or null if item is falsy, an empty array, or an empty object.
 *
 * @param {any} item Starting object
 * @returns {any} Returns passed item or null
 */


exports.omit = omit;

const nullIfEmpty = item => {
  if (item == null) {
    return null;
  }

  if (item.length === 0) {
    return null;
  }

  if (Object.keys(item).length === 0) {
    return null;
  }

  return item;
};

exports.nullIfEmpty = nullIfEmpty;