@naman_deep_singh/js-extensions 1.3.3 → 1.4.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.
Files changed (38) hide show
  1. package/README.md +174 -425
  2. package/dist/cjs/array/array-extensions.js +84 -50
  3. package/dist/cjs/core/performance.d.ts +1 -0
  4. package/dist/cjs/core/performance.js +6 -0
  5. package/dist/cjs/core/version.d.ts +1 -0
  6. package/dist/cjs/core/version.js +9 -0
  7. package/dist/cjs/index.d.ts +1 -0
  8. package/dist/cjs/index.js +1 -0
  9. package/dist/cjs/number/number-extensions.js +85 -97
  10. package/dist/cjs/object/object-extensions.js +102 -103
  11. package/dist/cjs/string/string-extensions.js +66 -43
  12. package/dist/cjs/types/global-augmentations.d.ts +1 -0
  13. package/dist/cjs/utils/defineExtension.d.ts +1 -0
  14. package/dist/cjs/utils/defineExtension.js +13 -0
  15. package/dist/cjs/utils/index.d.ts +1 -0
  16. package/dist/cjs/utils/index.js +1 -0
  17. package/dist/esm/array/array-extensions.js +84 -50
  18. package/dist/esm/core/performance.d.ts +1 -0
  19. package/dist/esm/core/performance.js +5 -0
  20. package/dist/esm/core/version.d.ts +1 -0
  21. package/dist/esm/core/version.js +5 -0
  22. package/dist/esm/index.d.ts +1 -0
  23. package/dist/esm/index.js +1 -0
  24. package/dist/esm/number/number-extensions.js +86 -98
  25. package/dist/esm/object/object-extensions.js +102 -103
  26. package/dist/esm/string/string-extensions.js +66 -43
  27. package/dist/esm/types/global-augmentations.d.ts +1 -0
  28. package/dist/esm/utils/defineExtension.d.ts +1 -0
  29. package/dist/esm/utils/defineExtension.js +10 -0
  30. package/dist/esm/utils/index.d.ts +1 -0
  31. package/dist/esm/utils/index.js +1 -0
  32. package/dist/types/core/performance.d.ts +1 -0
  33. package/dist/types/core/version.d.ts +1 -0
  34. package/dist/types/index.d.ts +1 -0
  35. package/dist/types/types/global-augmentations.d.ts +1 -0
  36. package/dist/types/utils/defineExtension.d.ts +1 -0
  37. package/dist/types/utils/index.d.ts +1 -0
  38. package/package.json +8 -4
package/README.md CHANGED
@@ -1,469 +1,218 @@
1
- # @naman_deep_singh/js-extensions
1
+ @naman_deep_singh/js-extensions
2
2
 
3
- **Version:** 1.3.3
3
+ Version: 1.4.0
4
4
 
5
- Universal JavaScript prototype extensions for common development utilities. Works in both Node.js and browser environments with 67+ utility methods.
5
+ Universal JavaScript prototype extensions for common development utilities. Works in both Node.js and browser environments with 70+ utility methods.
6
6
 
7
- ## Installation
7
+ ⚠️ This library extends native prototypes (String, Array, Object, Number). Use consciously in shared or library code.
8
+
9
+ ---
8
10
 
