@oscarpalmer/atoms 0.180.0 → 0.181.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.
@@ -8,16 +8,29 @@ import type {ArrayOrPlainObject, NestedPartial, PlainObject} from '../models';
8
8
  * Options for merging values
9
9
  */
10
10
  export type MergeOptions = {
11
+ /**
12
+ * Assign values to the first array or object instead of creating a new one?
13
+ */
14
+ assignValues?: boolean;
11
15
  /**
12
16
  * Key _(or key epxressions)_ for values that should be replaced
17
+ *
13
18
  * ```ts
14
19
  * merge([{items: [1, 2, 3]}, {items: [99]}]); // {items: [99]}
15
20
  * ```
16
21
  */
17
22
  replaceableObjects?: string | RegExp | Array<string | RegExp>;
23
+ /**
24
+ * Skip nullable values when merging objects?
25
+ *
26
+ * ```ts
27
+ * merge({a: 1, b: 2}, {b: null, c: 3}, {d: null}); // {a: 1, b: 2, c: 3}
28
+ * ```
29
+ */
18
30
  skipNullableAny?: boolean;
19
31
  /**
20
32
  * Skip nullable values when merging arrays?
33
+ *
21
34
  * ```ts
22
35
  * merge([1, 2, 3], [null, null, 99]); // [1, 2, 99]
23
36
  * ```
@@ -35,6 +48,7 @@ export type Merger<Model extends ArrayOrPlainObject = ArrayOrPlainObject> = (
35
48
  ) => Model;
36
49
 
37
50
  type Options = {
51
+ assignValues: boolean;
38
52
  replaceableObjects: ReplaceableObjectsCallback | undefined;
39
53
  skipNullableAny: boolean;
40
54
  skipNullableInArrays: boolean;
@@ -48,6 +62,7 @@ type ReplaceableObjectsCallback = (name: string) => boolean;
48
62
 
49
63
  function getMergeOptions(options?: MergeOptions): Options {
50
64
  const actual: Options = {
65
+ assignValues: false,
51
66
  replaceableObjects: undefined,
52
67
  skipNullableAny: false,
53
68
  skipNullableInArrays: false,
@@ -59,6 +74,7 @@ function getMergeOptions(options?: MergeOptions): Options {
59
74
 
60
75
  actual.replaceableObjects = getReplaceableObjects(options.replaceableObjects);
61
76
 
77
+ actual.assignValues = options.assignValues === true;
62
78
  actual.skipNullableAny = options.skipNullableAny === true;
63
79
  actual.skipNullableInArrays = options.skipNullableInArrays === true;
64
80
 
@@ -132,7 +148,7 @@ function mergeObjects(
132
148
  ): ArrayOrPlainObject {
133
149
  const {length} = values;
134
150
  const isArray = values.every(Array.isArray);
135
- const merged = (isArray ? [] : {}) as PlainObject;
151
+ const merged = (options.assignValues ? values[0] : isArray ? [] : {}) as PlainObject;
136
152
 
137
153
  for (let outerIndex = 0; outerIndex < length; outerIndex += 1) {
138
154
  const item = values[outerIndex] as PlainObject;
@@ -0,0 +1,36 @@
1
+ import {isNonPlainObject} from '../is';
2
+ import type {PlainObject} from '../models';
3
+
4
+ // #region Types
5
+
6
+ export type Shaken<Value extends PlainObject> = {
7
+ [Key in keyof Value]: Value[Key] extends undefined ? never : Value[Key];
8
+ };
9
+
10
+ // #endregion
11
+
12
+ // #region Functions
13
+
14
+ export function shake<Value extends PlainObject>(value: Value): Shaken<Value> {
15
+ const shaken: PlainObject = {};
16
+
17
+ if (isNonPlainObject(value)) {
18
+ return shaken as Shaken<Value>;
19
+ }
20
+
21
+ const keys = Object.keys(value) as (keyof Value)[];
22
+ const {length} = keys;
23
+
24
+ for (let index = 0; index < length; index += 1) {
25
+ const key = keys[index];
26
+ const val = value[key];
27
+
28
+ if (val !== undefined) {
29
+ shaken[key] = val;
30
+ }
31
+ }
32
+
33
+ return shaken as Shaken<Value>;
34
+ }
35
+
36
+ // #endregion