UNPKG

2.65 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)
52 .reduce((accumulator, [key, value]) => {
53 if (!rest.includes(key)) {
54 accumulator[key] = value;
55 }
56
57 return accumulator;
58 }, {});
59}
60
61/**
62 * @param rest
63 * @return {Array}
64 */
65function extract(...rest) {
66 const object = getObject(rest);
67
68 const map = value => {
69 if (value === object) {
70 return purge(...rest);
71 }
72
73 return object[value];
74 };
75
76 return rest.map(map);
77}
78
79// ZS-FIXME: complicated and unreadable.
80// 1) add ESDoc documentation for function purpose, paramaters and return value
81// 2) write unit tests
82// 3) enable ESLint
83// 4) refactor
84/*eslint-disable*/
85function get(obj, path, def) {
86 let fullPath = path
87 .replace(/\[/g, '.')
88 .replace(/]/g, '')
89 .split('.')
90 .filter(Boolean);
91
92 if (!obj) return def || undefined;
93
94 return fullPath.every(everyFunc) ? obj : def;
95
96 function everyFunc(step) {
97 return !(step && obj && (obj = obj[step]) === undefined);
98 }
99}
100
101/**
102 * @param {Object} object
103 * @param {Object} paramGetters
104 * @return {Object}
105 */
106function performGetOnProperties(object, paramGetters) {
107 return keys(object).reduce((acc, param) => {
108 acc[param] = get(object, paramGetters[param]);
109
110 return acc;
111 }, {});
112}
113
114/**
115 * @param {Object} object
116 * @param rest
117 * @return {Object}
118 */
119function filterProperties(object, ...rest) {
120 return rest.reduce(function addProperty(accumulator, x) {
121 if (object.hasOwnProperty(x)) {
122 accumulator[x] = object[x];
123 }
124
125 return accumulator;
126 }, {});
127}
128
129module.exports = expose({
130 cloneWithout,
131 extract,
132 filterProperties,
133 getObject,
134 get,
135 isObject,
136 performGetOnProperties,
137 purge,
138});