forked from RedHatInsights/curiosity-frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelpers.js
More file actions
140 lines (120 loc) · 3.15 KB
/
Copy pathhelpers.js
File metadata and controls
140 lines (120 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import _camelCase from 'lodash/camelCase';
import _isPlainObject from 'lodash/isPlainObject';
import { helpers } from '../../common';
/**
* @memberof Helpers
* @module ServiceHelpers
*/
/**
* Pass through generate hash, memo clone
*/
const { generateHash, memoClone } = helpers;
/**
* A timeout cancel for function calls.
*
* @param {Function} func Callback to be executed or cancelled
* @param {object} options
* @param {number} options.timeout Function timeout in milliseconds
* @param {string} options.errorMessage What the error message will read
* @returns {Promise<*>}
*/
const timeoutFunctionCancel = (func, { timeout = 3000, errorMessage = 'function timeout' } = {}) => {
let clearTimer;
const timer = () =>
new Promise((_, reject) => {
clearTimer = window.setTimeout(reject, timeout, new Error(errorMessage));
});
const updatedFunc = async () => {
const response = await func();
window.clearTimeout(clearTimer);
return response;
};
const execFunction = () =>
Promise.race([timer(), updatedFunc()]).finally(() => {
window.clearTimeout(clearTimer);
});
return execFunction();
};
/**
* Return objects with the keys camelCased. Normally applied to an array of objects.
*
* @param {object|Array|*} obj
* @returns {object|Array|*}
*/
const camelCase = obj => {
if (Array.isArray(obj)) {
return obj.map(camelCase);
}
if (_isPlainObject(obj)) {
const updatedObj = {};
Object.entries(obj).forEach(([key, val]) => {
updatedObj[_camelCase(key)] = camelCase(val);
});
return updatedObj;
}
return obj;
};
/**
* Apply data to a callback, pass original data on error.
*
* @param {Function} callback
* @param {Array} data
* @returns {{data: *, error}}
*/
const passDataToCallback = (callback, ...data) => {
let error;
let updatedData = data;
try {
updatedData = callback(...data);
} catch (e) {
error = e;
}
return { data: updatedData, error };
};
/**
* A callback for schema validation, and after-the-fact casing adjustments.
*
* @param {object} options
* @param {string} options.casing
* @param {boolean} options.convert
* @param {string} options.id
* @param {object|Array} options.response
* @param {*} options.schema
* @returns {*|{}}
*/
const schemaResponse = ({ casing, convert = true, id = null, response, schema } = {}) => {
const { value, error = { details: [] } } = schema?.validate(response, { convert }) || {};
if (error.details.length && !helpers.TEST_MODE) {
console.error(
new Error(
`Passing original API response. Schema validation failed for ${id || '...'}: ${error.details
.map(({ context = {}, message, type }) => `${message}:${type}, ${JSON.stringify(context)}`)
.join(', ')}`
)
);
}
switch (casing) {
case 'camel':
return camelCase(value);
default:
return value;
}
};
const serviceHelpers = {
camelCase,
generateHash,
memoClone,
passDataToCallback,
schemaResponse,
timeoutFunctionCancel
};
export {
serviceHelpers as default,
serviceHelpers,
camelCase,
generateHash,
memoClone,
passDataToCallback,
schemaResponse,
timeoutFunctionCancel
};