src/tools/helpers.js
import _ from 'lodash';
/**
* Не мутабельный set
* @param object
* @param path
* @param value
* @returns {Object}
*/
export const setIn = (object, path, value) =>
_.setWith(_.clone(object), path, value, _.clone);
function http_build_query(formdata, numeric_prefix, arg_separator) {
let key,
use_val,
use_key,
i = 0,
tmp_arr = [];
if (!arg_separator) {
arg_separator = '&';
}
for (key in formdata) {
if (!formdata.hasOwnProperty(key)) {
continue;
}
use_key = key;
use_val = String(formdata[key]);
use_val = use_val.replace(/%20/g, '+');
if (numeric_prefix && !isNaN(key)) {
use_key = numeric_prefix + i;
}
tmp_arr[i] = `${use_key}=${use_val}`;
i++;
}
return tmp_arr.join(arg_separator) && '?' + tmp_arr.join(arg_separator);
}
/**
* new method conversion in url for query
* see {NNO-266}
* @param data
* @returns {String}
*/
export function http_params_query(data) {
const params = [];
_.each(data, (val, key) => {
if (data.hasOwnProperty(key)) {
params.push({ name: key, value: val });
}
});
return params;
}
/**
* Make "flat" query string from object Json
* and extends params
* with new paramize method
* @param objectAim
* @param [Key] - key id start
* @param [$Res] - extender result object
* @param [delimiter] - extender result object
* @returns {String}
*/
export function generateParamQuery(objectAim, Key, $Res, delimiter) {
$Res = $generateFlatQuery(objectAim, Key, $Res, delimiter);
return http_params_query($Res);
}
/**
* Make "flat" query string from object Json
* and extends params
* @param objectAim
* @param [Key] - key id start
* @param [$Res] - extender result object
* @param [delimiter] - extender result object
* @returns {String}
*/
export function generateFlatQuery(objectAim, Key, $Res, delimiter) {
$Res = $generateFlatQuery(objectAim, Key, $Res, delimiter);
return http_build_query($Res);
}
function $generateFlatQuery(objectAim, Key, $Res, delimiter, options) {
delimiter = delimiter || '.';
$Res = $Res || {};
if (_.isObject(Key)) {
options = Key || {};
Key = '';
} else {
Key = Key || '';
options = options || {};
}
let ignoreNull = options.ignoreNull || false,
withoutEncode = options.withoutEncode || false;
_.each(objectAim, (val, key) => {
if (_.isArray(val)) {
_.each(val, ($val, $key) => {
if (_.isObject($val)) {
generateFlatQuery(
$val,
Key
? [Key, '?[?]'.format(key, $key)].join(delimiter)
: '?[?]'.format(key, $key),
$Res,
delimiter,
options
);
} else if ($val !== null && $val !== undefined) {
$Res[
Key
? [Key, '?[?]'.format(key, $key)].join(delimiter)
: '?[?]'.format(key, $key)
] =
!needLinked($val) && _.isString($val) && !withoutEncode
? encodeURIComponent($val)
: $val;
}
});
return;
}
if (_.isObject(val)) {
generateFlatQuery(
val,
Key ? Key + delimiter + key : key,
$Res,
delimiter,
options
);
} else if ((val !== null || ignoreNull) && val !== undefined) {
$Res[Key ? Key + delimiter + key : key] =
!needLinked(val) && _.isString(val) && !withoutEncode
? encodeURIComponent(val)
: val;
}
});
return $Res;
}
/**
* Create object form string with dot notation
*
* @example
* "Page.sdf.test" => {
* Page: {
* sdf: {
* test: 'default value'
* }
* }
* }
*
* @param {String} string
* @param [defaultValue]
* @param [delimiter]
* @returns {Object}
* @param {Object} [$resultObject]
*/
export function createObjectFromDotString(
string,
defaultValue,
delimiter,
$resultObject
) {
// defaultValue = defaultValue || {};
delimiter = delimiter || '.';
const keys = string.split(delimiter);
const res = $resultObject || {};
let $next = res;
_.each(keys, (item, i) => {
// if key array's
let resRegExp;
if ((resRegExp = item && item.match(/\[(\d)\]/))) {
const index = +resRegExp[1];
const $key = item.replace(/\[(\d)\]/, '');
$next[$key] = $next[$key] || [];
// about array[0][0] ???
$next[$key][index] = $next[$key][index] || {};
if (keys.length === i + 1) {
$next[$key][index] = defaultValue;
}
$next = $next[$key][index];
return $next;
}
$next[item] = $next[item] || {};
$next[item] = $next[item] || {};
if (keys.length === i + 1) {
$next[item] = defaultValue;
}
$next = $next[item];
});
return res;
}
/**
* Create object dy dot notation string and set value from context.
* @param key string with dot notation
* @param obj
* @param [delimiter]
* @returns {{}}
*/
export function createObjectByDotNotationKey(key, obj, delimiter) {
delimiter = delimiter || '.';
const keys = key.split(delimiter);
const res = {};
let $next = res;
const $val = obj;
const deep = [];
if (keys.length === 1) {
res[key] = obj[key];
return res;
}
_.each(keys, (item, i) => {
deep.push(item);
$next[item] = $next[item] || {};
$val[item] = $val[item];
if (keys.length === i + 1) {
$next[item] = getPathValue($val, deep.join(delimiter));
}
$next = $next[item];
});
return res;
}
/**
* get value from sub-path object
* @param object
* @param path
*/
export function getPathValue(object, path) {
const flatParams = $generateFlatQuery(object, { withoutEncode: true });
return flatParams[path];
}
/**
* get func from preFilter
* @param value
*/
export function preFilterIsFunction(value) {
const regExp = `${value}`.match(/^`(.*)`$/);
return regExp && regExp[1];
}
/**
* @ignore
*/
function needLinked(query) {
query = String(query);
// noinspection JSValidateTypes
const res = query.match('^(\\$|\\@)?{([^}^{]*)}$'); // => {Page.container.name}
if (res && res[2]) {
return res[2];
}
return false;
}
/**
* Возвращается widgetId на основе page и container
* @param pageId
* @param cntId
* @returns {string}
*/
export function getWidgetId(pageId, cntId) {
return `${pageId}.${cntId}`;
}
/**
* Проверка является ли объект Promise
* @param obj
* @returns {boolean}
*/
export function isPromise(obj) {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
);
}
/**
* Глубокое сравнение двух объектов
* @param {Object} object объект сравнания
* @param {Object} base объект с чем сарвнивают
* @return {Object} возвращает новый объект с разницей
*/
export function difference(object, base) {
const changes = (object, base) => {
return _.transform(object, (result, value, key) => {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key])
? changes(value, base[key])
: value;
}
});
};
return changes(object, base);
}
/**
* Глубокое удаление ключей
* @param collection
* @param excludeKeys
* @returns {*}
*/
export function omitDeep(collection, excludeKeys) {
function omitFn(value) {
if (value && typeof value === 'object') {
excludeKeys.forEach(key => {
delete value[key];
});
}
}
return _.cloneDeepWith(collection, omitFn);
}