topkat-utils 1.0.44 → 1.0.47

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,6 +834,7 @@ 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
  */
@@ -776,6 +846,7 @@ function forI(nbIterations, callback) {
776
846
  }
777
847
  return results;
778
848
  }
849
+ exports.forI = forI;
779
850
  async function forIasync(nbIterations, callback) {
780
851
  const results = [];
781
852
  for (let i = 0; i < nbIterations; i++) {
@@ -783,6 +854,7 @@ async function forIasync(nbIterations, callback) {
783
854
  }
784
855
  return results;
785
856
  }
857
+ exports.forIasync = forIasync;
786
858
  function cleanStackTrace(stack) {
787
859
  if (typeof stack !== 'string')
788
860
  return '';
@@ -824,9 +896,11 @@ function cleanStackTrace(stack) {
824
896
  .join('\n');
825
897
  return linesClean;
826
898
  }
899
+ exports.cleanStackTrace = cleanStackTrace;
827
900
  function isset(...elms) {
828
901
  return elms.every(elm => typeof elm !== 'undefined' && elm !== null);
829
902
  }
903
+ exports.isset = isset;
830
904
  function removeCircularJSONstringify(object, indent = 2) {
831
905
  const getCircularReplacer = () => {
832
906
  const seen = new WeakSet();
@@ -842,6 +916,7 @@ function removeCircularJSONstringify(object, indent = 2) {
842
916
  };
843
917
  return JSON.stringify(object, getCircularReplacer(), indent);
844
918
  }
919
+ exports.removeCircularJSONstringify = removeCircularJSONstringify;
845
920
  function shuffleArray(array) {
846
921
  for (let i = array.length - 1; i > 0; i--) {
847
922
  const j = Math.floor(Math.random() * (i + 1));
@@ -849,16 +924,21 @@ function shuffleArray(array) {
849
924
  }
850
925
  return array;
851
926
  }
927
+ exports.shuffleArray = shuffleArray;
928
+ exports.randomizeArray = shuffleArray;
852
929
  /**Eg: camelCase */
853
930
  function camelCase(...wordBits) {
854
931
  return wordBits.filter(e => e).map((w, i) => i === 0 ? w : capitalize1st(w)).join('');
855
932
  }
933
+ exports.camelCase = camelCase;
856
934
  /**Eg: snake_case
857
935
  * trimmed but not lowerCased
858
936
  */
859
937
  function snakeCase(...wordBits) {
860
938
  return wordBits.filter(e => e).map(w => w.trim()).join('_');
861
939
  }
940
+ exports.snakeCase = snakeCase;
941
+ exports.underscoreCase = snakeCase;
862
942
  /**Eg: kebab-case
863
943
  * trimmed AND lowerCased
864
944
  * undefined, null... => ''
@@ -866,26 +946,34 @@ function snakeCase(...wordBits) {
866
946
  function kebabCase(...wordBits) {
867
947
  return wordBits.filter(e => e).map(w => w.trim().toLowerCase()).join('-');
868
948
  }
949
+ exports.kebabCase = kebabCase;
950
+ exports.dashCase = kebabCase;
869
951
  /**Eg: PascalCase undefined, null... => '' */
870
952
  function pascalCase(...wordBits) {
871
953
  return wordBits.filter(e => e).map((w, i) => capitalize1st(w)).join('');
872
954
  }
955
+ exports.pascalCase = pascalCase;
873
956
  /**Eg: Titlecase undefined, null... => '' */
874
957
  function titleCase(...wordBits) {
875
958
  return capitalize1st(wordBits.filter(e => e).map(w => w.trim()).join(''));
876
959
  }
960
+ exports.titleCase = titleCase;
877
961
  /**Eg: UPPERCASE undefined, null... => '' */
878
962
  function upperCase(...wordBits) {
879
963
  return wordBits.filter(e => e).map(w => w.trim().toUpperCase()).join('');
880
964
  }
965
+ exports.upperCase = upperCase;
881
966
  /**Eg: lowercase undefined, null... => '' */
882
967
  function lowerCase(...wordBits) {
883
968
  return wordBits.filter(e => e).map(w => w.trim().toLowerCase()).join('');
884
969
  }
970
+ exports.lowerCase = lowerCase;
885
971
  function capitalize1st(str = '') { return str[0].toUpperCase() + str.slice(1); }
972
+ exports.capitalize1st = capitalize1st;
886
973
  function camelCaseToWords(str) {
887
974
  return str ? str.trim().replace(/([A-Z])/g, '-$1').toLowerCase().split('-') : [];
888
975
  }
976
+ exports.camelCaseToWords = camelCaseToWords;
889
977
  function escapeRegexp(str, config = {}) {
890
978
  const { parseStarChar = false } = config;
891
979
  if (parseStarChar)
@@ -893,10 +981,12 @@ function escapeRegexp(str, config = {}) {
893
981
  else
894
982
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
895
983
  }
984
+ exports.escapeRegexp = escapeRegexp;
896
985
  /** Get first match of the first capturing group of regexp
897
986
  * Eg: const basePath = firstMatch(apiFile, /basePath = '(.*?)'/); will get what is inside quotes
898
987
  */
899
988
  function firstMatch(str, regExp) { return (str.match(regExp) || [])[1]; }
989
+ exports.firstMatch = firstMatch;
900
990
  /** Get all matches from regexp with g flag
901
991
  * Eg: [ [full, match1, m2], [f, m1, m2]... ]
902
992
  * NOTE: the G flag will be appended to regexp
@@ -919,6 +1009,7 @@ function allMatches(str, reg) {
919
1009
  }
920
1010
  return arr;
921
1011
  }
1012
+ exports.allMatches = allMatches;
922
1013
  /** GIVEN A STRING '{ blah;2}, ['nested,(what,ever)']' AND A SEPARATOR ",""
923
1014
  * This will return the content separated by first level of separators
924
1015
  * @return ["{ blah;2}", "['nested,(what,ever)']"]
@@ -928,6 +1019,7 @@ function getValuesBetweenSeparator(str, separator, removeTrailingSpaces = true)
928
1019
  const { outer } = getValuesBetweenStrings(str, separator, undefined, undefined, undefined, removeTrailingSpaces);
929
1020
  return outer;
930
1021
  }
1022
+ exports.getValuesBetweenSeparator = getValuesBetweenSeparator;
931
1023
  /** GIVEN A STRING "a: [ 'str', /[^]]/, '[aa]]]str', () => [ nestedArray ] ], b: ['arr']"
932
1024
  * @return matching: [ "'str', /[^]]/, '[aa]]]str', () => [ nestedArray ]", "'arr'" ], between: [ "a:", ", b: " ]
933
1025
  * @param str base string
@@ -995,12 +1087,20 @@ function getValuesBetweenStrings(str, openingOrSeparator, closing, ignoreBetween
995
1087
  const replaceValz = arr => arr.map(v => v.replace(/§§"/g, '<<').replace(/"§§/g, '>>')).filter(v => v);
996
1088
  return { inner: replaceValz(arrayValues), outer: replaceValz(betweenArray) };
997
1089
  }
1090
+ exports.getValuesBetweenStrings = getValuesBetweenStrings;
998
1091
  function issetOr(...elms) { return elms.some(elm => typeof elm !== 'undefined' && elm !== null); }
1092
+ exports.issetOr = issetOr;
1093
+ exports.orIsset = issetOr;
999
1094
  function isEmptyOrNotSet(...elms) { return elms.some(elm => !isset(elm) || isEmpty(elm)); }
1095
+ exports.isEmptyOrNotSet = isEmptyOrNotSet;
1000
1096
  function errIfNotSet(objOfVarNamesWithValues, additionalMessage) { return errXXXIfNotSet(422, false, objOfVarNamesWithValues); }
1097
+ exports.errIfNotSet = errIfNotSet;
1001
1098
  function err500IfNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, false, objOfVarNamesWithValues); }
1099
+ exports.err500IfNotSet = err500IfNotSet;
1002
1100
  function errIfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(422, true, objOfVarNamesWithValues); }
1101
+ exports.errIfEmptyOrNotSet = errIfEmptyOrNotSet;
1003
1102
  function err500IfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, true, objOfVarNamesWithValues); }
1103
+ exports.err500IfEmptyOrNotSet = err500IfEmptyOrNotSet;
1004
1104
  function errXXXIfNotSet(errCode, checkEmpty, objOfVarNamesWithValues) {
1005
1105
  let missingVars = [];
1006
1106
  for (let prop in objOfVarNamesWithValues) {
@@ -1010,19 +1110,25 @@ function errXXXIfNotSet(errCode, checkEmpty, objOfVarNamesWithValues) {
1010
1110
  if (missingVars.length)
1011
1111
  throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, errCode, { origin: 'Validator', varNames: missingVars.join(', ') });
1012
1112
  }
1113
+ exports.errXXXIfNotSet = errXXXIfNotSet;
1013
1114
  function isDateObject(variable) { return variable instanceof Date; }
1115
+ exports.isDateObject = isDateObject;
1014
1116
  /** Check all values are set */
1015
1117
  function checkAllObjectValuesAreEmpty(o) { return Object.values(o).every(value => !isset(value)); }
1118
+ exports.checkAllObjectValuesAreEmpty = checkAllObjectValuesAreEmpty;
1016
1119
  /** Throw an error in case data passed is not a valid ctx */
1017
1120
  function checkCtxIntegrity(ctx) {
1018
1121
  if (!isset(ctx) || !isset(ctx.user))
1019
1122
  throw new dataValidationUtilErrorHandler('ctxNotSet', 500);
1020
1123
  }
1124
+ exports.checkCtxIntegrity = checkCtxIntegrity;
1021
1125
  function validator(...paramsToValidate) {
1022
1126
  const errArray = validatorReturnErrArray(...paramsToValidate);
1023
1127
  if (errArray.length)
1024
1128
  throw new dataValidationUtilErrorHandler(...errArray);
1025
1129
  }
1130
+ exports.validator = validator;
1131
+ exports.required = validator;
1026
1132
  const restTestMini = {
1027
1133
  throwOnErr: false,
1028
1134
  reset(throwOnErr = false) {
@@ -1056,6 +1162,7 @@ const restTestMini = {
1056
1162
  nbError: 0,
1057
1163
  lastErrors: []
1058
1164
  };
1165
+ exports.restTestMini = restTestMini;
1059
1166
  function assert(msg, value, validatorObject = {}) {
1060
1167
  try {
1061
1168
  if (typeof validatorObject !== 'object')
@@ -1078,6 +1185,7 @@ function assert(msg, value, validatorObject = {}) {
1078
1185
  restTestMini.newErr(err);
1079
1186
  }
1080
1187
  }
1188
+ exports.assert = assert;
1081
1189
  /** Same as validator but return a boolean
1082
1190
  * See {@link validator}
1083
1191
  */
@@ -1085,10 +1193,12 @@ function isValid(...paramsToValidate) {
1085
1193
  const errArray = validatorReturnErrArray(...paramsToValidate);
1086
1194
  return errArray.length ? false : true;
1087
1195
  }
1196
+ exports.isValid = isValid;
1088
1197
  /** Default types + custom types
1089
1198
  * 'objectId','dateInt6','dateInt','dateInt8','dateInt12','time','humanReadableTimestamp','date','array','object','buffer','string','function','boolean','number','bigint',
1090
1199
  */
1091
1200
  function isType(value, type) { return isValid({ name: 'Is type check', value, type }); }
1201
+ exports.isType = isType;
1092
1202
  function validatorReturnErrArray(...paramsToValidate) {
1093
1203
  let paramsFormatted = [];
1094
1204
  // support for multiple names with multiple values for one rule. Eg: {name: [{startDate:'20180101'}, {endDate:'20180101'}], type: 'dateInt8'}
@@ -1129,10 +1239,18 @@ function validatorReturnErrArray(...paramsToValidate) {
1129
1239
  return errMess('requiredVariableEmptyOrNotSet');
1130
1240
  if (!emptyAllowed && value === '')
1131
1241
  return errMess('requiredVariableEmpty');
1242
+ const isArray = paramObj.isArray;
1243
+ if (isArray && !Array.isArray(value))
1244
+ return errMess('wrongTypeForVar', { expectedTypes: 'array', gotType: typeof value });
1132
1245
  // TYPE
1133
1246
  if (isset(paramObj.type)) {
1134
- const types = Array.isArray(paramObj.type) ? paramObj.type : [paramObj.type]; // support for multiple type
1247
+ const types = asArray(paramObj.type); // support for multiple type
1135
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
+ }
1136
1254
  const allTypes = [
1137
1255
  'objectId',
1138
1256
  'dateInt6',
@@ -1152,6 +1270,7 @@ function validatorReturnErrArray(...paramsToValidate) {
1152
1270
  'number',
1153
1271
  'bigint',
1154
1272
  'year',
1273
+ 'any',
1155
1274
  //...Object.keys(configFn().customTypes)
1156
1275
  ];
1157
1276
  if (!allTypes.includes(type))
@@ -1169,7 +1288,8 @@ function validatorReturnErrArray(...paramsToValidate) {
1169
1288
  array: val => Array.isArray(val),
1170
1289
  object: val => !Array.isArray(val) && val !== null && typeof val === type,
1171
1290
  buffer: val => Buffer.isBuffer(val),
1172
- year: val => /^\d\d\d\d$/.test(val)
1291
+ year: val => /^\d\d\d\d$/.test(val),
1292
+ any: () => true,
1173
1293
  };
1174
1294
  return isset(basicTypeCheck[type]) && basicTypeCheck[type](value) ||
1175
1295
  typeof value === type && type !== 'object' || // for string, number, boolean...
@@ -1221,6 +1341,7 @@ function validatorReturnErrArray(...paramsToValidate) {
1221
1341
  }
1222
1342
  return [];
1223
1343
  }
1344
+ exports.validatorReturnErrArray = validatorReturnErrArray;
1224
1345
  function isEmpty(objOrArr) {
1225
1346
  if (Array.isArray(objOrArr) || typeof objOrArr === 'string')
1226
1347
  return objOrArr.length === 0;
@@ -1229,6 +1350,7 @@ function isEmpty(objOrArr) {
1229
1350
  else
1230
1351
  false;
1231
1352
  }
1353
+ exports.isEmpty = isEmpty;
1232
1354
  function err422IfNotSet(o) {
1233
1355
  let m = [];
1234
1356
  for (let p in o)
@@ -1238,11 +1360,13 @@ function err422IfNotSet(o) {
1238
1360
  throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, 422, { origin: 'Validator', varNames: m.join(', ') });
1239
1361
  }
1240
1362
  function getDateAsInt12(dateAllFormat, errIfNotValid) { return getDateAsInt(dateAllFormat, errIfNotValid, true); } // alias
1363
+ exports.getDateAsInt12 = getDateAsInt12;
1241
1364
  function humanReadableTimestamp(dateAllFormat) {
1242
1365
  if (isset(dateAllFormat))
1243
1366
  dateAllFormat = getDateAsObject(dateAllFormat);
1244
1367
  return parseInt(getDateAsInt12(dateAllFormat) + pad((dateAllFormat || new Date()).getUTCSeconds()) + pad((dateAllFormat || new Date()).getUTCMilliseconds(), 3));
1245
1368
  }
1369
+ exports.humanReadableTimestamp = humanReadableTimestamp;
1246
1370
  /** format for 6/8/2018 => 20180806
1247
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
1248
1372
  */
@@ -1268,6 +1392,8 @@ function getDateAsInt(dateAllFormat = new Date(), errIfNotValid$ = false, withHo
1268
1392
  isDateIntOrStringValid(dateInt, errIfNotValid$);
1269
1393
  return (withHoursAndMinutes$ ? dateInt : dateInt.substr(0, 8));
1270
1394
  }
1395
+ exports.getDateAsInt = getDateAsInt;
1396
+ exports.convertDateAsInt = getDateAsInt;
1271
1397
  function getMonthAsInt(dateAllFormat = new Date()) {
1272
1398
  let dateInt;
1273
1399
  if (isDateIntOrStringValid(dateAllFormat)) {
@@ -1283,6 +1409,7 @@ function getMonthAsInt(dateAllFormat = new Date()) {
1283
1409
  }
1284
1410
  return int(dateInt);
1285
1411
  }
1412
+ exports.getMonthAsInt = getMonthAsInt;
1286
1413
  /**
1287
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
1288
1415
  */
@@ -1301,6 +1428,8 @@ function getDateAsObject(dateAllFormat = new Date(), errIfNotValid$ = true) {
1301
1428
  isDateIsoOrObjectValid(dateObj, errIfNotValid$);
1302
1429
  return dateObj;
1303
1430
  }
1431
+ exports.getDateAsObject = getDateAsObject;
1432
+ exports.convertDateAsObject = getDateAsObject;
1304
1433
  function isDateIntOrStringValid(dateStringOrInt, outputAnError = false, length) {
1305
1434
  if (!isset(dateStringOrInt))
1306
1435
  return false;
@@ -1320,6 +1449,7 @@ function isDateIntOrStringValid(dateStringOrInt, outputAnError = false, length)
1320
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 });
1321
1450
  return true;
1322
1451
  }
1452
+ exports.isDateIntOrStringValid = isDateIntOrStringValid;
1323
1453
  function isDateIsoOrObjectValid(dateIsoOrObj, outputAnError = false) {
1324
1454
  let dateObj = dateIsoOrObj;
1325
1455
  if (typeof dateIsoOrObj === 'string')
@@ -1329,6 +1459,7 @@ function isDateIsoOrObjectValid(dateIsoOrObj, outputAnError = false) {
1329
1459
  throw new dataValidationUtilErrorHandler('dateIsoStringOrObjectIsNotValid', 422, { origin: 'Date Object validator', isoDate: dateIsoOrObj });
1330
1460
  return valid;
1331
1461
  }
1462
+ exports.isDateIsoOrObjectValid = isDateIsoOrObjectValid;
1332
1463
  /** [2018,01,06] */
1333
1464
  function dateStringToArray(strOrInt) {
1334
1465
  err422IfNotSet({ strOrInt });
@@ -1343,6 +1474,7 @@ function dateStringToArray(strOrInt) {
1343
1474
  dateStr.substr(14, 3) || '000', // MS
1344
1475
  ];
1345
1476
  }
1477
+ exports.dateStringToArray = dateStringToArray;
1346
1478
  /**
1347
1479
  * @param dateAllFormat default: actualDate
1348
1480
  * @returns ['01', '01', '2019'] OR **string** if separator is provided */
@@ -1354,6 +1486,7 @@ function dateArray(dateAllFormat = getDateAsInt()) {
1354
1486
  dateStr.substr(0, 4), // Y
1355
1487
  ];
1356
1488
  }
1489
+ exports.dateArray = dateArray;
1357
1490
  /**
1358
1491
  * @param dateAllFormat default: actualDate
1359
1492
  * @returns ['01', '01', '2019'] OR **string** if separator is provided */
@@ -1365,15 +1498,19 @@ function dateArrayInt(dateAllFormat = getDateAsInt()) {
1365
1498
  int(dateStr.substr(0, 4)), // Y
1366
1499
  ];
1367
1500
  }
1501
+ exports.dateArrayInt = dateArrayInt;
1368
1502
  /**
1369
1503
  * @return 01/01/2012 (alias of dateArrayFormatted(date, '/'))
1370
1504
  */
1371
1505
  function dateFormatted(dateAllFormat, separator = '/') { return dateArray(dateAllFormat).join(separator); }
1506
+ exports.dateSlash = dateFormatted;
1507
+ exports.dateFormatted = dateFormatted;
1372
1508
  /** Date with custom offset (Ex: +2 for France) */
1373
1509
  function dateOffset(offsetHours, dateObj = new Date()) {
1374
1510
  var utc = Date.UTC(dateObj.getUTCFullYear(), dateObj.getUTCMonth(), dateObj.getUTCDate(), dateObj.getUTCHours(), dateObj.getUTCMinutes(), dateObj.getUTCSeconds());
1375
1511
  return new Date(utc + (3600000 * offsetHours));
1376
1512
  }
1513
+ exports.dateOffset = dateOffset;
1377
1514
  //----------------------------------------
1378
1515
  // TIME UTILS
1379
1516
  //----------------------------------------
@@ -1388,6 +1525,7 @@ function getTimeAsInt(timeOrDateInt = getDateAsInt12()) {
1388
1525
  else
1389
1526
  return 'dateInvalid';
1390
1527
  }
1528
+ exports.getTimeAsInt = getTimeAsInt;
1391
1529
  /**
1392
1530
  * @param {timeInt|dateInt12} Eg: 2222 OR 201201012222. Default, actual dateInt12
1393
1531
  * @param {String} separator default: ":"
@@ -1397,6 +1535,7 @@ function getIntAsTime(intOrDateTimeInt = getDateAsInt12(), separator = ':') {
1397
1535
  const tl = time.length;
1398
1536
  return time.substring(tl - 4, tl - 2) + separator + time.substring(tl - 2, tl);
1399
1537
  }
1538
+ exports.getIntAsTime = getIntAsTime;
1400
1539
  function isTimeStringValid(timeStr, outputAnError$ = false) {
1401
1540
  let timeArr = timeStr.split(':');
1402
1541
  let h = int(timeArr[0]);
@@ -1408,6 +1547,7 @@ function isTimeStringValid(timeStr, outputAnError$ = false) {
1408
1547
  else
1409
1548
  return test1 && test2;
1410
1549
  }
1550
+ exports.isTimeStringValid = isTimeStringValid;
1411
1551
  //----------------------------------------
1412
1552
  // DURATIONS
1413
1553
  //----------------------------------------
@@ -1424,6 +1564,7 @@ function getDuration(startDate, endDate, inMinutes = false) {
1424
1564
  Math.floor(((diffInSec % (24 * 3600)) % 3600) / 60), // M
1425
1565
  ];
1426
1566
  }
1567
+ exports.getDuration = getDuration;
1427
1568
  /** compare two object with DATE INT, if they overlap return true
1428
1569
  * @param {Object} event1 {startDate, endDate}
1429
1570
  * @param {Object} event2 {startDate, endDate}
@@ -1439,6 +1580,7 @@ function doDateOverlap(event1, event2, fieldNameForStartDate$ = 'startDate', fie
1439
1580
  return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] < event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] > event2[fieldNameForStartDate$]);
1440
1581
  return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] <= event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] >= event2[fieldNameForStartDate$]);
1441
1582
  }
1583
+ exports.doDateOverlap = doDateOverlap;
1442
1584
  function nextWeekDay(fromDate, weekDayInt, outputFormat = 'date', sameDayAllowed = false) {
1443
1585
  const date = getDateAsObject(fromDate);
1444
1586
  if (!isset(weekDayInt))
@@ -1447,26 +1589,31 @@ function nextWeekDay(fromDate, weekDayInt, outputFormat = 'date', sameDayAllowed
1447
1589
  date.setUTCDate(date.getUTCDate() + toAdd + (7 + weekDayInt - date.getUTCDay()) % 7);
1448
1590
  return getDateAs(date, outputFormat);
1449
1591
  }
1592
+ exports.nextWeekDay = nextWeekDay;
1450
1593
  function addDays(dateAllFormat = getDateAsInt(), numberOfDays = 1, outputFormat = 'date') {
1451
1594
  let date = getDateAsObject(dateAllFormat);
1452
1595
  date.setTime(date.getTime() + numberOfDays * 24 * 60 * 60 * 1000);
1453
1596
  return getDateAs(date, outputFormat);
1454
1597
  }
1598
+ exports.addDays = addDays;
1455
1599
  function addMinutes(dateAllFormat = getDateAsInt(), numberOfMinutes = 1, outputFormat = 'date') {
1456
1600
  let date = getDateAsObject(dateAllFormat);
1457
1601
  date.setTime(date.getTime() + 1 * numberOfMinutes * 60 * 1000);
1458
1602
  return getDateAs(date, outputFormat);
1459
1603
  }
1604
+ exports.addMinutes = addMinutes;
1460
1605
  function addHours(dateAllFormat = getDateAsInt(), numberOfHours = 1, outputFormat = 'date') {
1461
1606
  let date = getDateAsObject(dateAllFormat);
1462
1607
  date.setTime(date.getTime() + 1 * numberOfHours * 60 * 60 * 1000);
1463
1608
  return getDateAs(date, outputFormat);
1464
1609
  }
1610
+ exports.addHours = addHours;
1465
1611
  function addMonths(dateAllFormat = getDateAsInt(), numberOfMonths = 1, outputFormat = 'date') {
1466
1612
  let date = getDateAsObject(dateAllFormat);
1467
1613
  date.setUTCMonth(date.getUTCMonth() + numberOfMonths);
1468
1614
  return getDateAs(date, outputFormat);
1469
1615
  }
1616
+ exports.addMonths = addMonths;
1470
1617
  /**
1471
1618
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1472
1619
  */
@@ -1475,26 +1622,31 @@ function addYears(dateAllFormat = getDateAsInt(), numberOfYears = 1, outputForma
1475
1622
  date.setUTCFullYear(date.getUTCFullYear() + numberOfYears);
1476
1623
  return getDateAs(date, outputFormat);
1477
1624
  }
1625
+ exports.addYears = addYears;
1478
1626
  function getDayOfMonth(dateAllFormat = getDateAsInt()) {
1479
1627
  let dateAsInt = getDateAsInt(dateAllFormat);
1480
1628
  const [, , d] = dateStringToArray(dateAsInt);
1481
1629
  return d;
1482
1630
  }
1631
+ exports.getDayOfMonth = getDayOfMonth;
1483
1632
  function getYear(dateAllFormat = getDateAsInt()) {
1484
1633
  let dateAsInt = getDateAsInt(dateAllFormat);
1485
1634
  const [y] = dateStringToArray(dateAsInt);
1486
1635
  return y;
1487
1636
  }
1637
+ exports.getYear = getYear;
1488
1638
  function getHours(dateAllFormat = getDateAsInt()) {
1489
1639
  let dateAsInt = getDateAsInt(dateAllFormat);
1490
1640
  const [, , , h,] = dateStringToArray(dateAsInt);
1491
1641
  return h;
1492
1642
  }
1643
+ exports.getHours = getHours;
1493
1644
  function getMinutes(dateAllFormat = getDateAsInt()) {
1494
1645
  let dateAsInt = getDateAsInt(dateAllFormat);
1495
1646
  const [, , , , m] = dateStringToArray(dateAsInt);
1496
1647
  return m;
1497
1648
  }
1649
+ exports.getMinutes = getMinutes;
1498
1650
  /**
1499
1651
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1500
1652
  */
@@ -1504,6 +1656,7 @@ function lastDayOfMonth(dateAllFormat = getDateAsInt(), outputFormat = 'date') {
1504
1656
  lastDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
1505
1657
  return getDateAs(lastDay, outputFormat);
1506
1658
  }
1659
+ exports.lastDayOfMonth = lastDayOfMonth;
1507
1660
  /**
1508
1661
  * @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
1509
1662
  */
@@ -1513,26 +1666,33 @@ function firstDayOfMonth(dateAllFormat = getDateAsInt(), outputFormat = 'date')
1513
1666
  firstDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
1514
1667
  return getDateAs(firstDay, outputFormat);
1515
1668
  }
1669
+ exports.firstDayOfMonth = firstDayOfMonth;
1516
1670
  function differenceInMilliseconds(startDateAllFormat, endDateAllFormat) {
1517
1671
  const startDate = getDateAsObject(startDateAllFormat);
1518
1672
  const endDate = getDateAsObject(endDateAllFormat);
1519
1673
  return endDate.getTime() - startDate.getTime();
1520
1674
  }
1675
+ exports.differenceInMilliseconds = differenceInMilliseconds;
1521
1676
  function differenceInSeconds(startDateAllFormat, endDateAllFormat) {
1522
1677
  return differenceInMilliseconds(startDateAllFormat, endDateAllFormat) / 1000;
1523
1678
  }
1679
+ exports.differenceInSeconds = differenceInSeconds;
1524
1680
  function differenceInMinutes(startDateAllFormat, endDateAllFormat) {
1525
1681
  return differenceInSeconds(startDateAllFormat, endDateAllFormat) / 60;
1526
1682
  }
1683
+ exports.differenceInMinutes = differenceInMinutes;
1527
1684
  function differenceInHours(startDateAllFormat, endDateAllFormat) {
1528
1685
  return differenceInMinutes(startDateAllFormat, endDateAllFormat) / 60;
1529
1686
  }
1687
+ exports.differenceInHours = differenceInHours;
1530
1688
  function differenceInDays(startDateAllFormat, endDateAllFormat) {
1531
1689
  return differenceInHours(startDateAllFormat, endDateAllFormat) / 24;
1532
1690
  }
1691
+ exports.differenceInDays = differenceInDays;
1533
1692
  function differenceInWeeks(startDateAllFormat, endDateAllFormat) {
1534
1693
  return differenceInDays(startDateAllFormat, endDateAllFormat) / 7;
1535
1694
  }
1695
+ exports.differenceInWeeks = differenceInWeeks;
1536
1696
  function getDateAs(dateAllFormat = new Date(), outputDateFormat = 'date') {
1537
1697
  switch (outputDateFormat) {
1538
1698
  case 'dateInt8':
@@ -1729,6 +1889,7 @@ const C = {
1729
1889
  // DEPRECATED
1730
1890
  useTheme() { },
1731
1891
  };
1892
+ exports.C = C;
1732
1893
  function logErrPrivate(type, color, ...errors) {
1733
1894
  const { isProd } = configFn();
1734
1895
  if (errors.length === 1 && typeof errors[0].log === 'function')
@@ -1846,6 +2007,7 @@ function cliProgressBar(step, char = '.', msg = `\x1b[2mⓘ Waiting response`) {
1846
2007
  process.stdout.write(`${msg}${char.repeat(step)}\x1b[0m`); // \x1b[0m == reset color
1847
2008
  }
1848
2009
  }
2010
+ exports.cliProgressBar = cliProgressBar;
1849
2011
  /** This allow an intuitive inline loading spinner with a check mark when loading as finished or a red cross for errors */
1850
2012
  class cliLoadingSpinner {
1851
2013
  constructor(type = 'dots', activeProcess = process) {
@@ -1885,6 +2047,7 @@ class cliLoadingSpinner {
1885
2047
  return this.end(true);
1886
2048
  }
1887
2049
  }
2050
+ exports.cliLoadingSpinner = cliLoadingSpinner;
1888
2051
  //----------------------------------------
1889
2052
  // STRING UTILS
1890
2053
  //----------------------------------------
@@ -1910,6 +2073,7 @@ function convertAccentedCharacters(str, config = {}) {
1910
2073
  output = output.replace(/\s+/g, '');
1911
2074
  return output;
1912
2075
  }
2076
+ exports.convertAccentedCharacters = convertAccentedCharacters;
1913
2077
  //----------------------------------------
1914
2078
  // MONGO UTILS
1915
2079
  //----------------------------------------
@@ -1936,16 +2100,20 @@ function mongoFilterMerger(filterA, filterB, assignToFilterA = false) {
1936
2100
  else
1937
2101
  return { ...filterA, ...filterB };
1938
2102
  }
2103
+ exports.mongoFilterMerger = mongoFilterMerger;
1939
2104
  function mongoPush(field, value, fields) {
1940
2105
  if (!isset(fields.$push))
1941
2106
  fields.$push = {};
1942
2107
  fields.$push[field] = value;
1943
2108
  }
2109
+ exports.mongoPush = mongoPush;
1944
2110
  //----------------------------------------
1945
2111
  // TIMEOUT UTILS
1946
2112
  //----------------------------------------
1947
2113
  async function timeout(ms, fn = () => { }) { return new Promise(res => setTimeout(res, ms)).then(fn); }
2114
+ exports.timeout = timeout;
1948
2115
  async function runAsync(callback, milliseconds$ = 1) { return timeout(milliseconds$, callback); }
2116
+ exports.runAsync = runAsync;
1949
2117
  /**
1950
2118
  *
1951
2119
  * @param {Function} callback function that shall return ===true asynchronously
@@ -1969,6 +2137,7 @@ async function waitUntilTrue(callback, timeoutSec = 10, errorAfterNSeconds = tru
1969
2137
  if (!generalTimeout && errorAfterNSeconds)
1970
2138
  throw new dataValidationUtilErrorHandler(errMess, 500);
1971
2139
  }
2140
+ exports.waitUntilTrue = waitUntilTrue;
1972
2141
  const delayedLoopParams = [];
1973
2142
  let isExecuting = false;
1974
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.
@@ -1993,6 +2162,7 @@ async function executeInDelayedLoop(callback, time = 500, errorCallback = e => C
1993
2162
  }
1994
2163
  isExecuting = false;
1995
2164
  }
2165
+ exports.executeInDelayedLoop = executeInDelayedLoop;
1996
2166
  //----------------------------------------
1997
2167
  // TRANSACTION
1998
2168
  //----------------------------------------
@@ -2034,6 +2204,7 @@ async function transaction(name, asyncCallback, timeout = 120000, doNotThrow = f
2034
2204
  removeItemFromQueue(name);
2035
2205
  });
2036
2206
  }
2207
+ exports.transaction = transaction;
2037
2208
  async function removeItemFromQueue(name) {
2038
2209
  if (transactionRunning[name] === true)
2039
2210
  return; // v
@@ -2055,6 +2226,7 @@ async function waitForTransaction(transactionName, forceReleaseInSeconds = 30) {
2055
2226
  await timeout(15);
2056
2227
  }
2057
2228
  }
2229
+ exports.waitForTransaction = waitForTransaction;
2058
2230
  const _ = {
2059
2231
  round,
2060
2232
  random,
@@ -2225,30 +2397,5 @@ const _ = {
2225
2397
  mongoPush,
2226
2398
  tryCatch,
2227
2399
  };
2228
- export default _;
2229
- export { round, random, cln, pad,
2230
- // ALIASES
2231
- 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,
2232
- //allias
2233
- arrayUniqueValue, deepClone, cloneObject, JSONstringyParse, has, isObject, mergeDeep, flattenObject, unflattenObject, recursiveGenericFunction, recursiveGenericFunctionSync, findByAddressAll, objFilterUndefined, readOnly, reassignForbidden, readOnlyForAll, mergeDeepOverrideArrays, mergeDeepConfigurable, objFilterUndefinedRecursive, removeUndefinedKeys, // alias
2234
- 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
2235
- validatorReturnErrArray, assert, restTestMini, isValid, isType, isDateObject, issetOr, isEmptyOrNotSet, errIfNotSet, err500IfNotSet, errIfEmptyOrNotSet, err500IfEmptyOrNotSet, errXXXIfNotSet, isEmpty, checkAllObjectValuesAreEmpty, checkCtxIntegrity,
2236
- // ALIASES
2237
- issetOr as orIsset,
2238
- // DATE
2239
- getDateAsInt12, humanReadableTimestamp, getDateAsInt, getDateAsObject, isDateIntOrStringValid, isDateIsoOrObjectValid, dateStringToArray, dateArray, dateArrayInt, dateFormatted as dateSlash, dateFormatted, dateOffset, getTimeAsInt, getIntAsTime, isTimeStringValid,
2240
- // isDateObject <= see validator.js
2241
- getDuration, doDateOverlap, getMonthAsInt, nextWeekDay, addMinutes, addHours, addDays, addMonths, addYears, getYear, getDayOfMonth, getHours, getMinutes, firstDayOfMonth, lastDayOfMonth, differenceInMilliseconds, differenceInSeconds, differenceInMinutes, differenceInHours, differenceInDays, differenceInWeeks,
2242
- // ALIASES
2243
- getDateAsInt as convertDateAsInt, getDateAsObject as convertDateAsObject,
2244
- // LOGGER
2245
- C, cliProgressBar, cliLoadingSpinner,
2246
- // STRING
2247
- convertAccentedCharacters,
2248
- // TIMEOUT
2249
- executeInDelayedLoop, timeout, runAsync, waitUntilTrue,
2250
- // TRANSACTION
2251
- transaction, waitForTransaction, getId, mergeMixins,
2252
- // MONGO
2253
- mongoFilterMerger, mongoPush, tryCatch, };
2400
+ exports.default = _;
2254
2401
  //# sourceMappingURL=utils.js.map