"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setIn = exports.getIn = void 0;
// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

const nameToPath = name => name.replace(/]/g, '').split('[');
const fixObj = (obj, key) => {
  if (isNaN(key) && (Array.isArray(obj) || typeof obj !== 'object' || obj === null)) {
    return {};
  }
  if (!isNaN(key) && !Array.isArray(obj)) {
    return [];
  }
  if (isNaN(key)) {
    return {
      ...obj
    };
  }
  // @ts-ignore
  return [...obj];
};

/**
 * Deeply get a value from an object via its path.
 *
 * @param {object} obj The object to query.
 * @param {string} name The path of the property to get.
 * @param {*} def The value returned for `undefined` resolved values.
 * @returns {*} Returns the resolved value.
 *
 * @example
 * const name = getIn(state, 'user[name]', 'Anonymous');
 *
 */
const getIn = (obj, name, def) => {
  const path = nameToPath(name);
  let val;
  try {
    val = path.reduce((curr, key) => curr[key], obj);
  } catch {}
  return val === undefined ? def : val;
};

/**
 * Deeply set a value from in object via it's path.
 * Does not mutate an original object.
 *
 * @param {object} obj The object to query.
 * @param {string} name The path of the property to set.
 * @param {*} val The value to set.
 * @returns {object} Returns a new object.
 *
 * @example
 * const nextState = setIn(state, 'user[name]', 'John');
 */
exports.getIn = getIn;
const setIn = (obj, name, val) => {
  const path = nameToPath(name);
  const next = fixObj(obj, path[0]);
  let key;
  let curr = next;
  while ((key = path.shift()) && path.length) {
    curr[key] = fixObj(curr[key], path[0]);
    curr = curr[key];
  }
  if (key) {
    curr[key] = val;
  }
  return next;
};
exports.setIn = setIn;