topkat-utils 1.0.42 → 1.0.45

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/utils.js CHANGED
@@ -1,31 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reassignForbidden = exports.readOnly = exports.objFilterUndefined = exports.findByAddressAll = exports.recursiveGenericFunctionSync = exports.recursiveGenericFunction = exports.unflattenObject = exports.flattenObject = exports.mergeDeep = exports.isObject = exports.has = exports.JSONstringyParse = exports.cloneObject = exports.deepClone = exports.arrayUniqueValue = exports.randomItemInArray = exports.isNotEmptyArray = exports.pushIfNotExist = exports.arrayToObjectSorted = exports.arrayCount = exports.noDuplicateFilter = exports.getNotInArrayA = exports.getArrayDiff = exports.getArrayInCommon = exports.compareArrays = exports.asArray = exports.strAsArray = exports.objForceWriteIfNotSet = exports.objForceWrite = exports.findByAddress = exports.configFn = exports.registerConfig = exports.parseBool = exports.ENV = exports.simpleObjectMaskOrSelect = exports.isBetween = exports.generateObjectId = exports.miniTemplater = exports.urlPathJoin = exports.sortUrlsByDeepnessInArrayOrObject = exports.sumArray = exports.average = exports.moyenne = exports.generateToken = exports.minMax = exports.int = exports.pad = exports.cln = exports.random = exports.round = void 0;
4
+ exports.isEmpty = exports.errXXXIfNotSet = exports.err500IfEmptyOrNotSet = exports.errIfEmptyOrNotSet = exports.err500IfNotSet = exports.errIfNotSet = exports.isEmptyOrNotSet = exports.issetOr = exports.isDateObject = exports.isType = exports.isValid = exports.restTestMini = exports.assert = exports.validatorReturnErrArray = exports.required = exports.validator = exports.escapeRegexp = exports.getValuesBetweenStrings = exports.getValuesBetweenSeparator = exports.allMatches = exports.firstMatch = exports.camelCaseToWords = exports.capitalize1st = exports.upperCase = exports.lowerCase = exports.pascalCase = exports.titleCase = exports.underscoreCase = exports.dashCase = exports.kebabCase = exports.snakeCase = exports.camelCase = exports.forIasync = exports.forI = exports.round2 = exports.randomizeArray = exports.shuffleArray = exports.cleanStackTrace = exports.isset = exports.removeCircularJSONstringify = exports.ensureIsArrayAndPush = exports.deleteByAddress = exports.filterKeys = exports.ensureObjectProp = exports.sortObjKeyAccordingToValue = exports.removeUndefinedKeys = exports.objFilterUndefinedRecursive = exports.mergeDeepConfigurable = exports.mergeDeepOverrideArrays = exports.readOnlyForAll = void 0;
5
+ exports.transaction = exports.waitUntilTrue = exports.runAsync = exports.timeout = exports.executeInDelayedLoop = exports.convertAccentedCharacters = exports.cliLoadingSpinner = exports.cliProgressBar = exports.C = exports.convertDateAsObject = exports.convertDateAsInt = exports.differenceInWeeks = exports.differenceInDays = exports.differenceInHours = exports.differenceInMinutes = exports.differenceInSeconds = exports.differenceInMilliseconds = exports.lastDayOfMonth = exports.firstDayOfMonth = exports.getMinutes = exports.getHours = exports.getDayOfMonth = exports.getYear = exports.addYears = exports.addMonths = exports.addDays = exports.addHours = exports.addMinutes = exports.nextWeekDay = exports.getMonthAsInt = exports.doDateOverlap = exports.getDuration = exports.isTimeStringValid = exports.getIntAsTime = exports.getTimeAsInt = exports.dateOffset = exports.dateFormatted = exports.dateSlash = exports.dateArrayInt = exports.dateArray = exports.dateStringToArray = exports.isDateIsoOrObjectValid = exports.isDateIntOrStringValid = exports.getDateAsObject = exports.getDateAsInt = exports.humanReadableTimestamp = exports.getDateAsInt12 = exports.orIsset = exports.checkCtxIntegrity = exports.checkAllObjectValuesAreEmpty = void 0;
6
+ exports.tryCatch = exports.mongoPush = exports.mongoFilterMerger = exports.mergeMixins = exports.getId = exports.waitForTransaction = void 0;
1
7
  // ALIASES
2
8
  const int = parseInt;
9
+ exports.int = int;
3
10
  const average = moyenne;
11
+ exports.average = average;
4
12
  const arrayUniqueValue = noDuplicateFilter;
13
+ exports.arrayUniqueValue = arrayUniqueValue;
5
14
  const JSONstringyParse = o => JSON.parse(removeCircularJSONstringify(o));
15
+ exports.JSONstringyParse = JSONstringyParse;
6
16
  const removeUndefinedKeys = objFilterUndefinedRecursive;
17
+ exports.removeUndefinedKeys = removeUndefinedKeys;
7
18
  /** Round with custom number of decimals (default:0) */
8
19
  function round(number, decimals = 0) { return Math.round(number * Math.pow(10, decimals)) / Math.pow(10, decimals); }
20
+ exports.round = round;
9
21
  /** Round with custom number of decimals (default:0) */
10
22
  function round2(number, decimals = 2) { return Math.round(number * Math.pow(10, decimals)) / Math.pow(10, decimals); }
23
+ exports.round2 = round2;
11
24
  /** Is number between two numbers (including those numbers) */
12
25
  function isBetween(number, min, max, inclusive = true) { return inclusive ? number <= max && number >= min : number < max && number > min; }
26
+ exports.isBetween = isBetween;
13
27
  /** Random number between two values with 0 decimals by default */
14
28
  function random(nb1, nb2, nbOfDecimals = 0) { return round(Math.random() * (nb2 - nb1) + nb1, nbOfDecimals); }
29
+ exports.random = random;
15
30
  /** Sum all values of an array, all values MUST be numbers */
16
31
  function sumArray(array) {
17
32
  return array.filter(item => typeof item === 'number').reduce((sum, val) => isset(val) ? val + sum : sum, 0);
18
33
  }
34
+ exports.sumArray = sumArray;
19
35
  /** Moyenne / average between array of values
20
36
  * @param {Number} round number of decimals to keep. Default:2
21
37
  */
22
38
  function moyenne(array, nbOfDecimals = 2) {
23
39
  return round(sumArray(array) / array.length, nbOfDecimals);
24
40
  }
41
+ exports.moyenne = moyenne;
25
42
  /** Clean output for outside world. All undefined / null / NaN / Infinity values are changed to '-' */
26
43
  function cln(val, replacerInCaseItIsUndefinNaN = '-') { return ['undefined', undefined, 'indéfini', 'NaN', NaN, Infinity, null].includes(val) ? replacerInCaseItIsUndefinNaN : val; }
44
+ exports.cln = cln;
27
45
  /** length default 2, shortcut for 1 to 01 */
28
46
  function pad(numberOrStr, length = 2) { return ('' + numberOrStr).padStart(length, '0'); }
47
+ exports.pad = pad;
29
48
  /** return the number or the closest number of the range
30
49
  * * nb min max => returns
31
50
  * * 7 5 10 => 7 // in the range
@@ -33,6 +52,7 @@ function pad(numberOrStr, length = 2) { return ('' + numberOrStr).padStart(lengt
33
52
  * * 99 5 10 => 10// above the max value
34
53
  */
35
54
  function minMax(nb, min, max) { return Math.max(min, Math.min(nb, max)); }
