topkat-utils 1.2.116 → 1.3.3

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.
Files changed (51) hide show
  1. package/README.md +260 -219
  2. package/coverage/clover.xml +533 -433
  3. package/coverage/coverage-final.json +9 -9
  4. package/coverage/lcov-report/clean-stack-trace.ts.html +1 -1
  5. package/coverage/lcov-report/config.ts.html +2 -2
  6. package/coverage/lcov-report/error-utils.ts.html +2 -2
  7. package/coverage/lcov-report/index.html +50 -50
  8. package/coverage/lcov-report/is-empty.ts.html +1 -1
  9. package/coverage/lcov-report/is-nodejs.ts.html +1 -1
  10. package/coverage/lcov-report/is-object.ts.html +1 -1
  11. package/coverage/lcov-report/isset.ts.html +1 -1
  12. package/coverage/lcov-report/logger-utils.ts.html +65 -50
  13. package/coverage/lcov-report/loop-utils.ts.html +179 -8
  14. package/coverage/lcov-report/math-utils.ts.html +35 -8
  15. package/coverage/lcov-report/object-utils.ts.html +20 -8
  16. package/coverage/lcov-report/regexp-utils.ts.html +45 -12
  17. package/coverage/lcov-report/remove-circular-json-stringify.ts.html +1 -1
  18. package/coverage/lcov-report/string-utils.ts.html +54 -12
  19. package/coverage/lcov-report/timer-utils.ts.html +2 -2
  20. package/coverage/lcov-report/transaction-utils.ts.html +1 -1
  21. package/coverage/lcov.info +634 -559
  22. package/dist/src/error-utils.js +1 -1
  23. package/dist/src/error-utils.js.map +1 -1
  24. package/dist/src/logger-utils.js +3 -0
  25. package/dist/src/logger-utils.js.map +1 -1
  26. package/dist/src/loop-utils.d.ts +54 -2
  27. package/dist/src/loop-utils.js +48 -2
  28. package/dist/src/loop-utils.js.map +1 -1
  29. package/dist/src/math-utils.d.ts +1 -1
  30. package/dist/src/math-utils.js +6 -2
  31. package/dist/src/math-utils.js.map +1 -1
  32. package/dist/src/object-utils.d.ts +3 -1
  33. package/dist/src/object-utils.js +7 -4
  34. package/dist/src/object-utils.js.map +1 -1
  35. package/dist/src/regexp-utils.d.ts +9 -4
  36. package/dist/src/regexp-utils.js +8 -5
  37. package/dist/src/regexp-utils.js.map +1 -1
  38. package/dist/src/string-utils.d.ts +13 -4
  39. package/dist/src/string-utils.js +16 -6
  40. package/dist/src/string-utils.js.map +1 -1
  41. package/dist/src/timer-utils.d.ts +1 -1
  42. package/dist/src/timer-utils.js +1 -1
  43. package/package.json +45 -8
  44. package/src/error-utils.ts +1 -1
  45. package/src/logger-utils.ts +5 -0
  46. package/src/loop-utils.ts +59 -2
  47. package/src/math-utils.ts +11 -2
  48. package/src/object-utils.ts +6 -2
  49. package/src/regexp-utils.ts +17 -6
  50. package/src/string-utils.ts +19 -5
  51. package/src/timer-utils.ts +1 -1
package/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ # Topkat Utils
1
2
 
2
3
  ```
3
4
  |\_____/| ▀▀▀█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ |\_____/|
@@ -6,225 +7,265 @@
6
7
  \__^__/ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀▀ \__^__/
7
8
  ```
8
9
 
