topkat-utils 1.0.35 → 1.0.38
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/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/utils.d.ts +33 -89
- package/utils.js +19 -211
- package/utils.js.map +1 -1
- package/utils.ts +37 -251
package/utils.ts
CHANGED
|
@@ -6,6 +6,7 @@ const JSONstringyParse = o => JSON.parse(removeCircularJSONstringify(o));
|
|
|
6
6
|
const removeUndefinedKeys = objFilterUndefinedRecursive;
|
|
7
7
|
|
|
8
8
|
type Color = [number, number, number]
|
|
9
|
+
type ObjectGeneric = { [k: string]: any }
|
|
9
10
|
|
|
10
11
|
type BaseTypes = 'objectId' | 'dateInt6' | 'dateInt' | 'dateInt8' | 'dateInt12' | 'time' | 'humanReadableTimestamp' | 'date' | 'dateObject' | 'array' | 'object' | 'buffer' | 'string' | 'function' | 'boolean' | 'number' | 'bigint' | 'year' | 'email'
|
|
11
12
|
|
|
@@ -36,7 +37,7 @@ function moyenne(array: number[], nbOfDecimals = 2) {
|
|
|
36
37
|
function cln(val, replacerInCaseItIsUndefinNaN = '-') { return ['undefined', undefined, 'indéfini', 'NaN', NaN, Infinity, null].includes(val) ? replacerInCaseItIsUndefinNaN : val; }
|
|
37
38
|
|
|
38
39
|
/** length default 2, shortcut for 1 to 01 */
|
|
39
|
-
function pad(numberOrStr, length = 2) { return ('' + numberOrStr).padStart(length, '0'); }
|
|
40
|
+
function pad(numberOrStr: number | string, length = 2) { return ('' + numberOrStr).padStart(length, '0'); }
|
|
40
41
|
|
|
41
42
|
/** return the number or the closest number of the range
|
|
42
43
|
* * nb min max => returns
|
|
@@ -46,7 +47,7 @@ function pad(numberOrStr, length = 2) { return ('' + numberOrStr).padStart(lengt
|
|
|
46
47
|
*/
|
|
47
48
|
function minMax(nb: number, min: number, max: number) { return Math.max(min, Math.min(nb, max)); }
|
|
48
49
|
|
|
49
|
-
async function tryCatch(callback, onErr: Function = () => { }) {
|
|
50
|
+
async function tryCatch(callback: Function, onErr: Function = () => { }) {
|
|
50
51
|
try {
|
|
51
52
|
return await callback()
|
|
52
53
|
} catch (err) {
|
|
@@ -63,7 +64,7 @@ let lastTs = new Date().getTime();
|
|
|
63
64
|
* @param {string} mode one of ['alphanumeric', 'hexadecimal']
|
|
64
65
|
* NOTE: to generate a mongoDB Random Id, use the params: 24, true, 'hexadecimal'
|
|
65
66
|
*/
|
|
66
|
-
function generateToken(length = 20, unique = true, mode = 'alphanumeric') {
|
|
67
|
+
function generateToken(length = 20, unique = true, mode: 'alphanumeric' | 'hexadecimal' = 'alphanumeric') {
|
|
67
68
|
let charConvNumeric = mode === 'alphanumeric' ? 36 : 16;
|
|
68
69
|
if (unique && length < 8) length = 8;
|
|
69
70
|
let token
|
|
@@ -73,19 +74,21 @@ function generateToken(length = 20, unique = true, mode = 'alphanumeric') {
|
|
|
73
74
|
token = unique ? tokenTs.toString(charConvNumeric) : '';
|
|
74
75
|
while (token.length < length) token += Math.random().toString(charConvNumeric).substr(2, 1); // char alphaNumeric aléatoire
|
|
75
76
|
} while (generatedTokens.includes(token))
|
|
76
|
-
if (lastTs < tokenTs)
|
|
77
|
-
generatedTokens = [] // reset generated token on new timestamp because cannot collide
|
|
78
|
-
}
|
|
77
|
+
if (lastTs < tokenTs) generatedTokens = [] // reset generated token on new timestamp because cannot collide
|
|
79
78
|
generatedTokens.push(token)
|
|
80
79
|
return token;
|
|
81
80
|
}
|
|
82
81
|
|
|
82
|
+
function generateObjectId() {
|
|
83
|
+
return generateToken(24, true, 'hexadecimal')
|
|
84
|
+
}
|
|
85
|
+
|
|
83
86
|
|
|
84
87
|
/** Useful to join differents bits of url with normalizing slashes
|
|
85
88
|
* * urlPathJoin('https://', 'www.kikou.lol/', '/user', '//2//') => https://www.kikou.lol/user/2/
|
|
86
89
|
* * urlPathJoin('http:/', 'kikou.lol') => https://www.kikou.lol
|
|
87
90
|
*/
|
|
88
|
-
function urlPathJoin(...bits) {
|
|
91
|
+
function urlPathJoin(...bits: string[]) {
|
|
89
92
|
return bits.join('/').replace(/\/+/g, '/').replace(/(https?:)\/\/?/, '$1//');
|
|
90
93
|
}
|
|
91
94
|
|
|
@@ -118,15 +121,19 @@ function sortUrlsByDeepnessInArrayOrObject(urlObjOrArr, propInObjectOrIndexInArr
|
|
|
118
121
|
});
|
|
119
122
|
}
|
|
120
123
|
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
|
|
125
|
+
type MiniTemplaterOptions = {
|
|
126
|
+
valueWhenNotSet?: string
|
|
127
|
+
regexp?: RegExp
|
|
128
|
+
}
|
|
129
|
+
/** Replace variables in a string like: `Hello {{userName}}!`
|
|
123
130
|
* @param {String} content
|
|
124
131
|
* @param {Object} varz object with key => value === toReplace => replacer
|
|
125
132
|
* @param {Object} options
|
|
126
133
|
* * valueWhenNotSet => replacer for undefined values. Default: ''
|
|
127
134
|
* * regexp => must be 'g' and first capturing group matching the value to replace. Default: /{{\s*([^}]*)\s*}}/g
|
|
128
135
|
*/
|
|
129
|
-
function miniTemplater(content, varz, options) {
|
|
136
|
+
function miniTemplater(content: string, varz: ObjectGeneric, options: MiniTemplaterOptions = {}) {
|
|
130
137
|
options = {
|
|
131
138
|
valueWhenNotSet: '',
|
|
132
139
|
regexp: /{{\s*([^}]*)\s*}}/g,
|
|
@@ -142,7 +149,7 @@ function miniTemplater(content, varz, options) {
|
|
|
142
149
|
* @param {Boolean} isMask default: true; determine the behavior of the function. If is mask, selected fields will not appear in the resulting object. If it's a select, only selected fields will appear.
|
|
143
150
|
* @param {Boolean} deleteKeysInsteadOfReturningAnewObject default:false; modify the existing object instead of creating a new instance
|
|
144
151
|
*/
|
|
145
|
-
function simpleObjectMaskOrSelect(object, maskedOrSelectedFields, isMask = true, deleteKeysInsteadOfReturningAnewObject = false) {
|
|
152
|
+
function simpleObjectMaskOrSelect(object: ObjectGeneric, maskedOrSelectedFields: string[], isMask = true, deleteKeysInsteadOfReturningAnewObject = false) {
|
|
146
153
|
const allKeys = Object.keys(object);
|
|
147
154
|
const keysToMask = allKeys.filter(keyName => {
|
|
148
155
|
if (isMask) return maskedOrSelectedFields.includes(keyName);
|
|
@@ -317,7 +324,7 @@ class dataValidationUtilErrorHandler extends Error {
|
|
|
317
324
|
* @param {Object} obj object to test against
|
|
318
325
|
* @param {string} addr `a.b.c.0.1` will test if myObject has props a that has prop b. Work wit arrays as well (like `arr.0`)
|
|
319
326
|
*/
|
|
320
|
-
function has(obj:
|
|
327
|
+
function has(obj: ObjectGeneric, addr: string) {
|
|
321
328
|
if (!isset(obj) || typeof obj !== 'object') return;
|
|
322
329
|
let propsArr = addr.replace(/\.?\[(\d+)\]/g, '.$1').split('.'); // replace a[3] => a.3;
|
|
323
330
|
let objChain = obj;
|
|
@@ -332,7 +339,7 @@ function has(obj: object, addr: string) {
|
|
|
332
339
|
* @param {string} addr accept syntax like "obj.subItem.[0].sub2" OR "obj.subItem.0.sub2" OR "obj.subItem[0].sub2"
|
|
333
340
|
* @returns {any} the last item of the chain OR undefined if not found
|
|
334
341
|
*/
|
|
335
|
-
function findByAddress(obj:
|
|
342
|
+
function findByAddress(obj: ObjectGeneric, addr: string) {
|
|
336
343
|
if (addr === '') return obj;
|
|
337
344
|
if (!isset(obj) || typeof obj !== 'object') return console.warn('Main object in `findByAddress` function is undefined or has the wrong type');
|
|
338
345
|
const propsArr = addr.replace(/\.?\[(\d+)\]/g, '.$1').split('.'); // replace .[4] AND [4] TO .4
|
|
@@ -346,7 +353,7 @@ function findByAddress(obj: object, addr: string) {
|
|
|
346
353
|
/** Enforce writing subItems. Eg: user.name.blah will ensure all are set until the writing of the last item
|
|
347
354
|
* NOTE: doesn't work with arrays
|
|
348
355
|
*/
|
|
349
|
-
function objForceWrite(obj:
|
|
356
|
+
function objForceWrite(obj: ObjectGeneric, addr: string, item) {
|
|
350
357
|
const chunks = addr.replace(/\.?\[(\d+)\]/g, '.[$1').split('.');
|
|
351
358
|
let lastItem = obj;
|
|
352
359
|
chunks.forEach((chunkRaw, i) => {
|
|
@@ -366,7 +373,7 @@ function objForceWrite(obj: object, addr: string, item) {
|
|
|
366
373
|
* if user.name.blah has a value it will not change it.
|
|
367
374
|
* NOTE: doesn't work with arrays
|
|
368
375
|
*/
|
|
369
|
-
function objForceWriteIfNotSet(obj:
|
|
376
|
+
function objForceWriteIfNotSet(obj: ObjectGeneric, addr: string, item) {
|
|
370
377
|
if (!isset(findByAddress(obj, addr))) return objForceWrite(obj, addr, item);
|
|
371
378
|
}
|
|
372
379
|
|
|
@@ -397,7 +404,7 @@ function asArray<T extends any[] | any>(item: T): T extends undefined ? undefine
|
|
|
397
404
|
/** Array comparison
|
|
398
405
|
* @return {object} { inCommon, notInB, notInA }
|
|
399
406
|
*/
|
|
400
|
-
function compareArrays(arrayA
|
|
407
|
+
function compareArrays(arrayA: any[], arrayB: any[], compare = (a, b) => a === b) {
|
|
401
408
|
return {
|
|
402
409
|
inCommon: getArrayInCommon(arrayA, arrayB, compare),
|
|
403
410
|
notInB: getNotInArrayA(arrayB, arrayA, compare),
|
|
@@ -1164,6 +1171,9 @@ function validator(...paramsToValidate: ValidatorObject[]) {
|
|
|
1164
1171
|
|
|
1165
1172
|
const restTestMini = {
|
|
1166
1173
|
reset() {
|
|
1174
|
+
restTestMini.nbSuccess = 0
|
|
1175
|
+
restTestMini.nbError = 0
|
|
1176
|
+
restTestMini.lastErrors = []
|
|
1167
1177
|
},
|
|
1168
1178
|
printStats() {
|
|
1169
1179
|
// TODO print last errz
|
|
@@ -1366,7 +1376,7 @@ function err422IfNotSet(o) {
|
|
|
1366
1376
|
if (m.length) throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, 422, { origin: 'Validator', varNames: m.join(', ') })
|
|
1367
1377
|
}
|
|
1368
1378
|
|
|
1369
|
-
function getDateAsInt12(dateAllFormat?: Date | string | number, errIfNotValid?):
|
|
1379
|
+
function getDateAsInt12(dateAllFormat?: Date | string | number, errIfNotValid?): string { return getDateAsInt(dateAllFormat, errIfNotValid, true); } // alias
|
|
1370
1380
|
|
|
1371
1381
|
function humanReadableTimestamp(dateAllFormat: any): number {
|
|
1372
1382
|
if (isset(dateAllFormat)) dateAllFormat = getDateAsObject(dateAllFormat);
|
|
@@ -1376,9 +1386,13 @@ function humanReadableTimestamp(dateAllFormat: any): number {
|
|
|
1376
1386
|
/** format for 6/8/2018 => 20180806
|
|
1377
1387
|
* @param dateAllFormat multiple format allowed 2012, 20120101, 201201011200, new Date(), "2019-12-08T16:19:10.341Z" and all string that new Date() can parse
|
|
1378
1388
|
*/
|
|
1379
|
-
function getDateAsInt(dateAllFormat: Date | string | number = new Date(), errIfNotValid$ = false, withHoursAndMinutes$ = false):
|
|
1389
|
+
function getDateAsInt(dateAllFormat: Date | string | number = new Date(), errIfNotValid$ = false, withHoursAndMinutes$ = false): string { // optional
|
|
1380
1390
|
let dateInt;
|
|
1381
|
-
if (
|
|
1391
|
+
if (typeof dateAllFormat === 'string' && dateAllFormat.includes('/')) {
|
|
1392
|
+
// 01/01/2020 format
|
|
1393
|
+
const [d, m, y] = dateAllFormat.split('/')
|
|
1394
|
+
return y + m.toString().padStart(2, '0') + d.toString().padStart(2, '0')
|
|
1395
|
+
} else if (isDateIntOrStringValid(dateAllFormat)) {
|
|
1382
1396
|
// we can pass an int or string format (20180106)
|
|
1383
1397
|
dateInt = (dateAllFormat + '00000000').substr(0, 12); // add default 000000 for "month days minutes:sec" if not set
|
|
1384
1398
|
} else {
|
|
@@ -1575,106 +1589,6 @@ function doDateOverlap(event1, event2, fieldNameForStartDate$ = 'startDate', fie
|
|
|
1575
1589
|
return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] <= event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] >= event2[fieldNameForStartDate$]);
|
|
1576
1590
|
}
|
|
1577
1591
|
|
|
1578
|
-
|
|
1579
|
-
/** Get all dates at specified days between two dates
|
|
1580
|
-
* @param daysArray [0,1,2,3,4,5,6]
|
|
1581
|
-
* @param {*} startDate all format
|
|
1582
|
-
* @param {*} endDate all format
|
|
1583
|
-
* @param {'int'|'object'} outputFormat default: int
|
|
1584
|
-
*/
|
|
1585
|
-
function getDatesForDaysArrayBetweenTwoDates(daysArray, startDate, endDate, outputFormat = 'int') {
|
|
1586
|
-
const dateArr = [];
|
|
1587
|
-
let actualDate = getDateAsObject(startDate);
|
|
1588
|
-
endDate = getDateAsObject(endDate);
|
|
1589
|
-
while (actualDate <= endDate) {
|
|
1590
|
-
if (daysArray.includes(actualDate.getUTCDay())) dateArr.push(getDateAsObject(actualDate)); // cloned
|
|
1591
|
-
actualDate.setUTCDate(actualDate.getUTCDate() + 1);
|
|
1592
|
-
}
|
|
1593
|
-
return dateArr.map(d => getDateAs(d, outputFormat));
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
function getEndTimeFromDurationAndStartTime(startTime, duration) {
|
|
1597
|
-
const timeArr = startTime.split(':').map(n => parseInt(n));
|
|
1598
|
-
let endTime = (timeArr[0] * 60 + timeArr[1]) + duration;
|
|
1599
|
-
|
|
1600
|
-
return {
|
|
1601
|
-
days: Math.floor(endTime / 1440),
|
|
1602
|
-
time: pad(Math.floor((endTime % 1440) / 60)) + ':' + pad(endTime % 60)
|
|
1603
|
-
};
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
function getDate12FromDateAndTime(dateAllFormat: Date | string | number, timeAllFormat) {
|
|
1607
|
-
if (typeof dateAllFormat !== 'number' || dateAllFormat > 99991231 || dateAllFormat < 0) dateAllFormat = getDateAsInt(dateAllFormat);
|
|
1608
|
-
|
|
1609
|
-
if (typeof timeAllFormat !== 'number' || timeAllFormat > 2359 || timeAllFormat < 0) timeAllFormat = getTimeAsInt(timeAllFormat);
|
|
1610
|
-
|
|
1611
|
-
return dateAllFormat * 10000 + timeAllFormat;
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
function eachDayOfInterval(startDateAllFormat, endDateAllFormat, outputFormat = 'int') {
|
|
1615
|
-
const start = getDateAsObject(startDateAllFormat);
|
|
1616
|
-
const end = getDateAsObject(endDateAllFormat);
|
|
1617
|
-
let days = [];
|
|
1618
|
-
let current = new Date();
|
|
1619
|
-
current.setTime(start.getTime());
|
|
1620
|
-
while (current <= end) {
|
|
1621
|
-
days.push(new Date(current.getTime()));
|
|
1622
|
-
current.setTime(current.getTime() + 1000 * 60 * 60 * 24);
|
|
1623
|
-
}
|
|
1624
|
-
return days.map(d => getDateAs(d, outputFormat));
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
function eachMonthOfInterval(startDateAllFormat, endDateAllFormat) {
|
|
1628
|
-
const months = [];
|
|
1629
|
-
const current: any = firstDayOfMonth(startDateAllFormat, 'Object');
|
|
1630
|
-
const end = firstDayOfMonth(endDateAllFormat, 'Object');
|
|
1631
|
-
while (current <= end) {
|
|
1632
|
-
months.push(getMonthAsInt(current));
|
|
1633
|
-
current.setUTCMonth(current.getUTCMonth() + 1);
|
|
1634
|
-
}
|
|
1635
|
-
return months;
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
function isSunday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1639
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1640
|
-
return date.getUTCDay() === 0;
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
function isMonday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1644
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1645
|
-
return date.getUTCDay() === 1;
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
function isTuesday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1649
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1650
|
-
return date.getUTCDay() === 2;
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
function isWednesday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1654
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1655
|
-
return date.getUTCDay() === 3;
|
|
1656
|
-
}
|
|
1657
|
-
|
|
1658
|
-
function isThursday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1659
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1660
|
-
return date.getUTCDay() === 4;
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
|
-
function isFriday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1664
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1665
|
-
return date.getUTCDay() === 5;
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
function isSaturday(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1669
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1670
|
-
return date.getUTCDay() === 6;
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
function isWeekend(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1674
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1675
|
-
return date.getUTCDay() === 6 || date.getUTCDay() === 0;
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
1592
|
type DateAllFormat = 'dateInt8' | 'dateInt12' | 'date' | 'humanReadableTimestamp'
|
|
1679
1593
|
|
|
1680
1594
|
function nextWeekDay(fromDate, weekDayInt?: 0 | 1 | 2 | 3 | 4 | 5 | 6, outputFormat?: 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp', sameDayAllowed?: boolean): number
|
|
@@ -1759,6 +1673,7 @@ function getMinutes(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
|
1759
1673
|
const [, , , , m] = dateStringToArray(dateAsInt);
|
|
1760
1674
|
return m;
|
|
1761
1675
|
}
|
|
1676
|
+
|
|
1762
1677
|
/**
|
|
1763
1678
|
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
1764
1679
|
*/
|
|
@@ -1768,6 +1683,7 @@ function lastDayOfMonth(dateAllFormat: Date | string | number = getDateAsInt(),
|
|
|
1768
1683
|
lastDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
|
|
1769
1684
|
return getDateAs(lastDay, outputFormat);
|
|
1770
1685
|
}
|
|
1686
|
+
|
|
1771
1687
|
/**
|
|
1772
1688
|
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
1773
1689
|
*/
|
|
@@ -1804,100 +1720,6 @@ function differenceInWeeks(startDateAllFormat, endDateAllFormat) {
|
|
|
1804
1720
|
return differenceInDays(startDateAllFormat, endDateAllFormat) / 7;
|
|
1805
1721
|
}
|
|
1806
1722
|
|
|
1807
|
-
function differenceInMonths(startDateAllFormat, endDateAllFormat) {
|
|
1808
|
-
const startDate = getDateAsInt(startDateAllFormat);
|
|
1809
|
-
const endDate = getDateAsInt(endDateAllFormat);
|
|
1810
|
-
const monthesForStart = parseInt(getYear(startDate)) * 12 + parseInt(getMonthForHuman(startDate));
|
|
1811
|
-
const monthesForEnd = parseInt(getYear(endDate)) * 12 + parseInt(getMonthForHuman(endDate));
|
|
1812
|
-
if (monthesForStart === monthesForEnd) {
|
|
1813
|
-
const firstDay = firstDayOfMonth(startDate);
|
|
1814
|
-
const lastDay = lastDayOfMonth(endDate);
|
|
1815
|
-
const differenceBetweenStartAndEnd = differenceInDays(startDate, endDate);
|
|
1816
|
-
const numberOfDaysInMonth = differenceInDays(firstDay, lastDay);
|
|
1817
|
-
return round(differenceBetweenStartAndEnd / numberOfDaysInMonth, 2);
|
|
1818
|
-
}
|
|
1819
|
-
const firstDayOfStartDateMonth = firstDayOfMonth(startDate);
|
|
1820
|
-
const lastDayOfStartDateMonth = lastDayOfMonth(startDate);
|
|
1821
|
-
const firstDayOfEndDateMonth = firstDayOfMonth(endDate);
|
|
1822
|
-
const lastDayOfEndDateMonth = lastDayOfMonth(endDate);
|
|
1823
|
-
const differenceBetweenStartDateAndEndOfStartMonth = differenceInDays(startDate, lastDayOfStartDateMonth);
|
|
1824
|
-
const differenceBetweenStartOfEndMonthAndEndDate = differenceInDays(firstDayOfEndDateMonth, endDate);
|
|
1825
|
-
const numberOfDaysInStartMonth = differenceInDays(firstDayOfStartDateMonth, lastDayOfStartDateMonth);
|
|
1826
|
-
const numberOfDaysInEndMonth = differenceInDays(firstDayOfEndDateMonth, lastDayOfEndDateMonth);
|
|
1827
|
-
return round(monthesForEnd - monthesForStart - 1 + differenceBetweenStartDateAndEndOfStartMonth / numberOfDaysInStartMonth + differenceBetweenStartOfEndMonthAndEndDate / numberOfDaysInEndMonth, 2);
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
/** Will check if that date exists, and if not, this will
|
|
1832
|
-
* Usefull for monthly subscription or reccuring month dates
|
|
1833
|
-
* @param {any} dateAllFormat default: new Date()
|
|
1834
|
-
* @returns {Date} Date object
|
|
1835
|
-
*/
|
|
1836
|
-
function getClosestExistingDateOfMonth(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
1837
|
-
let [day, month, year] = dateArrayInt(dateAllFormat);
|
|
1838
|
-
const zeroBasedMonth = minMax(month - 1, 0, 11);
|
|
1839
|
-
if (!isBetween(month, 1, 12)) console.error('Wrong month provided for getClosestExistingDateOfMonth: ' + month + ' Shall be between 1-12. Converted to ' + zeroBasedMonth);
|
|
1840
|
-
let dayNb = minMax(day, 1, 31);
|
|
1841
|
-
let date;
|
|
1842
|
-
let increment = dayNb < 1;
|
|
1843
|
-
let tooMuchRecursionCount = 0;
|
|
1844
|
-
do date = new Date(year, zeroBasedMonth, (increment ? dayNb++ : dayNb--), 12);
|
|
1845
|
-
while (date.getUTCMonth() !== zeroBasedMonth && tooMuchRecursionCount < 99);
|
|
1846
|
-
if (tooMuchRecursionCount) throw new dataValidationUtilErrorHandler(`tooMuchRecursionCount`, 500, { origin: 'getClosestExistingDateOfMonth', day, month, year });
|
|
1847
|
-
return date;
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
/** Compute the best possible date for next month same day
|
|
1851
|
-
* Usefull for monthly subscription or reccuring month dates
|
|
1852
|
-
* @param {any} dateAllFormat default: new Date()
|
|
1853
|
-
* @param {Boolean} onlyFuture if true return the future date relative to any date in the past, else, it return the next month date possible relative to the dateAllFormat
|
|
1854
|
-
* @returns {Date} Date object
|
|
1855
|
-
*/
|
|
1856
|
-
function getNextMonthlyDate(dateAllFormat: Date | string | number = getDateAsInt(), onlyFuture = false) {
|
|
1857
|
-
let [day, month, year] = dateArrayInt(dateAllFormat);
|
|
1858
|
-
day = minMax(day, 1, 31);
|
|
1859
|
-
month = minMax(month, 1, 12);
|
|
1860
|
-
err422IfNotSet({ year, month, day });
|
|
1861
|
-
const isDatePast = getDateAsInt(dateAllFormat) <= getDateAsInt();
|
|
1862
|
-
if (onlyFuture && isDatePast) {
|
|
1863
|
-
let [, todayMonth, todayYear] = dateArrayInt();
|
|
1864
|
-
month = todayMonth
|
|
1865
|
-
year = todayYear
|
|
1866
|
-
}
|
|
1867
|
-
let nextMonth;
|
|
1868
|
-
if (month === 12) {
|
|
1869
|
-
nextMonth = 1;
|
|
1870
|
-
year++;
|
|
1871
|
-
} else nextMonth = month + 1;
|
|
1872
|
-
return getClosestExistingDateOfMonth(new Date(year, nextMonth - 1, day));
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
function getHolidayReferenceYear(dateAllFormat: Date | string | number) {
|
|
1876
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1877
|
-
if (date.getUTCMonth() > 4) return date.getUTCFullYear();
|
|
1878
|
-
return date.getUTCFullYear() - 1;
|
|
1879
|
-
}
|
|
1880
|
-
/**
|
|
1881
|
-
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
1882
|
-
*/
|
|
1883
|
-
function getFirstDayOfHolidayReferenceYear(dateAllFormat: Date | string | number, outputFormat = 'int') {
|
|
1884
|
-
const date = getDateAsObject(dateAllFormat);
|
|
1885
|
-
let year = date.getUTCFullYear();
|
|
1886
|
-
if (date.getUTCMonth() < 4) year = date.getUTCFullYear() - 1;
|
|
1887
|
-
const firstDayAsInt = year + '0601';
|
|
1888
|
-
return getDateAs(firstDayAsInt, outputFormat);
|
|
1889
|
-
}
|
|
1890
|
-
/**
|
|
1891
|
-
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
1892
|
-
*/
|
|
1893
|
-
function getLastDayOfHolidayReferenceYear(dateAllFormat: Date | string | number, outputFormat = 'int') {
|
|
1894
|
-
let date = getDateAsObject(dateAllFormat);
|
|
1895
|
-
let year = date.getUTCFullYear() + 1;
|
|
1896
|
-
if (date.getUTCMonth() < 4) year = date.getUTCFullYear();
|
|
1897
|
-
const firstDayAsInt = year + '0531';
|
|
1898
|
-
return getDateAs(firstDayAsInt, outputFormat);
|
|
1899
|
-
}
|
|
1900
|
-
|
|
1901
1723
|
/**
|
|
1902
1724
|
* @param {String} outputDateFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
1903
1725
|
*/
|
|
@@ -2446,6 +2268,7 @@ const _ = {
|
|
|
2446
2268
|
sortUrlsByDeepnessInArrayOrObject,
|
|
2447
2269
|
urlPathJoin,
|
|
2448
2270
|
miniTemplater,
|
|
2271
|
+
generateObjectId,
|
|
2449
2272
|
isBetween,
|
|
2450
2273
|
simpleObjectMaskOrSelect,
|
|
2451
2274
|
ENV,
|
|
@@ -2563,18 +2386,7 @@ const _ = {
|
|
|
2563
2386
|
isTimeStringValid,
|
|
2564
2387
|
getDuration,
|
|
2565
2388
|
doDateOverlap,
|
|
2566
|
-
getDatesForDaysArrayBetweenTwoDates,
|
|
2567
|
-
getEndTimeFromDurationAndStartTime,
|
|
2568
|
-
getDate12FromDateAndTime,
|
|
2569
2389
|
getMonthAsInt,
|
|
2570
|
-
isSunday,
|
|
2571
|
-
isMonday,
|
|
2572
|
-
isTuesday,
|
|
2573
|
-
isWednesday,
|
|
2574
|
-
isThursday,
|
|
2575
|
-
isFriday,
|
|
2576
|
-
isSaturday,
|
|
2577
|
-
isWeekend,
|
|
2578
2390
|
nextWeekDay,
|
|
2579
2391
|
addMinutes,
|
|
2580
2392
|
addHours,
|
|
@@ -2587,20 +2399,12 @@ const _ = {
|
|
|
2587
2399
|
getMinutes,
|
|
2588
2400
|
firstDayOfMonth,
|
|
2589
2401
|
lastDayOfMonth,
|
|
2590
|
-
eachDayOfInterval,
|
|
2591
|
-
eachMonthOfInterval,
|
|
2592
2402
|
differenceInMilliseconds,
|
|
2593
2403
|
differenceInSeconds,
|
|
2594
2404
|
differenceInMinutes,
|
|
2595
2405
|
differenceInHours,
|
|
2596
2406
|
differenceInDays,
|
|
2597
2407
|
differenceInWeeks,
|
|
2598
|
-
differenceInMonths,
|
|
2599
|
-
getClosestExistingDateOfMonth,
|
|
2600
|
-
getNextMonthlyDate,
|
|
2601
|
-
getHolidayReferenceYear,
|
|
2602
|
-
getFirstDayOfHolidayReferenceYear,
|
|
2603
|
-
getLastDayOfHolidayReferenceYear,
|
|
2604
2408
|
// ALIASES
|
|
2605
2409
|
getDateAsArrayFormatted: dateArray,
|
|
2606
2410
|
getDateAsArray: dateStringToArray,
|
|
@@ -2650,6 +2454,7 @@ export {
|
|
|
2650
2454
|
sortUrlsByDeepnessInArrayOrObject,
|
|
2651
2455
|
urlPathJoin,
|
|
2652
2456
|
miniTemplater,
|
|
2457
|
+
generateObjectId,
|
|
2653
2458
|
isBetween,
|
|
2654
2459
|
simpleObjectMaskOrSelect,
|
|
2655
2460
|
ENV,
|
|
@@ -2769,18 +2574,7 @@ export {
|
|
|
2769
2574
|
// isDateObject <= see validator.js
|
|
2770
2575
|
getDuration,
|
|
2771
2576
|
doDateOverlap,
|
|
2772
|
-
getDatesForDaysArrayBetweenTwoDates,
|
|
2773
|
-
getEndTimeFromDurationAndStartTime,
|
|
2774
|
-
getDate12FromDateAndTime,
|
|
2775
2577
|
getMonthAsInt,
|
|
2776
|
-
isSunday,
|
|
2777
|
-
isMonday,
|
|
2778
|
-
isTuesday,
|
|
2779
|
-
isWednesday,
|
|
2780
|
-
isThursday,
|
|
2781
|
-
isFriday,
|
|
2782
|
-
isSaturday,
|
|
2783
|
-
isWeekend,
|
|
2784
2578
|
nextWeekDay,
|
|
2785
2579
|
addMinutes,
|
|
2786
2580
|
addHours,
|
|
@@ -2793,20 +2587,12 @@ export {
|
|
|
2793
2587
|
getMinutes,
|
|
2794
2588
|
firstDayOfMonth,
|
|
2795
2589
|
lastDayOfMonth,
|
|
2796
|
-
eachDayOfInterval,
|
|
2797
|
-
eachMonthOfInterval,
|
|
2798
2590
|
differenceInMilliseconds,
|
|
2799
2591
|
differenceInSeconds,
|
|
2800
2592
|
differenceInMinutes,
|
|
2801
2593
|
differenceInHours,
|
|
2802
2594
|
differenceInDays,
|
|
2803
2595
|
differenceInWeeks,
|
|
2804
|
-
differenceInMonths,
|
|
2805
|
-
getClosestExistingDateOfMonth,
|
|
2806
|
-
getNextMonthlyDate,
|
|
2807
|
-
getHolidayReferenceYear,
|
|
2808
|
-
getFirstDayOfHolidayReferenceYear,
|
|
2809
|
-
getLastDayOfHolidayReferenceYear,
|
|
2810
2596
|
// ALIASES
|
|
2811
2597
|
getDateAsInt as convertDateAsInt,
|
|
2812
2598
|
getDateAsObject as convertDateAsObject,
|