11
+ ## Installation
9
12
  ```bash
10
13
  npm install @naman_deep_singh/js-extensions
11
14
  # or
12
15
  pnpm add @naman_deep_singh/js-extensions
13
- ```
14
-
15
- ## Quick Start
16
-
17
- ```typescript
16
+ Quick Start
18
17
  import { initializeExtensions } from '@naman_deep_singh/js-extensions';
19
18
 
20
19
  // Initialize all extensions
21
20
  initializeExtensions();
22
21
 
23
22
  // String utilities
24
- "hello world".toCapitalize(); // "Hello world"
25
- "test@email.com".isEmail(); // true
26
- "hello world".words(); // ["hello", "world"]
23
+ "hello world".toCapitalize(); // "Hello world"
24
+ "hello world".capitalizeWords(); // "Hello World"
25
+ "hello world".reverseWords(); // "world hello"
26
+ "test@email.com".isEmail(); // true
27
+ "hello world".words(); // ["hello", "world"]
27
28
 
28
29
  // Array utilities
29
- [1, 2, 2, 3].unique(); // [1, 2, 3]
30
- [1, 2, 3, 4, 5].chunk(2); // [[1, 2], [3, 4], [5]]
31
- [1, 2, 3].sample(); // Random element
30
+ [1, 2, 2, 3].unique(); // [1, 2, 3]
31
+ [1, 2, 3, 4, 5].chunk(2); // [[1,2],[3,4],[5]]
32
+ [1, 2, 3].sample(); // random element
33
+ [1,2,3,4].last(); // 4
34
+ [{id:1},{id:2},{id:1}].uniqueBy(x => x.id); // [{id:1},{id:2}]
35
+ [3,1,2].sortBy(x => x); // [1,2,3]
32
36
 
33
37
  // Number utilities
34
- (42).toOrdinal(); // "42nd"
35
- (0.75).toPercent(); // "75.00%"
36
- (5).times(i => console.log(i)); // Logs 0,1,2,3,4
38
+ (42).toOrdinal(); // "42nd"
39
+ (0.75).toPercent(); // "75.00%"
40
+ (3.14159).toFixedNumber(2); // 3.14
41
+ (5).randomUpTo(); // 0..5 random number
42
+ (5).times(i => console.log(i)); // 0..4
37
43
 
38
44
  // Object utilities
39
- ({a: 1, b: 2}).pick(['a']); // {a: 1}
40
- ({}).isEmpty(); // true
41
- ({user: {name: "John"}}).getPath('user.name'); // "John"
42
- ```
43
-
45
+ ({ a: 1, b: 2 }).pick(['a']); // { a: 1 }
46
+ ({ a: 1, b: 2 }).mapValues(v => v * 2); // { a: 2, b: 4 }
47
+ ({ a: 1, b: 2 }).mapKeys(k => k + "_"); // { a_: 1, b_: 2 }
48
+ ({}).isEmpty(); // true
49
+ ({ user: { name: "John" } }).getPath('user.name'); // "John"
50
+ ({ a: 1, b: 2 }).filterKeys(k => k === 'a'); // { a: 1 }
51
+ ({ a: 1, b: 2 }).filterValues(v => v === 1); // { a: 1 }
52
+ Error Handling & Validation
53
+ All methods include strict runtime validation and throw clear native errors.
44
54
 
45
- ## Error Handling & Validation
55
+ "hello".count(123);
56
+ // TypeError: count: substring must be a string, got number
46
57
 
47
- All methods now include comprehensive input validation to ensure reliability and prevent runtime errors.
58
+ "hello".count("");
59
+ // TypeError: count: substring cannot be empty
48
60
 
49
- ### Input Validation
50
- ```typescript
51
- // Invalid inputs now throw clear TypeError messages
52
- "hello".count(123); // TypeError: count: substring must be a string, got number
53
- "hello".count(""); // TypeError: count: substring cannot be empty
54
- [].sum(); // TypeError: sum: array must contain at least one number
55
- ({a: 1}).pick(null); // TypeError: pick: keys must be an array, got object
56
- (3.14).round(-1); // TypeError: round: decimals must be a non-negative integer, got -1
57
- ```
61
+ [].sum();
62
+ // TypeError: sum: array must contain at least one number
58
63
 
59
- ### Consistent Error Types
60
- - **`TypeError`** - Invalid parameter types or missing required values
61
- - **`RangeError`** - Out-of-range values (e.g., `toRoman` number limits)
64
+ ({ a: 1 }).pick(null as any);
65
+ // TypeError: pick: keys must be an array, got object
62
66
 
63
- ### Performance vs Validation Trade-off
64
- ```typescript
65
- import { setPerformanceConfig } from '@naman_deep_singh/js-extensions';
66
-
67
- // Validation is enabled by default for reliability
68
- setPerformanceConfig({
69
- enableCaching: true, // Cache expensive operations
70
- enableValidation: true // Input validation enabled (built-in, cannot be disabled)
71
- });
67
+ (3.14).round(-1);
68
+ // TypeError: round: decimals must be a non-negative integer, got -1
69
+ Error Types Used
72
70
 
73
- // Note: Validation is built into all methods and cannot be disabled for maximum performance
74
- ```
71
+ TypeError invalid type or missing argument
75
72
 
