nhb-toolbox 4.12.26 → 4.12.27

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,11 @@ All notable changes to this package will be documented in this file.
6
6
 
7
7
  ---
8
8
 
9
+ ## [4.12.27] - 2025-06-02
10
+
11
+ - Updated [README](README.md).
12
+ - Added new utility types, can be imported from `'nhb-toolbox/utils/types'`.
13
+
9
14
  ## [4.12.25-26] - 2025-06-02
10
15
 
11
16
  - Updated JSDoc for some `Chronos` methods and exposed `INTERNALS` Symbol
package/README.md CHANGED
@@ -72,6 +72,8 @@ See [Changelog](CHANGELOG.md) for recent updates.
72
72
 
73
73
  The ultimate date/time manipulation class with 100+ methods for parsing, formatting, calculating, and comparing dates. Handles all edge cases and timezones safely.
74
74
 
75
+ > 🧩 **Note**: Some methods in `Chronos` are available only through the [plugin system](https://nhb-toolbox.vercel.app/docs/classes/Chronos/plugins#-official-plugins). This modular design ensures the core bundle stays lightweight — plugins are loaded only when needed, reducing unnecessary code in your final build.
76
+
75
77
  ```typescript
76
78
  new Chronos('2025-01-01').addDays(3).format('YYYY-MM-DD'); // "2025-01-04"
77
79
  ```
@@ -134,6 +136,37 @@ getColorForInitial('Banana', 50); // '#00376E80' (50% opacity)
134
136
 
135
137
  [Documentation →](https://nhb-toolbox.vercel.app/docs/utilities/color/getColorForInitial)
136
138
 
139
+ ### FormData Preparation
140
+
141
+ Convert JavaScript objects into `FormData` with extensive configuration options for handling nested structures, files, and data transformations.
142
+
143
+ ```typescript
144
+ import { createFormData } from 'nhb-toolbox';
145
+
146
+ const formData = createFormData({
147
+ user: {
148
+ name: ' John Doe ',
149
+ age: 30,
150
+ preferences: { theme: 'dark' }
151
+ },
152
+ files: [file1, file2]
153
+ }, {
154
+ trimStrings: true,
155
+ lowerCaseValues: ['user.name'],
156
+ dotNotateNested: ['user.preferences'],
157
+ breakArray: ['files']
158
+ });
159
+
160
+ // Resulting FormData:
161
+ // user.name=john doe
162
+ // user.age=30
163
+ // user.preferences.theme=dark
164
+ // files[0]=[File1]
165
+ // files[1]=[File2]
166
+ ```
167
+
168
+ [Documentation →](https://nhb-toolbox.vercel.app/docs/utilities/form/createFormData)
169
+
137
170
  ### 🛡️ **Sanitize Data**
138
171
 
139
172
  Clean and normalize strings/objects by trimming whitespace, removing empty values, and applying customizable filters.
@@ -38,4 +38,163 @@ export interface PageListOptions {
38
38
  /** Number of siblings pages to show around the current page (default 1). */
39
39
  siblingCount?: number;
40
40
  }
41
+ /**
42
+ * * Extracts the union of all property value types from a given object type.
43
+ *
44
+ * @example
45
+ * type Colors = { primary: string; secondary: string; id: number; };
46
+ * type ColorValues = ValueOf<Colors>; // string | number
47
+ */
48
+ export type ValueOf<T> = T[keyof T];
49
+ /**
50
+ * * Gets all keys from a union of object types.
51
+ *
52
+ * @example
53
+ * type A = { a: string };
54
+ * type B = { b: number };
55
+ * type Union = A | B;
56
+ * type Keys = KeysOfUnion<Union>; // "a" | "b"
57
+ */
58
+ export type KeysOfUnion<T> = T extends T ? keyof T : never;
59
+ /**
60
+ * * Recursively makes all properties in an object type optional.
61
+ *
62
+ * @example
63
+ * type Config = { a: string; nested: { b: number } };
64
+ * type PartialConfig = DeepPartial<Config>;
65
+ * // { a?: string; nested?: { b?: number } }
66
+ */
67
+ export type DeepPartial<T> = {
68
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
69
+ };
70
+ /**
71
+ * * Removes `readonly` modifiers from all properties of an object type.
72
+ *
73
+ * @example
74
+ * type ReadonlyObj = { readonly id: number };
75
+ * type WritableObj = Mutable<ReadonlyObj>;
76
+ * // { id: number }
77
+ */
78
+ export type Mutable<T> = {
79
+ -readonly [K in keyof T]: T[K];
80
+ };
81
+ /**
82
+ * * Recursively adds `readonly` to all properties of an object type.
83
+ *
84
+ * @example
85
+ * type State = { user: { id: number } };
86
+ * type ReadonlyState = Immutable<State>;
87
+ * // { readonly user: { readonly id: number } }
88
+ */
89
+ export type Immutable<T> = {
90
+ readonly [K in keyof T]: Immutable<T[K]>;
91
+ };
92
+ /**
93
+ * * Combines two object types. In case of conflicts, keys from `U` override `T`.
94
+ *
95
+ * @example
96
+ * type A = { id: number; name: string };
97
+ * type B = { name: boolean; active: boolean };
98
+ * type Merged = Merge<A, B>;
99
+ * // { id: number; name: boolean; active: boolean }
100
+ */
101
+ export type Merge<T, U> = {
102
+ [K in keyof T | keyof U]: K extends keyof U ? U[K] : K extends keyof T ? T[K] : never;
103
+ };
104
+ /**
105
+ * * Omits properties from an object type whose value types match `ValueType`.
106
+ *
107
+ * @example
108
+ * type Model = { id: number; name: string; hidden: boolean };
109
+ * type VisibleModel = OmitByValue<Model, boolean>;
110
+ * // { id: number; name: string }
111
+ */
112
+ export type OmitByValue<T, ValueType> = {
113
+ [K in keyof T as T[K] extends ValueType ? never : K]: T[K];
114
+ };
115
+ /**
116
+ * * Makes only the specified keys in a type required; others remain optional.
117
+ *
118
+ * @example
119
+ * type User = { id?: number; name?: string };
120
+ * type UserWithId = RequireOnly<User, 'id'>;
121
+ * // { id: number; name?: string }
122
+ */
123
+ export type RequireOnly<T, K extends keyof T> = Partial<T> & Required<Pick<T, K>>;
124
+ /**
125
+ * * Forces TypeScript to simplify a complex or inferred type into a more readable flat object.
126
+ *
127
+ * *Useful when working with utility types like `Merge`, `Omit`, etc., that produce deeply nested or unresolved intersections.*
128
+ *
129
+ * @example
130
+ * type A = { a: number };
131
+ * type B = { b: string };
132
+ * type Merged = A & B;
133
+ * type Pretty = Prettify<Merged>;
134
+ * // Type will now display as: { a: number; b: string }
135
+ */
136
+ export type Prettify<T> = {
137
+ [K in keyof T]: T[K];
138
+ } & {};
139
+ /**
140
+ * * Broadens a literal union (typically `string` or `number`) to also accept any other value of the base type, without losing IntelliSense autocomplete for the provided literals.
141
+ *
142
+ * *This is especially useful in API design where you want to provide suggestions for common options but still allow flexibility for custom user-defined values.*
143
+ *
144
+ * @example
145
+ * // ✅ String literal usage
146
+ * type Variant = LooseLiteral<'primary' | 'secondary'>;
147
+ * const v1: Variant = 'primary'; // suggested
148
+ * const v2: Variant = 'custom'; // also valid
149
+ *
150
+ * // ✅ Number literal usage
151
+ * type StatusCode = LooseLiteral<200 | 404 | 500>;
152
+ * const s1: StatusCode = 200; // suggested
153
+ * const s2: StatusCode = 999; // also valid
154
+ *
155
+ * // ✅ Mixed literal
156
+ * type Mixed = LooseLiteral<'one' | 2>;
157
+ * const m1: Mixed = 'one'; // ✅
158
+ * const m2: Mixed = 2; // ✅
159
+ * const m3: Mixed = 'anything'; // ✅
160
+ * const m4: Mixed = 123; // ✅
161
+ *
162
+ * @note Technically, this uses intersection with primitive base types (`string & {}` or `number & {}`) to retain IntelliSense while avoiding type narrowing.
163
+ */
164
+ export type LooseLiteral<T extends string | number> = T | (T extends string ? string & {} : number & {});
165
+ /**
166
+ * * Extracts an object type containing only the optional keys from `T`.
167
+ *
168
+ * @template T - The original object type
169
+ * @returns A new object type with only optional keys from `T`
170
+ * @example
171
+ * type Example = { a: string; b?: number; c?: boolean };
172
+ * type OptionalPart = OptionalShape<Example>;
173
+ * // { b?: number; c?: boolean }
174
+ */
175
+ export type OptionalShape<T> = {
176
+ [K in keyof T as {} extends Pick<T, K> ? K : never]?: T[K];
177
+ };
178
+ /**
179
+ * * Extracts an object type containing only the required keys from `T`.
180
+ *
181
+ * @template T - The original object type
182
+ * @returns A new object type with only required keys from `T`
183
+ * @example
184
+ * type Example = { a: string; b?: number; c: boolean };
185
+ * type RequiredPart = RequiredShape<Example>;
186
+ * // { a: string; c: boolean }
187
+ */
188
+ export type RequiredShape<T> = {
189
+ [K in keyof T as {} extends Pick<T, K> ? never : K]: T[K];
190
+ };
191
+ /**
192
+ * * Converts a readonly tuple to a union of its element types.
193
+ *
194
+ * @template T - A tuple type (must be readonly if using `as const`)
195
+ * @example
196
+ * const roles = ['admin', 'user', 'guest'] as const;
197
+ * type Role = TupleToUnion<typeof roles>; // "admin" | "user" | "guest"
198
+ */
199
+ export type TupleToUnion<T extends readonly unknown[]> = T[number];
41
200
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAChC,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,yBAAyB;AACzB,MAAM,WAAW,aAAa;IAC7B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;CACf;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GAAG,IAAI,CACjC,aAAa,EACb,YAAY,GAAG,cAAc,GAAG,aAAa,CAC7C,CAAC;AAEF,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC/B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "4.12.26",
3
+ "version": "4.12.27",
4
4
  "description": "A versatile collection of smart, efficient, and reusable utility functions and classes for everyday development needs.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",