@dereekb/util 13.35.0 → 13.37.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/oidc/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/oidc",
3
- "version": "13.35.0",
3
+ "version": "13.37.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.35.0"
5
+ "@dereekb/util": "13.37.0"
6
6
  },
7
7
  "exports": {
8
8
  "./package.json": "./package.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/util",
3
- "version": "13.35.0",
3
+ "version": "13.37.0",
4
4
  "sideEffects": false,
5
5
  "exports": {
6
6
  "./test": {
@@ -1,5 +1,6 @@
1
1
  export * from './object.array.delta';
2
2
  export * from './object.array';
3
+ export * from './object.copy';
3
4
  export * from './object.empty';
4
5
  export * from './object.equal';
5
6
  export * from './object.key';
@@ -0,0 +1,139 @@
1
+ import { type Maybe } from '../value/maybe.type';
2
+ import { type POJOKey } from './object';
3
+ import { type FilterKeyValueTuplesInput } from './object.filter.tuple';
4
+ /**
5
+ * How a {@link CopyValueDeepFunction} handles a value within an array that the filter removes.
6
+ *
7
+ * - `remove`: the value is left out of the copied array, shortening it.
8
+ * - `retain`: the value is copied as-is. Effectively exempts array values from filtering.
9
+ * - `nullify`: the value is replaced with `null`, retaining the array's length and indexes.
10
+ */
11
+ export type CopyValueDeepArrayValuesMode = 'remove' | 'retain' | 'nullify';
12
+ /**
13
+ * Transform applied to a value before it is filtered and copied.
14
+ *
15
+ * The transform's result is what gets recursed into, so returning an object/array from a primitive (or
16
+ * vice-versa) is allowed. The key is the key/index the value was read from, and is `undefined` for the
17
+ * root value.
18
+ */
19
+ export type CopyValueDeepTransformFunction = (value: unknown, key: Maybe<POJOKey>) => unknown;
20
+ /**
21
+ * Configuration for {@link copyValueDeep} and {@link copyValueDeepFunction}.
22
+ */
23
+ export interface CopyValueDeepConfig {
24
+ /**
25
+ * Filter that decides which key/value pairs are retained. Applied to every object and array
26
+ * encountered, at every depth.
27
+ *
28
+ * Defaults to {@link KeyValueTypleValueFilter.UNDEFINED}, which removes `undefined` values.
29
+ */
30
+ readonly filter?: FilterKeyValueTuplesInput<Record<string, unknown>>;
31
+ /**
32
+ * How a filtered value within an array is handled. Defaults to `remove`.
33
+ */
34
+ readonly arrayValues?: CopyValueDeepArrayValuesMode;
35
+ /**
36
+ * Whether an object/array that the copy leaves empty is itself filtered out of its parent.
37
+ *
38
+ * Defaults to `false`, so `{ a: { b: undefined } }` copies to `{ a: {} }`. When `true` it copies to
39
+ * `{}` instead, since the nested object carries nothing once `b` is gone.
40
+ */
41
+ readonly filterEmptyValues?: boolean;
42
+ /**
43
+ * Transform applied to each value before it is filtered and copied.
44
+ */
45
+ readonly transform?: CopyValueDeepTransformFunction;
46
+ }
47
+ /**
48
+ * Recursively copies a value, filtering values as it goes.
49
+ */
50
+ export type CopyValueDeepFunction = <T>(value: T) => T;
51
+ /**
52
+ * Creates a reusable {@link CopyValueDeepFunction}.
53
+ *
54
+ * Plain objects and arrays are copied recursively. Every other value is retained by reference:
55
+ * primitives have nothing to copy, and a `Date`/`Map`/`Set`/class instance is a value in its own right,
56
+ * not a bag of keys to rebuild — copying one key-by-key would replace a `Date` with `{}`. This is what
57
+ * makes the function safe to use on data that carries such instances (a Firestore `Timestamp`, a
58
+ * `DocumentReference`) alongside plain json.
59
+ *
60
+ * The root value itself is never filtered — only the values found within an object or array are, since
61
+ * the filter is a decision about a key/value pair. A root `undefined` therefore copies to `undefined`.
62
+ *
63
+ * Repeated and cyclical references are tracked, so a value referenced twice is copied once and a cycle
64
+ * terminates rather than overflowing the stack.
65
+ *
66
+ * @param config - Filter, array handling, and transform configuration. Defaults to removing `undefined` values.
67
+ * @returns Recursively copies any input value.
68
+ *
69
+ * @dbxUtil
70
+ * @dbxUtilCategory object
71
+ * @dbxUtilKind factory
72
+ * @dbxUtilTags object, copy, clone, deep, recursive, filter, transform, undefined, factory
73
+ * @dbxUtilRelated copy-value-deep, filter-from-pojo-function, copy-object
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * // remove undefined values at any depth
78
+ * const copyFn = copyValueDeepFunction();
79
+ * copyFn({ a: 1, b: undefined, c: { d: undefined, e: [1, undefined] } });
80
+ * // { a: 1, c: { e: [1] } }
81
+ *
82
+ * // remove null and undefined values, and prune anything left empty
83
+ * const copyCleanFn = copyValueDeepFunction({ filter: KeyValueTypleValueFilter.NULL, filterEmptyValues: true });
84
+ * copyCleanFn({ a: 1, b: { c: null } });
85
+ * // { a: 1 }
86
+ * ```
87
+ *
88
+ * @__NO_SIDE_EFFECTS__
89
+ */
90
+ export declare function copyValueDeepFunction(config?: Maybe<CopyValueDeepConfig>): CopyValueDeepFunction;
91
+ /**
92
+ * Recursively copies a value, filtering values as it goes.
93
+ *
94
+ * See {@link copyValueDeepFunction} for the copy/filter semantics. Prefer the factory when copying more
95
+ * than one value with the same configuration.
96
+ *
97
+ * @param value - The value to copy.
98
+ * @param config - Filter, array handling, and transform configuration. Defaults to removing `undefined` values.
99
+ * @returns A recursive copy of the value.
100
+ *
101
+ * @dbxUtil
102
+ * @dbxUtilCategory object
103
+ * @dbxUtilTags object, copy, clone, deep, recursive, filter, transform, undefined
104
+ * @dbxUtilRelated copy-value-deep-function, filter-from-pojo, copy-object
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * copyValueDeep({ a: 1, b: { c: undefined } });
109
+ * // { a: 1, b: {} }
110
+ * ```
111
+ */
112
+ export declare function copyValueDeep<T>(value: T, config?: Maybe<CopyValueDeepConfig>): T;
113
+ /**
114
+ * Pre-built {@link CopyValueDeepFunction} that recursively copies a value, removing every `undefined`
115
+ * value at every depth.
116
+ *
117
+ * This is the deep counterpart to {@link filterOnlyUndefinedValues}, and is what a consumer that rejects
118
+ * `undefined` outright (Firestore, `JSON.stringify` in a strict schema) needs before a write.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * copyValueWithoutUndefinedValues({ a: 1, b: undefined, c: [{ d: undefined }] });
123
+ * // { a: 1, c: [{}] }
124
+ * ```
125
+ */
126
+ export declare const copyValueWithoutUndefinedValues: CopyValueDeepFunction;
127
+ /**
128
+ * Pre-built {@link CopyValueDeepFunction} that recursively copies a value, removing every `null` and
129
+ * `undefined` value at every depth.
130
+ *
131
+ * This is the deep counterpart to {@link filterNullAndUndefinedValues}.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * copyValueWithoutNullAndUndefinedValues({ a: 1, b: null, c: [{ d: undefined }] });
136
+ * // { a: 1, c: [{}] }
137
+ * ```
138
+ */
139
+ export declare const copyValueWithoutNullAndUndefinedValues: CopyValueDeepFunction;
@@ -87,6 +87,23 @@ export declare function applyToMultipleFields<T extends object, X = unknown>(val
87
87
  export declare function mapToObject<T, K extends PropertyKey>(map: Map<K, T>): {
88
88
  [key: PropertyKey]: T;
89
89
  };
90
+ /**
91
+ * Checks whether the value is a "plain" object, meaning an object literal or an object created with a
92
+ * null prototype.
93
+ *
94
+ * Arrays, `Date`, `RegExp`, `Map`, `Set`, and class instances are NOT plain objects. This is the check
95
+ * to use before recursing into a value's keys: a class instance's keys are an implementation detail and
96
+ * copying them key-by-key produces a lifeless imitation of the original (a `Date` becomes `{}`).
97
+ *
98
+ * @param value - The value to check.
99
+ * @returns `true` if the value is an object literal or has a null prototype.
100
+ *
101
+ * @dbxUtil
102
+ * @dbxUtilCategory object
103
+ * @dbxUtilTags object, pojo, plain, literal, type-guard, check
104
+ * @dbxUtilRelated object-has-no-keys, copy-value-deep
105
+ */
106
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
90
107
  /**
91
108
  * Returns a copy of the input object.
92
109
  */
package/test/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/test",
3
- "version": "13.35.0",
3
+ "version": "13.37.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.35.0",
5
+ "@dereekb/util": "13.37.0",
6
6
  "make-error": "^1.3.6"
7
7
  },
8
8
  "exports": {