76
- ## Configuration
73
+ RangeError – out-of-range numeric values (e.g. toRoman)
77
74
 
78
- ### Selective Extensions
75
+ No custom error classes are exposed — only standard JS errors.
79
76
 
80
- ```typescript
77
+ Configuration
78
+ Selective Extension Loading
81
79
  import { initializeExtensions, extend } from '@naman_deep_singh/js-extensions';
82
80
 
83
- // Only specific types
81
+ // Enable only specific prototypes
84
82
  initializeExtensions({
85
- string: true,
86
- array: true,
87
- object: false,
88
- number: false
83
+ string: true,
84
+ array: true,
85
+ object: false,
86
+ number: false,
89
87
  });
90
88
 
91
- // Individual extension functions
92
- extend.string(); // Only string methods
93
- extend.array(); // Only array methods
94
- ```
95
-
96
- ### Performance Configuration
97
-
98
- ```typescript
99
- import { initializeExtensions, setPerformanceConfig } from '@naman_deep_singh/js-extensions';
100
-
101
- // Configure performance options
102
- initializeExtensions({
103
- performance: {
104
- enableCaching: true, // Cache expensive operations
105
- maxCacheSize: 200 // LRU cache size
106
- }
107
- });
89
+ // Or initialize individually
90
+ extend.string();
91
+ extend.array();
92
+ Performance Configuration
93
+ Caching System
94
+ import { setPerformanceConfig } from '@naman_deep_singh/js-extensions';
108
95
 
109
- // Or configure separately
110
96
  setPerformanceConfig({
111
97
  enableCaching: true,
112
- maxCacheSize: 100
98
+ maxCacheSize: 200,
113
99
  });
114
- ```
115
-
116
- ## String Extensions
117
-
118
- ### Case Conversion
119
- ```typescript
120
- "hello world".toCapitalize(); // "Hello world"
121
- "hello-world".toCamelCase(); // "helloWorld"
122
- "HelloWorld".toKebabCase(); // "hello-world"
123
- "Hello World".toSnakeCase(); // "hello_world"
124
- "hello world".toTitleCase(); // "Hello World"
125
- ```
126
-
127
- ### Validation
128
- ```typescript
129
- "test@example.com".isEmail(); // true
130
- "https://example.com".isUrl(); // true
131
- "racecar".isPalindrome(); // true
132
- ```
133
-
134
- ### Text Processing
135
- ```typescript
136
- "Long text here".truncate(8); // "Long tex..."
137
- "Long text here".truncate(8, "!"); // "Long tex!"
138
- "hello world".removeWhitespace(); // "helloworld"
139
- "<p>Hello</p>".stripHtml(); // "Hello"
140
- "hello".reverse(); // "olleh"
141
- ```
142
-
143
- ### Padding & Formatting
144
- ```typescript
145
- "5".padStart(3, "0"); // "005"
146
- "5".padEnd(3, "0"); // "500"
147
- "hello world hello".count("hello"); // 2
148
- ```
149
-
150
- ### Text Analysis
151
- ```typescript
152
- "hello world test".words(); // ["hello", "world", "test"]
153
- "line1\nline2\nline3".lines(); // ["line1", "line2", "line3"]
154
- ```
155
-
156
- ## Array Extensions
157
-
158
- ### Basic Operations
159
- ```typescript
160
- [1, 2, 2, 3, 1].unique(); // [1, 2, 3]
161
- [1, 2, 3, 4, 5].shuffle(); // [3, 1, 5, 2, 4] (random)
162
- [1, 2, 3, 4, 5].chunk(2); // [[1, 2], [3, 4], [5]]
163
- [0, 1, false, 2, "", 3].compact(); // [1, 2, 3]
164
- ```
165
-
166
- ### Mathematical Operations
167
- ```typescript
168
- [1, 2, 3, 4, 5].sum(); // 15
169
- [1, 2, 3, 4, 5].average(); // 3
170
- ```
171
-
172
- ### Advanced Filtering & Grouping
173
- ```typescript
174
- const users = [{name: 'John', age: 25}, {name: 'Jane', age: 30}];
175
- users.groupBy(u => u.age > 25); // {false: [{name: 'John'...}], true: [{name: 'Jane'...}]}
176
- users.pluck('name'); // ['John', 'Jane']
177
-
178
- [1, 2, 3, 4, 5].partition(x => x % 2 === 0); // [[2, 4], [1, 3, 5]]
179
- [1, 2, 3, 4, 5].findLast(x => x > 3); // 5
180
- ```
181
-
182
- ### Array Manipulation
183
- ```typescript
184
- [1, [2, [3, 4]]].flatten(1); // [1, 2, [3, 4]]
185
- [1, [2, [3, 4]]].deepFlatten(); // [1, 2, 3, 4]
186
- ```
187
-
188
- ### Set Operations
189
- ```typescript
190
- [1, 2, 3].difference([2, 3, 4]); // [1]
191
- [1, 2, 3].intersection([2, 3, 4]); // [2, 3]
192
- [1, 2, 3].union([3, 4, 5]); // [1, 2, 3, 4, 5]
193
- ```
194
-
195
- ### Sampling & Slicing
196
- ```typescript
197
- [1, 2, 3, 4, 5].sample(); // Random element (e.g., 3)
198
- [1, 2, 3, 4, 5].take(3); // [1, 2, 3]
199
- [1, 2, 3, 4, 5].drop(2); // [3, 4, 5]
200
- ```
201
-
202
- ## Object Extensions
203
-
204
- ### Basic Operations
205
- ```typescript
206
- ({}).isEmpty(); // true
207
- ({a: 1, b: 2}).isEmpty(); // false
208
-
209
- const obj = {a: 1, b: 2, c: 3};
210
- obj.pick(['a', 'c']); // {a: 1, c: 3}
211
- obj.omit(['b']); // {a: 1, c: 3}
212
- ```
213
-
214
- ### Deep Operations
215
- ```typescript
216
- const original = {a: 1, b: {c: 2}};
217
- const cloned = original.deepClone(); // Complete deep copy
218
- const frozen = original.deepFreeze(); // Recursively frozen
219
-
220
- const obj1 = {a: 1, b: 2};
221
- const obj2 = {c: 3, d: 4};
222
- obj1.merge(obj2); // {a: 1, b: 2, c: 3, d: 4}
223
- ```
224
-
225
- ### Path Operations
226
- ```typescript
227
- const data = {
228
- user: {
229
- profile: {
230
- name: "John",
231
- age: 30
232
- }
233
- }
234
- };
235
-
236
- data.hasPath('user.profile.name'); // true
237
- data.hasPath('user.profile.email'); // false
238
- data.getPath('user.profile.name'); // "John"
239
- data.getPath('user.profile.email', 'N/A'); // "N/A"
100
+ Notes:
101
+
102
+ Validation cannot be disabled
103
+
104
+ Caching is optional
105
+
106
+ Uses a simple LRU cache
107
+
108
+ String Extensions (21 methods)
109
+ Case Conversion
110
+
111
+ "hello world".toCapitalize(); // "Hello world"
112
+ "hello world".capitalizeWords(); // "Hello World"
113
+ "hello-world".toCamelCase(); // "helloWorld"
114
+ "HelloWorld".toKebabCase(); // "hello-world"
115
+ "Hello World".toSnakeCase(); // "hello_world"
116
+ "hello world".toTitleCase(); // "Hello World"
117
+ Validation & Checks
118
+
119
+ "test@example.com".isEmail(); // true
120
+ "https://example.com".isUrl(); // true
121
+ "racecar".isPalindrome(); // true
122
+ Text Utilities
123
+
124
+ "Long text here".truncate(8); // "Long tex..."
125
+ "hello world".truncateWords(1); // "hello..."
126
+ "hello world".removeWhitespace(); // "helloworld"
127
+ "<p>Hello</p>".stripHtml(); // "Hello"
128
+ "hello".reverse(); // "olleh"
129
+ "hello world".reverseWords(); // "world hello"
130
+ "hello hello".count("hello"); // 2
131
+ "Hello World".slugify(); // "hello-world"
132
+ "hello world".words(); // ["hello", "world"]
133
+ "hello\nworld".lines(); // ["hello","world"]
134
+ Array Extensions (23 methods)
135
+ Core Utilities
136
+
137
+ [1, 2, 2, 3].unique(); // [1,2,3]
138
+ [{id:1},{id:2},{id:1}].uniqueBy(x => x.id); // [{id:1},{id:2}]
139
+ [1,2,3,4,5].shuffle(); // random order
140
+ [1,2,3,4,5].chunk(2); // [[1,2],[3,4],[5]]
141
+ [0,1,false,2,"",3].compact(); // [1,2,3] removes null, undefined, false, and empty strings
142
+ [1,2,3,4].last(); // 4
143
+ [3,1,2].sortBy(x => x); // [1,2,3]
144
+ Math
145
+
146
+ [1,2,3].sum(); // 6
147
+ [1,2,3].average(); // 2
148
+ Advanced
149
+
150
+ users.groupBy(u => u.age);
151
+ users.pluck('name');
152
+ [1,2,3,4].partition(n => n % 2 === 0);
153
+ // [[2,4],[1,3]]
154
+ Set Operations
155
+
156
+ [1,2,3].difference([2]); // [1,3]
157
+ [1,2,3].intersection([2,3]); // [2,3]
158
+ [1,2,3].union([3,4]); // [1,2,3,4]
159
+ Object Extensions (13 methods)
160
+ ({}).isEmpty(); // true
161
+ ({ a: 1, b: 2 }).pick(['a']); // { a: 1 }
162
+ ({ a: 1, b: 2 }).omit(['b']); // { a: 1 }
163
+ ({ a: 1, b: 2 }).mapValues(v => v*2); // { a: 2, b: 4 }
164
+ ({ a: 1, b: 2 }).mapKeys(k => k+"_"); // { a_:1, b_:2 }
165
+ ({ a: 1, b: 2 }).filterKeys(k => k==='a'); // { a:1 }
166
+ ({ a: 1, b: 2 }).filterValues(v => v===1); // { a:1 }
167
+ ({ a: { b: 2 } }).deepClone();
168
+ ({ a: { b: 2 } }).deepFreeze();
169
+ data.hasPath('user.profile.name');
170
+ data.getPath('user.profile.email', 'N/A');
240
171
  data.setPath('user.profile.email', 'john@example.com');
241
- // Sets nested property, creates path if needed
242
- ```
243
-
244
- ## Number Extensions
245
-
246
- ### Formatting
247
- ```typescript
248
- (0.75).toPercent(); // "75.00%"
249
- (0.123).toPercent(1); // "12.3%"
250
- (1234.56).toCurrency(); // "$1,234.56"
251
- (1234.56).toCurrency('EUR', 'de-DE'); // "1.234,56 €"
252
- ```
253
-
254
- ### Ordinal & Roman
255
- ```typescript
256
- (1).toOrdinal(); // "1st"
257
- (42).toOrdinal(); // "42nd"
258
- (1984).toRoman(); // "MCMLXXXIV"
259
- (2023).toRoman(); // "MMXXIII"
260
- ```
261
-
262
- ### Mathematical Operations
263
- ```typescript
264
- (15).clamp(10, 20); // 15
265
- (5).clamp(10, 20); // 10
266
- (25).clamp(10, 20); // 20
267
-
268
- (15).inRange(10, 20); // true
269
- (5).inRange(10, 20); // false
270
- ```
271
-
272
- ### Number Properties
273
- ```typescript
274
- (4).isEven(); // true
275
- (5).isOdd(); // true
276
- (7).isPrime(); // true
277
- (5).factorial(); // 120
278
- ```
279
-
280
- ### Precision & Math
281
- ```typescript
282
- (3.14159).round(2); // 3.14
283
- (3.14159).ceil(2); // 3.15
284
- (3.14159).floor(2); // 3.14
285
- (-5).abs(); // 5
286
- (-5).sign(); // -1
287
- ```
288
-
289
- ### Iteration
290
- ```typescript
291
- (3).times(i => console.log(`Item ${i}`));
292
- // Logs: "Item 0", "Item 1", "Item 2"
293
- ```
294
-
295
- ## Performance Configuration
296
-
297
- ### Caching System
298
- ```typescript
299
- import { setPerformanceConfig, getPerformanceConfig } from '@naman_deep_singh/js-extensions';
300
-
301
- // Enable caching for expensive operations
302
- setPerformanceConfig({
303
- enableCaching: true,
304
- maxCacheSize: 200
305
- });
172
+ Number Extensions (19 methods)
173
+ (0.75).toPercent(); // "75.00%"
174
+ (3.14159).toFixedNumber(2); // 3.14
175
+ (1234.56).toCurrency(); // "$1,234.56"
176
+ (1234.56).toCurrency('EUR','de-DE'); // "1.234,56 €"
177
+ (5).clamp(1,10); // 5
178
+ (5).inRange(1,10); // true
179
+ (7).isPrime(); // true
180
+ (5).factorial(); // 120
181
+ (5).randomUpTo(); // 0..5
182
+ (3).times(i => console.log(i)); // 0,1,2
183
+ (42).toOrdinal(); // "42nd"
184
+ (123).sign(); // 1
185
+ Caching Details
186
+ Cached Methods (when enabled):
187
+
188
+ Number.isPrime()
189
+
190
+ Number.factorial()
191
+
192
+ Number.toRoman()
193
+
194
+ Custom Caching:
306
195
 
307
- // Check current config
308
- const config = getPerformanceConfig();
309
- console.log(config); // {enableCaching: true, maxCacheSize: 200}
310
- ```
196
+ import { withCache } from '@naman_deep_singh/js-extensions';
197
+ const result = withCache('key', () => expensiveFn());
198
+ TypeScript Support
199
+ Full global augmentation
311
200
 
