forked from waja/action-debian-package
55 lines
1.2 KiB
JavaScript
55 lines
1.2 KiB
JavaScript
'use strict';
|
|
|
|
const isObject = value => typeof value === 'object' && value !== null;
|
|
|
|
// Customized for this use-case
|
|
const isObjectCustom = value =>
|
|
isObject(value) &&
|
|
!(value instanceof RegExp) &&
|
|
!(value instanceof Error) &&
|
|
!(value instanceof Date);
|
|
|
|
const mapObject = (object, mapper, options, isSeen = new WeakMap()) => {
|
|
options = {
|
|
deep: false,
|
|
target: {},
|
|
...options
|
|
};
|
|
|
|
if (isSeen.has(object)) {
|
|
return isSeen.get(object);
|
|
}
|
|
|
|
isSeen.set(object, options.target);
|
|
|
|
const {target} = options;
|
|
delete options.target;
|
|
|
|
const mapArray = array => array.map(element => isObjectCustom(element) ? mapObject(element, mapper, options, isSeen) : element);
|
|
if (Array.isArray(object)) {
|
|
return mapArray(object);
|
|
}
|
|
|
|
for (const [key, value] of Object.entries(object)) {
|
|
let [newKey, newValue] = mapper(key, value, object);
|
|
|
|
if (options.deep && isObjectCustom(newValue)) {
|
|
newValue = Array.isArray(newValue) ?
|
|
mapArray(newValue) :
|
|
mapObject(newValue, mapper, options, isSeen);
|
|
}
|
|
|
|
target[newKey] = newValue;
|
|
}
|
|
|
|
return target;
|
|
};
|
|
|
|
module.exports = (object, mapper, options) => {
|
|
if (!isObject(object)) {
|
|
throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`);
|
|
}
|
|
|
|
return mapObject(object, mapper, options);
|
|
};
|