nhb-toolbox 4.26.66 → 4.26.69

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/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ All notable changes to the package will be documented here.
6
6
 
7
7
  ---
8
8
 
9
+ ## [4.26.69] - 2025-11-18
10
+
11
+ - **Updated** *return type* of `sanitizeData` utility:
12
+ - **Fixed** *return type* when keys are ignored by *removing those keys* using `SanitizedData`, `OmitPath` and other new `type helpers`.
13
+ - **Fixed** the *return type* when it is called with `_return = 'partial'` parameter by *making all the nested properties optional*.
14
+ - **Created** new *utility type* `$DeepPartial` to satisfy this *return type*.
15
+
9
16
  ## [4.26.66] - 2025-11-17
10
17
 
11
18
  - **Changed** the signature of `Chronos` `get()` method to `get<Unit extends TimeUnit>(unit: Unit): TimeUnitValue<Unit>` to align with `set()` method.
@@ -1,5 +1,5 @@
1
- import type { Any, FlattenPartial, PartialOrRequired } from '../types/index';
2
- import type { GenericObject, SanitizeOptions } from './types';
1
+ import type { Any, PartialOrRequired } from '../types/index';
2
+ import type { DotNotationKey, GenericObject, SanitizedData, SanitizeOptions } from './types';
3
3
  /**
4
4
  * * Trims all the words in a string.
5
5
  *
@@ -23,7 +23,7 @@ export declare function sanitizeData(input: string[]): string[];
23
23
  * @param _return - By default return type is as it is, passing this parameter `true` makes the return type `Partial<T>`.
24
24
  * @returns A new object with the specified modifications.
25
25
  */
26
- export declare function sanitizeData<T extends GenericObject, B extends PartialOrRequired = 'required'>(object: T, options?: SanitizeOptions<T>, _return?: B): B extends 'partial' ? FlattenPartial<T> : T;
26
+ export declare function sanitizeData<Data extends GenericObject, Ignored extends DotNotationKey<Data> = never, PoR extends PartialOrRequired = 'required'>(object: Data, options?: SanitizeOptions<Data, Ignored>, _return?: PoR): SanitizedData<Data, Ignored, PoR>;
27
27
  /**
28
28
  * * Sanitizes a deeply nested array that may contain arrays, objects or other (mixed) data types.
29
29
  * * Preserves structure while removing empty values and trimming strings and other operations.
@@ -33,7 +33,7 @@ export declare function sanitizeData<T extends GenericObject, B extends PartialO
33
33
  * @param _return - By default return type is as it is, passing this parameter `partial` makes the return type `Partial<T>`.
34
34
  * @returns A new sanitized array with the specified modifications.
35
35
  */
36
- export declare function sanitizeData<T extends GenericObject, B extends PartialOrRequired = 'required'>(array: T[], options?: SanitizeOptions<T>, _return?: B): B extends 'partial' ? FlattenPartial<T>[] : T[];
36
+ export declare function sanitizeData<Data extends GenericObject, Ignored extends DotNotationKey<Data> = never, PoR extends PartialOrRequired = 'required'>(array: Data[], options?: SanitizeOptions<Data, Ignored>, _return?: PoR): Array<SanitizedData<Data, Ignored, PoR>>;
37
37
  /**
38
38
  * * Parse an object of stringified values into their appropriate primitive types.
39
39
  *
@@ -1,5 +1,5 @@
1
- import type { AdvancedTypes, NormalPrimitive, ValidArray } from '../types/index';
2
- import type { $UnionToIntersection, Prettify, Split, Tuple } from '../utils/types';
1
+ import type { AdvancedTypes, NormalPrimitive, PartialOrRequired, ValidArray } from '../types/index';
2
+ import type { $DeepPartial, $UnionToIntersection, Prettify, Split, Tuple } from '../utils/types';
3
3
  import type { COUNTRIES } from './countries';
4
4
  /** - Generic object with `unknown` value */
5
5
  export type StrictObject = Record<string, unknown>;
@@ -103,13 +103,13 @@ export type DeepKeys<T extends GenericObject> = T extends AdvancedTypes ? never
103
103
  /** - Converts the union of keys from {@link DeepKeys<T>} into a tuple. */
104
104
  export type DeepKeysTuple<T extends GenericObject> = Tuple<DeepKeys<T>>;