55
+ exports.minMax = minMax;
36
56
  async function tryCatch(callback, onErr = () => { }) {
37
57
  try {
38
58
  return await callback();
@@ -41,6 +61,7 @@ async function tryCatch(callback, onErr = () => { }) {
41
61
  return await onErr(err);
42
62
  }
43
63
  }
64
+ exports.tryCatch = tryCatch;
44
65
  let generatedTokens = []; // cache to avoid collision
45
66
  let lastTs = new Date().getTime();
46
67
  /** minLength 8 if unique
@@ -66,9 +87,11 @@ function generateToken(length = 20, unique = true, mode = 'alphanumeric') {
66
87
  generatedTokens.push(token);
67
88
  return token;
68
89
  }
90
+ exports.generateToken = generateToken;
69
91
  function generateObjectId() {
70
92
  return generateToken(24, true, 'hexadecimal');
71
93
  }
94
+ exports.generateObjectId = generateObjectId;
72
95
  /** Useful to join differents bits of url with normalizing slashes
73
96
  * * urlPathJoin('https://', 'www.kikou.lol/', '/user', '//2//') => https://www.kikou.lol/user/2/
74
97
  * * urlPathJoin('http:/', 'kikou.lol') => https://www.kikou.lol
@@ -76,6 +99,7 @@ function generateObjectId() {
76
99
  function urlPathJoin(...bits) {
77
100
  return bits.join('/').replace(/\/+/g, '/').replace(/(https?:)\/\/?/, '$1//');
78
101
  }
102
+ exports.urlPathJoin = urlPathJoin;
79
103
  /** path shall always be sorted before using in express
80
104
  * to avoid a generic route like /* to catch a specific one like /bonjour
81
105
  *
@@ -105,6 +129,7 @@ function sortUrlsByDeepnessInArrayOrObject(urlObjOrArr, propInObjectOrIndexInArr
105
129
  bUrl.length - aUrl.length; // help separating / vs /blah
106
130
  });
107
131
  }
132
+ exports.sortUrlsByDeepnessInArrayOrObject = sortUrlsByDeepnessInArrayOrObject;
108
133
  /** Replace variables in a string like: `Hello {{userName}}!`
109
134
  * @param {String} content
110
135
  * @param {Object} varz object with key => value === toReplace => replacer
@@ -120,6 +145,7 @@ function miniTemplater(content, varz, options = {}) {
120
145
  };
121
146
  return content.replace(options.regexp, (m, $1) => isset(varz[$1]) ? varz[$1] : options.valueWhenNotSet);
122
147
  }
148
+ exports.miniTemplater = miniTemplater;
123
149
  /**
124
150
  *
125
151
  * @param {Object} object main object
@@ -147,6 +173,7 @@ function simpleObjectMaskOrSelect(object, maskedOrSelectedFields, isMask = true,
147
173
  }, {});
148
174
  }
149
175
  }
176
+ exports.simpleObjectMaskOrSelect = simpleObjectMaskOrSelect;
150
177
  /** Parse one dimention object undefined, true, false, null represented as string will be converted to primitives */
151
178
  function parseEnv(env) {
152
179
  const newEnv = {};
@@ -176,6 +203,7 @@ function ENV() {
176
203
  deleteProperty: throwErr,
177
204
  });
178
205
  }
206
+ exports.ENV = ENV;
179
207
  /**
180
208
  * @param {any} mayBeAstring
181
209
  * @return !!value
@@ -186,6 +214,7 @@ function parseBool(mayBeAstring) {
186
214
  else
187
215
  return mayBeAstring === 'true' ? true : mayBeAstring === 'false' ? false : !!mayBeAstring;
188
216
  }
217
+ exports.parseBool = parseBool;
189
218
  function dim(str = '') {
190
219
  return configFn().terminal.noColor ? str : `\x1b[2m${str.toString().split('\n').join('\x1b[0m\n\x1b[2m')}\x1b[0m`;
191
220
  }
@@ -209,6 +238,7 @@ let config = {
209
238
  };
210
239
  /** Allow dynamic changing of config */
211
240
  function configFn() { return config; }
241
+ exports.configFn = configFn;
212
242
  /** Register custom config
213
243
  * @param {object} customConfig { 'email': email => /.+@.+/.test(email), type2 : myTestFunction() }
214
244
  * * env: 'development',
@@ -246,6 +276,7 @@ function registerConfig(customConfig) {
246
276
  config = newconfig;
247
277
  config.isProd = config.env.includes('prod');
248
278
  }
279
+ exports.registerConfig = registerConfig;
249
280
  //----------------------------------------
250
281
  // ERROR HANDLER
251
282
  //----------------------------------------
@@ -283,6 +314,7 @@ function has(obj, addr) {
283
314
  return isset(objChain);
284
315
  });
285
316
  }
317
+ exports.has = has;
286
318
  /** Find address in an object "a.b.c" IN { a : { b : {c : 'blah' }}} RETURNS 'blah'
287
319
  * @param {object} obj
288
320
  * @param {string} addr accept syntax like "obj.subItem.[0].sub2" OR "obj.subItem.0.sub2" OR "obj.subItem[0].sub2"
@@ -302,6 +334,7 @@ function findByAddress(obj, addr) {
302
334
  }, obj);
303
335
  return objRef;
304
336
  }
337
+ exports.findByAddress = findByAddress;
305
338
  /** Enforce writing subItems. Eg: user.name.blah will ensure all are set until the writing of the last item
306
339
  * NOTE: doesn't work with arrays
307
340
  */
@@ -324,6 +357,7 @@ function objForceWrite(obj, addr, item) {
324
357
  lastItem = lastItem[chunk];
325
358
  });
326
359
  }
360
+ exports.objForceWrite = objForceWrite;
327
361
  /** Enforce writing subItems, only if obj.addr is empty.
328
362
  * Eg: user.name.blah will ensure all are set until the writing of the last item
329
363
  * if user.name.blah has a value it will not change it.
@@ -333,6 +367,7 @@ function objForceWriteIfNotSet(obj, addr, item) {
333
367
  if (!isset(findByAddress(obj, addr)))
334
368
  return objForceWrite(obj, addr, item);
335
369
  }
370
+ exports.objForceWriteIfNotSet = objForceWriteIfNotSet;
336
371
  /** Merge mixins into class. Use it in the constructor like: mergeMixins(this, {myMixin: true}) */
337
372
  function mergeMixins(that, ...mixins) {
338
373
  mixins.forEach(mixin => {
@@ -341,16 +376,19 @@ function mergeMixins(that, ...mixins) {
341
376
  }
342
377
  });
343
378
  }
379
+ exports.mergeMixins = mergeMixins;
344
380
  /** If a string is provided, return it as array else return the value */
345
381
  function strAsArray(arrOrStr) {
346
382
  return typeof arrOrStr === 'string' ? [arrOrStr] : arrOrStr;
347
383
  }
384
+ exports.strAsArray = strAsArray;
348
385
  /** If not an array provided, return the array with the value
349
386
  * /!\ NOTE /!\ In case the value is null or undefined, it will return that value
350
387
  */
351
388
  function asArray(item) {
352
389
  return (typeof item === 'undefined' ? item : Array.isArray(item) ? item : [item]);
353
390
  }
391
+ exports.asArray = asArray;
354
392
  /** Array comparison
355
393
  * @return {object} { inCommon, notInB, notInA }
356
394
  */
@@ -361,6 +399,7 @@ function compareArrays(arrayA, arrayB, compare = (a, b) => a === b) {
361
399
  notInA: getNotInArrayA(arrayA, arrayB, compare),
362
400
  };
363
401
  }
402
+ exports.compareArrays = compareArrays;
364
403
  /**
365
404
  * @return [] only elements that are both in arrayA and arrayB
366
405
  */
@@ -370,6 +409,7 @@ function getArrayInCommon(arrayA = [], arrayB = [], compare = (a, b) => a === b)
370
409
  else
371
410
  return arrayA.filter(a => arrayB.some(b => compare(a, b)));
372
411
  }
412
+ exports.getArrayInCommon = getArrayInCommon;
373
413
  /**
374
414
  * @return [] only elements that are in arrayB and not in arrayA
375
415
  */
@@ -381,12 +421,14 @@ function getNotInArrayA(arrayA = [], arrayB = [], compare = (a, b) => a === b) {
381
421
  else
382
422
  return arrayB.filter(b => !arrayA.some(a => compare(a, b)));
383
423
  }
424
+ exports.getNotInArrayA = getNotInArrayA;
384
425
  /**
385
426
  * @return [] only elements that are in neither arrayA and arrayB
386
427
  */
387
428
  function getArrayDiff(arrayA = [], arrayB = [], compare = (a, b) => a === b) {
388
429
  return [...getNotInArrayA(arrayA, arrayB, compare), ...getNotInArrayA(arrayB, arrayA, compare)];
389
430
  }
431
+ exports.getArrayDiff = getArrayDiff;
390
432
  /** filter duplicate values in an array
391
433
  * @param {function} comparisonFn default:(a, b) => a === b. A function that shall return true if two values are considered equal
392
434
  * @return {array|function}
@@ -394,10 +436,12 @@ function getArrayDiff(arrayA = [], arrayB = [], compare = (a, b) => a === b) {
394
436
  function noDuplicateFilter(arr, comparisonFn = (a, b) => a === b) {
395
437
  return arr.filter((a, i, arr) => arr.findIndex(b => comparisonFn(a, b)) === i);
396
438
  }
439
+ exports.noDuplicateFilter = noDuplicateFilter;
397
440
  /** Count number of occurence of item in array */
