@evolis/evolis-library 1.1.0 → 1.2.1
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.
- package/EvoArray.js +113 -0
- package/EvoDate.js +192 -0
- package/EvoMisc.js +148 -0
- package/EvoNumber.js +44 -0
- package/EvoObject.js +40 -0
- package/EvoString.js +88 -0
- package/README.md +130 -112
- package/index.js +6 -3
- package/package.json +1 -1
- package/checkers.js +0 -242
- package/converters.js +0 -190
- package/functions.js +0 -78
package/EvoArray.js
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoArray
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
import EvoObject from "./EvoObject.js";
|
8
|
+
import EvoMisc from "./EvoMisc.js";
|
9
|
+
|
10
|
+
/*****************************************************
|
11
|
+
* Checkers
|
12
|
+
*****************************************************/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @function isArray
|
16
|
+
*
|
17
|
+
* @param {any} value - The value to test
|
18
|
+
* @returns {boolean} Return true if the value is an array
|
19
|
+
*/
|
20
|
+
function isArray(value) {
|
21
|
+
return Array.isArray(value);
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @function isDeepEqual
|
26
|
+
*
|
27
|
+
* @param {Array} array1 - First array
|
28
|
+
* @param {Array} array2 - Second array
|
29
|
+
* @param {string|null} [sortBy] - Property name used to sort objects in the array. Two identical arrays in different order will not be equal
|
30
|
+
* @returns {Boolean} Are the two array deeply equal ?
|
31
|
+
*
|
32
|
+
* @example
|
33
|
+
* EvoArray.isDeepEqual([{id: 1}, {id: 2}], [{id: 1}, {id: 2}]) // return true
|
34
|
+
* EvoArray.isDeepEqual([{id: 1}, {id: 2}], [{id: 2}, {id: 1}]) // return false
|
35
|
+
* EvoArray.isDeepEqual([{id: 1}, {id: 2}], [{id: 2}, {id: 1}], "id") // return true
|
36
|
+
*/
|
37
|
+
function isDeepEqual(array1, array2, sortBy = null) {
|
38
|
+
const arr1 = [...array1], arr2 = [...array2];
|
39
|
+
const sort = (a, b) => {
|
40
|
+
if (EvoMisc.isDefined(a) && EvoMisc.isDefined(b)) {
|
41
|
+
return a[sortBy] > b[sortBy] ? 1 : -1;
|
42
|
+
} else {
|
43
|
+
return !EvoMisc.isDefined(a) ? -1 : 1;
|
44
|
+
}
|
45
|
+
};
|
46
|
+
|
47
|
+
if (sortBy) {
|
48
|
+
arr1.sort(sort);
|
49
|
+
arr2.sort(sort);
|
50
|
+
}
|
51
|
+
|
52
|
+
return arr1.every((value, index) => EvoObject.isDeepEqual(arr1[index], arr2[index]));
|
53
|
+
}
|
54
|
+
|
55
|
+
/*****************************************************
|
56
|
+
* Converters
|
57
|
+
*****************************************************/
|
58
|
+
|
59
|
+
/* ---- Array ----------------------------------- */
|
60
|
+
/**
|
61
|
+
* @function toSerialComma
|
62
|
+
*
|
63
|
+
* @param {Array<*>} array - The array to convert
|
64
|
+
* @returns {string} A string formatted as a serial comma
|
65
|
+
*
|
66
|
+
* @example
|
67
|
+
* EvoArray.toSerialComma([]) // return ""
|
68
|
+
* EvoArray.toSerialComma(["un", 2, "trois"]) // return "un, 2 et trois"
|
69
|
+
*/
|
70
|
+
function toSerialComma(array) {
|
71
|
+
return isArray(array) && array.length > 0
|
72
|
+
? array.length === 1
|
73
|
+
? array[0]
|
74
|
+
: `${array.slice(0, -1).join(", ")} et ${array.slice(-1)}`
|
75
|
+
: "";
|
76
|
+
}
|
77
|
+
|
78
|
+
/*****************************************************
|
79
|
+
* Functions
|
80
|
+
*****************************************************/
|
81
|
+
|
82
|
+
/**
|
83
|
+
* @function shuffle
|
84
|
+
*
|
85
|
+
* @param {Array<*>} array - The array to shuffle
|
86
|
+
* @returns {Array<*>} The shuffled array
|
87
|
+
*
|
88
|
+
* @example
|
89
|
+
* EvoArray.shuffle([1, 2, 3]) // return [2, 1, 3] or [3, 2, 1] or [1, 3, 2] or ...
|
90
|
+
*/
|
91
|
+
function shuffle(array) {
|
92
|
+
let arr = [...array], length = array.length, element, cache;
|
93
|
+
|
94
|
+
while (length) {
|
95
|
+
element = Math.floor(Math.random() * length--);
|
96
|
+
|
97
|
+
cache = arr[length];
|
98
|
+
arr[length] = arr[element];
|
99
|
+
arr[element] = cache;
|
100
|
+
}
|
101
|
+
|
102
|
+
return arr;
|
103
|
+
}
|
104
|
+
|
105
|
+
/*****************************************************
|
106
|
+
* Export
|
107
|
+
*****************************************************/
|
108
|
+
|
109
|
+
export default {
|
110
|
+
isArray, isDeepEqual, // Checkers
|
111
|
+
toSerialComma, // Converters
|
112
|
+
shuffle // Functions
|
113
|
+
};
|
package/EvoDate.js
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoDate
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
import EvoString from "./EvoString.js";
|
8
|
+
import EvoMisc from "./EvoMisc.js";
|
9
|
+
|
10
|
+
/*****************************************************
|
11
|
+
* Checkers
|
12
|
+
*****************************************************/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @function isDate
|
16
|
+
*
|
17
|
+
* @param {any} value - The value to test
|
18
|
+
* @returns {boolean} Return true if the value is a valid date
|
19
|
+
*/
|
20
|
+
function isDate(value) {
|
21
|
+
return Object.prototype.toString.call(value) === "[object Date]" && !!value.getDate();
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @function isMySQLDate
|
26
|
+
*
|
27
|
+
* @param {any} value - The value to test
|
28
|
+
* @returns {boolean} Return true if the value is a string with the valid MySQL date format (yyyy-mm-dd)
|
29
|
+
*/
|
30
|
+
function isMySQLDate(value) {
|
31
|
+
return EvoString.isString(value) && !EvoString.isBlank(value) && /^\d{4}-\d{1,2}-\d{1,2}$/.test(value);
|
32
|
+
}
|
33
|
+
|
34
|
+
/*****************************************************
|
35
|
+
* Converters
|
36
|
+
*****************************************************/
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @function toDate
|
40
|
+
*
|
41
|
+
* @param {*} d - The thing to convert
|
42
|
+
* @returns {Date|NaN} A date object or NaN if it's not convertible.
|
43
|
+
*
|
44
|
+
* @example
|
45
|
+
* EvoDate.toDate(null) // return NaN
|
46
|
+
* EvoDate.toDate(new Date().toISOString()) // return a Date object
|
47
|
+
*/
|
48
|
+
function toDate(d) {
|
49
|
+
return (
|
50
|
+
!EvoMisc.isDefined(d) ? NaN :
|
51
|
+
d.constructor === Date ? d :
|
52
|
+
d.constructor === Array ? new Date(d[0],d[1],d[2]) :
|
53
|
+
d.constructor === Number ? new Date(d) :
|
54
|
+
d.constructor === String ? new Date(d) :
|
55
|
+
typeof d === "object" ? new Date(d.year, d.month, (d.date || d.day), d.hours, d.minutes, d.seconds) :
|
56
|
+
NaN
|
57
|
+
);
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @function toString
|
62
|
+
*
|
63
|
+
* @param {Date} date - The date to convert
|
64
|
+
* @param {Boolean} [withTime=true] - Include time in the result
|
65
|
+
* @param {string} [locale="fr-FR"] - The locale used in the conversion. It may changed the returned string format
|
66
|
+
* @returns {string} A date formatted like "dd/MM/yyyy [hh:mm:ss]"
|
67
|
+
*
|
68
|
+
* @example
|
69
|
+
* EvoDate.toString(new Date()) // return "13/07/2021, 14:59:48"
|
70
|
+
*/
|
71
|
+
function toString(date, withTime = true, locale = "fr-FR") {
|
72
|
+
return withTime ? date.toLocaleString(locale) : date.toLocaleDateString(locale);
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @function toTimeString
|
77
|
+
*
|
78
|
+
* @param {Date} date - The date to convert
|
79
|
+
* @param {string} [locale="fr-FR"] - The locale used in the conversion. It may changed the returned string format
|
80
|
+
* @returns {string} A date formatted like "hh:mm:ss"
|
81
|
+
*
|
82
|
+
* @example
|
83
|
+
* EvoDate.toTimeString(new Date()) // return "14:59:48"
|
84
|
+
*/
|
85
|
+
function toTimeString(date, locale = "fr-FR") {
|
86
|
+
return date.toLocaleTimeString(locale);
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* @function toFieldString
|
91
|
+
*
|
92
|
+
* @param {Date} date - The date to convert
|
93
|
+
* @returns {string} A date formatted like "yyyy-MM-dd"
|
94
|
+
*
|
95
|
+
* @example
|
96
|
+
* EvoDate.toFieldString(new Date()) // return "2021-07-13"
|
97
|
+
*/
|
98
|
+
function toFieldString(date) {
|
99
|
+
return isDate(date)
|
100
|
+
? `${date.getFullYear()}-${EvoMisc.padLeft(date.getMonth() + 1)}-${EvoMisc.padLeft(date.getDate())}`
|
101
|
+
: null;
|
102
|
+
}
|
103
|
+
|
104
|
+
/**
|
105
|
+
* @function timeStrToDate
|
106
|
+
*
|
107
|
+
* @param {string} time - The time to convert
|
108
|
+
* @param {string} [format="hh:mm"] - The format used for conversion
|
109
|
+
* @returns {Date} A date object filled with the time string provided
|
110
|
+
* @throws {Error} In case of invalid format/time string
|
111
|
+
*
|
112
|
+
* @example
|
113
|
+
* EvoDate.timeStrToDate("12:57") // works
|
114
|
+
* EvoDate.timeStrToDate("9:21") // works
|
115
|
+
* EvoDate.timeStrToDate("9::21") // error
|
116
|
+
*/
|
117
|
+
function timeStrToDate(time, format = "hh:mm") {
|
118
|
+
if (!EvoString.isString(time) || !EvoString.isString(format)) return null;
|
119
|
+
|
120
|
+
const now = new Date();
|
121
|
+
const timeSplit = time.split(":");
|
122
|
+
const formatSplit = format.split(":");
|
123
|
+
|
124
|
+
formatSplit.forEach((f, index) => {
|
125
|
+
if (index >= timeSplit.length) throw Error("EvoMisc (timeStrToDate): Supplied format is invalid.");
|
126
|
+
const t = parseInt(timeSplit[index], 10);
|
127
|
+
|
128
|
+
if (f === "hh") now.setHours(t);
|
129
|
+
else if (f === "mm") now.setMinutes(t);
|
130
|
+
else if (f === "ss") now.setSeconds(t);
|
131
|
+
});
|
132
|
+
|
133
|
+
return now;
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* @function secondsToReadable
|
138
|
+
*
|
139
|
+
* @param {number} seconds - Seconds to convert
|
140
|
+
* @returns {string} The converted seconds and epoch
|
141
|
+
*
|
142
|
+
* @example
|
143
|
+
* EvoDate.secondsToReadable(120) // return "2 minutes"
|
144
|
+
* EvoDate.secondsToReadable(3600) // return "1 heure"
|
145
|
+
*/
|
146
|
+
function secondsToReadable(seconds) {
|
147
|
+
const epochs = { "années": 31536000, "mois": 2592000, "jours": 86400, "heures": 3600, "minutes": 60, "secondes": 1 };
|
148
|
+
const singular = { "années": "ans", "mois": "mois", "jours": "jour", "heures": "heure", "minutes": "minute", "secondes": "seconde" };
|
149
|
+
const epoch = Object.entries(epochs).filter(([, value]) => seconds >= value).shift();
|
150
|
+
const readable = {
|
151
|
+
epoch: epoch[0],
|
152
|
+
interval: Math.trunc(seconds / epoch[1])
|
153
|
+
};
|
154
|
+
|
155
|
+
if (readable.interval === 1) {
|
156
|
+
readable.epoch = singular[readable.epoch];
|
157
|
+
}
|
158
|
+
|
159
|
+
return `${readable.interval} ${readable.epoch}`;
|
160
|
+
}
|
161
|
+
|
162
|
+
/*****************************************************
|
163
|
+
* Functions
|
164
|
+
*****************************************************/
|
165
|
+
|
166
|
+
/**
|
167
|
+
* @function dayDiff
|
168
|
+
*
|
169
|
+
* @param {Date} start - Start date
|
170
|
+
* @param {Date} end - End date
|
171
|
+
* @returns {Number} How many days between these two dates
|
172
|
+
*
|
173
|
+
* @example
|
174
|
+
* EvoDate.dayDiff(new Date("07/14/2021"), new Date("07/18/2021")) // return 4
|
175
|
+
* EvoDate.dayDiff(new Date("07/14/2021"), new Date("07/01/2021")) // return -13
|
176
|
+
*/
|
177
|
+
function dayDiff(start, end) {
|
178
|
+
start.setHours(0, 0, 0, 0);
|
179
|
+
end.setHours(0, 0, 0, 0);
|
180
|
+
|
181
|
+
return Math.round((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
|
182
|
+
}
|
183
|
+
|
184
|
+
/*****************************************************
|
185
|
+
* Export
|
186
|
+
*****************************************************/
|
187
|
+
|
188
|
+
export default {
|
189
|
+
isDate, isMySQLDate, // Checkers
|
190
|
+
toDate, toString, toTimeString, toFieldString, timeStrToDate, secondsToReadable, // Converters
|
191
|
+
dayDiff // Functions
|
192
|
+
};
|
package/EvoMisc.js
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoMisc
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
import EvoArray from "./EvoArray.js";
|
8
|
+
|
9
|
+
/*****************************************************
|
10
|
+
* Checkers
|
11
|
+
*****************************************************/
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @function isDefined
|
15
|
+
*
|
16
|
+
* @param {*} value - The value to test
|
17
|
+
* @returns {Boolean} Return true if the value is not undefined or null
|
18
|
+
*
|
19
|
+
* @example
|
20
|
+
* EvoMisc.isDefined("") // return true
|
21
|
+
* EvoMisc.isDefined(65) // return true
|
22
|
+
* EvoMisc.isDefined(false) // return true
|
23
|
+
* EvoMisc.isDefined(null) // return false
|
24
|
+
* EvoMisc.isDefined(undefined) // return false
|
25
|
+
*/
|
26
|
+
function isDefined(value) {
|
27
|
+
return value !== undefined && value !== null;
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* @function isEmail
|
32
|
+
*
|
33
|
+
* @param {any} value - The value to test
|
34
|
+
* @returns {boolean} Return true if the value is a string containing a valid email address
|
35
|
+
*/
|
36
|
+
function isEmail(value) {
|
37
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* @typedef {Object} PasswordRules
|
42
|
+
*
|
43
|
+
* @property {object} mustContain - What type of character the password must contain
|
44
|
+
* @property {boolean} [mustContain.lowerCase] - Must contain at least one lower cased character
|
45
|
+
* @property {boolean} [mustContain.upperCase] - Must contain at least one upper cased character
|
46
|
+
* @property {boolean} [mustContain.digit] - Must contain at least one number
|
47
|
+
* @property {boolean} [mustContain.special] - Must contain at least one special character
|
48
|
+
* @property {number} minLength - The minimal length
|
49
|
+
*/
|
50
|
+
|
51
|
+
/**
|
52
|
+
* @const
|
53
|
+
* @type {PasswordRules}
|
54
|
+
*/
|
55
|
+
export const passwordRules = {
|
56
|
+
mustContain: {
|
57
|
+
lowerCase: true,
|
58
|
+
upperCase: true,
|
59
|
+
digit: true,
|
60
|
+
special: true
|
61
|
+
},
|
62
|
+
minLength: 8
|
63
|
+
};
|
64
|
+
|
65
|
+
/**
|
66
|
+
* @function isPasswordSafe
|
67
|
+
*
|
68
|
+
* @param {string|Array} password - One or multiple passwords
|
69
|
+
* @param {PasswordRules} [rules] - An object that describe security rules to follow
|
70
|
+
* @returns {boolean} Return true if the value is a safe password
|
71
|
+
*/
|
72
|
+
function isPasswordSafe(password, rules) {
|
73
|
+
const usedRules = rules ? { ...passwordRules, ...rules } : passwordRules;
|
74
|
+
|
75
|
+
if (EvoArray.isArray(password)) {
|
76
|
+
return password.every(pwd => isPasswordSafe(pwd, usedRules));
|
77
|
+
}
|
78
|
+
|
79
|
+
let regex = "";
|
80
|
+
|
81
|
+
if (usedRules.mustContain.lowerCase) regex += "(?=.*[a-z])";
|
82
|
+
if (usedRules.mustContain.upperCase) regex += "(?=.*[A-Z])";
|
83
|
+
if (usedRules.mustContain.digit) regex += "(?=.*[0-9])";
|
84
|
+
// Replacing backtick (`) with quote (") will break the check for some dark magic reason
|
85
|
+
// eslint-disable-next-line quotes
|
86
|
+
if (usedRules.mustContain.special) regex += `(?=.*[\\"'!?@#$£%^&:;<>\\[\\]()\\\\\\-_+=*.])`;
|
87
|
+
regex += `.{${usedRules.minLength},}$`;
|
88
|
+
|
89
|
+
const strongPwd = new RegExp(regex);
|
90
|
+
return strongPwd.test(password);
|
91
|
+
}
|
92
|
+
|
93
|
+
/*****************************************************
|
94
|
+
* Converters
|
95
|
+
*****************************************************/
|
96
|
+
|
97
|
+
/**
|
98
|
+
* @function bytesToReadable
|
99
|
+
*
|
100
|
+
* @param {number} bytes - Bytes to convert
|
101
|
+
* @param {number} [decimals=2] - How many decimals
|
102
|
+
* @returns {string} The converted bytes size to the closest unit
|
103
|
+
*
|
104
|
+
* @example
|
105
|
+
* EvoMisc.bytesToReadable(8000000) // return "7.63 MB"
|
106
|
+
* EvoMisc.bytesToReadable(8000000, 0) // return "8 MB"
|
107
|
+
*/
|
108
|
+
function bytesToReadable(bytes, decimals = 2) {
|
109
|
+
if (bytes === 0) return "0 Bytes";
|
110
|
+
|
111
|
+
const k = 1024;
|
112
|
+
const dm = decimals < 0 ? 0 : decimals;
|
113
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
114
|
+
|
115
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
116
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
117
|
+
}
|
118
|
+
|
119
|
+
/*****************************************************
|
120
|
+
* Functions
|
121
|
+
*****************************************************/
|
122
|
+
|
123
|
+
/**
|
124
|
+
* @function padLeft
|
125
|
+
*
|
126
|
+
* @param {*} value - The value to pad
|
127
|
+
* @param {string} [pad="00"] - With what to pad
|
128
|
+
* @returns {string} The padded string
|
129
|
+
*
|
130
|
+
* @example
|
131
|
+
* EvoMisc.padLeft(5, "000") // return "005"
|
132
|
+
* EvoMisc.padLeft("796", "00") // return "796"
|
133
|
+
*/
|
134
|
+
function padLeft(value, pad = "00") {
|
135
|
+
return isDefined(value)
|
136
|
+
? (value.toString().length >= pad.length) ? value : (pad + value).slice(-pad.length)
|
137
|
+
: pad;
|
138
|
+
}
|
139
|
+
|
140
|
+
/*****************************************************
|
141
|
+
* Export
|
142
|
+
*****************************************************/
|
143
|
+
|
144
|
+
export default {
|
145
|
+
isDefined, isEmail, isPasswordSafe, // Checkers
|
146
|
+
bytesToReadable, // Converters
|
147
|
+
padLeft // Functions
|
148
|
+
};
|
package/EvoNumber.js
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoNumber
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
import EvoString from "./EvoString.js";
|
8
|
+
|
9
|
+
/*****************************************************
|
10
|
+
* Checkers
|
11
|
+
*****************************************************/
|
12
|
+
/**
|
13
|
+
* @function isNumber
|
14
|
+
*
|
15
|
+
* @param {any} value - The value to test
|
16
|
+
* @param {boolean} [parse=false] - If set to true, the function will parse the value to find a integer (base 10)
|
17
|
+
* @returns {boolean} Return true if the value is a number
|
18
|
+
*/
|
19
|
+
function isNumber(value, parse = false) {
|
20
|
+
const val = parse ? (EvoString.isString(value) ? parseInt(value, 10) : value) : value;
|
21
|
+
return typeof val === "number" && !isNaN(val);
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @function isFloat
|
26
|
+
*
|
27
|
+
* @param {any} value - The value to test
|
28
|
+
* @param {boolean} [parse=false] - If set to true, the function will parse the value to find a float
|
29
|
+
* @returns {boolean} Return true if the value is a float
|
30
|
+
*/
|
31
|
+
function isFloat(value, parse = true) {
|
32
|
+
const val = parse ? (EvoString.isString(value) ? parseFloat(value) : value) : value;
|
33
|
+
return typeof val === "number" && !isNaN(val);
|
34
|
+
}
|
35
|
+
|
36
|
+
/*****************************************************
|
37
|
+
* Export
|
38
|
+
*****************************************************/
|
39
|
+
|
40
|
+
export default {
|
41
|
+
isNumber, isFloat // Checkers
|
42
|
+
// Converters
|
43
|
+
// Functions
|
44
|
+
};
|
package/EvoObject.js
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoObject
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
|
8
|
+
/*****************************************************
|
9
|
+
* Checkers
|
10
|
+
*****************************************************/
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @function isDeepEqual
|
14
|
+
*
|
15
|
+
* @param {Object} obj1 - First object
|
16
|
+
* @param {Object} obj2 - Second object
|
17
|
+
* @returns {Boolean} Are the two objects deeply equal ?
|
18
|
+
*
|
19
|
+
* @example
|
20
|
+
* EvoObject.isDeepEqual({id: 1, title: "skibidi wap-pa-pa"}, {title: "skibidi wap-pa-pa", id: 1}) // return true
|
21
|
+
* EvoObject.isDeepEqual({id: 7, title: "skibidi wap-pa-pa"}, {title: "skibidi woosh-oosh-oosh", id: 1}) // return false
|
22
|
+
*/
|
23
|
+
function isDeepEqual(obj1, obj2) {
|
24
|
+
if (typeof obj1 === "object" && Object.keys(obj1).length > 0) {
|
25
|
+
return Object.keys(obj1).length === Object.keys(obj2).length &&
|
26
|
+
Object.keys(obj1).every(prop => isDeepEqual(obj1[prop], obj2[prop]));
|
27
|
+
} else {
|
28
|
+
return obj1 === obj2;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
/*****************************************************
|
33
|
+
* Export
|
34
|
+
*****************************************************/
|
35
|
+
|
36
|
+
export default {
|
37
|
+
isDeepEqual // Checkers
|
38
|
+
// Converters
|
39
|
+
// Functions
|
40
|
+
};
|
package/EvoString.js
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
/**
|
2
|
+
* @module EvoString
|
3
|
+
* @author EmpireDemocratiqueDuPoulpe
|
4
|
+
* @version 1.2.0
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
import EvoArray from "./EvoArray.js";
|
8
|
+
import EvoMisc from "./EvoMisc.js";
|
9
|
+
|
10
|
+
/*****************************************************
|
11
|
+
* Checkers
|
12
|
+
*****************************************************/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @function isString
|
16
|
+
*
|
17
|
+
* @param {any} value - The value to test
|
18
|
+
* @returns {boolean} Return true if the value is a string
|
19
|
+
*/
|
20
|
+
function isString(value) {
|
21
|
+
return Object.prototype.toString.call(value) === "[object String]";
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @function isEmpty
|
26
|
+
*
|
27
|
+
* @param {any} value - The value to test
|
28
|
+
* @returns {boolean} Return true if the value is a string and if its empty
|
29
|
+
*
|
30
|
+
* @example
|
31
|
+
* EvoString.isEmpty(""); // return true
|
32
|
+
* EvoString.isEmpty(" "); // return false
|
33
|
+
*/
|
34
|
+
function isEmpty(value) {
|
35
|
+
return value === "";
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @function isBlank
|
40
|
+
*
|
41
|
+
* @param {any} value - The value to test
|
42
|
+
* @returns {boolean} Return true if the value is a string and if its blank
|
43
|
+
*
|
44
|
+
* @example
|
45
|
+
* EvoString.isBlank(""); // return true
|
46
|
+
* EvoString.isBlank(" "); // return true
|
47
|
+
*/
|
48
|
+
function isBlank(value) {
|
49
|
+
return isString(value) && value.trim().length === 0;
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* @function inRange
|
54
|
+
*
|
55
|
+
* @param {*|Array<*>} value - The value to test
|
56
|
+
* @param {Number} min - The minimum length of the string (nullable)
|
57
|
+
* @param {Number} max - The maximum length of the string (nullable)
|
58
|
+
* @param {Boolean} [includeBounds=true] - Include the min and max bounds in the range
|
59
|
+
* @param {Boolean} [canBeNull=false] - Authorize or not the string to be null or undefined
|
60
|
+
* @returns {Boolean} Return true if the value is a string between min and max or if it's an undefined/null with canBeNull set at true.
|
61
|
+
*
|
62
|
+
* @example
|
63
|
+
* EvoString.inRange("never gonna give you up", null, 100); // return true
|
64
|
+
* EvoString.inRange("oof", 5); // return false
|
65
|
+
*/
|
66
|
+
function inRange(value, min, max, includeBounds = true, canBeNull = false) {
|
67
|
+
if (EvoArray.isArray(value)) {
|
68
|
+
return value.every(s => inRange(s, min, max, includeBounds, canBeNull));
|
69
|
+
}
|
70
|
+
|
71
|
+
return EvoMisc.isDefined(value)
|
72
|
+
? isString(value)
|
73
|
+
? includeBounds
|
74
|
+
? (EvoMisc.isDefined(min) ? value.length >= min : true) && (EvoMisc.isDefined(max) ? value.length <= max : true)
|
75
|
+
: (EvoMisc.isDefined(min) ? value.length > min : true) && (EvoMisc.isDefined(max) ? value.length < max : true)
|
76
|
+
: false
|
77
|
+
: canBeNull;
|
78
|
+
}
|
79
|
+
|
80
|
+
/*****************************************************
|
81
|
+
* Export
|
82
|
+
*****************************************************/
|
83
|
+
|
84
|
+
export default {
|
85
|
+
isString, isEmpty, isBlank, inRange // Checkers
|
86
|
+
// Converters
|
87
|
+
// Functions
|
88
|
+
};
|