@slickgrid-universal/utils 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,385 +1,385 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uniqueObjectArray = exports.uniqueArray = exports.toSnakeCase = exports.toSentenceCase = exports.toKebabCase = exports.toCamelCase = exports.titleCase = exports.setDeepValue = exports.removeAccentFromText = exports.parseBoolean = exports.isObjectEmpty = exports.isNumber = exports.hasData = exports.isPrimmitive = exports.isObject = exports.isEmptyObject = exports.emptyObject = exports.objectAssignAndExtend = exports.deepMerge = exports.deepCopy = exports.arrayRemoveItemByIndex = exports.addWhiteSpaces = exports.addToArrayWhenNotExists = void 0;
4
- /**
5
- * Add an item to an array only when the item does not exists, when the item is an object we will be using their "id" to compare
6
- * @param inputArray
7
- * @param inputItem
8
- * @param itemIdPropName
9
- */
10
- function addToArrayWhenNotExists(inputArray, inputItem, itemIdPropName = 'id') {
11
- let arrayRowIndex = -1;
12
- if (inputItem && typeof inputItem === 'object' && itemIdPropName in inputItem) {
13
- arrayRowIndex = inputArray.findIndex((item) => item[itemIdPropName] === inputItem[itemIdPropName]);
14
- }
15
- else {
16
- arrayRowIndex = inputArray.findIndex((item) => item === inputItem);
17
- }
18
- if (arrayRowIndex < 0) {
19
- inputArray.push(inputItem);
20
- }
21
- }
22
- exports.addToArrayWhenNotExists = addToArrayWhenNotExists;
23
- /**
24
- * Simple function to which will loop and create as demanded the number of white spaces,
25
- * this is used in the CSV export
26
- * @param {Number} nbSpaces - number of white spaces to create
27
- * @param {String} spaceChar - optionally provide character to use as a space (could be override to use &nbsp; in html)
28
- */
29
- function addWhiteSpaces(nbSpaces, spaceChar = ' ') {
30
- let result = '';
31
- for (let i = 0; i < nbSpaces; i++) {
32
- result += spaceChar;
33
- }
34
- return result;
35
- }
36
- exports.addWhiteSpaces = addWhiteSpaces;
37
- /**
38
- * Remove a column from the grid by it's index in the grid
39
- * @param array input
40
- * @param index
41
- */
42
- function arrayRemoveItemByIndex(array, index) {
43
- return array.filter((_el, i) => index !== i);
44
- }
45
- exports.arrayRemoveItemByIndex = arrayRemoveItemByIndex;
46
- /**
47
- * Create an immutable clone of an array or object
48
- * (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings.com
49
- * @param {Array|Object} objectOrArray - the array or object to copy
50
- * @return {Array|Object} - the clone of the array or object
51
- */
52
- function deepCopy(objectOrArray) {
53
- /**
54
- * Create an immutable copy of an object
55
- * @return {Object}
56
- */
57
- const cloneObj = () => {
58
- // Create new object
59
- const clone = {};
60
- // Loop through each item in the original
61
- // Recursively copy it's value and add to the clone
62
- for (const key in objectOrArray) {
63
- if (Object.prototype.hasOwnProperty.call(objectOrArray, key)) {
64
- clone[key] = deepCopy(objectOrArray[key]);
65
- }
66
- }
67
- return clone;
68
- };
69
- /**
70
- * Create an immutable copy of an array
71
- * @return {Array}
72
- */
73
- const cloneArr = () => objectOrArray.map((item) => deepCopy(item));
74
- // -- init --//
75
- // Get object type
76
- const type = Object.prototype.toString.call(objectOrArray).slice(8, -1).toLowerCase();
77
- // If an object
78
- if (type === 'object') {
79
- return cloneObj();
80
- }
81
- // If an array
82
- if (type === 'array') {
83
- return cloneArr();
84
- }
85
- // Otherwise, return it as-is
86
- return objectOrArray;
87
- }
88
- exports.deepCopy = deepCopy;
89
- /**
90
- * Performs a deep merge of objects and returns new object, it does not modify the source object, objects (immutable) and merges arrays via concatenation.
91
- * Also, if first argument is undefined/null but next argument is an object then it will proceed and output will be an object
92
- * @param {Object} target - the target object — what to apply the sources' properties to, which is returned after it is modified.
93
- * @param {Object} sources - the source object(s) — objects containing the properties you want to apply.
94
- * @returns {Object} The target object.
95
- */
96
- function deepMerge(target, ...sources) {
97
- if (!sources.length) {
98
- return target;
99
- }
100
- const source = sources.shift();
101
- // when target is not an object but source is an object, then we'll assign as object
102
- target = (!isObject(target) && isObject(source)) ? {} : target;
103
- if (isObject(target) && isObject(source)) {
104
- for (const prop in source) {
105
- if (source.hasOwnProperty(prop)) {
106
- if (prop in target) {
107
- // handling merging of two properties with equal names
108
- if (typeof target[prop] !== 'object') {
109
- target[prop] = source[prop];
110
- }
111
- else {
112
- if (typeof source[prop] !== 'object') {
113
- target[prop] = source[prop];
114
- }
115
- else {
116
- if (target[prop].concat && source[prop].concat) {
117
- // two arrays get concatenated
118
- target[prop] = target[prop].concat(source[prop]);
119
- }
120
- else {
121
- // two objects get merged recursively
122
- target[prop] = deepMerge(target[prop], source[prop]);
123
- }
124
- }
125
- }
126
- }
127
- else {
128
- // new properties get added to target
129
- target[prop] = source[prop];
130
- }
131
- }
132
- }
133
- }
134
- return deepMerge(target, ...sources);
135
- }
136
- exports.deepMerge = deepMerge;
137
- /**
138
- * This method is similar to `Object.assign` with the exception that it will also extend the object properties when filled.
139
- * There's also a distinction with extend vs merge, we are only extending when the property is not filled (if it is filled then it remains untouched and will not be merged)
140
- * It also applies the change directly on the target object which mutates the original object.
141
- * For example using these 2 objects: obj1 = { a: 1, b: { c: 2, d: 3 }} and obj2 = { b: { d: 2, e: 3}}:
142
- * - Object.assign(obj1, obj2) => { a: 1, b: { e: 4 }}
143
- * - objectAssignAndExtend(obj1, obj2) => { a: 1, b: { c: 2, d: 3, e: 4 }
144
- * @param {Object} target - the target object — what to apply the sources properties and mutate into
145
- * @param {Object} sources - the source object(s) — objects containing the properties you want to apply.
146
- * @returns {Object} The target object.
147
- */
148
- function objectAssignAndExtend(target, ...sources) {
149
- if (!sources.length || sources[0] === undefined) {
150
- return target;
151
- }
152
- const source = sources.shift();
153
- // when target is not an object but source is an object, then we'll assign as object
154
- target = (!isObject(target) && isObject(source)) ? {} : target;
155
- if (isObject(target) && isObject(source)) {
156
- for (const key of Object.keys(source)) {
157
- if (typeof source[key] === 'object' && source[key] !== null) {
158
- objectAssignAndExtend(target[key], source[key]);
159
- }
160
- if ((target[key] === null || target[key] === undefined) && source[key] !== null && source[key] !== undefined) {
161
- target[key] = source[key];
162
- }
163
- }
164
- }
165
- return objectAssignAndExtend(target, ...sources);
166
- }
167
- exports.objectAssignAndExtend = objectAssignAndExtend;
168
- /**
169
- * Empty an object properties by looping through them all and deleting them
170
- * @param obj - input object
171
- */
172
- function emptyObject(obj) {
173
- for (const key in obj) {
174
- if (obj.hasOwnProperty(key)) {
175
- delete obj[key];
176
- }
177
- }
178
- obj = null;
179
- obj = {};
180
- return obj;
181
- }
182
- exports.emptyObject = emptyObject;
183
- /**
184
- * Check if an object is empty
185
- * @param obj - input object
186
- * @returns - boolean
187
- */
188
- function isEmptyObject(obj) {
189
- if (obj === null || obj === undefined) {
190
- return true;
191
- }
192
- return Object.entries(obj).length === 0;
193
- }
194
- exports.isEmptyObject = isEmptyObject;
195
- /**
196
- * Simple object check.
197
- * @param item
198
- * @returns {boolean}
199
- */
200
- function isObject(item) {
201
- return item !== null && typeof item === 'object' && !Array.isArray(item) && !(item instanceof Date);
202
- }
203
- exports.isObject = isObject;
204
- /**
205
- * Simple check to detect if the value is a primitive type
206
- * @param val
207
- * @returns {boolean}
208
- */
209
- function isPrimmitive(val) {
210
- return val === null || val === undefined || typeof val === 'boolean' || typeof val === 'number' || typeof val === 'string';
211
- }
212
- exports.isPrimmitive = isPrimmitive;
213
- /**
214
- * Check if a value has any data (undefined, null or empty string will return False...)
215
- * NOTE: a `false` boolean is consider as having data so it will return True
216
- */
217
- function hasData(value) {
218
- return value !== undefined && value !== null && value !== '';
219
- }
220
- exports.hasData = hasData;
221
- /**
222
- * Check if input value is a number, by default it won't be a strict checking
223
- * but optionally we could check for strict equality, for example in strict "3" will return False but without strict it will return True
224
- * @param value - input value of any type
225
- * @param strict - when using strict it also check for strict equality, for example in strict "3" would return False but without strict it would return True
226
- */
227
- function isNumber(value, strict = false) {
228
- if (strict) {
229
- return (value === null || value === undefined || typeof value === 'string') ? false : !isNaN(value);
230
- }
231
- return (value === null || value === undefined || value === '') ? false : !isNaN(+value);
232
- }
233
- exports.isNumber = isNumber;
234
- /** Check if an object is empty, it will also be considered empty when the input is null, undefined or isn't an object */
235
- function isObjectEmpty(obj) {
236
- return !obj || (obj && typeof obj === 'object' && Object.keys(obj).length === 0);
237
- }
238
- exports.isObjectEmpty = isObjectEmpty;
239
- /** Parse any input (bool, number, string) and return a boolean or False when not possible */
240
- function parseBoolean(input) {
241
- return /(true|1)/i.test(input + '');
242
- }
243
- exports.parseBoolean = parseBoolean;
244
- /**
245
- * Remove any accents from a string by normalizing it
246
- * @param {String} text - input text
247
- * @param {Boolean} shouldLowerCase - should we also lowercase the string output?
248
- * @returns
249
- */
250
- function removeAccentFromText(text, shouldLowerCase = false) {
251
- const normalizedText = (typeof text.normalize === 'function') ? text.normalize('NFD').replace(/[\u0300-\u036f]/g, '') : text;
252
- return shouldLowerCase ? normalizedText.toLowerCase() : normalizedText;
253
- }
254
- exports.removeAccentFromText = removeAccentFromText;
255
- /** Set the object value of deeper node from a given dot (.) notation path (e.g.: "user.firstName") */
256
- function setDeepValue(obj, path, value) {
257
- if (typeof path === 'string') {
258
- path = path.split('.');
259
- }
260
- if (path.length > 1) {
261
- const e = path.shift();
262
- if (obj && e !== undefined) {
263
- setDeepValue((obj)[e] = (hasData(obj[e]) && (Array.isArray(obj[e]) || Object.prototype.toString.call((obj)[e]) === '[object Object]'))
264
- ? (obj)[e]
265
- : {}, path, value);
266
- }
267
- }
268
- else if (obj && path[0]) {
269
- (obj)[path[0]] = value;
270
- }
271
- }
272
- exports.setDeepValue = setDeepValue;
273
- /**
274
- * Title case (or capitalize) first char of a string, for example "hello world" will become "Hello world"
275
- * Change the string to be title case on the complete sentence (upper case first char of each word while changing everything else to lower case)
276
- * @param inputStr
277
- * @returns string
278
- */
279
- function titleCase(inputStr, shouldTitleCaseEveryWords = false) {
280
- if (typeof inputStr === 'string') {
281
- if (shouldTitleCaseEveryWords) {
282
- return inputStr.replace(/\w\S*/g, (outputStr) => {
283
- return outputStr.charAt(0).toUpperCase() + outputStr.substring(1).toLowerCase();
284
- });
285
- }
286
- return inputStr.charAt(0).toUpperCase() + inputStr.slice(1);
287
- }
288
- return inputStr;
289
- }
290
- exports.titleCase = titleCase;
291
- /**
292
- * Converts a string to camel case (camelCase), for example "hello-world" (or "hellow world") will become "helloWorld"
293
- * @param inputStr the string to convert
294
- * @return the string in camel case
295
- */
296
- function toCamelCase(inputStr) {
297
- if (typeof inputStr === 'string') {
298
- return inputStr.replace(/(?:^\w|[A-Z]|\b\w|[\s+\-_\/])/g, (match, offset) => {
299
- // remove white space or hypens or underscores
300
- if (/[\s+\-_\/]/.test(match)) {
301
- return '';
302
- }
303
- return offset === 0 ? match.toLowerCase() : match.toUpperCase();
304
- });
305
- }
306
- return inputStr;
307
- }
308
- exports.toCamelCase = toCamelCase;
309
- /**
310
- * Converts a string to kebab (hypen) case, for example "helloWorld" will become "hello-world"
311
- * @param str the string to convert
312
- * @return the string in kebab case
313
- */
314
- function toKebabCase(inputStr) {
315
- if (typeof inputStr === 'string') {
316
- return toCamelCase(inputStr).replace(/([A-Z])/g, '-$1').toLowerCase();
317
- }
318
- return inputStr;
319
- }
320
- exports.toKebabCase = toKebabCase;
321
- /**
322
- * Converts a camelCase or kebab-case string to a sentence case, for example "helloWorld" will become "Hello World" and "hello-world" will become "Hello world"
323
- * @param str the string to convert
324
- * @return the string in kebab case
325
- */
326
- function toSentenceCase(inputStr) {
327
- if (typeof inputStr === 'string') {
328
- const result = inputStr.replace(/([A-Z])|(\-)/g, ' $1').replace(/\s+/g, ' ').trim();
329
- return result.charAt(0).toUpperCase() + result.slice(1);
330
- }
331
- return inputStr;
332
- }
333
- exports.toSentenceCase = toSentenceCase;
334
- /**
335
- * Converts a string from camelCase to snake_case (underscore) case
336
- * @param str the string to convert
337
- * @return the string in kebab case
338
- */
339
- function toSnakeCase(inputStr) {
340
- if (typeof inputStr === 'string') {
341
- return toCamelCase(inputStr).replace(/([A-Z])/g, '_$1').toLowerCase();
342
- }
343
- return inputStr;
344
- }
345
- exports.toSnakeCase = toSnakeCase;
346
- /**
347
- * Takes an input array and makes sure the array has unique values by removing duplicates
348
- * @param array input with possible duplicates
349
- * @return array output without duplicates
350
- */
351
- function uniqueArray(arr) {
352
- if (Array.isArray(arr) && arr.length > 0) {
353
- return arr.filter((item, index) => {
354
- return arr.indexOf(item) >= index;
355
- });
356
- }
357
- return arr;
358
- }
359
- exports.uniqueArray = uniqueArray;
360
- /**
361
- * Takes an input array of objects and makes sure the array has unique object values by removing duplicates
362
- * it will loop through the array using a property name (or "id" when is not provided) to compare uniqueness
363
- * @param array input with possible duplicates
364
- * @param propertyName defaults to "id"
365
- * @return array output without duplicates
366
- */
367
- function uniqueObjectArray(arr, propertyName = 'id') {
368
- if (Array.isArray(arr) && arr.length > 0) {
369
- const result = [];
370
- const map = new Map();
371
- for (const item of arr) {
372
- if (item && !map.has(item[propertyName])) {
373
- map.set(item[propertyName], true); // set any value to Map
374
- result.push({
375
- id: item[propertyName],
376
- name: item.name
377
- });
378
- }
379
- }
380
- return result;
381
- }
382
- return arr;
383
- }
384
- exports.uniqueObjectArray = uniqueObjectArray;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uniqueObjectArray = exports.uniqueArray = exports.toSnakeCase = exports.toSentenceCase = exports.toKebabCase = exports.toCamelCase = exports.titleCase = exports.setDeepValue = exports.removeAccentFromText = exports.parseBoolean = exports.isObjectEmpty = exports.isNumber = exports.hasData = exports.isPrimmitive = exports.isObject = exports.isEmptyObject = exports.emptyObject = exports.objectAssignAndExtend = exports.deepMerge = exports.deepCopy = exports.arrayRemoveItemByIndex = exports.addWhiteSpaces = exports.addToArrayWhenNotExists = void 0;
4
+ /**
5
+ * Add an item to an array only when the item does not exists, when the item is an object we will be using their "id" to compare
6
+ * @param inputArray
7
+ * @param inputItem
8
+ * @param itemIdPropName
9
+ */
10
+ function addToArrayWhenNotExists(inputArray, inputItem, itemIdPropName = 'id') {
11
+ let arrayRowIndex = -1;
12
+ if (inputItem && typeof inputItem === 'object' && itemIdPropName in inputItem) {
13
+ arrayRowIndex = inputArray.findIndex((item) => item[itemIdPropName] === inputItem[itemIdPropName]);
14
+ }
15
+ else {
16
+ arrayRowIndex = inputArray.findIndex((item) => item === inputItem);
17
+ }
18
+ if (arrayRowIndex < 0) {
19
+ inputArray.push(inputItem);
20
+ }
21
+ }
22
+ exports.addToArrayWhenNotExists = addToArrayWhenNotExists;
23
+ /**
24
+ * Simple function to which will loop and create as demanded the number of white spaces,
25
+ * this is used in the CSV export
26
+ * @param {Number} nbSpaces - number of white spaces to create
27
+ * @param {String} spaceChar - optionally provide character to use as a space (could be override to use &nbsp; in html)
28
+ */
29
+ function addWhiteSpaces(nbSpaces, spaceChar = ' ') {
30
+ let result = '';
31
+ for (let i = 0; i < nbSpaces; i++) {
32
+ result += spaceChar;
33
+ }
34
+ return result;
35
+ }
36
+ exports.addWhiteSpaces = addWhiteSpaces;
37
+ /**
38
+ * Remove a column from the grid by it's index in the grid
39
+ * @param array input
40
+ * @param index
41
+ */
42
+ function arrayRemoveItemByIndex(array, index) {
43
+ return array.filter((_el, i) => index !== i);
44
+ }
45
+ exports.arrayRemoveItemByIndex = arrayRemoveItemByIndex;
46
+ /**
47
+ * Create an immutable clone of an array or object
48
+ * (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings.com
49
+ * @param {Array|Object} objectOrArray - the array or object to copy
50
+ * @return {Array|Object} - the clone of the array or object
51
+ */
52
+ function deepCopy(objectOrArray) {
53
+ /**
54
+ * Create an immutable copy of an object
55
+ * @return {Object}
56
+ */
57
+ const cloneObj = () => {
58
+ // Create new object
59
+ const clone = {};
60
+ // Loop through each item in the original
61
+ // Recursively copy it's value and add to the clone
62
+ for (const key in objectOrArray) {
63
+ if (Object.prototype.hasOwnProperty.call(objectOrArray, key)) {
64
+ clone[key] = deepCopy(objectOrArray[key]);
65
+ }
66
+ }
67
+ return clone;
68
+ };
69
+ /**
70
+ * Create an immutable copy of an array
71
+ * @return {Array}
72
+ */
73
+ const cloneArr = () => objectOrArray.map((item) => deepCopy(item));
74
+ // -- init --//
75
+ // Get object type
76
+ const type = Object.prototype.toString.call(objectOrArray).slice(8, -1).toLowerCase();
77
+ // If an object
78
+ if (type === 'object') {
79
+ return cloneObj();
80
+ }
81
+ // If an array
82
+ if (type === 'array') {
83
+ return cloneArr();
84
+ }
85
+ // Otherwise, return it as-is
86
+ return objectOrArray;
87
+ }
88
+ exports.deepCopy = deepCopy;
89
+ /**
90
+ * Performs a deep merge of objects and returns new object, it does not modify the source object, objects (immutable) and merges arrays via concatenation.
91
+ * Also, if first argument is undefined/null but next argument is an object then it will proceed and output will be an object
92
+ * @param {Object} target - the target object — what to apply the sources' properties to, which is returned after it is modified.
93
+ * @param {Object} sources - the source object(s) — objects containing the properties you want to apply.
94
+ * @returns {Object} The target object.
95
+ */
96
+ function deepMerge(target, ...sources) {
97
+ if (!sources.length) {
98
+ return target;
99
+ }
100
+ const source = sources.shift();
101
+ // when target is not an object but source is an object, then we'll assign as object
102
+ target = (!isObject(target) && isObject(source)) ? {} : target;
103
+ if (isObject(target) && isObject(source)) {
104
+ for (const prop in source) {
105
+ if (source.hasOwnProperty(prop)) {
106
+ if (prop in target) {
107
+ // handling merging of two properties with equal names
108
+ if (typeof target[prop] !== 'object') {
109
+ target[prop] = source[prop];
110
+ }
111
+ else {
112
+ if (typeof source[prop] !== 'object') {
113
+ target[prop] = source[prop];
114
+ }
115
+ else {
116
+ if (target[prop].concat && source[prop].concat) {
117
+ // two arrays get concatenated
118
+ target[prop] = target[prop].concat(source[prop]);
119
+ }
120
+ else {
121
+ // two objects get merged recursively
122
+ target[prop] = deepMerge(target[prop], source[prop]);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ else {
128
+ // new properties get added to target
129
+ target[prop] = source[prop];
130
+ }
131
+ }
132
+ }
133
+ }
134
+ return deepMerge(target, ...sources);
135
+ }
136
+ exports.deepMerge = deepMerge;
137
+ /**
138
+ * This method is similar to `Object.assign` with the exception that it will also extend the object properties when filled.
139
+ * There's also a distinction with extend vs merge, we are only extending when the property is not filled (if it is filled then it remains untouched and will not be merged)
140
+ * It also applies the change directly on the target object which mutates the original object.
141
+ * For example using these 2 objects: obj1 = { a: 1, b: { c: 2, d: 3 }} and obj2 = { b: { d: 2, e: 3}}:
142
+ * - Object.assign(obj1, obj2) => { a: 1, b: { e: 4 }}
143
+ * - objectAssignAndExtend(obj1, obj2) => { a: 1, b: { c: 2, d: 3, e: 4 }
144
+ * @param {Object} target - the target object — what to apply the sources properties and mutate into
145
+ * @param {Object} sources - the source object(s) — objects containing the properties you want to apply.
146
+ * @returns {Object} The target object.
147
+ */
148
+ function objectAssignAndExtend(target, ...sources) {
149
+ if (!sources.length || sources[0] === undefined) {
150
+ return target;
151
+ }
152
+ const source = sources.shift();
153
+ // when target is not an object but source is an object, then we'll assign as object
154
+ target = (!isObject(target) && isObject(source)) ? {} : target;
155
+ if (isObject(target) && isObject(source)) {
156
+ for (const key of Object.keys(source)) {
157
+ if (typeof source[key] === 'object' && source[key] !== null) {
158
+ objectAssignAndExtend(target[key], source[key]);
159
+ }
160
+ if ((target[key] === null || target[key] === undefined) && source[key] !== null && source[key] !== undefined) {
161
+ target[key] = source[key];
162
+ }
163
+ }
164
+ }
165
+ return objectAssignAndExtend(target, ...sources);
166
+ }
167
+ exports.objectAssignAndExtend = objectAssignAndExtend;
168
+ /**
169
+ * Empty an object properties by looping through them all and deleting them
170
+ * @param obj - input object
171
+ */
172
+ function emptyObject(obj) {
173
+ for (const key in obj) {
174
+ if (obj.hasOwnProperty(key)) {
175
+ delete obj[key];
176
+ }
177
+ }
178
+ obj = null;
179
+ obj = {};
180
+ return obj;
181
+ }
182
+ exports.emptyObject = emptyObject;
183
+ /**
184
+ * Check if an object is empty
185
+ * @param obj - input object
186
+ * @returns - boolean
187
+ */
188
+ function isEmptyObject(obj) {
189
+ if (obj === null || obj === undefined) {
190
+ return true;
191
+ }
192
+ return Object.entries(obj).length === 0;
193
+ }
194
+ exports.isEmptyObject = isEmptyObject;
195
+ /**
196
+ * Simple object check.
197
+ * @param item
198
+ * @returns {boolean}
199
+ */
200
+ function isObject(item) {
201
+ return item !== null && typeof item === 'object' && !Array.isArray(item) && !(item instanceof Date);
202
+ }
203
+ exports.isObject = isObject;
204
+ /**
205
+ * Simple check to detect if the value is a primitive type
206
+ * @param val
207
+ * @returns {boolean}
208
+ */
209
+ function isPrimmitive(val) {
210
+ return val === null || val === undefined || typeof val === 'boolean' || typeof val === 'number' || typeof val === 'string';
211
+ }
212
+ exports.isPrimmitive = isPrimmitive;
213
+ /**
214
+ * Check if a value has any data (undefined, null or empty string will return False...)
215
+ * NOTE: a `false` boolean is consider as having data so it will return True
216
+ */
217
+ function hasData(value) {
218
+ return value !== undefined && value !== null && value !== '';
219
+ }
220
+ exports.hasData = hasData;
221
+ /**
222
+ * Check if input value is a number, by default it won't be a strict checking
223
+ * but optionally we could check for strict equality, for example in strict "3" will return False but without strict it will return True
224
+ * @param value - input value of any type
225
+ * @param strict - when using strict it also check for strict equality, for example in strict "3" would return False but without strict it would return True
226
+ */
227
+ function isNumber(value, strict = false) {
228
+ if (strict) {
229
+ return (value === null || value === undefined || typeof value === 'string') ? false : !isNaN(value);
230
+ }
231
+ return (value === null || value === undefined || value === '') ? false : !isNaN(+value);
232
+ }
233
+ exports.isNumber = isNumber;
234
+ /** Check if an object is empty, it will also be considered empty when the input is null, undefined or isn't an object */
235
+ function isObjectEmpty(obj) {
236
+ return !obj || (obj && typeof obj === 'object' && Object.keys(obj).length === 0);
237
+ }
238
+ exports.isObjectEmpty = isObjectEmpty;
239
+ /** Parse any input (bool, number, string) and return a boolean or False when not possible */
240
+ function parseBoolean(input) {
241
+ return /(true|1)/i.test(input + '');
242
+ }
243
+ exports.parseBoolean = parseBoolean;
244
+ /**
245
+ * Remove any accents from a string by normalizing it
246
+ * @param {String} text - input text
247
+ * @param {Boolean} shouldLowerCase - should we also lowercase the string output?
248
+ * @returns
249
+ */
250
+ function removeAccentFromText(text, shouldLowerCase = false) {
251
+ const normalizedText = (typeof text.normalize === 'function') ? text.normalize('NFD').replace(/[\u0300-\u036f]/g, '') : text;
252
+ return shouldLowerCase ? normalizedText.toLowerCase() : normalizedText;
253
+ }
254
+ exports.removeAccentFromText = removeAccentFromText;
255
+ /** Set the object value of deeper node from a given dot (.) notation path (e.g.: "user.firstName") */
256
+ function setDeepValue(obj, path, value) {
257
+ if (typeof path === 'string') {
258
+ path = path.split('.');
259
+ }
260
+ if (path.length > 1) {
261
+ const e = path.shift();
262
+ if (obj && e !== undefined) {
263
+ setDeepValue((obj)[e] = (hasData(obj[e]) && (Array.isArray(obj[e]) || Object.prototype.toString.call((obj)[e]) === '[object Object]'))
264
+ ? (obj)[e]
265
+ : {}, path, value);
266
+ }
267
+ }
268
+ else if (obj && path[0]) {
269
+ (obj)[path[0]] = value;
270
+ }
271
+ }
272
+ exports.setDeepValue = setDeepValue;
273
+ /**
274
+ * Title case (or capitalize) first char of a string, for example "hello world" will become "Hello world"
275
+ * Change the string to be title case on the complete sentence (upper case first char of each word while changing everything else to lower case)
276
+ * @param inputStr
277
+ * @returns string
278
+ */
279
+ function titleCase(inputStr, shouldTitleCaseEveryWords = false) {
280
+ if (typeof inputStr === 'string') {
281
+ if (shouldTitleCaseEveryWords) {
282
+ return inputStr.replace(/\w\S*/g, (outputStr) => {
283
+ return outputStr.charAt(0).toUpperCase() + outputStr.substring(1).toLowerCase();
284
+ });
285
+ }
286
+ return inputStr.charAt(0).toUpperCase() + inputStr.slice(1);
287
+ }
288
+ return inputStr;
289
+ }
290
+ exports.titleCase = titleCase;
291
+ /**
292
+ * Converts a string to camel case (camelCase), for example "hello-world" (or "hellow world") will become "helloWorld"
293
+ * @param inputStr the string to convert
294
+ * @return the string in camel case
295
+ */
296
+ function toCamelCase(inputStr) {
297
+ if (typeof inputStr === 'string') {
298
+ return inputStr.replace(/(?:^\w|[A-Z]|\b\w|[\s+\-_\/])/g, (match, offset) => {
299
+ // remove white space or hypens or underscores
300
+ if (/[\s+\-_\/]/.test(match)) {
301
+ return '';
302
+ }
303
+ return offset === 0 ? match.toLowerCase() : match.toUpperCase();
304
+ });
305
+ }
306
+ return inputStr;
307
+ }
308
+ exports.toCamelCase = toCamelCase;
309
+ /**
310
+ * Converts a string to kebab (hypen) case, for example "helloWorld" will become "hello-world"
311
+ * @param str the string to convert
312
+ * @return the string in kebab case
313
+ */
314
+ function toKebabCase(inputStr) {
315
+ if (typeof inputStr === 'string') {
316
+ return toCamelCase(inputStr).replace(/([A-Z])/g, '-$1').toLowerCase();
317
+ }
318
+ return inputStr;
319
+ }
320
+ exports.toKebabCase = toKebabCase;
321
+ /**
322
+ * Converts a camelCase or kebab-case string to a sentence case, for example "helloWorld" will become "Hello World" and "hello-world" will become "Hello world"
323
+ * @param str the string to convert
324
+ * @return the string in kebab case
325
+ */
326
+ function toSentenceCase(inputStr) {
327
+ if (typeof inputStr === 'string') {
328
+ const result = inputStr.replace(/([A-Z])|(\-)/g, ' $1').replace(/\s+/g, ' ').trim();
329
+ return result.charAt(0).toUpperCase() + result.slice(1);
330
+ }
331
+ return inputStr;
332
+ }
333
+ exports.toSentenceCase = toSentenceCase;
334
+ /**
335
+ * Converts a string from camelCase to snake_case (underscore) case
336
+ * @param str the string to convert
337
+ * @return the string in kebab case
338
+ */
339
+ function toSnakeCase(inputStr) {
340
+ if (typeof inputStr === 'string') {
341
+ return toCamelCase(inputStr).replace(/([A-Z])/g, '_$1').toLowerCase();
342
+ }
343
+ return inputStr;
344
+ }
345
+ exports.toSnakeCase = toSnakeCase;
346
+ /**
347
+ * Takes an input array and makes sure the array has unique values by removing duplicates
348
+ * @param array input with possible duplicates
349
+ * @return array output without duplicates
350
+ */
351
+ function uniqueArray(arr) {
352
+ if (Array.isArray(arr) && arr.length > 0) {
353
+ return arr.filter((item, index) => {
354
+ return arr.indexOf(item) >= index;
355
+ });
356
+ }
357
+ return arr;
358
+ }
359
+ exports.uniqueArray = uniqueArray;
360
+ /**
361
+ * Takes an input array of objects and makes sure the array has unique object values by removing duplicates
362
+ * it will loop through the array using a property name (or "id" when is not provided) to compare uniqueness
363
+ * @param array input with possible duplicates
364
+ * @param propertyName defaults to "id"
365
+ * @return array output without duplicates
366
+ */
367
+ function uniqueObjectArray(arr, propertyName = 'id') {
368
+ if (Array.isArray(arr) && arr.length > 0) {
369
+ const result = [];
370
+ const map = new Map();
371
+ for (const item of arr) {
372
+ if (item && !map.has(item[propertyName])) {
373
+ map.set(item[propertyName], true); // set any value to Map
374
+ result.push({
375
+ id: item[propertyName],
376
+ name: item.name
377
+ });
378
+ }
379
+ }
380
+ return result;
381
+ }
382
+ return arr;
383
+ }
384
+ exports.uniqueObjectArray = uniqueObjectArray;
385
385
  //# sourceMappingURL=utils.js.map