0
# Sugar Object Module
1
2
The Sugar Object module provides comprehensive utilities for object manipulation, querying, filtering, and type checking. It extends JavaScript's native Object capabilities with over 80 methods for working with objects in a functional programming style.
3
4
## Core Imports
5
6
```typescript
7
import Sugar from "sugar";
8
// Methods available as Sugar.Object.methodName()
9
```
10
11
For CommonJS:
12
13
```javascript
14
const Sugar = require("sugar");
15
// Methods available as Sugar.Object.methodName()
16
```
17
18
## Capabilities
19
20
### Object Creation
21
22
Creates objects from various input formats.
23
24
```typescript { .api }
25
/**
26
* Creates an object from a query string with parsing options
27
* @param str - Query string to parse
28
* @param options - Parsing configuration options
29
* @returns Parsed object
30
*/
31
function fromQueryString<T,U>(
32
str: string,
33
options?: QueryStringParseOptions<T,U>
34
): any;
35
36
interface QueryStringParseOptions<T,U> {
37
deep?: boolean;
38
separator?: string;
39
transform?: (key: string, value: any) => any;
40
}
41
```
42
43
**Usage Examples:**
44
45
```typescript
46
import Sugar from "sugar";
47
48
// Basic query string parsing
49
const params = Sugar.Object.fromQueryString("name=John&age=30&active=true");
50
// Result: { name: "John", age: "30", active: "true" }
51
52
// With custom separator
53
const data = Sugar.Object.fromQueryString("name:John;age:30", { separator: ";" });
54
55
// With transformation
56
const typed = Sugar.Object.fromQueryString("age=30&score=95.5", {
57
transform: (key, value) => {
58
if (key === "age" || key === "score") {
59
return parseFloat(value);
60
}
61
return value;
62
}
63
});
64
```
65
66
### Object Manipulation
67
68
Methods for adding, merging, cloning, and modifying objects.
69
70
```typescript { .api }
71
/**
72
* Adds properties from source object to target
73
* @param instance - Target object to modify
74
* @param obj - Source object to add from
75
* @param options - Merge options
76
* @returns Modified target object
77
*/
78
function add<T>(
79
instance: T,
80
obj: any,
81
options?: ObjectMergeOptions<T>
82
): T;
83
84
/**
85
* Adds properties from multiple source objects
86
* @param instance - Target object to modify
87
* @param sources - Array of source objects
88
* @param options - Merge options
89
* @returns Modified target object
90
*/
91
function addAll<T>(
92
instance: T,
93
sources: any[],
94
options?: ObjectMergeOptions<T>
95
): T;
96
97
/**
98
* Creates a copy of the object (shallow or deep)
99
* @param instance - Object to clone
100
* @param deep - Whether to perform deep cloning
101
* @returns Cloned object
102
*/
103
function clone(instance: any, deep?: boolean): any;
104
105
/**
106
* Sets default values for undefined properties
107
* @param instance - Target object
108
* @param sources - Default values object or array
109
* @param options - Merge options
110
* @returns Object with defaults applied
111
*/
112
function defaults<T>(
113
instance: T,
114
sources: any,
115
options?: ObjectMergeOptions<T>
116
): T;
117
118
/**
119
* Merges source object into target object
120
* @param instance - Target object
121
* @param source - Source object to merge
122
* @param options - Merge options
123
* @returns Merged object
124
*/
125
function merge<T>(
126
instance: T,
127
source: any,
128
options?: ObjectMergeOptions<T>
129
): T;
130
131
/**
132
* Merges multiple source objects into target
133
* @param instance - Target object
134
* @param sources - Array of source objects
135
* @param options - Merge options
136
* @returns Merged object
137
*/
138
function mergeAll<T>(
139
instance: T,
140
sources: any[],
141
options?: ObjectMergeOptions<T>
142
): T;
143
144
/**
145
* Sets a property value on the object
146
* @param instance - Target object
147
* @param key - Property key to set
148
* @param val - Value to set
149
* @returns Modified object
150
*/
151
function set<T>(instance: T, key: string, val: any): T;
152
153
/**
154
* Executes a function with the object and returns the object
155
* @param instance - Object to tap
156
* @param tapFn - Function to execute with object
157
* @returns Original object (for chaining)
158
*/
159
function tap(instance: any, tapFn: Function): any;
160
161
interface ObjectMergeOptions<T> {
162
deep?: boolean;
163
descriptor?: boolean;
164
hidden?: boolean;
165
resolve?: boolean;
166
}
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
import Sugar from "sugar";
173
174
// Adding properties
175
const user = { name: "John" };
176
Sugar.Object.add(user, { age: 30, city: "NYC" });
177
// Result: { name: "John", age: 30, city: "NYC" }
178
179
// Deep cloning
180
const original = { user: { name: "John", scores: [1, 2, 3] } };
181
const copy = Sugar.Object.clone(original, true);
182
183
// Setting defaults
184
const config = { port: 3000 };
185
Sugar.Object.defaults(config, { host: "localhost", ssl: false });
186
// Result: { port: 3000, host: "localhost", ssl: false }
187
188
// Tapping for side effects
189
const result = Sugar.Object.tap(user, (obj) => console.log("Processing:", obj.name));
190
```
191
192
### Object Query
193
194
Methods for accessing and inspecting object properties.
195
196
```typescript { .api }
197
/**
198
* Gets a property value from the object
199
* @param instance - Object to query
200
* @param key - Property key to get
201
* @param inherited - Whether to include inherited properties
202
* @returns Property value
203
*/
204
function get<T>(instance: any, key: string, inherited?: boolean): T;
205
206
/**
207
* Tests if object has a specific property
208
* @param instance - Object to test
209
* @param key - Property key to check
210
* @param inherited - Whether to include inherited properties
211
* @returns True if property exists
212
*/
213
function has(instance: any, key: string, inherited?: boolean): boolean;
214
215
/**
216
* Returns an array of the object's property keys
217
* @param instance - Object to get keys from
218
* @returns Array of property keys
219
*/
220
function keys<T>(instance: T): string[];
221
222
/**
223
* Returns an array of the object's property values
224
* @param instance - Object to get values from
225
* @returns Array of property values
226
*/
227
function values<T>(instance: T): any[];
228
229
/**
230
* Returns the number of properties in the object
231
* @param instance - Object to count properties
232
* @returns Number of properties
233
*/
234
function size(instance: any): number;
235
236
/**
237
* Tests if the object is empty (has no enumerable properties)
238
* @param instance - Object to test
239
* @returns True if object is empty
240
*/
241
function isEmpty(instance: any): boolean;
242
```
243
244
**Usage Examples:**
245
246
```typescript
247
import Sugar from "sugar";
248
249
const user = { name: "John", age: 30, city: "NYC" };
250
251
// Getting values
252
const name = Sugar.Object.get(user, "name"); // "John"
253
const missing = Sugar.Object.get(user, "email", false); // undefined
254
255
// Checking existence
256
const hasAge = Sugar.Object.has(user, "age"); // true
257
const hasEmail = Sugar.Object.has(user, "email"); // false
258
259
// Getting keys and values
260
const userKeys = Sugar.Object.keys(user); // ["name", "age", "city"]
261
const userValues = Sugar.Object.values(user); // ["John", 30, "NYC"]
262
263
// Size and emptiness
264
const count = Sugar.Object.size(user); // 3
265
const empty = Sugar.Object.isEmpty({}); // true
266
```
267
268
### Object Filtering
269
270
Methods for selecting, excluding, and filtering object properties.
271
272
```typescript { .api }
273
/**
274
* Excludes properties that match the search criteria
275
* @param instance - Object to filter
276
* @param search - Criteria to exclude by
277
* @returns Object with excluded properties removed
278
*/
279
function exclude<T>(instance: T, search: any): T;
280
281
/**
282
* Filters properties that match the search criteria
283
* @param instance - Object to filter
284
* @param search - Criteria to filter by
285
* @returns Object with matching properties only
286
*/
287
function filter<T>(instance: T, search: any): T;
288
289
/**
290
* Rejects properties that match the pattern
291
* @param instance - Object to process
292
* @param find - Pattern to reject
293
* @returns Object with rejected properties removed
294
*/
295
function reject(instance: any, find: any): any;
296
297
/**
298
* Removes properties that match the search criteria
299
* @param instance - Object to modify
300
* @param search - Criteria for removal
301
* @returns Modified object
302
*/
303
function remove<T>(instance: T, search: any): T;
304
305
/**
306
* Selects properties that match the pattern
307
* @param instance - Object to process
308
* @param find - Pattern to select
309
* @returns Object with selected properties only
310
*/
311
function select(instance: any, find: any): any;
312
```
313
314
**Usage Examples:**
315
316
```typescript
317
import Sugar from "sugar";
318
319
const user = {
320
name: "John",
321
age: 30,
322
password: "secret",
323
email: "john@example.com"
324
};
325
326
// Filtering by function
327
const publicData = Sugar.Object.filter(user, (key, value) => key !== "password");
328
// Result: { name: "John", age: 30, email: "john@example.com" }
329
330
// Excluding specific keys
331
const withoutAge = Sugar.Object.exclude(user, ["age", "password"]);
332
// Result: { name: "John", email: "john@example.com" }
333
334
// Selecting with regex
335
const emailFields = Sugar.Object.select(user, /email/);
336
// Result: { email: "john@example.com" }
337
```
338
339
### Object Set Operations
340
341
Methods for performing set-like operations on objects.
342
343
```typescript { .api }
344
/**
345
* Returns properties that exist in both objects
346
* @param instance - First object
347
* @param obj - Second object to intersect with
348
* @returns Object containing common properties
349
*/
350
function intersect(instance: any, obj: any): any;
351
352
/**
353
* Removes properties that exist in the second object
354
* @param instance - Object to subtract from
355
* @param obj - Object containing properties to remove
356
* @returns Object with subtracted properties removed
357
*/
358
function subtract(instance: any, obj: any): any;
359
360
/**
361
* Inverts the key-value pairs of the object
362
* @param instance - Object to invert
363
* @param multi - Whether to handle multiple keys with same value
364
* @returns Object with inverted key-value pairs
365
*/
366
function invert(instance: any, multi?: boolean): any;
367
```
368
369
**Usage Examples:**
370
371
```typescript
372
import Sugar from "sugar";
373
374
const obj1 = { a: 1, b: 2, c: 3 };
375
const obj2 = { b: 2, c: 4, d: 5 };
376
377
// Intersection (common properties)
378
const common = Sugar.Object.intersect(obj1, obj2);
379
// Result: { b: 2 }
380
381
// Subtraction
382
const diff = Sugar.Object.subtract(obj1, obj2);
383
// Result: { a: 1 }
384
385
// Inversion
386
const lookup = Sugar.Object.invert({ name: "John", city: "NYC" });
387
// Result: { "John": "name", "NYC": "city" }
388
```
389
390
### Object Iteration
391
392
Methods for iterating over and testing object properties.
393
394
```typescript { .api }
395
/**
396
* Tests if all properties match the search criteria
397
* @param instance - Object to test
398
* @param search - Criteria to test against
399
* @returns True if all properties match
400
*/
401
function every<T>(instance: T, search: any): boolean;
402
403
/**
404
* Finds the first property that matches the search criteria
405
* @param instance - Object to search
406
* @param search - Criteria to search for
407
* @returns First matching property value
408
*/
409
function find<T>(instance: T, search: any): any;
410
411
/**
412
* Iterates over object properties with a callback function
413
* @param instance - Object to iterate
414
* @param eachFn - Function to call for each property
415
* @returns Original object
416
*/
417
function forEach<T>(instance: T, eachFn: Function): T;
418
419
/**
420
* Tests if no properties match the search criteria
421
* @param instance - Object to test
422
* @param search - Criteria to test against
423
* @returns True if no properties match
424
*/
425
function none<T>(instance: T, search: any): boolean;
426
427
/**
428
* Tests if some properties match the search criteria
429
* @param instance - Object to test
430
* @param search - Criteria to test against
431
* @returns True if any properties match
432
*/
433
function some<T>(instance: T, search: any): boolean;
434
435
/**
436
* Counts properties that match the search criteria
437
* @param instance - Object to count in
438
* @param search - Criteria to count
439
* @returns Number of matching properties
440
*/
441
function count<T>(instance: T, search: any): number;
442
443
/**
444
* Reduces object properties to a single value
445
* @param instance - Object to reduce
446
* @param reduceFn - Reducer function
447
* @param init - Initial value
448
* @returns Reduced value
449
*/
450
function reduce<T>(instance: T, reduceFn: Function, init?: any): any;
451
```
452
453
**Usage Examples:**
454
455
```typescript
456
import Sugar from "sugar";
457
458
const scores = { math: 95, science: 87, english: 92, history: 78 };
459
460
// Testing all properties
461
const allPassing = Sugar.Object.every(scores, (key, value) => value >= 70); // true
462
463
// Finding first match
464
const firstHigh = Sugar.Object.find(scores, (key, value) => value >= 90); // 95
465
466
// Iterating with side effects
467
Sugar.Object.forEach(scores, (key, value) => {
468
console.log(`${key}: ${value}`);
469
});
470
471
// Counting matches
472
const highScores = Sugar.Object.count(scores, (key, value) => value >= 90); // 2
473
474
// Reducing to total
475
const total = Sugar.Object.reduce(scores, (sum, key, value) => sum + value, 0); // 352
476
```
477
478
### Object Statistical
479
480
Methods for calculating statistics on object values.
481
482
```typescript { .api }
483
/**
484
* Calculates the average of object values
485
* @param instance - Object to average
486
* @param map - Optional mapping function
487
* @returns Average value
488
*/
489
function average<T,U>(instance: T, map?: Function): number;
490
491
/**
492
* Finds the minimum values in the object
493
* @param instance - Object to search
494
* @param all - Whether to return all minimum values
495
* @param map - Optional mapping function
496
* @returns Minimum value(s)
497
*/
498
function least<T,U>(instance: T, all?: boolean, map?: Function): any;
499
500
/**
501
* Finds the maximum values in the object
502
* @param instance - Object to search
503
* @param all - Whether to return all maximum values
504
* @param map - Optional mapping function
505
* @returns Maximum value(s)
506
*/
507
function max<T,U>(instance: T, all?: boolean, map?: Function): any;
508
509
/**
510
* Calculates the median of object values
511
* @param instance - Object to calculate median for
512
* @param map - Optional mapping function
513
* @returns Median value
514
*/
515
function median<T,U>(instance: T, map?: Function): number;
516
517
/**
518
* Finds the minimum values in the object
519
* @param instance - Object to search
520
* @param all - Whether to return all minimum values
521
* @param map - Optional mapping function
522
* @returns Minimum value(s)
523
*/
524
function min<T,U>(instance: T, all?: boolean, map?: Function): any;
525
526
/**
527
* Finds the maximum values in the object
528
* @param instance - Object to search
529
* @param all - Whether to return all maximum values
530
* @param map - Optional mapping function
531
* @returns Maximum value(s)
532
*/
533
function most<T,U>(instance: T, all?: boolean, map?: Function): any;
534
535
/**
536
* Calculates the sum of object values
537
* @param instance - Object to sum
538
* @param map - Optional mapping function
539
* @returns Sum of values
540
*/
541
function sum<T,U>(instance: T, map?: Function): number;
542
```
543
544
**Usage Examples:**
545
546
```typescript
547
import Sugar from "sugar";
548
549
const prices = { laptop: 999, mouse: 29, keyboard: 79, monitor: 299 };
550
551
// Statistical calculations
552
const avgPrice = Sugar.Object.average(prices); // 351.5
553
const total = Sugar.Object.sum(prices); // 1406
554
const cheapest = Sugar.Object.min(prices); // 29
555
const mostExpensive = Sugar.Object.max(prices); // 999
556
const medianPrice = Sugar.Object.median(prices); // 189
557
558
// With mapping function
559
const lengths = { short: "hi", medium: "hello", long: "hello world" };
560
const avgLength = Sugar.Object.average(lengths, (key, value) => value.length); // 6.33
561
```
562
563
### Object Type Tests
564
565
Methods for checking the type and nature of values.
566
567
```typescript { .api }
568
/**
569
* Tests if value is an arguments object
570
* @param instance - Value to test
571
* @returns True if value is arguments object
572
*/
573
function isArguments(instance: any): boolean;
574
575
/**
576
* Tests if value is an array
577
* @param instance - Value to test
578
* @returns True if value is array
579
*/
580
function isArray(instance: any): instance is any[];
581
582
/**
583
* Tests if value is a boolean
584
* @param instance - Value to test
585
* @returns True if value is boolean
586
*/
587
function isBoolean(instance: any): instance is boolean;
588
589
/**
590
* Tests if value is a Date object
591
* @param instance - Value to test
592
* @returns True if value is Date
593
*/
594
function isDate(instance: any): instance is Date;
595
596
/**
597
* Tests if value is empty (null, undefined, empty string/array/object)
598
* @param instance - Value to test
599
* @returns True if value is empty
600
*/
601
function isEmpty(instance: any): boolean;
602
603
/**
604
* Tests deep equality between two values
605
* @param instance - First value
606
* @param other - Second value to compare
607
* @returns True if values are deeply equal
608
*/
609
function isEqual(instance: any, other: any): boolean;
610
611
/**
612
* Tests if value is an Error object
613
* @param instance - Value to test
614
* @returns True if value is Error
615
*/
616
function isError(instance: any): instance is Error;
617
618
/**
619
* Tests if value is a function
620
* @param instance - Value to test
621
* @returns True if value is function
622
*/
623
function isFunction(instance: any): instance is Function;
624
625
/**
626
* Tests if value is a Map object
627
* @param instance - Value to test
628
* @returns True if value is Map
629
*/
630
function isMap(instance: any): instance is Map<any, any>;
631
632
/**
633
* Tests if value is a number
634
* @param instance - Value to test
635
* @returns True if value is number
636
*/
637
function isNumber(instance: any): instance is number;
638
639
/**
640
* Tests if value is an object (but not null or array)
641
* @param instance - Value to test
642
* @returns True if value is object
643
*/
644
function isObject(instance: any): instance is object;
645
646
/**
647
* Tests if value is a RegExp object
648
* @param instance - Value to test
649
* @returns True if value is RegExp
650
*/
651
function isRegExp(instance: any): instance is RegExp;
652
653
/**
654
* Tests if value is a Set object
655
* @param instance - Value to test
656
* @returns True if value is Set
657
*/
658
function isSet(instance: any): instance is Set<any>;
659
660
/**
661
* Tests if value is a string
662
* @param instance - Value to test
663
* @returns True if value is string
664
*/
665
function isString(instance: any): instance is string;
666
```
667
668
**Usage Examples:**
669
670
```typescript
671
import Sugar from "sugar";
672
673
// Type checking
674
const data = { items: [1, 2, 3], name: "test", count: 42 };
675
676
Sugar.Object.isArray(data.items); // true
677
Sugar.Object.isObject(data); // true
678
Sugar.Object.isString(data.name); // true
679
Sugar.Object.isNumber(data.count); // true
680
Sugar.Object.isDate(new Date()); // true
681
682
// Emptiness testing
683
Sugar.Object.isEmpty([]); // true
684
Sugar.Object.isEmpty({}); // true
685
Sugar.Object.isEmpty(""); // true
686
Sugar.Object.isEmpty(null); // true
687
Sugar.Object.isEmpty({ a: 1 }); // false
688
689
// Deep equality
690
const obj1 = { a: [1, 2], b: { c: 3 } };
691
const obj2 = { a: [1, 2], b: { c: 3 } };
692
Sugar.Object.isEqual(obj1, obj2); // true
693
694
// Function testing
695
Sugar.Object.isFunction(() => {}); // true
696
Sugar.Object.isFunction(console.log); // true
697
```
698
699
### Object Serialization
700
701
Methods for converting objects to and from serialized formats.
702
703
```typescript { .api }
704
/**
705
* Converts object to query string format
706
* @param instance - Object to serialize
707
* @param options - Serialization options
708
* @returns Query string representation
709
*/
710
function toQueryString<T,U>(
711
instance: T,
712
options?: QueryStringOptions<T,U>
713
): string;
714
715
interface QueryStringOptions<T,U> {
716
deep?: boolean;
717
prefix?: string;
718
separator?: string;
719
transform?: (key: string, value: any) => any;
720
}
721
```
722
723
**Usage Examples:**
724
725
```typescript
726
import Sugar from "sugar";
727
728
// Basic serialization
729
const params = { name: "John", age: 30, active: true };
730
const query = Sugar.Object.toQueryString(params);
731
// Result: "name=John&age=30&active=true"
732
733
// With custom separator and prefix
734
const custom = Sugar.Object.toQueryString(params, {
735
separator: ";",
736
prefix: "user"
737
});
738
739
// With transformation
740
const encoded = Sugar.Object.toQueryString(params, {
741
transform: (key, value) => {
742
if (typeof value === "boolean") {
743
return value ? "1" : "0";
744
}
745
return value;
746
}
747
});
748
// Result: "name=John&age=30&active=1"
749
750
// Deep serialization for nested objects
751
const nested = { user: { name: "John", prefs: { theme: "dark" } } };
752
const deep = Sugar.Object.toQueryString(nested, { deep: true });
753
```
754
755
## Types
756
757
```typescript { .api }
758
interface ObjectMergeOptions<T> {
759
/** Whether to perform deep merging of nested objects */
760
deep?: boolean;
761
/** Whether to copy property descriptors */
762
descriptor?: boolean;
763
/** Whether to include non-enumerable properties */
764
hidden?: boolean;
765
/** Whether to resolve conflicts using a resolution function */
766
resolve?: boolean;
767
}
768
769
interface QueryStringParseOptions<T,U> {
770
/** Whether to parse nested objects from dot notation */
771
deep?: boolean;
772
/** Custom separator for key-value pairs */
773
separator?: string;
774
/** Function to transform parsed values */
775
transform?: (key: string, value: any) => any;
776
}
777
778
interface QueryStringOptions<T,U> {
779
/** Whether to serialize nested objects using dot notation */
780
deep?: boolean;
781
/** Prefix to add to all parameter names */
782
prefix?: string;
783
/** Custom separator for key-value pairs */
784
separator?: string;
785
/** Function to transform values before serialization */
786
transform?: (key: string, value: any) => any;
787
}
788
```