9
- ⚡️ Fast, functional and typed utils ⚡️
10
-
11
- ``` javascript
12
- const topkatUtils = {
13
- isset, // check undefined or null values but not falsey
14
- random, // random number between two values
15
- cln, // clean string for print. Eg: undefined, null, NaN => '-'
16
- pad, // simple padStart for numbers
17
- isObject, // check is value is a "straight" object (not null, not date, not an array, not undefined...)
18
- /** return the number or the closest number of the range
19
- * * nb min max => returns
20
- * * 7 5 10 => 7 // in the range
21
- * * 2 5 10 => 5 // below the min value
22
- * * 99 5 10 => 10// above the max value
23
- */
24
- minMax, //
25
- generateToken(length, isUnique, mode: 'alphanumeric' | 'hexadecimal' = 'alphanumeric'): string,
26
- // average between array of values. Eg: [5, 15] => 10
27
- average,
28
- // sum values in an array
29
- sumArray,
30
- // sort an array of urls (useful for expressJs or react router. It avoid generic route home/ to take precedence over a more specific route like home/dshboard1)
31
- sortUrlsByDeepnessInArrayOrObject,
32
- // like nodeJs path.join() but for urls
33
- urlPathJoin,
34
- // miniTemplater(`Hello {{name}}`, { name: 'John' }) => `Hello John`
35
- miniTemplater,
36
- asArray,
37
- compareArrays,
38
- // is number between
39
- isBetween,
40
- simpleObjectMaskOrSelect,
41
- // get the environment variables (Eg. NODE_ENV) with parsed values ("true" => true, "4" => 4). On env variables all values are strings
42
- ENV,
43
- parseBool,
44
-
45
- registerConfig,
46
- configFn,
47
- findByAddress,
48
- objForceWrite,
49
- objForceWriteIfNotSet,
50
-
51
-
52
-
53
- strAsArray,
54
- getArrayInCommon,
55
- getArrayDiff,
56
- getNotInArrayA,
57
- noDuplicateFilter,
58
- pushIfNotExist,
59
- isNotEmptyArray,
60
- randomItemInArray,
61
- //allias
62
- arrayUniqueValue,
63
-
64
-
65
- deepClone,
66
- cloneObject,
67
- JSONstringyParse,
68
- has,
69
- isObject,
70
- mergeDeep,
71
- flattenObject,
72
- unflattenObject,
73
- recursiveGenericFunction,
74
- recursiveGenericFunctionSync,
75
- findByAddressAll,
76
- objFilterUndefined,
77
- readOnly,
78
- reassignForbidden,
79
- readOnlyForAll,
80
- mergeDeepOverrideArrays,
81
- mergeDeepConfigurable,
82
- objFilterUndefinedRecursive,
83
- removeUndefinedKeys, // alias
84
- sortObjKeyAccordingToValue,
85
- ensureObjectProp,
86
- filterKeys,
87
- deleteByAddress,
88
- ensureIsArrayAndPush,
89
- removeCircularJSONstringify,
90
-
91
- cleanStackTrace,
92
- shuffleArray,
93
- randomizeArray: shuffleArray,
94
- round2,
95
-
96
- camelCase,
97
- snakeCase,
98
- kebabCase,
99
- dashCase: kebabCase,
100
- underscoreCase: snakeCase,
101
- titleCase,
102
- pascalCase,
103
- lowerCase,
104
- upperCase,
105
- capitalize1st,
106
- camelCaseToWords,
107
- nbOccurenceInString,
108
-
109
- firstMatch,
110
- allMatches,
111
- getValuesBetweenSeparator,
112
- getValuesBetweenStrings,
113
- escapeRegexp,
114
-
115
- validator,
116
- required: validator, // alias for readability
117
- validatorReturnErrArray,
118
- isValid,
119
- isType,
120
- isDateObject,
121
- issetOr,
122
- isEmptyOrNotSet,
123
- errIfNotSet,
124
- err500IfNotSet,
125
- errIfEmptyOrNotSet,
126
- err500IfEmptyOrNotSet,
127
- errXXXIfNotSet,
128
- isEmpty,
129
- checkAllObjectValuesAreEmpty,
130
- checkCtxIntegrity,
131
- // ALIASES
132
- orIsset: issetOr,
133
-
134
- // DATE
135
- getDateAsInt12,
136
- humanReadableTimestamp,
137
- getDateAsInt,
138
- getDateAsObject,
139
- isDateIntOrStringValid,
140
- isDateIsoOrObjectValid,
141
- dateStringToArray,
142
- dateArrayFormatted: dateArray,
143
- dateFormatted,
144
- dateSlash: dateFormatted,
145
- dateOffset,
146
- getTimeAsInt,
147
- getIntAsTime,
148
- isTimeStringValid,
149
- // isDateObject <= see validator.js
150
- getDuration,
151
- doDateOverlap,
152
- getDatesForDaysArrayBetweenTwoDates,
153
- getEndTimeFromDurationAndStartTime,
154
- getDate12FromDateAndTime,
155
- getMonthAsInt,
156
- isSunday,
157
- isMonday,
158
- isTuesday,
159
- isWednesday,
160
- isThursday,
161
- isFriday,
162
- isSaturday,
163
- isWeekend,
164
- nextMonday,
165
- nextTuesday,
166
- nextWednesday,
167
- nextThursday,
168
- nextFriday,
169
- nextSaturday,
170
- nextSunday,
171
- addMinutes,
172
- addHours,
173
- addDays,
174
- addMonths,
175
- addYears,
176
- getYear,
177
- getDayOfMonth,
178
- getHours,
179
- getMinutes,
180
- firstDayOfMonth,
181
- lastDayOfMonth,
182
- eachDayOfInterval,
183
- eachMonthOfInterval,
184
- differenceInMilliseconds,
185
- differenceInSeconds,
186
- differenceInMinutes,
187
- differenceInHours,
188
- differenceInDays,
189
- differenceInWeeks,
190
- differenceInMonths,
191
- getClosestExistingDateOfMonth,
192
- getNextMonthlyDate,
193
- getHolidayReferenceYear,
194
- getFirstDayOfHolidayReferenceYear,
195
- getLastDayOfHolidayReferenceYear,
196
- // ALIASES
197
- getDateAsArrayFormatted: dateArray,
198
- getDateAsArray: dateStringToArray,
199
- convertDateAsInt: getDateAsInt,
200
- convertDateAsObject: getDateAsObject,
201
-
202
- // LOGGER
203
- C,
204
- cliProgressBar,
205
- cliLoadingSpinner,
206
- outputLogs: logger,
207
-
208
- // STRING
209
- convertAccentedCharacters,
210
-
211
- // TIMEOUT
212
- executeInDelayedLoop,
213
- timeout,
214
- runAsync,
215
- waitUntilTrue,
216
-
217
- // TRANSACTION
218
- transaction,
219
- waitForTransaction,
220
- getId,
221
- mergeMixins,
222
-
223
- // MONGO
224
- mongoFilterMerger,
225
- mongoPush,
226
- tryCatch,
10
+ A powerful collection of utility functions for JavaScript/TypeScript projects. Fast, functional, and fully typed.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install topkat-utils
16
+ # or
17
+ yarn add topkat-utils
18
+ ```
19
+
20
+ ## Error handler
21
+
22
+ - `DescriptiveError(value, type)`: Improves JS `Error` class by adding a way to add extraInformations to error, which is a must have in the context of debugging and logging the right informations
23
+ ```typescript
24
+ // Example usage
25
+ try {
26
+ if(user.age < 18) {
27
+ throw new DescriptiveError('Not allowed', { age: user.age, code: 403, ...additionalInfosToDisplayInLogs })
28
+ }
29
+ } catch (error) {
30
+ // Error message: "Expected number, got string: '25'"
31
+ C.error(error.message) //
32
+ C.error(error.logs) // display logs as string array
33
+ C.error(error.errorDescription) // display all extraInfos / options provided as second param
34
+ }
35
+ ```
36
+
37
+ ## Logger
38
+
39
+ - `C`: all in one logger util
40
+ ```typescript
41
+ // Basic usage
42
+ C.log('Hello World') // [INFO] Hello World
43
+ C.info('Info!') // [INFO] Info! Usually blue
44
+
45
+ // Errors and warning will take the most informations out of your errors and does particularly fit with DescriptiveError() class
46
+ C.error('Oops!') // [ERROR] Oops! Error: Something went wrong\nat doSomething (/app/src/utils.js:42:15)...
47
+ C.error(false, 'Oops!')// Error without stack trace
48
+ C.warning('Warning!') // [WARN] Warning! Error: Something went wrong\nat doSomething (/app/src/utils.js:42:15)...
49
+ C.warning(false, 'Warning!') // Same without stack trace
50
+
51
+ // With objects parsing
52
+ C.log({ user: 'John', age: 30 }) // [INFO] { user: 'John', age: 30 }
53
+ // Terminal custom colors
54
+ C.log(C.red('Hello') + C.dim('World') + C.green('of') + C.logClr('Typescript', [0, 255, 150]))
55
+
56
+ C.success('Successfully built') // Color green `'✓ Successfully built'`
57
+
58
+ C.clearLastLines(2) // clears the last two lines of the terminal
59
+ ```
60
+ - `perfTimer()`: Util to measure performances
61
+ ``` typescript
62
+ const time = perfTimer()
63
+
64
+ for(let i = 0; i < 9999;i++) longProcess()
65
+
66
+ console.log('Process took ' + time.end()) // 'Process took 2.22 seconds
67
+ ```
68
+ - `cliProgressBar`
69
+ - `cliLoadingSpinner`
70
+ - `removeCircularJSONstringify(str)`: convert circular structures to valid JSON // TypeError: Converting circular structure to JSON
71
+
72
+ ## Core Utilities
73
+
74
+ ### Value Checking & Validation
75
+ - `validator(value, type)`: Type validation utility. Will throw an error if not valid. If you prefer that the function returns an error array, use `validatorReturnErrArray`
76
+ ```typescript
77
+ validator(
78
+ { value: 3, type: 'number', gte: 1, lte: 3 },
79
+ { name: 'email', value: 'name@site.com', regexp: /[^\s@]+@[^\s@]+\.[^\s@]/},
80
+ )
81
+ ```
82
+ - `isset(value)`: Check if a value is defined and not null (ignores other falsy values)
83
+ - `isEmpty(value)`: Check if a value is empty
84
+ - `isObject(value)`: Check if value is a plain object (not null, not Date, not array, etc.)
85
+
86
+ ### Object Manipulation
87
+ - `deepClone(obj)`: Deep clone objects, useful when you want to manipulate object with subobjects without modifying any references to those objects
88
+ - `mergeDeep(obj1, obj2)`: Deep merge objects
89
+ - `objForceWrite(obj, 'user.address.line1', addressVar)`, `objForceWriteIfNotSet()`: Forces a path to be written in nested object and create subObjects if necessary
90
+ - `flattenObject(obj)`: Flatten nested objects with pros as dot notation
91
+ ```typescript
92
+ // Example of flattenObject
93
+ const nested = {
94
+ user: {
95
+ name: 'John',
96
+ address: {
97
+ street: '123 Main St',
98
+ city: 'New York'
99
+ }
100
+ },
101
+ settings: {
102
+ theme: 'dark'
103
+ }
227
104
  }
105
+
106
+ const flattened = flattenObject(nested)
107
+ // Result:
108
+ // {
109
+ // 'user.name': 'John',
110
+ // 'user.address.street': '123 Main St',
111
+ // 'user.address.city': 'New York',
112
+ // 'settings.theme': 'dark'
113
+ // }
114
+ ```
115
+ - `unflattenObject(obj)`: Unflatten objects back to nested structure
116
+ - `objFilterUndefined(obj)`: Remove undefined values from object
117
+ - `findByAddress(obj, path)`: Get value by dot notation path
118
+ ```typescript
119
+ const obj = {
120
+ user: {
121
+ profile: {
122
+ name: 'John'
123
+ }
124
+ }
125
+ }
126
+
127
+ findByAddress(obj, 'user.profile.name') // 'John'
128
+ findByAddress(obj, 'user.settings.theme') // undefined
129
+ ```
130
+
131
+ ### Array Operations
132
+ - `shuffleArray(array)`: Randomize array order
133
+ - `randomItemInArray(array)`: Get random item from array
134
+ - `pushIfNotExist(array, item)`: Push item if not already present
135
+ - `noDuplicateFilter(array)`: Remove duplicates from array
136
+ - `getArrayInCommon(arr1, arr2)`: Get common elements between arrays
137
+ - `getArrayDiff(arr1, arr2)`: Get difference between arrays
138
+ - `arrayCount(arr, 'stringInstance')`: Count number of occurence of item in array
139
+
140
+
141
+ ### Number Operations
142
+ - `isBetween(value, min, max)`: Check if a number is within a range
143
+ - `random(min, max)`: Generate random number between two values
144
+ - `minMax(value, min, max)`: Clamp a number between min and max values
145
+ - `average(array)`: Calculate average of array values
146
+ - `sumArray(array)`: Sum values in an array
147
+ - `round(number, nbDecimals)`: Round number to X decimal places
148
+ - `round2(number)`: Round number to 2 decimal places
149
+
150
+ ### String Manipulation
151
+ - `miniTemplater(template, data)`: Simple template engine
152
+ ```typescript
153
+ // Basic usage
154
+ miniTemplater('Hello {{name}}!', { name: 'John' }) // 'Hello John!'
155
+ ```
156
+ - `cln(value)`: Clean string for printing (undefined, null, NaN)
157
+ - `pad(number, length)`: Pad numbers with leading zeros
158
+ - `generateToken(length, isUnique, mode)`: Generate random tokens (not to use un security workflows)
159
+ - `convertAccentedCharacters(str, options)`: Eg: `'éçàÉ' => 'ecaE'`. Convert accented characters to non-accented with options to remove spaces or numbers
160
+ - `nbOccurenceInString(str, occurence)`
161
+
162
+ ### Loop Operations
163
+ - `forI`, `forIAsync`: A mix between js `for(let i = ....i++)` loop and a map. Iterates over a specified number of times, passing each iteration's result to the next callback
164
+ ```typescript
165
+ // Generate Fibonacci sequence
166
+ forI(8, (i, previousItem, results) => {
167
+ if (i <= 1) return 1
168
+ return results[i-1] + results[i-2]
169
+ })
170
+ // Returns: [1, 1, 2, 3, 5, 8, 13, 21]
171
+ ```
172
+ - `recursiveGenericFunction`, `recursiveGenericFunctionSync`: The simplest way do iterate recursively on every item of an object
173
+ ```typescript
174
+ recursiveGenericFunctionSync(
175
+ { a: { b: true } }, // object OR array
176
+ (item, addr, lastElementKey, parent) => {
177
+ C.log(item) // true
178
+ C.log(addr) // 'a.b'
179
+ C.log(lastElementKey) // 'b'
180
+ C.log(parent) // { a: { b: 3 } }
181
+ C.log(findByAddress(addr)) // true // just aother way to get the value
182
+ return false
183
+ }
184
+ )
185
+ ```
186
+
187
+ ### Date Operations
188
+ - `getDateAsInt(date)`: Convert date to integer format (20290101)
189
+ - `dateOffset(date, offset)`: Add time offset to date
190
+ - `getDuration(start, end)`: Calculate duration between dates
191
+ - `isWeekend(date)`: Check if date is weekend
192
+ - `firstDayOfMonth(date)`: Get first day of month
193
+ - `lastDayOfMonth(date)`: Get last day of month
194
+
195
+ ### URL & Path Operations
196
+ - `urlPathJoin(...paths)`: Join URL paths (like path.join but for URLs)
197
+ ```typescript
198
+ // Handles double slashes correctly
199
+ urlPathJoin('https://api.example.com//v1', '/users/', 'userId') // => 'https://api.example.com/v1/users/userId'
200
+ ```
201
+
202
+ - `escapeRegexp(str)`: Will escape all special character in a string to output a valid regexp string to put in RegExp(myString)
203
+ - Eg: from `'path.*.addr(*)'` will output `'aa\..*?\.addr\(.*?\)'` so regexp match `'path.random.addr(randomItem)'`
204
+
205
+ ### Case Conversion
206
+ - `camelCaseify(str)`: Replace `'hello-world'`, `'hello World'`, `'hello_World'`, `'helloWorld'` => `'helloWorld'`
207
+ - `capitalize1st(string)`: `helloWorld` => `HelloWorld`
208
+ - `camelCase([word1, word2])`: Convert to camelCase
209
+ - `snakeCase([word1, word2])`: Convert to snake_case
210
+ - `kebabCase([word1, word2])`: Convert to kebab-case
211
+ - `pascalCase([word1, word2])`: Convert to PascalCase
212
+ - `titleCase([word1, word2])`: Convert to Titlecase
213
+
214
+ ## Additional Utilities
215
+
216
+
217
+ ### Environment & Configuration
218
+ - `ENV`: shortcut to `process.env`. Parse boolean and number values
219
+ - `parseBool(value)`: Parse boolean values
220
+
221
+
222
+ ### Async Operations
223
+ - `timeout(ms)`: Promise-based timeout
224
+
225
+ ## Object Control
226
+ - `readOnly(obj)`: Lock all 1st level props of an object to read only (not rewritable / modifiable)
227
+ - `reassignForbidden(obj)`: Fields of the object can be created BUT NOT reassignated
228
+ - `readOnlyRecursive(obj)`: All fields and subFields of the object will be readOnly
229
+
230
+ ### Typescript equivalent of Js functions (Fix types)
231
+ - `lowerCase(str)`: `lowerCase('HelloWorld' as const) // type: 'helloworld'` (Equivalent of type `LowerCase<MyString>`)
232
+ - `upperCase(str)`: `upperCase('HelloWorld' as const) // type: 'HELLOWORLD'` (Equivalent of type `UpperCase<MyString>`)
233
+ - `objEntries(obj)`: In JS object entries are not correctly typed (`Object.entries({ a: 1, b: true }) // type: [string, number | boolean]`). With this function we are typed like `objEntries({ a: 1, b: true }) // ["a", number] | ["b", boolean]`
234
+ - `objKeys`: In JS object keys are not correctly typed (`Object.keys({ a: 1, b: 2 }) // type: string`). With this function we are typed like `objKeys({ a: 1, b: 2 }) // type: 'a' | 'b'`
235
+ - `includes(str)`: Fix this always happening ts error when using includes and your search string is not typed as an array element (which is very dumb IMO)
236
+
237
+ ## Configuration
238
+
239
+ Place that at the top of your code
240
+
241
+ ``` typescript
242
+ registerConfig({
243
+ terminal: {
244
+ // Custom colors for terminal logs
245
+ theme: {...},
246
+ // disable colors in case your logs are outputted as plain text
247
+ noColor: true,
248
+ },
249
+ // if you use topkatUtils as a logger and error handler
250
+ // onError custom callback
251
+ onError: () => { /** */ },
252
+ /** Exemple of preprocessing log */
253
+ preprocessLog(log: string) { return 'MyAppName: ' + Date.now() + ' ' + log }
254
+ })
228
255
  ```
229
256
 
230
- Please contact me if you need further informations ( issue on github :) )
257
+ ## TypeScript Support
258
+
259
+ This library is fully typed and provides TypeScript definitions out of the box. Every Util is documented via JsDoc and documentation should appear on hover in your IDE
260
+
261
+ ## Contributing
262
+
263
+ Contributions are welcome! Please feel free to submit a Pull Request
264
+
265
+ ## License
266
+
267
+ MIT
268
+
269
+ ## Support
270
+
271
+ If you need help or have questions, please open an issue on GitHub.