312
- ### Methods with Built-in Caching
313
- The following methods automatically use LRU cache when enabled:
314
- - **`isPrime()`** - Prime number calculations cached for repeated calls
315
- - **`factorial()`** - Factorial results cached to avoid recalculation
316
- - **`toRoman()`** - Roman numeral conversions cached for reuse
201
+ Strict typing for all methods
317
202
 
318
- ### External Caching
319
- ```typescript
320
- import { withCache } from '@naman_deep_singh/js-extensions';
203
+ Zero any leakage in public APIs
321
204
 
322
- // Use caching in your own functions
323
- const expensiveOperation = (input: string) => {
324
- return withCache(`myOp_${input}`, () => {
325
- // Your expensive computation here
326
- return complexCalculation(input);
327
- });
328
- };
329
- ```
330
-
331
- ### Memory Management
332
- The LRU (Least Recently Used) cache automatically:
333
- - Removes oldest entries when cache is full
334
- - Moves frequently accessed items to front
335
- - Prevents memory leaks in long-running applications
336
-
337
- ## Browser Usage
338
-
339
- ```html
340
- <script src="path/to/js-extensions.js"></script>
341
- <script>
342
- // Extensions are automatically initialized
343
- console.log("hello".toCapitalize()); // "Hello"
344
- console.log([1,2,2,3].unique()); // [1, 2, 3]
345
- console.log((42).toOrdinal()); // "42nd"
346
- console.log({a: 1, b: 2}.pick(['a'])); // {a: 1}
347
- </script>
348
- ```
349
-
350
- ## TypeScript Support
351
-
352
- Full TypeScript support with complete type definitions:
353
-
354
- ```typescript
355
- // All methods are fully typed
356
- const result: string = "hello".toCapitalize();
357
- const numbers: number[] = [1, 2, 2, 3].unique();
358
- const picked: Pick<{a: number, b: string}, 'a'> = {a: 1, b: "test"}.pick(['a']);
359
-
360
- // Performance configuration is also typed
361
- const config: PerformanceConfig = {
362
- enableCaching: true,
363
- maxCacheSize: 100
364
- };
365
- ```
366
-
367
-
368
- ## Package Stats
369
-
370
- - **67 utility methods** across 4 JavaScript types
371
- - **Zero dependencies** - lightweight and fast
372
- - **Universal compatibility** - Node.js and browser
373
- - **TypeScript native** - complete type definitions
374
- - **Performance optimized** - optional caching system
375
- - **Production-ready** - comprehensive input validation
376
- - **Tree-shakable** - selective imports supported
377
-
378
- ## Complete API Reference
379
-
380
- ### Core Functions
381
- ```typescript
382
- initializeExtensions(options?: ExtensionOptions): void
383
- extendAll(): void
384
- setPerformanceConfig(config: Partial<PerformanceConfig>): void
385
- getPerformanceConfig(): PerformanceConfig
386
-
387
- // Individual extension functions
388
- extend.string(): void
389
- extend.array(): void
390
- extend.object(): void
391
- extend.number(): void
392
- ```
393
-
394
- ### String Methods (19 methods)
395
- ```typescript
396
- toCapitalize(): string
397
- toCamelCase(): string
398
- toKebabCase(): string
399
- toSnakeCase(): string
400
- toTitleCase(): string
401
- truncate(length: number, suffix?: string): string
402
- isEmail(): boolean
403
- isUrl(): boolean
404
- isPalindrome(): boolean
405
- removeWhitespace(): string
406
- stripHtml(): string
407
- reverse(): string
408
- padStart(targetLength: number, padString?: string): string
409
- padEnd(targetLength: number, padString?: string): string
410
- count(substring: string): number
411
- words(): string[]
412
- lines(): string[]
413
- ```
414
-
415
- ### Array Methods (21 methods)
416
- ```typescript
417
- unique<T>(): T[]
418
- shuffle<T>(): T[]
419
- chunk<T>(size: number): T[][]
420
- groupBy<T, K>(keyFn: (item: T) => K): Record<K, T[]>
421
- sum(): number
422
- average(): number
423
- compact<T>(): T[]
424
- pluck<T, K>(key: K): T[K][]
425
- findLast<T>(predicate: (item: T) => boolean): T | undefined
426
- partition<T>(predicate: (item: T) => boolean): [T[], T[]]
427
- flatten(depth?: number): any[]
428
- deepFlatten(): any[]
429
- difference<T>(other: T[]): T[]
430
- intersection<T>(other: T[]): T[]
431
- union<T>(other: T[]): T[]
432
- sample<T>(): T | undefined
433
- take<T>(count: number): T[]
434
- drop<T>(count: number): T[]
435
- ```
436
-
437
- ### Object Methods (9 methods)
438
- ```typescript
439
- isEmpty(): boolean
440
- pick<T, K>(keys: K[]): Pick<T, K>
441
- omit<T, K>(keys: K[]): Omit<T, K>
442
- deepClone<T>(): T
443
- deepFreeze<T>(): T
444
- merge(other: Record<string, any>): Record<string, any>
445
- hasPath(path: string): boolean
446
- getPath(path: string, defaultValue?: any): any
447
- setPath(path: string, value: any): any
448
- ```
449
-
450
- ### Number Methods (18 methods)
451
- ```typescript
452
- toPercent(decimals?: number): string
453
- toCurrency(currency?: string, locale?: string): string
454
- toOrdinal(): string
455
- toRoman(): string
456
- clamp(min: number, max: number): number
457
- inRange(min: number, max: number): boolean
458
- isEven(): boolean
459
- isOdd(): boolean
460
- isPrime(): boolean
461
- factorial(): number
462
- round(decimals?: number): number
463
- ceil(decimals?: number): number
464
- floor(decimals?: number): number
465
- abs(): number
466
- sign(): number
467
- times(callback: (index: number) => void): void
468
- ```
205
+ const x: number[] = [1,2,2].unique();
206
+ const y: string = "hello".toCapitalize();
207
+ Package Stats
208
+ ~70 utility methods
209
+
210
+ Zero dependencies
211
+
212
+ Node.js + Browser
213
+
214
+ TypeScript-first
215
+
216
+ Optional LRU caching
469
217
 
218
+ Strict runtime validation