398
441
  function arrayCount(item, arr) {
399
442
  return arr.reduce((total, item2) => item === item2 ? total + 1 : total, 0);
400
443
  }
444
+ exports.arrayCount = arrayCount;
401
445
  /**
402
446
  * Sort an array in an object of subArrays, no duplicate.
403
447
  * @param {Array} array
@@ -412,6 +456,7 @@ function arrayToObjectSorted(array, getFieldFromItem) {
412
456
  });
413
457
  return res;
414
458
  }
459
+ exports.arrayToObjectSorted = arrayToObjectSorted;
415
460
  /**
416
461
  * @param {Function} comparisonFunction default: (itemToPush, itemAlreadyInArray) => itemToPush === itemAlreadyInArray; comparison function to consider the added item duplicate
417
462
  */
@@ -420,15 +465,19 @@ function pushIfNotExist(arrayToPushInto, valueOrArrayOfValuesToBePushed, compari
420
465
  arrayToPushInto.push(...valuesToPush);
421
466
  return arrayToPushInto;
422
467
  }
468
+ exports.pushIfNotExist = pushIfNotExist;
423
469
  function isNotEmptyArray(arr) {
424
470
  return Array.isArray(arr) && !!arr.length;
425
471
  }
472
+ exports.isNotEmptyArray = isNotEmptyArray;
426
473
  function randomItemInArray(array) {
427
474
  return array[Math.floor(Math.random() * array.length)];
428
475
  }
476
+ exports.randomItemInArray = randomItemInArray;
429
477
  function cloneObject(o) {
430
478
  return JSON.parse(JSON.stringify(o));
431
479
  }
480
+ exports.cloneObject = cloneObject;
432
481
  /** Deep clone. WILL REMOVE circular references */
433
482
  function deepClone(obj, cache = []) {
434
483
  let copy;
@@ -462,8 +511,10 @@ function deepClone(obj, cache = []) {
462
511
  }
463
512
  return obj; // number, string...
464
513
  }
514
+ exports.deepClone = deepClone;
465
515
  /** test if object but not array and not null (null is an object in Js) */
466
516
  function isObject(o) { return o instanceof Object && [Object, Error].includes(o.constructor); }
517
+ exports.isObject = isObject;
467
518
  /** object and array merge
468
519
  * @warn /!\ Array will be merged and duplicate values will be deleted /!\
469
520
  * @return {Object} new object result from merge
@@ -471,6 +522,7 @@ function isObject(o) { return o instanceof Object && [Object, Error].includes(o.
471
522
  function mergeDeep(...objects) {
472
523
  return mergeDeepConfigurable((previousVal, currentVal) => [...previousVal, ...currentVal].filter((elm, i, arr) => arr.indexOf(elm) === i), (previousVal, currentVal) => mergeDeep(previousVal, currentVal), undefined, ...objects);
473
524
  }
525
+ exports.mergeDeep = mergeDeep;
474
526
  /** object and array merge
475
527
  * @warn /!\ Array will be replaced by the latest object /!\
476
528
  * @return {Object} new object result from merge
@@ -478,6 +530,7 @@ function mergeDeep(...objects) {
478
530
  function mergeDeepOverrideArrays(...objects) {
479
531
  return mergeDeepConfigurable(undefined, (previousVal, currentVal) => mergeDeepOverrideArrays(previousVal, currentVal), undefined, ...objects);
480
532
  }
533
+ exports.mergeDeepOverrideArrays = mergeDeepOverrideArrays;
481
534
  /** object and array merge
482
535
  * @param {Function} replacerForArrays item[key] = (prevValue, currentVal) => () When 2 values are arrays,
483
536
  * @param {Function} replacerForObjects item[key] = (prevValue, currentVal) => () When 2 values are objects,
@@ -504,6 +557,7 @@ function mergeDeepConfigurable(replacerForArrays = (prev, curr) => curr, replace
504
557
  return actuallyMerged;
505
558
  }, {});
506
559
  }
560
+ exports.mergeDeepConfigurable = mergeDeepConfigurable;
507
561
  /** { a: {b:2}} => {'a.b':2} useful for translations
508
562
  * NOTE: will remove circular references
509
563
  */
@@ -546,6 +600,7 @@ function flattenObject(data, config = {}) {
546
600
  recurse(data, '');
547
601
  return result;
548
602
  }
603
+ exports.flattenObject = flattenObject;
549
604
  /** {'a.b':2} => { a: {b:2}} */
550
605
  function unflattenObject(data) {
551
606
  const newO = {};
@@ -553,6 +608,7 @@ function unflattenObject(data) {
553
608
  objForceWrite(newO, addr, value);
554
609
  return newO;
555
610
  }
611
+ exports.unflattenObject = unflattenObject;
556
612
  /**
557
613
  * @param {any} item the first array or object or whatever you want to recursively browse
558
614
  * @param {function} callback the callback you want to apply on items including the main one
@@ -586,6 +642,7 @@ async function recursiveGenericFunction(item, callback, addr$ = '', lastElementK
586
642
  }
587
643
  return item;
588
644
  }
645
+ exports.recursiveGenericFunction = recursiveGenericFunction;
589
646
  /**
590
647
  * @param {any} item the first array or object or whatever you want to recursively browse
591
648
  * @param {function} callback the callback you want to apply on items including the main one
@@ -620,11 +677,13 @@ function recursiveGenericFunctionSync(item, callback, addr$ = '', lastElementKey
620
677
  }
621
678
  return item;
622
679
  }
680
+ exports.recursiveGenericFunctionSync = recursiveGenericFunctionSync;
623
681
  /** Remove all key/values pair if value is undefined */
624
682
  function objFilterUndefined(o) {
625
683
  Object.keys(o).forEach(k => !isset(o[k]) && delete o[k]);
626
684
  return o;
627
685
  }
686
+ exports.objFilterUndefined = objFilterUndefined;
628
687
  /** Lock all 1st level props of an object to read only */
629
688
  function readOnly(o) {
630
689
  const throwErr = () => { throw new dataValidationUtilErrorHandler('Cannot modify object that is read only', 500); };
@@ -634,6 +693,7 @@ function readOnly(o) {
634
693
  deleteProperty: throwErr,
635
694
  });
636
695
  }
696
+ exports.readOnly = readOnly;
637
697
  /** Fields of the object can be created BUT NOT reassignated */
638
698
  function reassignForbidden(o) {
639
699
  return new Proxy(o, {
@@ -650,6 +710,7 @@ function reassignForbidden(o) {
650
710
  }
651
711
  });
652
712
  }
713
+ exports.reassignForbidden = reassignForbidden;
653
714
  /** All fileds and subFields of the object will become readOnly */