105
105
  /** - Options for `sanitizeData` utility. */
106
- export interface SanitizeOptions<T> {
106
+ export interface SanitizeOptions<T, Ignored extends DotNotationKey<T>> {
107
107
  /**
108
108
  * An array of dot-notation keys to exclude from the sanitized output.
109
109
  * This is only applicable when sanitizing plain objects or arrays of objects.
110
110
  * When applied to nested or irregular array structures, behavior may be inconsistent or partially ignored.
111
111
  */
112
- keysToIgnore?: DotNotationKey<T>[];
112
+ keysToIgnore?: Ignored[];
113
113
  /** Whether to trim string values. Defaults to `true`. */
114
114
  trimStrings?: boolean;
115
115
  /** Whether to exclude nullish (`null` or `undefined`) values. Defaults to `false`. */
@@ -125,6 +125,85 @@ export interface SanitizeOptions<T> {
125
125
  */
126
126
  requiredKeys?: '*' | DotNotationKey<T>[];
127
127
  }
128
+ /**
129
+ * * Produces sanitized output data by omitting keys in `keysToIgnore` from {@link SanitizeOptions} and optionally applying partial deep nesting based on `_return` parameter.
130
+ *
131
+ * @remarks
132
+ * - When `PoR` is `'partial'`, all nested properties become optional after path omission.
133
+ * - When `PoR` is `'required'`, the resulting type keeps full property requirements.
134
+ * - Intended for return type of `sanitizeData` utility.
135
+ */
136
+ export type SanitizedData<Data extends GenericObject, Ignored extends DotNotationKey<Data>, PoR extends PartialOrRequired> = PoR extends 'partial' ? $DeepPartial<OmitPath<Data, Ignored>> : OmitPath<Data, Ignored>;
137
+ /**
138
+ * * Extracts only the string keys from an object type.
139
+ *
140
+ * @remarks
141
+ * - Useful when iterating over object keys inside template-literal-based utility types,
142
+ * because TypeScript may include `symbol` keys in `keyof T`, which cannot be used in
143
+ * template literal types.
144
+ * - By filtering to `string`, all keys become safe for path operations.
145
+ *
146
+ * @example
147
+ * type A = { a: number; b: string; 1: boolean; [Symbol.iterator]: () => void };
148
+ * type Keys = ExtractStringKey<A>;
149
+ * // Result: "a" | "b"
150
+ */
151
+ export type ExtractStringKey<T> = Extract<keyof T, string>;
152
+ /**
153
+ * * Joins a parent key and a child key into a dot-notation path.
154
+ *
155
+ * @remarks
156
+ * - If the parent path is an empty string, the child key is returned as-is.
157
+ * - Otherwise, the function produces `"parent.child"` formatting.
158
+ *
159
+ * @example
160
+ * type A = $JoinDotKey<'', 'user'>; // "user"
161
+ * type B = $JoinDotKey<'settings', 'theme'>; // "settings.theme"
162
+ */
163
+ export type $JoinDotKey<Parent extends string, Key extends string> = Parent extends '' ? Key : `${Parent}.${Key}`;
164
+ /**
165
+ * * Checks whether a dot-notation path starts with the specified prefix.
166
+ *
167
+ * @remarks
168
+ * A path is considered a match if it is **exactly equal** to the prefix, or begins with `"prefix."`.
169
+ *
170
+ * @example
171
+ * type A = $DoesPathStartWith<'settings.timeout', 'settings'>; // true
172
+ * type B = $DoesPathStartWith<'settings', 'settings'>; // true
173
+ * type C = $DoesPathStartWith<'user.name', 'settings'>; // false
174
+ */
175
+ export type $DoesPathStartWith<Path extends string, Prefix extends string> = Path extends Prefix | `${Prefix}.${string}` ? true : false;
176
+ /** Recursive utility that removes a specific dot-notation path from an object. */
177
+ type $OmitPath<T extends GenericObject, I extends string, P extends string = ''> = Prettify<{
178
+ [K in ExtractStringKey<T> as $DoesPathStartWith<$JoinDotKey<P, K>, I> extends true ? never : K]: T[K] extends GenericObject ? T[K] extends AdvancedTypes ? T[K] : $OmitPath<T[K], I, $JoinDotKey<P, K>> : T[K];
179
+ }>;
180
+ /**
181
+ * * Removes a dot-notation path from an object type while preserving its original shape.
182
+ *
183
+ * @remarks
184
+ * - It excludes the specified dot path, but **retains the full structure** of the parent object.
185
+ * - Only the targeted property is removed.
186
+ *
187
+ * @example
188
+ * type Input = {
189
+ * settings: {
190
+ * timeout: number;
191
+ * theme: string;
192
+ * };
193
+ * version: string;
194
+ * };
195
+ *
196
+ * type Clean = OmitPath<Input, "settings.timeout">;
197
+ *
198
+ * // Result:
199
+ * // {
200
+ * // settings: {
201
+ * // theme: string;
202
+ * // };
203
+ * // version: string;
204
+ * // }
205
+ */
206
+ export type OmitPath<Object extends GenericObject, Ignored extends DotNotationKey<Object>> = $OmitPath<Object, Ignored>;
128
207
  /** Options for `convertObjectValues` utility */
129
208
  export interface ConvertObjectOptions<T extends GenericObject, Key extends NumericDotKey<T>, C extends 'string' | 'number'> {
130
209
  /** Array of keys (properties) to convert to `number` or `string` */
@@ -75,28 +75,45 @@ export type KeysOfUnion<T> = T extends T ? keyof T : never;
75
75
  * * Recursively makes all potential standard js object properties optional.
76
76
  *
77
77
  * @remarks
78
- * - It excludes complex types like `Array`, `Map`, `File`, `Date`, `Chronos` etc. from being recursively partial.
79
- * - Please, refer to {@link AdvancedTypes} to learn more about these complex types.
78
+ * - It excludes keys of complex types like `Array`, `Map`, `File`, `Date`, `Chronos` etc. from being recursively partial.
79
+ * - Please, refer to {@link AdvancedTypes} to allow these complex types.
80
+ * - Also refer to {@link $DeepPartial} for less strict version.
80
81
  *
81
82
  * @example
82
83
  * type Config = { a: string; nested: { b: number } };
83
84
  * type PartialConfig = DeepPartial<Config>;
84
85
  * // { a?: string; nested?: { b?: number } }
85
86
  */
86
- export type DeepPartial<T> = {
87
+ export type DeepPartial<T> = Prettify<{
87
88
  [K in keyof T]?: T[K] extends AdvancedTypes ? T[K] : T[K] extends object ? DeepPartial<T[K]> : T[K];
88
- };
89
+ }>;
90
+ /**
91
+ * * Recursively makes all potential standard js object (also object in array) properties optional.
92
+ *
93
+ * @remarks
94
+ * - It excludes keys of complex types like `Map`, `File`, `Date`, `Chronos` etc. from being recursively partial.
95
+ * - Please, refer to {@link AdvancedTypes} to allow these complex types.
96
+ * - Also refer to {@link DeepPartial} for more strict version.
97
+ *
98
+ * @example
99
+ * type Config = { a: string; nested: { b: number }[] };
100
+ * type PartialConfig = $DeepPartial<Config>;
101
+ * // { a?: string; nested?: { b?: number; }[]; }
102
+ */
103
+ export type $DeepPartial<T> = Prettify<{
104
+ [K in keyof T]?: T[K] extends Array<infer El> ? Array<$DeepPartial<El>> : T[K] extends AdvancedTypes ? T[K] : $DeepPartial<T[K]>;
105
+ }>;
89
106
  /**
90
107
  * * Recursively makes all properties in any object or array type optional.
91
108
  *
92
109
  * @example
93
110
  * type Config = { a: string; nested: { b: number } };
94
- * type PartialConfig = DeepPartial<Config>;
111
+ * type PartialConfig = DeepPartialAll<Config>;
95
112
  * // { a?: string; nested?: { b?: number } }
96
113
  */
97
- export type DeepPartialAll<T> = T extends Array<infer El> ? Array<DeepPartialAll<El>> : {
114
+ export type DeepPartialAll<T> = T extends Array<infer El> ? Array<DeepPartialAll<El>> : Prettify<{
98
115
  [K in keyof T]?: DeepPartialAll<T[K]>;
99
- };
116
+ }>;
100
117
  /**
101
118
  * * Removes `readonly` modifiers from all properties of an object type.
102
119
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "4.26.66",
3
+ "version": "4.26.69",
4
4
  "description": "A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",