UNPKG

2.89 kBJavaScriptView Raw
1const expose = require('./expose');
2const { keys, entries } = Object;
3
4/**
5 * Get a shallow clone of an object without the specified properties.
6 *
7 * @param {Object} object
8 * @param {*} exclusions
9 * @return {Object}
10 */
11const cloneWithout = (object, ...exclusions) =>
12 keys(object).reduce((accumulator, key) => {
13 if (!exclusions.includes(key)) {
14 accumulator[key] = object[key];
15 }
16
17 return accumulator;
18 }, {});
19
20/**
21 * @param {Object|string} value
22 * @return {boolean}
23 */
24const isObject = value => typeof value !== 'string';
25
26/**
27 * @param {Array} array
28 * @return {Object}
29 */
30function getObject(array) {
31 const [object, invalid] = array.filter(value => isObject(value));
32
33 if (object === undefined) {
34 throw new TypeError('no object');
35 }
36
37 if (invalid !== undefined) {
38 throw new TypeError('multiple objects');
39 }
40
41 return object;
42}
43
44/**
45 * @param {Array} rest
46 * @return {Object}
47 */
48function purge(...rest) {
49 const object = getObject(rest);
50
51 return entries(object).reduce((accumulator, [key, value]) => {
52 if (!rest.includes(key)) {
53 accumulator[key] = value;
54 }
55
56 return accumulator;
57 }, {});
58}
59
60/**
61 * @param rest
62 * @return {Array}
63 */
64function extract(...rest) {
65 const object = getObject(rest);
66
67 const map = value => {
68 if (value === object) {
69 return purge(...rest);
70 }
71
72 return object[value];
73 };
74
75 return rest.map(map);
76}
77
78// ZS-FIXME: complicated and unreadable.
79// 1) add ESDoc documentation for function purpose, paramaters and return value
80// 2) write unit tests
81// 3) enable ESLint
82// 4) refactor
83/*eslint-disable*/
84function get(obj, path, def) {
85 let fullPath = path
86 .replace(/\[/g, '.')
87 .replace(/]/g, '')
88 .split('.')
89 .filter(Boolean);
90
91 if (!obj) return def || undefined;
92
93 return fullPath.every(everyFunc) ? obj : def;
94
95 function everyFunc(step) {
96 return !(step && obj && (obj = obj[step]) === undefined);
97 }
98}
99
100/**
101 * @param {Object} object
102 * @param {Object} paramGetters
103 * @return {Object}
104 */
105function performGetOnProperties(object, paramGetters) {
106 return keys(object).reduce((acc, param) => {
107 acc[param] = get(object, paramGetters[param]);
108
109 return acc;
110 }, {});
111}
112
113/**
114 * @param {Object} object
115 * @param rest
116 * @return {Object}
117 */
118function filterProperties(object, ...rest) {
119 return rest.reduce(function addProperty(accumulator, x) {
120 if (object.hasOwnProperty(x)) {
121 accumulator[x] = object[x];
122 }
123
124 return accumulator;
125 }, {});
126}
127
128function filterPropertiesOnValues(object, filter) {
129 return keys(object).reduce(function filterProps(accumulator, x) {
130 if (filter(object[x])) {
131 accumulator[x] = object[x];
132 }
133
134 return accumulator;
135 }, {});
136}
137
138module.exports = expose({
139 cloneWithout,
140 extract,
141 filterProperties,
142 filterPropertiesOnValues,
143 getObject,
144 get,
145 isObject,
146 performGetOnProperties,
147 purge,
148});