654
715
  function readOnlyForAll(object) {
655
716
  recursiveGenericFunctionSync(object, (item, _, lastElementKey, parent) => {
@@ -658,6 +719,7 @@ function readOnlyForAll(object) {
658
719
  });
659
720
  return object;
660
721
  }
722
+ exports.readOnlyForAll = readOnlyForAll;
661
723
  function objFilterUndefinedRecursive(obj) {
662
724
  if (obj) {
663
725
  const flattenedObj = flattenObject(obj);
@@ -671,6 +733,7 @@ function objFilterUndefinedRecursive(obj) {
671
733
  else
672
734
  return obj;
673
735
  }
736
+ exports.objFilterUndefinedRecursive = objFilterUndefinedRecursive;
674
737
  /** Will return all objects matching that path. Eg: user.*.myVar */
675
738
  function findByAddressAll(obj, addr) {
676
739
  err500IfNotSet({ obj, addr });
@@ -688,6 +751,7 @@ function findByAddressAll(obj, addr) {
688
751
  });
689
752
  return matchingItems;
690
753
  }
754
+ exports.findByAddressAll = findByAddressAll;
691
755
  function sortObjKeyAccordingToValue(unorderedObj, ascending = true) {
692
756
  const orderedObj = {};
693
757
  const sortingConst = ascending ? 1 : -1;
@@ -696,6 +760,7 @@ function sortObjKeyAccordingToValue(unorderedObj, ascending = true) {
696
760
  .forEach(key => { orderedObj[key] = unorderedObj[key]; });
697
761
  return orderedObj;
698
762
  }
763
+ exports.sortObjKeyAccordingToValue = sortObjKeyAccordingToValue;
699
764
  /**
700
765
  * Make default value if object key do not exist
701
766
  * @param {object} obj
@@ -711,6 +776,7 @@ function ensureObjectProp(obj, addr, defaultValue, callback = o => o) {
711
776
  callback(obj[addr]);
712
777
  return obj[addr];
713
778
  }
779
+ exports.ensureObjectProp = ensureObjectProp;
714
780
  /**
715
781
  * Maye sure obj[addr] is an array and push a value to it
716
782
  * @param {Object} obj parent object
@@ -734,6 +800,7 @@ function ensureIsArrayAndPush(obj, addr, valToPush, onlyUniqueValues) {
734
800
  objValue.push(valToPush);
735
801
  });
736
802
  }
803
+ exports.ensureIsArrayAndPush = ensureIsArrayAndPush;
737
804
  /**
738
805
  * @param {Object} obj the object on which we want to filter the keys
739
806
  * @param {function} filterFunc function that returns true if the key match the wanted criteria
@@ -746,6 +813,7 @@ function filterKeys(obj, filter) {
746
813
  });
747
814
  return clone;
748
815
  }
816
+ exports.filterKeys = filterKeys;
749
817
  /**
750
818
  * @param {Object} obj the object on which we want to delete a property
751
819
  * @param {Array} addr addressArray on which to delete the property
@@ -756,6 +824,7 @@ function deleteByAddress(obj, addr) {
756
824
  current = current[addr[i]];
757
825
  delete current[addr[addr.length - 1]];
758
826
  }
827
+ exports.deleteByAddress = deleteByAddress;
759
828
  /** @return undefined if cannot find _id */
760
829
  function getId(obj = {}) {
761
830
  if (!obj)
@@ -765,16 +834,19 @@ function getId(obj = {}) {
765
834
  else if (isType(obj, 'objectId'))
766
835
  return obj.toString();
767
836
  }
837
+ exports.getId = getId;
768
838
  /**
769
839
  * @returns {array} return values of all callbacks
770
840
  */
771
841
  function forI(nbIterations, callback) {
772
842
  const results = [];
773
843
  for (let i = 0; i < nbIterations; i++) {
774
- results.push(callback(i));
844
+ const prevValue = results[results.length - 1];
845
+ results.push(callback(i, prevValue, results));
775
846
  }
776
847
  return results;
777
848
  }
849
+ exports.forI = forI;
778
850
  async function forIasync(nbIterations, callback) {
779
851
  const results = [];
780
852
  for (let i = 0; i < nbIterations; i++) {
@@ -782,6 +854,7 @@ async function forIasync(nbIterations, callback) {
782
854
  }
783
855
  return results;
784
856
  }
857
+ exports.forIasync = forIasync;
785
858
  function cleanStackTrace(stack) {
786
859
  if (typeof stack !== 'string')
787
860
  return '';
@@ -823,9 +896,11 @@ function cleanStackTrace(stack) {
823
896
  .join('\n');
824
897
  return linesClean;
825
898
  }
899
+ exports.cleanStackTrace = cleanStackTrace;
826
900
  function isset(...elms) {
827
901
  return elms.every(elm => typeof elm !== 'undefined' && elm !== null);
828
902
  }
903
+ exports.isset = isset;
829
904
  function removeCircularJSONstringify(object, indent = 2) {
830
905
  const getCircularReplacer = () => {
831
906
  const seen = new WeakSet();
@@ -841,6 +916,7 @@ function removeCircularJSONstringify(object, indent = 2) {
841
916
  };
842
917
  return JSON.stringify(object, getCircularReplacer(), indent);
843
918
  }
919
+ exports.removeCircularJSONstringify = removeCircularJSONstringify;
844
920
  function shuffleArray(array) {
845
921
  for (let i = array.length - 1; i > 0; i--) {
846
922
  const j = Math.floor(Math.random() * (i + 1));
@@ -848,16 +924,21 @@ function shuffleArray(array) {
848
924
  }
849
925
  return array;
850
926
  }
927
+ exports.shuffleArray = shuffleArray;
928
+ exports.randomizeArray = shuffleArray;
851
929
  /**Eg: camelCase */
852
930
  function camelCase(...wordBits) {
853
931
  return wordBits.filter(e => e).map((w, i) => i === 0 ? w : capitalize1st(w)).join('');
854
932
  }
933
+ exports.camelCase = camelCase;
855
934
  /**Eg: snake_case
856
935
  * trimmed but not lowerCased
857
936
  */
858
937
  function snakeCase(...wordBits) {
859
938
  return wordBits.filter(e => e).map(w => w.trim()).join('_');
860
939
  }
940
+ exports.snakeCase = snakeCase;
941
+ exports.underscoreCase = snakeCase;
861
942
  /**Eg: kebab-case
862
943
  * trimmed AND lowerCased
863
944
  * undefined, null... => ''
@@ -865,26 +946,34 @@ function snakeCase(...wordBits) {
865
946
  function kebabCase(...wordBits) {
866
947
  return wordBits.filter(e => e).map(w => w.trim().toLowerCase()).join('-');
867
948
  }
949
+ exports.kebabCase = kebabCase;
950
+ exports.dashCase = kebabCase;
868
951
  /**Eg: PascalCase undefined, null... => '' */
869
952
  function pascalCase(...wordBits) {
870
953
  return wordBits.filter(e => e).map((w, i) => capitalize1st(w)).join('');
871
954
  }
955
+ exports.pascalCase = pascalCase;
872
956
  /**Eg: Titlecase undefined, null... => '' */
873
957
  function titleCase(...wordBits) {
874
958
  return capitalize1st(wordBits.filter(e => e).map(w => w.trim()).join(''));
875
959
  }
960
+ exports.titleCase = titleCase;
876
961
  /**Eg: UPPERCASE undefined, null... => '' */
877
962
  function upperCase(...wordBits) {
878
963
  return wordBits.filter(e => e).map(w => w.trim().toUpperCase()).join('');
879
964
  }
965
+ exports.upperCase = upperCase;
880
966
  /**Eg: lowercase undefined, null... => '' */
881
967
  function lowerCase(...wordBits) {
882
968
  return wordBits.filter(e => e).map(w => w.trim().toLowerCase()).join('');
883
969
  }
970
+ exports.lowerCase = lowerCase;
884
971
  function capitalize1st(str = '') { return str[0].toUpperCase() + str.slice(1); }
972
+ exports.capitalize1st = capitalize1st;
885
973
  function camelCaseToWords(str) {
886
974
  return str ? str.trim().replace(/([A-Z])/g, '-$1').toLowerCase().split('-') : [];
887
975
  }
976
+ exports.camelCaseToWords = camelCaseToWords;
888
977
  function escapeRegexp(str, config = {}) {
889
978
  const { parseStarChar = false } = config;
890
979
  if (parseStarChar)
@@ -892,10 +981,12 @@ function escapeRegexp(str, config = {}) {
892
981
  else
893
982
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
894
983
  }
984
+ exports.escapeRegexp = escapeRegexp;
895
985
  /** Get first match of the first capturing group of regexp
896
986
  * Eg: const basePath = firstMatch(apiFile, /basePath = '(.*?)'/); will get what is inside quotes
897
987
  */
898
988
  function firstMatch(str, regExp) { return (str.match(regExp) || [])[1]; }
989
+ exports.firstMatch = firstMatch;
899
990
  /** Get all matches from regexp with g flag
900
991
  * Eg: [ [full, match1, m2], [f, m1, m2]... ]
901
992
  * NOTE: the G flag will be appended to regexp
@@ -918,6 +1009,7 @@ function allMatches(str, reg) {
918
1009
  }
919
1010
  return arr;
920
1011
  }
1012
+ exports.allMatches = allMatches;
921
1013
  /** GIVEN A STRING '{ blah;2}, ['nested,(what,ever)']' AND A SEPARATOR ",""
922
1014
  * This will return the content separated by first level of separators
923
1015
  * @return ["{ blah;2}", "['nested,(what,ever)']"]
@@ -927,6 +1019,7 @@ function getValuesBetweenSeparator(str, separator, removeTrailingSpaces = true)
927
1019
  const { outer } = getValuesBetweenStrings(str, separator, undefined, undefined, undefined, removeTrailingSpaces);
928
1020
  return outer;
929
1021
  }
1022
+ exports.getValuesBetweenSeparator = getValuesBetweenSeparator;
930
1023
  /** GIVEN A STRING "a: [ 'str', /[^]]/, '[aa]]]str', () => [ nestedArray ] ], b: ['arr']"
931
1024
  * @return matching: [ "'str', /[^]]/, '[aa]]]str', () => [ nestedArray ]", "'arr'" ], between: [ "a:", ", b: " ]
932
1025
  * @param str base string
@@ -994,12 +1087,20 @@ function getValuesBetweenStrings(str, openingOrSeparator, closing, ignoreBetween
994
1087
  const replaceValz = arr => arr.map(v => v.replace(/§§"/g, '<<').replace(/"§§/g, '>>')).filter(v => v);
995
1088
  return { inner: replaceValz(arrayValues), outer: replaceValz(betweenArray) };
996
1089
  }
1090
+ exports.getValuesBetweenStrings = getValuesBetweenStrings;
997
1091
  function issetOr(...elms) { return elms.some(elm => typeof elm !== 'undefined' && elm !== null); }
1092
+ exports.issetOr = issetOr;
1093
+ exports.orIsset = issetOr;
998
1094
  function isEmptyOrNotSet(...elms) { return elms.some(elm => !isset(elm) || isEmpty(elm)); }
1095
+ exports.isEmptyOrNotSet = isEmptyOrNotSet;
999
1096
  function errIfNotSet(objOfVarNamesWithValues, additionalMessage) { return errXXXIfNotSet(422, false, objOfVarNamesWithValues); }
1097
+ exports.errIfNotSet = errIfNotSet;
1000
1098
  function err500IfNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, false, objOfVarNamesWithValues); }
1099
+ exports.err500IfNotSet = err500IfNotSet;
1001
1100
  function errIfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(422, true, objOfVarNamesWithValues); }
1101
+ exports.errIfEmptyOrNotSet = errIfEmptyOrNotSet;
1002
1102
  function err500IfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, true, objOfVarNamesWithValues); }
1103
+ exports.err500IfEmptyOrNotSet = err500IfEmptyOrNotSet;
1003
1104
  function errXXXIfNotSet(errCode, checkEmpty, objOfVarNamesWithValues) {
1004
1105
  let missingVars = [];
1005
1106
  for (let prop in objOfVarNamesWithValues) {
@@ -1009,19 +1110,25 @@ function errXXXIfNotSet(errCode, checkEmpty, objOfVarNamesWithValues) {
1009
1110
  if (missingVars.length)
1010
1111
  throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, errCode, { origin: 'Validator', varNames: missingVars.join(', ') });
1011
1112
  }
1113
+ exports.errXXXIfNotSet = errXXXIfNotSet;
1012
1114
  function isDateObject(variable) { return variable instanceof Date; }
1115
+ exports.isDateObject = isDateObject;
1013
1116
  /** Check all values are set */
1014
1117
  function checkAllObjectValuesAreEmpty(o) { return Object.values(o).every(value => !isset(value)); }
1118
+ exports.checkAllObjectValuesAreEmpty = checkAllObjectValuesAreEmpty;
1015
1119
  /** Throw an error in case data passed is not a valid ctx */
1016
1120
  function checkCtxIntegrity(ctx) {
1017
1121
  if (!isset(ctx) || !isset(ctx.user))
1018
1122
  throw new dataValidationUtilErrorHandler('ctxNotSet', 500);
1019
1123
  }
1124
+ exports.checkCtxIntegrity = checkCtxIntegrity;
1020
1125
  function validator(...paramsToValidate) {
1021
1126
  const errArray = validatorReturnErrArray(...paramsToValidate);
1022
1127
  if (errArray.length)
1023
1128
  throw new dataValidationUtilErrorHandler(...errArray);
1024
1129
  }
1130
+ exports.validator = validator;
1131
+ exports.required = validator;
1025
1132
  const restTestMini = {
1026
1133
  throwOnErr: false,
1027
1134
  reset(throwOnErr = false) {
@@ -1055,6 +1162,7 @@ const restTestMini = {
1055
1162
  nbError: 0,
1056
1163
  lastErrors: []
1057
1164
  };
1165
+ exports.restTestMini = restTestMini;
1058
1166
  function assert(msg, value, validatorObject = {}) {
1059
1167
  try {
1060
1168
  if (typeof validatorObject !== 'object')
@@ -1077,6 +1185,7 @@ function assert(msg, value, validatorObject = {}) {
1077
1185
  restTestMini.newErr(err);
1078
1186
  }
1079
1187
  }
1188
+ exports.assert = assert;
1080
1189
  /** Same as validator but return a boolean
1081
1190
  * See {@link validator}
1082
1191
  */
@@ -1084,10 +1193,12 @@ function isValid(...paramsToValidate) {
1084
1193
  const errArray = validatorReturnErrArray(...paramsToValidate);
1085
1194
  return errArray.length ? false : true;
1086
1195
  }
1196
+ exports.isValid = isValid;
1087
1197
  /** Default types + custom types
1088
1198
  * 'objectId','dateInt6','dateInt','dateInt8','dateInt12','time','humanReadableTimestamp','date','array','object','buffer','string','function','boolean','number','bigint',
1089
1199
  */
1090
1200
  function isType(value, type) { return isValid({ name: 'Is type check', value, type }); }
1201
+ exports.isType = isType;
1091
1202
  function validatorReturnErrArray(...paramsToValidate) {
1092
1203
  let paramsFormatted = [];
1093
1204
  // support for multiple names with multiple values for one rule. Eg: {name: [{startDate:'20180101'}, {endDate:'20180101'}], type: 'dateInt8'}
@@ -1128,10 +1239,18 @@ function validatorReturnErrArray(...paramsToValidate) {
1128
1239
  return errMess('requiredVariableEmptyOrNotSet');
1129
1240
  if (!emptyAllowed && value === '')
1130
1241
  return errMess('requiredVariableEmpty');
1242
+ const isArray = paramObj.isArray;
1243
+ if (isArray && !Array.isArray(value))
1244
+ return errMess('wrongTypeForVar', { expectedTypes: 'array', gotType: typeof value });
1131
1245
  // TYPE
1132
1246
  if (isset(paramObj.type)) {
1133
- const types = Array.isArray(paramObj.type) ? paramObj.type : [paramObj.type]; // support for multiple type
1247
+ const types = asArray(paramObj.type); // support for multiple type
1134
1248
  const areSomeTypeValid = types.some(type => {
1249
+ if (type.endsWith('[]')) {
1250
+ if (!Array.isArray(value))
1251
+ errMess('wrongTypeForVar', { expectedTypes: 'array', gotType: typeof value });
1252
+ type = type.replace('[]', '');
1253
+ }
1135
1254
  const allTypes = [
1136
1255
  'objectId',
1137
1256
  'dateInt6',
@@ -1151,6 +1270,7 @@ function validatorReturnErrArray(...paramsToValidate) {
1151
1270
  'number',
1152
1271
  'bigint',
1153
1272
  'year',
1273
+ 'any',
1154
1274
  //...Object.keys(configFn().customTypes)
1155
1275
  ];
1156
1276
  if (!allTypes.includes(type))
@@ -1168,7 +1288,8 @@ function validatorReturnErrArray(...paramsToValidate) {
1168
1288
  array: val => Array.isArray(val),
1169
1289
  object: val => !Array.isArray(val) && val !== null && typeof val === type,
1170
1290
  buffer: val => Buffer.isBuffer(val),
1171
- year: val => /^\d\d\d\d$/.test(val)
1291
+ year: val => /^\d\d\d\d$/.test(val),
1292
+ any: () => true,
1172
1293
  };
1173
1294
  return isset(basicTypeCheck[type]) && basicTypeCheck[type](value) ||
1174
1295
  typeof value === type && type !== 'object' || // for string, number, boolean...
@@ -1220,6 +1341,7 @@ function validatorReturnErrArray(...paramsToValidate) {
1220
1341
  }
1221
1342
  return [];
1222
1343
  }
1344
+ exports.validatorReturnErrArray = validatorReturnErrArray;
1223
1345
  function isEmpty(objOrArr) {
1224
1346
  if (Array.isArray(objOrArr) || typeof objOrArr === 'string')
1225
1347
  return objOrArr.length === 0;
@@ -1228,6 +1350,7 @@ function isEmpty(objOrArr) {
1228
1350
  else
1229
1351
  false;
1230
1352
  }
1353
+ exports.isEmpty = isEmpty;
1231
1354
  function err422IfNotSet(o) {
1232
1355
  let m = [];
1233
1356
  for (let p in o)
@@ -1237,11 +1360,13 @@ function err422IfNotSet(o) {
1237
1360
  throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, 422, { origin: 'Validator', varNames: m.join(', ') });
1238
1361
  }
1239
1362
  function getDateAsInt12(dateAllFormat, errIfNotValid) { return getDateAsInt(dateAllFormat, errIfNotValid, true); } // alias
1363
+ exports.getDateAsInt12 = getDateAsInt12;
1240
1364
  function humanReadableTimestamp(dateAllFormat) {
1241
1365
  if (isset(dateAllFormat))
1242
1366
  dateAllFormat = getDateAsObject(dateAllFormat);
1243
1367
  return parseInt(getDateAsInt12(dateAllFormat) + pad((dateAllFormat || new Date()).getUTCSeconds()) + pad((dateAllFormat || new Date()).getUTCMilliseconds(), 3));
1244
1368
  }
1369
+ exports.humanReadableTimestamp = humanReadableTimestamp;
1245
1370
  /** format for 6/8/2018 => 20180806
1246
1371
  * @param dateAllFormat multiple format allowed 2012, 20120101, 201201011200, new Date(), "2019-12-08T16:19:10.341Z" and all string that new Date() can parse
1247
1372
  */
@@ -1267,6 +1392,8 @@ function getDateAsInt(dateAllFormat = new Date(), errIfNotValid$ = false, withHo
1267
1392
  isDateIntOrStringValid(dateInt, errIfNotValid$);
1268
1393
  return (withHoursAndMinutes$ ? dateInt : dateInt.substr(0, 8));
1269
1394
  }
1395
+ exports.getDateAsInt = getDateAsInt;
1396
+ exports.convertDateAsInt = getDateAsInt;
1270
1397
  function getMonthAsInt(dateAllFormat = new Date()) {
1271
1398
  let dateInt;
1272
1399
  if (isDateIntOrStringValid(dateAllFormat)) {
@@ -1282,6 +1409,7 @@ function getMonthAsInt(dateAllFormat = new Date()) {
1282
1409
  }
1283
1410
  return int(dateInt);
1284
1411
  }
1412
+ exports.getMonthAsInt = getMonthAsInt;
1285
1413
  /**
1286
1414
  * @param dateAllFormat multiple format allowed 2012, 20120101, 201201011200, new Date(), "2019-12-08T16:19:10.341Z" and all string that new Date() can parse
1287
1415
  */
@@ -1300,6 +1428,8 @@ function getDateAsObject(dateAllFormat = new Date(), errIfNotValid$ = true) {
1300
1428
  isDateIsoOrObjectValid(dateObj, errIfNotValid$);
1301
1429
  return dateObj;
1302
1430
  }
1431
+ exports.getDateAsObject = getDateAsObject;
1432
+ exports.convertDateAsObject = getDateAsObject;
1303
1433
  function isDateIntOrStringValid(dateStringOrInt, outputAnError = false, length) {
1304
1434
  if (!isset(dateStringOrInt))
1305
1435
  return false;
@@ -1319,6 +1449,7 @@ function isDateIntOrStringValid(dateStringOrInt, outputAnError = false, length)
1319
1449
  throw new dataValidationUtilErrorHandler(`dateStringOrIntFormatInvalid`, 422, { origin: 'Date Int validator', dateStringOrInt: dateStringOrInt, extraInfo: 'Needs YYYYMMDD[HHMM] between 100001010000 and 999912312359', dateArr, isYearValid: test1, isMonthValid: test2, isDayValid: test3, isHourValid: test4, isMinutesValid: test5 });
1320
1450
  return true;
1321
1451
  }
1452
+ exports.isDateIntOrStringValid = isDateIntOrStringValid;
1322
1453
  function isDateIsoOrObjectValid(dateIsoOrObj, outputAnError = false) {
1323
1454
  let dateObj = dateIsoOrObj;
1324
1455
  if (typeof dateIsoOrObj === 'string')
@@ -1328,6 +1459,7 @@ function isDateIsoOrObjectValid(dateIsoOrObj, outputAnError = false) {
1328
1459
  throw new dataValidationUtilErrorHandler('dateIsoStringOrObjectIsNotValid', 422, { origin: 'Date Object validator', isoDate: dateIsoOrObj });
1329
1460
  return valid;
1330
1461
  }
1462
+ exports.isDateIsoOrObjectValid = isDateIsoOrObjectValid;
1331
1463
  /** [2018,01,06] */
1332
1464
  function dateStringToArray(strOrInt) {
1333
1465
  err422IfNotSet({ strOrInt });
@@ -1342,6 +1474,7 @@ function dateStringToArray(strOrInt) {
1342
1474
  dateStr.substr(14, 3) || '000', // MS
1343
1475
  ];
1344
1476
  }
1477
+ exports.dateStringToArray = dateStringToArray;
1345
1478
  /**
1346
1479
  * @param dateAllFormat default: actualDate
1347
1480
  * @returns ['01', '01', '2019'] OR **string** if separator is provided */
@@ -1353,6 +1486,7 @@ function dateArray(dateAllFormat = getDateAsInt()) {
1353
1486
  dateStr.substr(0, 4), // Y
1354
1487
  ];
1355
1488
  }
1489
+ exports.dateArray = dateArray;
1356
1490
  /**
1357
1491
  * @param dateAllFormat default: actualDate
1358
1492
  * @returns ['01', '01', '2019'] OR **string** if separator is provided */
@@ -1364,15 +1498,19 @@ function dateArrayInt(dateAllFormat = getDateAsInt()) {
1364
1498
  int(dateStr.substr(0, 4)), // Y
1365
1499
  ];
1366
1500
  }
1501
+ exports.dateArrayInt = dateArrayInt;
1367
1502
  /**
1368
1503
  * @return 01/01/2012 (alias of dateArrayFormatted(date, '/'))
1369
1504
  */
1370
1505
  function dateFormatted(dateAllFormat, separator = '/') { return dateArray(dateAllFormat).join(separator); }
1506
+ exports.dateSlash = dateFormatted;
1507
+ exports.dateFormatted = dateFormatted;
1371
1508
  /** Date with custom offset (Ex: +2 for France) */
1372
1509
  function dateOffset(offsetHours, dateObj = new Date()) {
1373
1510
  var utc = Date.UTC(dateObj.getUTCFullYear(), dateObj.getUTCMonth(), dateObj.getUTCDate(), dateObj.getUTCHours(), dateObj.getUTCMinutes(), dateObj.getUTCSeconds());
1374
1511
  return new Date(utc + (3600000 * offsetHours));
1375
1512
  }
1513
+ exports.dateOffset = dateOffset;
1376
1514
  //----------------------------------------
1377
1515
  // TIME UTILS
1378
1516
  //----------------------------------------
@@ -1387,6 +1525,7 @@ function getTimeAsInt(timeOrDateInt = getDateAsInt12()) {
1387
1525
  else
1388
1526
  return 'dateInvalid';
1389
1527
  }
1528
+ exports.getTimeAsInt = getTimeAsInt;
1390
1529
  /**
1391
1530
  * @param {timeInt|dateInt12} Eg: 2222 OR 201201012222. Default, actual dateInt12
1392
1531
  * @param {String} separator default: ":"
@@ -1396,6 +1535,7 @@ function getIntAsTime(intOrDateTimeInt = getDateAsInt12(), separator = ':') {
1396
1535
  const tl = time.length;
1397
1536
  return time.substring(tl - 4, tl - 2) + separator + time.substring(tl - 2, tl);
1398
1537
  }
1538
+ exports.getIntAsTime = getIntAsTime;
1399
1539
  function isTimeStringValid(timeStr, outputAnError$ = false) {
1400
1540
  let timeArr = timeStr.split(':');
1401
1541
  let h = int(timeArr[0]);
@@ -1407,6 +1547,7 @@ function isTimeStringValid(timeStr, outputAnError$ = false) {
1407
1547
  else
1408
1548
  return test1 && test2;
1409
1549
  }
1550
+ exports.isTimeStringValid = isTimeStringValid;
1410
1551
  //----------------------------------------
1411
1552
  // DURATIONS
1412
1553
  //----------------------------------------
@@ -1423,6 +1564,7 @@ function getDuration(startDate, endDate, inMinutes = false) {
1423
1564
  Math.floor(((diffInSec % (24 * 3600)) % 3600) / 60), // M
1424
1565
  ];
1425
1566
  }
1567
+ exports.getDuration = getDuration;
1426
1568
  /** compare two object with DATE INT, if they overlap return true
1427
1569
  * @param {Object} event1 {startDate, endDate}
1428
1570
  * @param {Object} event2 {startDate, endDate}
@@ -1438,6 +1580,7 @@ function doDateOverlap(event1, event2, fieldNameForStartDate$ = 'startDate', fie
1438
1580
  return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] < event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] > event2[fieldNameForStartDate$]);
1439
1581
  return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] <= event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] >= event2[fieldNameForStartDate$]);
1440
1582
  }
1583
+ exports.doDateOverlap = doDateOverlap;
1441
1584
  function nextWeekDay(fromDate, weekDayInt, outputFormat = 'date', sameDayAllowed = false) {
1442
1585
  const date = getDateAsObject(fromDate);
1443
1586
  if (!isset(weekDayInt))
@@ -1446,26 +1589,31 @@ function nextWeekDay(fromDate, weekDayInt, outputFormat = 'date', sameDayAllowed
1446
1589
  date.setUTCDate(date.getUTCDate() + toAdd + (7 + weekDayInt - date.getUTCDay()) % 7);
1447
1590
  return getDateAs(date, outputFormat);
1448
1591
  }
1592
+ exports.nextWeekDay = nextWeekDay;
1449
1593
  function addDays(dateAllFormat = getDateAsInt(), numberOfDays = 1, outputFormat = 'date') {
1450
1594
  let date = getDateAsObject(dateAllFormat);
1451
1595
  date.setTime(date.getTime() + numberOfDays * 24 * 60 * 60 * 1000);
1452
1596
  return getDateAs(date, outputFormat);
1453
1597
  }
1598
+ exports.addDays = addDays;
1454
1599
  function addMinutes(dateAllFormat = getDateAsInt(), numberOfMinutes = 1, outputFormat = 'date') {
1455
1600
  let date = getDateAsObject(dateAllFormat);
1456
1601
  date.setTime(date.getTime() + 1 * numberOfMinutes * 60 * 1000);
1457
1602
  return getDateAs(date, outputFormat);
1458
1603
  }
1604
+ exports.addMinutes = addMinutes;
1459
1605
  function addHours(dateAllFormat = getDateAsInt(), numberOfHours = 1, outputFormat = 'date') {
1460
1606
  let date = getDateAsObject(dateAllFormat);
1461
1607
  date.setTime(date.getTime() + 1 * numberOfHours * 60 * 60 * 1000);
1462
1608
  return getDateAs(date, outputFormat);
1463
1609
  }
1610
+ exports.addHours = addHours;
1464
1611
  function addMonths(dateAllFormat = getDateAsInt(), numberOfMonths = 1, outputFormat = 'date') {
1465
1612
  let date = getDateAsObject(dateAllFormat);
1466
1613
  date.setUTCMonth(date.getUTCMonth() + numberOfMonths);
1467
1614
  return getDateAs(date, outputFormat);
1468
1615
  }
1616
+ exports.addMonths = addMonths;
1469
1617
  /**
1470
1618
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1471
1619
  */
@@ -1474,26 +1622,31 @@ function addYears(dateAllFormat = getDateAsInt(), numberOfYears = 1, outputForma
1474
1622
  date.setUTCFullYear(date.getUTCFullYear() + numberOfYears);
1475
1623
  return getDateAs(date, outputFormat);
1476
1624
  }
1625
+ exports.addYears = addYears;
1477
1626
  function getDayOfMonth(dateAllFormat = getDateAsInt()) {
1478
1627
  let dateAsInt = getDateAsInt(dateAllFormat);
1479
1628
  const [, , d] = dateStringToArray(dateAsInt);
1480
1629
  return d;
1481
1630
  }
1631
+ exports.getDayOfMonth = getDayOfMonth;
1482
1632
  function getYear(dateAllFormat = getDateAsInt()) {
1483
1633
  let dateAsInt = getDateAsInt(dateAllFormat);
1484
1634
  const [y] = dateStringToArray(dateAsInt);
1485
1635
  return y;
1486
1636
  }
1637
+ exports.getYear = getYear;
1487
1638
  function getHours(dateAllFormat = getDateAsInt()) {
1488
1639
  let dateAsInt = getDateAsInt(dateAllFormat);
1489
1640
  const [, , , h,] = dateStringToArray(dateAsInt);
1490
1641
  return h;
1491
1642
  }
1643
+ exports.getHours = getHours;
1492
1644
  function getMinutes(dateAllFormat = getDateAsInt()) {
1493
1645
  let dateAsInt = getDateAsInt(dateAllFormat);
1494
1646
  const [, , , , m] = dateStringToArray(dateAsInt);
1495
1647
  return m;
1496
1648
  }
1649
+ exports.getMinutes = getMinutes;
1497
1650
  /**
1498
1651
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1499
1652
  */
@@ -1503,6 +1656,7 @@ function lastDayOfMonth(dateAllFormat = getDateAsInt(), outputFormat = 'date') {
1503
1656
  lastDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
1504
1657
  return getDateAs(lastDay, outputFormat);
1505
1658
  }
1659
+ exports.lastDayOfMonth = lastDayOfMonth;
1506
1660
  /**
1507
1661
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1508
1662
  */
@@ -1512,30 +1666,34 @@ function firstDayOfMonth(dateAllFormat = getDateAsInt(), outputFormat = 'date')
1512
1666
  firstDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
1513
1667
  return getDateAs(firstDay, outputFormat);
1514
1668
  }
1669
+ exports.firstDayOfMonth = firstDayOfMonth;
1515
1670
  function differenceInMilliseconds(startDateAllFormat, endDateAllFormat) {
1516
1671
  const startDate = getDateAsObject(startDateAllFormat);
1517
1672
  const endDate = getDateAsObject(endDateAllFormat);
1518
1673
  return endDate.getTime() - startDate.getTime();
1519
1674
  }
1675
+ exports.differenceInMilliseconds = differenceInMilliseconds;
1520
1676
  function differenceInSeconds(startDateAllFormat, endDateAllFormat) {
1521
1677
  return differenceInMilliseconds(startDateAllFormat, endDateAllFormat) / 1000;
1522
1678
  }
1679
+ exports.differenceInSeconds = differenceInSeconds;
1523
1680
  function differenceInMinutes(startDateAllFormat, endDateAllFormat) {
1524
1681
  return differenceInSeconds(startDateAllFormat, endDateAllFormat) / 60;
1525
1682
  }
1683
+ exports.differenceInMinutes = differenceInMinutes;
1526
1684
  function differenceInHours(startDateAllFormat, endDateAllFormat) {
1527
1685
  return differenceInMinutes(startDateAllFormat, endDateAllFormat) / 60;
1528
1686
  }
1687
+ exports.differenceInHours = differenceInHours;
1529
1688
  function differenceInDays(startDateAllFormat, endDateAllFormat) {
1530
1689
  return differenceInHours(startDateAllFormat, endDateAllFormat) / 24;
1531
1690
  }
1691
+ exports.differenceInDays = differenceInDays;
1532
1692
  function differenceInWeeks(startDateAllFormat, endDateAllFormat) {
1533
1693
  return differenceInDays(startDateAllFormat, endDateAllFormat) / 7;
1534
1694
  }
1535
- /**
1536
- * @param {String} outputDateFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1537
- */
1538
- function getDateAs(dateAllFormat = new Date(), outputDateFormat = 'dateInt8') {
1695
+ exports.differenceInWeeks = differenceInWeeks;
1696
+ function getDateAs(dateAllFormat = new Date(), outputDateFormat = 'date') {
1539
1697
  switch (outputDateFormat) {
1540
1698
  case 'dateInt8':
1541
1699
  return getDateAsInt(dateAllFormat);
@@ -1731,6 +1889,7 @@ const C = {
1731
1889
  // DEPRECATED
1732
1890
  useTheme() { },
1733
1891
  };
1892
+ exports.C = C;
1734
1893
  function logErrPrivate(type, color, ...errors) {
1735
1894
  const { isProd } = configFn();
1736
1895
  if (errors.length === 1 && typeof errors[0].log === 'function')
@@ -1848,6 +2007,7 @@ function cliProgressBar(step, char = '.', msg = `\x1b[2mⓘ Waiting response`) {
1848
2007
  process.stdout.write(`${msg}${char.repeat(step)}\x1b[0m`); // \x1b[0m == reset color
1849
2008
  }
1850
2009
  }
2010
+ exports.cliProgressBar = cliProgressBar;
1851
2011
  /** This allow an intuitive inline loading spinner with a check mark when loading as finished or a red cross for errors */
1852
2012
  class cliLoadingSpinner {
1853
2013
  constructor(type = 'dots', activeProcess = process) {
@@ -1887,6 +2047,7 @@ class cliLoadingSpinner {
1887
2047
  return this.end(true);
1888
2048
  }
1889
2049
  }
2050
+ exports.cliLoadingSpinner = cliLoadingSpinner;
1890
2051
  //----------------------------------------
1891
2052
  // STRING UTILS
1892
2053
  //----------------------------------------
@@ -1912,6 +2073,7 @@ function convertAccentedCharacters(str, config = {}) {
1912
2073
  output = output.replace(/\s+/g, '');
1913
2074
  return output;
1914
2075
  }
2076
+ exports.convertAccentedCharacters = convertAccentedCharacters;
1915
2077
  //----------------------------------------
1916
2078
  // MONGO UTILS
1917
2079
  //----------------------------------------
@@ -1938,16 +2100,20 @@ function mongoFilterMerger(filterA, filterB, assignToFilterA = false) {
1938
2100
  else
1939
2101
  return { ...filterA, ...filterB };
1940
2102
  }
2103
+ exports.mongoFilterMerger = mongoFilterMerger;
1941
2104
  function mongoPush(field, value, fields) {
1942
2105
  if (!isset(fields.$push))
1943
2106
  fields.$push = {};
1944
2107
  fields.$push[field] = value;
1945
2108
  }
2109
+ exports.mongoPush = mongoPush;
1946
2110
  //----------------------------------------
1947
2111
  // TIMEOUT UTILS
1948
2112
  //----------------------------------------
1949
2113
  async function timeout(ms, fn = () => { }) { return new Promise(res => setTimeout(res, ms)).then(fn); }
2114
+ exports.timeout = timeout;
1950
2115
  async function runAsync(callback, milliseconds$ = 1) { return timeout(milliseconds$, callback); }
2116
+ exports.runAsync = runAsync;
1951
2117
  /**
1952
2118
  *
1953
2119
  * @param {Function} callback function that shall return ===true asynchronously
@@ -1971,6 +2137,7 @@ async function waitUntilTrue(callback, timeoutSec = 10, errorAfterNSeconds = tru
1971
2137
  if (!generalTimeout && errorAfterNSeconds)
1972
2138
  throw new dataValidationUtilErrorHandler(errMess, 500);
1973
2139
  }
2140
+ exports.waitUntilTrue = waitUntilTrue;
1974
2141
  const delayedLoopParams = [];
1975
2142
  let isExecuting = false;
1976
2143
  /** Allow to perform an action in a delayed loop, useful for example to avoid reaching limits on servers. This function can be securely called multiple times.
@@ -1995,6 +2162,7 @@ async function executeInDelayedLoop(callback, time = 500, errorCallback = e => C
1995
2162
  }
1996
2163
  isExecuting = false;
1997
2164
  }
2165
+ exports.executeInDelayedLoop = executeInDelayedLoop;
1998
2166
  //----------------------------------------
1999
2167
  // TRANSACTION
2000
2168
  //----------------------------------------
@@ -2036,6 +2204,7 @@ async function transaction(name, asyncCallback, timeout = 120000, doNotThrow = f
2036
2204
  removeItemFromQueue(name);
2037
2205
  });
2038
2206
  }
2207
+ exports.transaction = transaction;
2039
2208
  async function removeItemFromQueue(name) {
2040
2209
  if (transactionRunning[name] === true)
2041
2210
  return; // v
@@ -2057,6 +2226,7 @@ async function waitForTransaction(transactionName, forceReleaseInSeconds = 30) {
2057
2226
  await timeout(15);
2058
2227
  }
2059
2228
  }
2229
+ exports.waitForTransaction = waitForTransaction;
2060
2230
  const _ = {
2061
2231
  round,
2062
2232
  random,
@@ -2227,30 +2397,5 @@ const _ = {
2227
2397
  mongoPush,
2228
2398
  tryCatch,
2229
2399
  };
2230
- export default _;
2231
- export { round, random, cln, pad,
2232
- // ALIASES
2233
- int, minMax, generateToken, moyenne, average, sumArray, sortUrlsByDeepnessInArrayOrObject, urlPathJoin, miniTemplater, generateObjectId, isBetween, simpleObjectMaskOrSelect, ENV, parseBool, registerConfig, configFn, findByAddress, objForceWrite, objForceWriteIfNotSet, strAsArray, asArray, compareArrays, getArrayInCommon, getArrayDiff, getNotInArrayA, noDuplicateFilter, arrayCount, arrayToObjectSorted, pushIfNotExist, isNotEmptyArray, randomItemInArray,
2234
- //allias
2235
- arrayUniqueValue, deepClone, cloneObject, JSONstringyParse, has, isObject, mergeDeep, flattenObject, unflattenObject, recursiveGenericFunction, recursiveGenericFunctionSync, findByAddressAll, objFilterUndefined, readOnly, reassignForbidden, readOnlyForAll, mergeDeepOverrideArrays, mergeDeepConfigurable, objFilterUndefinedRecursive, removeUndefinedKeys, // alias
2236
- sortObjKeyAccordingToValue, ensureObjectProp, filterKeys, deleteByAddress, ensureIsArrayAndPush, removeCircularJSONstringify, isset, cleanStackTrace, shuffleArray, shuffleArray as randomizeArray, round2, forI, forIasync, camelCase, snakeCase, kebabCase, kebabCase as dashCase, snakeCase as underscoreCase, titleCase, pascalCase, lowerCase, upperCase, capitalize1st, camelCaseToWords, firstMatch, allMatches, getValuesBetweenSeparator, getValuesBetweenStrings, escapeRegexp, validator, validator as required, // alias for readability
2237
- validatorReturnErrArray, assert, restTestMini, isValid, isType, isDateObject, issetOr, isEmptyOrNotSet, errIfNotSet, err500IfNotSet, errIfEmptyOrNotSet, err500IfEmptyOrNotSet, errXXXIfNotSet, isEmpty, checkAllObjectValuesAreEmpty, checkCtxIntegrity,
2238
- // ALIASES
2239
- issetOr as orIsset,
2240
- // DATE
2241
- getDateAsInt12, humanReadableTimestamp, getDateAsInt, getDateAsObject, isDateIntOrStringValid, isDateIsoOrObjectValid, dateStringToArray, dateArray, dateArrayInt, dateFormatted as dateSlash, dateFormatted, dateOffset, getTimeAsInt, getIntAsTime, isTimeStringValid,
2242
- // isDateObject <= see validator.js
2243
- getDuration, doDateOverlap, getMonthAsInt, nextWeekDay, addMinutes, addHours, addDays, addMonths, addYears, getYear, getDayOfMonth, getHours, getMinutes, firstDayOfMonth, lastDayOfMonth, differenceInMilliseconds, differenceInSeconds, differenceInMinutes, differenceInHours, differenceInDays, differenceInWeeks,
2244
- // ALIASES
2245
- getDateAsInt as convertDateAsInt, getDateAsObject as convertDateAsObject,
2246
- // LOGGER
2247
- C, cliProgressBar, cliLoadingSpinner,
2248
- // STRING
2249
- convertAccentedCharacters,
2250
- // TIMEOUT
2251
- executeInDelayedLoop, timeout, runAsync, waitUntilTrue,
2252
- // TRANSACTION
2253
- transaction, waitForTransaction, getId, mergeMixins,
2254
- // MONGO
2255
- mongoFilterMerger, mongoPush, tryCatch, };
2400
+ exports.default = _;
2256
2401
  //# sourceMappingURL=utils.js.map