@salespark/toolkit 2.0.0

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/README.md ADDED
@@ -0,0 +1,556 @@
1
+ # SalesPark Toolkit v2 - Documentation
2
+
3
+ ## @salespark/toolkit
4
+
5
+ Shared toolkit of helpers and utilities for **Node.js**, **React**, and browser environments.
6
+ Tree-shakeable, TypeScript-first, ESM + CJS outputs.
7
+
8
+ [![Coverage](https://codecov.io/gh/FBlade/salespark-toolkit/branch/main/graph/badge.svg)](https://codecov.io/gh/FBlade/salespark-toolkit)
9
+ [![npm version](https://img.shields.io/npm/v/%40salespark%2Ftoolkit.svg)](https://www.npmjs.com/package/@salespark/toolkit)
10
+ ![types](https://img.shields.io/npm/types/%40salespark%2Ftoolkit)
11
+ ![modules](https://img.shields.io/badge/modules-ESM%20%2B%20CJS-1f6feb)
12
+ ![tree-shakeable](https://img.shields.io/badge/tree--shakeable-yes-success)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](#-license)
14
+
15
+ ---
16
+
17
+ ## ๐Ÿ“ฆ Install
18
+
19
+ ```bash
20
+ yarn add @salespark/toolkit
21
+ # or
22
+ npm i @salespark/toolkit
23
+ ```
24
+
25
+ ## โœจ Features
26
+
27
+ - **Array utilities**: chunk, uniqBy, deep equality, flatten, etc.
28
+ - **Object utilities**: pick, omit, clean objects, etc.
29
+ - **String utilities**: slugify, template fill, deburr, sanitize, etc.
30
+ - **Number utilities**: clamp, round, safe parse, random digits, etc.
31
+ - **Boolean utilities**: safe boolean conversion with common representations.
32
+ - **Function utilities**: debounce, throttle, nil/empty checks, formatBytes, string similarity, etc.
33
+ - **Environment detection**: `isBrowser`, `isNode`.
34
+
35
+ ---
36
+
37
+ ## ๐Ÿš€ Usage
38
+
39
+ Get started in seconds with a few common utilities:
40
+
41
+ ### Named Imports (Tree-shakeable)
42
+
43
+ ```typescript
44
+ import {
45
+ debounce,
46
+ chunk,
47
+ slugify,
48
+ clamp,
49
+ isBrowser,
50
+ toBool,
51
+ } from "@salespark/toolkit";
52
+
53
+ // Debounce a function
54
+ const debouncedFn = debounce(() => {
55
+ /* ... */
56
+ }, 200);
57
+
58
+ // Chunk an array
59
+ const chunks = chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
60
+
61
+ // Slugify a string
62
+ const slug = slugify("Olรก mundo!"); // "ola-mundo"
63
+
64
+ // Clamp a number
65
+ const safe = clamp(15, 0, 10); // 10
66
+
67
+ // Convert to boolean
68
+ const bool = toBool("yes"); // true
69
+
70
+ // Check environment
71
+ if (isBrowser) {
72
+ /* browser-specific code */
73
+ }
74
+ ```
75
+
76
+ ### Lodash-style Import (Alternative)
77
+
78
+ ```typescript
79
+ import * as _ from "@salespark/toolkit";
80
+
81
+ // Debounce a function
82
+ const debouncedFn = _.debounce(() => {
83
+ /* ... */
84
+ }, 200);
85
+
86
+ // Chunk an array
87
+ const chunks = _.chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
88
+
89
+ // Slugify a string
90
+ const slug = _.slugify("Olรก mundo!"); // "ola-mundo"
91
+
92
+ // Clamp a number
93
+ const safe = _.clamp(15, 0, 10); // 10
94
+
95
+ // Convert to boolean
96
+ const bool = _.toBool("yes"); // true
97
+
98
+ // Check environment
99
+ if (_.isBrowser) {
100
+ /* browser-specific code */
101
+ }
102
+ ```
103
+
104
+ ## ๐Ÿ“š API Reference
105
+
106
+ ### ๐Ÿ“‹ Array Utilities
107
+
108
+ **`chunk<T>(arr: T[], size: number): T[][]`** โ€” Splits an array into equally sized pieces.
109
+
110
+ ```javascript
111
+ chunk([1, 2, 3, 4, 5], 2);
112
+ // Result: [[1, 2], [3, 4], [5]]
113
+ ```
114
+
115
+ **`uniq<T>(arr: T[]): T[]`** โ€” Removes duplicate values from an array.
116
+
117
+ ```javascript
118
+ uniq([1, 2, 2, 3, 3, 3]);
119
+ // Result: [1, 2, 3]
120
+ ```
121
+
122
+ **`uniqBy<T, K>(arr: T[], key: (v: T) => K): T[]`** โ€” Returns unique items based on a computed key.
123
+
124
+ ```javascript
125
+ uniqBy(
126
+ [
127
+ { id: 1, name: "John" },
128
+ { id: 2, name: "Jane" },
129
+ { id: 1, name: "John" },
130
+ ],
131
+ (x) => x.id
132
+ );
133
+ // Result: [{id: 1, name: 'John'}, {id: 2, name: 'Jane'}]
134
+ ```
135
+
136
+ **`areArraysEqual<T>(arr1: T[], arr2: T[]): boolean`** โ€” Deeply compares two arrays for equality.
137
+
138
+ ```javascript
139
+ areArraysEqual([1, 2, 3], [1, 2, 3]);
140
+ // Result: true
141
+ ```
142
+
143
+ **`flatten<T>(arr: any[]): T[]`** โ€” Flattens nested arrays into a single array (1 level deep).
144
+
145
+ ```javascript
146
+ flatten([1, [2, 3], [4, [5]]]);
147
+ // Result: [1, 2, 3, 4, [5]]
148
+ ```
149
+
150
+ **`flattenOnce<T>(array): T[]`** โ€” Flattens array a single level deep.
151
+
152
+ ```javascript
153
+ flattenOnce([1, [2, 3], [4, 5]]);
154
+ // Result: [1, 2, 3, 4, 5]
155
+ ```
156
+
157
+ **`flattenDepth<T>(array, depth?, options?): T[]`** โ€” Flattens array up to specified depth.
158
+
159
+ ```javascript
160
+ flattenDepth([1, [2, [3, [4]]]], 2);
161
+ // Result: [1, 2, 3, [4]]
162
+ ```
163
+
164
+ **`groupBy<T, K>(arr: T[], key: ((item: T) => K) | K): Record<string, T[]>`** โ€” Groups array items by a key or function.
165
+
166
+ ```javascript
167
+ groupBy(
168
+ [
169
+ { type: "fruit", name: "apple" },
170
+ { type: "fruit", name: "banana" },
171
+ { type: "veggie", name: "carrot" },
172
+ ],
173
+ "type"
174
+ );
175
+ // Result: {fruit: [{type: 'fruit', name: 'apple'}, {type: 'fruit', name: 'banana'}], veggie: [{type: 'veggie', name: 'carrot'}]}
176
+ ```
177
+
178
+ **`sortBy<T>(arr: T[], key: ((item: T) => any) | keyof T): T[]`** โ€” Sorts array by a key or function.
179
+
180
+ ```javascript
181
+ sortBy([{ age: 30 }, { age: 20 }, { age: 25 }], "age");
182
+ // Result: [{age: 20}, {age: 25}, {age: 30}]
183
+ ```
184
+
185
+ **`difference<T>(arr1: T[], arr2: T[]): T[]`** โ€” Returns elements in arr1 not present in arr2.
186
+
187
+ ```javascript
188
+ difference([1, 2, 3, 4], [2, 4, 6]);
189
+ // Result: [1, 3]
190
+ ```
191
+
192
+ **`intersection<T>(arr1: T[], arr2: T[]): T[]`** โ€” Returns elements common to both arrays.
193
+
194
+ ```javascript
195
+ intersection([1, 2, 3], [2, 3, 4]);
196
+ // Result: [2, 3]
197
+ ```
198
+
199
+ **`compact<T>(arr: T[]): T[]`** โ€” Removes falsy values from array.
200
+
201
+ ```javascript
202
+ compact([0, 1, false, 2, "", 3, null, undefined, 4]);
203
+ // Result: [1, 2, 3, 4]
204
+ ```
205
+
206
+ **`pluck<T, K>(arr: T[], key: K): Array<T[K]>`** โ€” Extracts a property from each object in array.
207
+
208
+ ```javascript
209
+ pluck(
210
+ [
211
+ { name: "John", age: 30 },
212
+ { name: "Jane", age: 25 },
213
+ ],
214
+ "name"
215
+ );
216
+ // Result: ['John', 'Jane']
217
+ ```
218
+
219
+ **`shuffle<T>(arr: T[]): T[]`** โ€” Shuffles array elements randomly.
220
+
221
+ ```javascript
222
+ shuffle([1, 2, 3, 4, 5]);
223
+ // Result: [3, 1, 5, 2, 4] (random order)
224
+ ```
225
+
226
+ **`isFlattenable(value: unknown): boolean`** โ€” Checks if a value can be flattened.
227
+
228
+ ```javascript
229
+ isFlattenable([1, 2, 3]);
230
+ // Result: true
231
+ ```
232
+
233
+ **`pushAll<T>(array: T[], values: readonly T[]): T[]`** โ€” Appends all values into array in-place.
234
+
235
+ ```javascript
236
+ const arr = [1, 2];
237
+ pushAll(arr, [3, 4, 5]);
238
+ // Result: arr is now [1, 2, 3, 4, 5]
239
+ ```
240
+
241
+ ### ๐Ÿ“ฆ Object Utilities
242
+
243
+ **`pick<T, K>(obj: T, keys: K[]): Pick<T, K>`** โ€” Picks specified properties from an object.
244
+
245
+ ```javascript
246
+ pick({ name: "John", age: 30, city: "NYC" }, ["name", "age"]);
247
+ // Result: {name: 'John', age: 30}
248
+ ```
249
+
250
+ **`omit<T, K>(obj: T, keys: K[]): Omit<T, K>`** โ€” Omits specified properties from an object.
251
+
252
+ ```javascript
253
+ omit({ name: "John", age: 30, city: "NYC" }, ["age"]);
254
+ // Result: {name: 'John', city: 'NYC'}
255
+ ```
256
+
257
+ **`objectToString(obj: unknown): string`** โ€” Converts an object to a clean string without JSON braces.
258
+
259
+ ```javascript
260
+ objectToString({ name: "John", age: 30 });
261
+ // Result: "name=John_age=30"
262
+ ```
263
+
264
+ **`cleanObject<T>(obj: T): any`** โ€” Deep-cleans an object by removing null/undefined values.
265
+
266
+ ```javascript
267
+ cleanObject({
268
+ name: "John",
269
+ age: null,
270
+ city: undefined,
271
+ data: { valid: true, invalid: null },
272
+ });
273
+ // Result: {name: 'John', data: {valid: true}}
274
+ ```
275
+
276
+ ### ๐Ÿ”ค String Utilities
277
+
278
+ **`slugify(input: string): string`** โ€” Converts a string to a URL-friendly slug.
279
+
280
+ ```javascript
281
+ slugify("Olรก Mundo! Como estรก?");
282
+ // Result: "ola-mundo-como-esta"
283
+ ```
284
+
285
+ **`fill(template: string, values: Record<string, string|number>): string`** โ€” Fills a template string with values.
286
+
287
+ ```javascript
288
+ fill("Hello {name}, you are {age} years old!", { name: "John", age: 30 });
289
+ // Result: "Hello John, you are 30 years old!"
290
+ ```
291
+
292
+ **`deburr(str: string): string`** โ€” Removes diacritic marks from a string.
293
+
294
+ ```javascript
295
+ deburr("cafรฉ rรฉsumรฉ naรฏve");
296
+ // Result: "cafe resume naive"
297
+ ```
298
+
299
+ **`sanitize(input: unknown, maxLength?: number): string`** โ€” Sanitizes input by removing dangerous content.
300
+
301
+ ```javascript
302
+ sanitize("<script>alert('hack')</script>Hello World!", 20);
303
+ // Result: "Hello World!"
304
+ ```
305
+
306
+ ### ๐Ÿ”ข Number Utilities
307
+
308
+ **`clamp(n: number, min: number, max: number): number`** โ€” Restricts a number within min and max bounds.
309
+
310
+ ```javascript
311
+ clamp(15, 0, 10);
312
+ // Result: 10
313
+ ```
314
+
315
+ **`round(n: number, decimals?: number): number`** โ€” Rounds a number to fixed decimal places.
316
+
317
+ ```javascript
318
+ round(3.14159, 2);
319
+ // Result: 3.14
320
+ ```
321
+
322
+ **`toInteger(value: unknown, defaultValue?: number): number`** โ€” Safely converts a value to an integer.
323
+
324
+ ```javascript
325
+ toInteger("42.7");
326
+ // Result: 42
327
+ ```
328
+
329
+ **`safeParseInt(value: unknown, defaultValue?: number): number`** โ€” Alias for safe integer conversion.
330
+
331
+ ```javascript
332
+ safeParseInt("abc", 0);
333
+ // Result: 0
334
+ ```
335
+
336
+ **`toNumber(value: unknown, decimals?: number): number`** โ€” Safely parses a value into a number with optional decimal precision.
337
+
338
+ ```javascript
339
+ toNumber("123,45", 2);
340
+ // Result: 123.45
341
+ ```
342
+
343
+ **`randomDigits(length?: number, options?: { charset?: string; noLeadingZero?: boolean }): string`** โ€” Generates a random string of digits with secure randomness when available.
344
+
345
+ ```javascript
346
+ randomDigits(6);
347
+ // Result: "482751" (random)
348
+ ```
349
+
350
+ ### โœ… Boolean Utilities
351
+
352
+ **`toBool(value: unknown, def?: boolean): boolean`** โ€” Converts a value to boolean, supporting common string/number representations.
353
+
354
+ ```javascript
355
+ toBool("yes");
356
+ // Result: true
357
+
358
+ toBool("0");
359
+ // Result: false
360
+ ```
361
+
362
+ ### โšก Function Utilities
363
+
364
+ **`debounce<T>(fn: T, wait?: number): T`** โ€” Returns a debounced version of a function.
365
+
366
+ ```javascript
367
+ const debouncedFn = debounce(() => console.log("Called!"), 300);
368
+ debouncedFn(); // Will only execute after 300ms of no further calls
369
+ ```
370
+
371
+ **`throttle<T>(fn: T, wait?: number): T`** โ€” Returns a throttled version of a function.
372
+
373
+ ```javascript
374
+ const throttledFn = throttle(() => console.log("Called!"), 1000);
375
+ throttledFn(); // Will execute at most once per 1000ms
376
+ ```
377
+
378
+ **`isNil(value: unknown): boolean`** โ€” Checks if a value is null or undefined.
379
+
380
+ ```javascript
381
+ isNil(null);
382
+ // Result: true
383
+
384
+ isNil(undefined);
385
+ // Result: true
386
+
387
+ isNil(0);
388
+ // Result: false
389
+ ```
390
+
391
+ **`isNilText(value: unknown): boolean`** โ€” Checks if value is null/undefined or the text "null"/"undefined".
392
+
393
+ ```javascript
394
+ isNilText("null");
395
+ // Result: true
396
+
397
+ isNilText("undefined");
398
+ // Result: true
399
+ ```
400
+
401
+ **`isNilOrEmpty(value: unknown): boolean`** โ€” Checks if value is null/undefined or an empty string.
402
+
403
+ ```javascript
404
+ isNilOrEmpty("");
405
+ // Result: true
406
+
407
+ isNilOrEmpty(null);
408
+ // Result: true
409
+ ```
410
+
411
+ **`hasNilOrEmpty(array: unknown): boolean`** โ€” Checks if any element in array is nil or empty.
412
+
413
+ ```javascript
414
+ hasNilOrEmpty([1, "", 3]);
415
+ // Result: true
416
+
417
+ hasNilOrEmpty([1, 2, 3]);
418
+ // Result: false
419
+ ```
420
+
421
+ **`isNilEmptyOrZeroLen(value: unknown): boolean`** โ€” Checks if value is nil, empty string, or has zero length.
422
+
423
+ ```javascript
424
+ isNilEmptyOrZeroLen([]);
425
+ // Result: true
426
+
427
+ isNilEmptyOrZeroLen("");
428
+ // Result: true
429
+ ```
430
+
431
+ **`isNilOrZeroLen(value: unknown): boolean`** โ€” Checks if value is nil or has zero length.
432
+
433
+ ```javascript
434
+ isNilOrZeroLen([]);
435
+ // Result: true
436
+
437
+ isNilOrZeroLen(null);
438
+ // Result: true
439
+ ```
440
+
441
+ **`isNilOrNaN(value: unknown): boolean`** โ€” Checks if value is nil or NaN.
442
+
443
+ ```javascript
444
+ isNilOrNaN(NaN);
445
+ // Result: true
446
+
447
+ isNilOrNaN("abc");
448
+ // Result: true (coerced to NaN)
449
+ ```
450
+
451
+ **`formatBytes(bytes: number, si?: boolean, dp?: number): string`** โ€” Formats bytes as human-readable text.
452
+
453
+ ```javascript
454
+ formatBytes(1024);
455
+ // Result: "1.0 KiB"
456
+
457
+ formatBytes(1000, true);
458
+ // Result: "1.0 kB"
459
+ ```
460
+
461
+ **`stringSimilarity(s1: string, s2: string): number`** โ€” Returns the similarity between two strings (0..1).
462
+
463
+ ```javascript
464
+ stringSimilarity("hello", "hallo");
465
+ // Result: 0.8
466
+ ```
467
+
468
+ **`addThousandsSpace(value: number | string): string`** โ€” Adds spaces between thousands in a number.
469
+
470
+ ```javascript
471
+ addThousandsSpace(1234567);
472
+ // Result: "1 234 567"
473
+ ```
474
+
475
+ ### ๐ŸŒ Environment Detection
476
+
477
+ **`isBrowser: boolean`** โ€” True if running in browser.
478
+
479
+ ```javascript
480
+ if (isBrowser) {
481
+ console.log("Running in browser");
482
+ }
483
+ ```
484
+
485
+ **`isNode: boolean`** โ€” True if running in Node.js.
486
+
487
+ ```javascript
488
+ if (isNode) {
489
+ console.log("Running in Node.js");
490
+ }
491
+ ```
492
+
493
+ ## โš ๏ธ Deprecated Functions
494
+
495
+ The following functions are deprecated but maintained for backward compatibility:
496
+
497
+ ### ๐Ÿ“‹ Array Utilities (Deprecated)
498
+
499
+ - `areArraysDeepEqualUnordered` โ€” Use `areArraysEqual` instead.
500
+
501
+ ### โœ… Boolean Utilities (Deprecated)
502
+
503
+ - `parseToBool` โ€” Use `toBool` instead.
504
+
505
+ ### โšก Function Utilities (Deprecated)
506
+
507
+ - `isNullOrUndefined` โ€” Use `isNil` instead.
508
+ - `isNullOrUndefinedTextInc` โ€” Use `isNilText` instead.
509
+ - `isNullUndefinedOrEmpty` โ€” Use `isNilOrEmpty` instead.
510
+ - `isNullOrUndefinedInArray` โ€” Use `hasNilOrEmpty` instead.
511
+ - `isNullOrUndefinedEmptyOrZero` โ€” Use `isNilEmptyOrZeroLen` instead.
512
+ - `isNullUndefinedOrZero` โ€” Use `isNilOrZeroLen` instead.
513
+ - `isNullOrUndefinedOrNaN` โ€” Use `isNilOrNaN` instead.
514
+ - `humanFileSize` โ€” Use `formatBytes` instead.
515
+ - `getStringSimilarity` โ€” Use `stringSimilarity` instead.
516
+ - `addSpaceBetweenNumbers` โ€” Use `addThousandsSpace` instead.
517
+
518
+ ### ๐Ÿ”ข Number Utilities (Deprecated)
519
+
520
+ - `parseToNumber` โ€” Use `toNumber` instead.
521
+ - `otp` โ€” Use `randomDigits` instead.
522
+
523
+ ### ๐Ÿ”ค String Utilities (Deprecated)
524
+
525
+ - `removeDiacritics` โ€” Use `deburr` instead.
526
+ - `basicSanitize` โ€” Use `sanitize` instead.
527
+
528
+ ## ๐Ÿท๏ธ TypeScript
529
+
530
+ All functions are fully typed for best developer experience.
531
+
532
+ ---
533
+
534
+ ### ๐Ÿ”’ Internal Usage Notice
535
+
536
+ This package is primarily designed and maintained for internal use within the SalesPark ecosystem.
537
+ While it can technically be used in other Node.js/Mongoose projects, no official support or guarantees are provided outside of SalesPark-managed projects.
538
+
539
+ All code follows the same engineering standards applied across the SalesPark platform, ensuring consistency, reliability, and long-term maintainability of our internal systems.
540
+
541
+ โšก Note: This package is most efficient and works best when used together with other official SalesPark packages, where interoperability and optimizations are fully leveraged.
542
+
543
+ Disclaimer: This software is provided "as is", without warranties of any kind, express or implied. SalesPark shall not be held liable for any issues, damages, or losses arising from its use outside the intended SalesPark environment.
544
+
545
+ Organization packages: https://www.npmjs.com/org/salespark
546
+
547
+ ---
548
+
549
+ ## ๐Ÿ“„ License
550
+
551
+ MIT ยฉ [SalesPark](https://salespark.io)
552
+
553
+ ---
554
+
555
+ _Document version: 2_
556
+ _Last update: 22-08-2025_